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
Its control flow was confusing before; now it's much more
straightforward. We make a string representing classes of words, split
that by a regular expression for number words, then parse each number
and build up our return string and list. It works just as well as the
previous method, is a bit shorter, and I feel that it's clearer as well.
It wasn't actually guaranteed, it turns out. I was iterating over
dictionary keys, which is done in arbitrary order. The result was that
in different executions of the program, the corpus was generated
differently, so the hashes differed, and the language had to be updated.
Sorting the keys before adding them to the list of number-words fixed
the problem.
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.
This fork is called Kaylee, not Blather. Let's at least be consistent
with referring to the program as Kaylee, even if the code is still in
blather.py.
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.