There's no reason that continuous_stop should be a different command
from stop. Sending a stop command when in continuous listen mode would
confuse matters, so preventing that from happening at all is beneficial.
Finally, some sort of built-in TTS support. When a plugin emits a "tts"
signal, the Kaylee object will receive it and speak the given text
aloud. It even stops listening while it speaks to prevent Kaylee from
talking to herself. If no TTS is configured, it will print the text
instead, but since a default TTS setting is provided in the new
options.json.tmp, that shouldn't happen much.
Currently there's no way for the shell plugin to use TTS. The D-Bus
interface will change that once I get around to making it. Speaking of
D-Bus, UIs are broken again and I'm sure I can fix them once they're
separate processes talking to Kaylee by D-Bus.
After listening to HPR 1284 today, I realized that it's important to
keep configuration of what Kaylee *does* separate from other
configuration. Specifically, once TTS integration is done, voice
configuration will need to be separate from configuration of actions,
because it's common to have several computers with the same actions but
different voices. Therefore, I've moved all configuration about plugins
into a new file called plugins.json.
Now the Kaylee object handles the invalid_sentence_command as well. It
does this by having the last handler for the recognizer's 'finished'
signal. If this handler is ever run, the voice command was obviously
not wanted by any of the plugins, so the invalid_sentence_command should
be run.
Also, I fixed the UIs to work as before. It's a temporary fix!
The plugins shouldn't be in charge of running the
valid_sentence_command. They also certainly shouldn't have to manage
the history file. Both of these functions have been delegated to the
Kaylee object, by way of a 'processed' signal emitted by a plugin as
soon as it knows it will handle the voice command.
As part of the effort for resolving #12, I've started work on a plugin
API for Kaylee. While very much a work in progress, it will allow
Python plugins to be written, loaded from user configuration, and
hooked in to events from necessary portions of Kaylee to handle voice
commands.
Currently there is only one plugin, a partial implementation of shell
command support as existed previously. It works in that it executes
commands, but several old features are missing. Also, the GUIs are
probably broken, but I'm not worried about that at the moment.
This makes pocketsphinx pick up way fewer false-positives of single
number-words as recognised sentences. It doesn't seem to make any
difference in anything else, but fewer false-positives is always nice.
They still need work of course, since I'm a programmer and not an
artist. The new icons of course are Kaylee's parasol, and anyone who
doesn't know that needs to watch Firefly.
Now we check a hash of the voice commands before writing the strings
file to reduce how much we write to the hard disk. In implementing
this, I realized that some code was being duplicated in an easily
fixable way, so I created a Hasher object that keeps track of the
hash.json file.
Resolves #6
See commands.tmp for an example. It's pretty neat, but it could still
use some work. I thought of a really clever way to parse numbers, better
than the one I came up with last night, but since I have a working
implementation now I figure I'd better commit it.
We have a new bug which causes the dictionary to be updated every time the
program starts. I hope I didn't force that to happen last night or
something, but I have a vague feeling I did.
At the same time, I moved the logic to check if the language should be
updated into the new LanguageUpdater class. The README has been updated
to reflect the fact that you no longer need to do any of this manually
ever.
Paths of important files and directories are part of the program's
configuration, no?
We're making better use of XDG paths now. Only configuration-y things
go in $XDG_CONFIG_HOME now, with cache-y and data-y things going in the
appropriate places instead of just being crammed in with configuration.
Removed a bunch of print statements that looked like they were added for
debugging, then never removed.
Reorganized GStreamer pipeline code so that all configuration is done
when the pipeline is created.
The configuration file is now properly overridden by argument parsing.
This was accomplished by loading the config file, then treating the
specified options as a namespace for the ArgumentParser. This makes
things from the config file get overridden iff they were specified on
the command line (not simply from defaults set in the ArgumentParser).
Hashes are now stored in hash.json, not hash.yaml. Also, we use the XDG
configuration directory rather than assuming we should use ~/.config/.
Maybe I should also make use of XDG data and/or cache directories.
Mostly working for the options file now. Still some difficulty with
command-line arguments, though; they're overriding the config file even
when not specified. If I made them simply not get stored at all when
not specified, there would be further problems when a configuration file
is not present. Maybe I should make a whole new class to handle this.
Personally, I don't see a point to a switch that must be turned on to
make all other switches work at all. It's a confusing behaviour that
made me think I somehow broke the GUIs.
We now have a hash.yaml file which contains a SHA256 hash of
sentences.corpus. If this differs from the hash the file calculated
when Kaylee sarts, the language is updated and the new hash is stored in
hash.yaml.
Removed QT interface, renamed interfaces to Kaylee
I'm a GTK man myself. I don't know if I have Python QT bindings
installed on any of my computers. It follows then that I would not
maintain the QT interface well, let alone use it at all. It has
therefore been removed to avoid having someone try to use it only to
find that it's broken.
Gotta keep that stuff up-to-date, yo. Pocketsphinx changed so it needs
GStreamer 1.0, and that required rewriting everything to use GObject
Introspection instead of the old, static Python bindings for GObject.