Bläddra i källkod

Update language automatically on startup

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.
Clara Hobbs 8 år sedan
förälder
incheckning
900a3d8d2f
2 ändrade filer med 70 tillägg och 28 borttagningar
  1. 66
    24
      blather.py
  2. 4
    4
      recognizer.py

+ 66
- 24
blather.py Visa fil

5
 # Copyright 2013 Jezra
5
 # Copyright 2013 Jezra
6
 # Copyright 2015 Clayton G. Hobbs
6
 # Copyright 2015 Clayton G. Hobbs
7
 
7
 
8
+from __future__ import print_function
8
 import sys
9
 import sys
9
 import signal
10
 import signal
10
-from gi.repository import GObject
11
+import hashlib
11
 import os.path
12
 import os.path
12
 import subprocess
13
 import subprocess
13
 from optparse import OptionParser
14
 from optparse import OptionParser
15
+from gi.repository import GObject
14
 try:
16
 try:
15
     import yaml
17
     import yaml
16
 except:
18
 except:
17
-    print "YAML is not supported. ~/.config/blather/options.yaml will not function"
19
+    print("YAML is not supported; unable to use config file")
18
 
20
 
19
 from recognizer import Recognizer
21
 from recognizer import Recognizer
20
 
22
 
25
 strings_file = os.path.join(conf_dir, "sentences.corpus")
27
 strings_file = os.path.join(conf_dir, "sentences.corpus")
26
 history_file = os.path.join(conf_dir, "blather.history")
28
 history_file = os.path.join(conf_dir, "blather.history")
27
 opt_file = os.path.join(conf_dir, "options.yaml")
29
 opt_file = os.path.join(conf_dir, "options.yaml")
28
-lang_file = os.path.join(lang_dir,'lm')
29
-dic_file = os.path.join(lang_dir,'dic')
30
+hash_file = os.path.join(conf_dir, "hash.yaml")
31
+lang_file = os.path.join(lang_dir, 'lm')
32
+dic_file = os.path.join(lang_dir, 'dic')
30
 # Make the lang_dir if it doesn't exist
33
 # Make the lang_dir if it doesn't exist
31
 if not os.path.exists(lang_dir):
34
 if not os.path.exists(lang_dir):
32
     os.makedirs(lang_dir)
35
     os.makedirs(lang_dir)
34
 class Blather:
37
 class Blather:
35
 
38
 
36
     def __init__(self, opts):
39
     def __init__(self, opts):
37
-        # Import the recognizer so Gst doesn't clobber our -h
38
         self.ui = None
40
         self.ui = None
39
         self.options = {}
41
         self.options = {}
40
         ui_continuous_listen = False
42
         ui_continuous_listen = False
48
         # Load the options file
50
         # Load the options file
49
         self.load_options()
51
         self.load_options()
50
 
52
 
51
-        # Merge the opts
52
-        for k,v in opts.__dict__.items():
53
+        # Merge the options with the ones provided by command-line arguments
54
+        for k, v in opts.__dict__.items():
53
             if (not k in self.options) or opts.override:
55
             if (not k in self.options) or opts.override:
54
                 self.options[k] = v
56
                 self.options[k] = v
55
 
57
 
59
             elif self.options['interface'] == "gt":
61
             elif self.options['interface'] == "gt":
60
                 from gtktrayui import UI
62
                 from gtktrayui import UI
61
             else:
63
             else:
62
-                print "no GUI defined"
64
+                print("no GUI defined")
63
                 sys.exit()
65
                 sys.exit()
64
 
66
 
65
             self.ui = UI(args, self.options['continuous'])
67
             self.ui = UI(args, self.options['continuous'])
76
         if self.options['history']:
78
         if self.options['history']:
77
             self.history = []
79
             self.history = []
78
 
80
 
81
+        # Update the language if necessary
82
+        self.update_language()
83
+
79
         # Create the recognizer
84
         # Create the recognizer
80
         try:
85
         try:
81
             self.recognizer = Recognizer(lang_file, dic_file, self.options['microphone'])
86
             self.recognizer = Recognizer(lang_file, dic_file, self.options['microphone'])
82
-        except Exception, e:
83
-            #no recognizer? bummer
84
-            print 'error making recognizer'
87
+        except Exception as e:
88
+            # No recognizer? bummer
89
+            print('error making recognizer')
85
             sys.exit()
90
             sys.exit()
86
 
91
 
87
         self.recognizer.connect('finished', self.recognizer_finished)
92
         self.recognizer.connect('finished', self.recognizer_finished)
88
 
93
 
89
-        print "Using Options: ", self.options
94
+        print("Using Options: ", self.options)
90
 
95
 
91
     def read_commands(self):
96
     def read_commands(self):
92
         # Read the commands file
97
         # Read the commands file
93
         file_lines = open(command_file)
98
         file_lines = open(command_file)
94
         strings = open(strings_file, "w")
99
         strings = open(strings_file, "w")
95
         for line in file_lines:
100
         for line in file_lines:
96
-            print line
101
+            print(line)
97
             # Trim the white spaces
102
             # Trim the white spaces
98
             line = line.strip()
103
             line = line.strip()
99
             # If the line has length and the first char isn't a hash
104
             # If the line has length and the first char isn't a hash
100
             if len(line) and line[0]!="#":
105
             if len(line) and line[0]!="#":
101
                 # This is a parsible line
106
                 # This is a parsible line
102
-                (key,value) = line.split(":",1)
103
-                print key, value
107
+                (key, value) = line.split(":", 1)
108
+                print(key, value)
104
                 self.commands[key.strip().lower()] = value.strip()
109
                 self.commands[key.strip().lower()] = value.strip()
105
                 strings.write( key.strip()+"\n")
110
                 strings.write( key.strip()+"\n")
106
         # Close the strings file
111
         # Close the strings file
107
         strings.close()
112
         strings.close()
108
 
113
 
109
     def load_options(self):
114
     def load_options(self):
115
+        """If possible, load options from the options.yaml file"""
110
         # Is there an opt file?
116
         # Is there an opt file?
111
         try:
117
         try:
112
             opt_fh = open(opt_file)
118
             opt_fh = open(opt_file)
113
             text = opt_fh.read()
119
             text = opt_fh.read()
114
             self.options = yaml.load(text)
120
             self.options = yaml.load(text)
115
         except:
121
         except:
122
+            # Do nothing if the options file cannot be loaded
116
             pass
123
             pass
117
 
124
 
118
-
119
-    def log_history(self,text):
125
+    def log_history(self, text):
120
         if self.options['history']:
126
         if self.options['history']:
121
             self.history.append(text)
127
             self.history.append(text)
122
             if len(self.history) > self.options['history']:
128
             if len(self.history) > self.options['history']:
130
             # Close the file
136
             # Close the file
131
             hfile.close()
137
             hfile.close()
132
 
138
 
139
+    def update_language(self):
140
+        """Update the language if its hash has changed"""
141
+        try:
142
+            # Load the stored hash from the hash file
143
+            try:
144
+                with open(hash_file, 'r') as f:
145
+                    text = f.read()
146
+                    hashes = yaml.load(text)
147
+                stored_hash = hashes['language']
148
+            except (IOError, KeyError, TypeError):
149
+                # No stored hash
150
+                stored_hash = ''
151
+
152
+            # Calculate the hash the language file has right now
153
+            hasher = hashlib.sha256()
154
+            with open(strings_file, 'rb') as sfile:
155
+                buf = sfile.read()
156
+                hasher.update(buf)
157
+            new_hash = hasher.hexdigest()
158
+
159
+            # If the hashes differ
160
+            if stored_hash != new_hash:
161
+                # Update the language
162
+                # FIXME: Do this with Python, not Bash
163
+                self.run_command('./language_updater.sh')
164
+                # Store the new hash
165
+                new_hashes = {'language': new_hash}
166
+                with open(hash_file, 'w') as f:
167
+                    f.write(yaml.dump(new_hashes))
168
+        except Exception as e:
169
+            # Do nothing if the hash file cannot be loaded
170
+            # FIXME: This is kind of bad; maybe YAML should be mandatory.
171
+            print('error updating language')
172
+            print(e)
173
+            pass
174
+
133
     def run_command(self, cmd):
175
     def run_command(self, cmd):
134
-        '''Print the command, then run it'''
135
-        print cmd
176
+        """Print the command, then run it"""
177
+        print(cmd)
136
         subprocess.call(cmd, shell=True)
178
         subprocess.call(cmd, shell=True)
137
 
179
 
138
     def recognizer_finished(self, recognizer, text):
180
     def recognizer_finished(self, recognizer, text):
154
             # Run the invalid_sentence_command if there is an invalid sentence command
196
             # Run the invalid_sentence_command if there is an invalid sentence command
155
             if self.options['invalid_sentence_command']:
197
             if self.options['invalid_sentence_command']:
156
                 subprocess.call(self.options['invalid_sentence_command'], shell=True)
198
                 subprocess.call(self.options['invalid_sentence_command'], shell=True)
157
-            print "no matching command %s" % t
199
+            print("no matching command {0}".format(t))
158
         # If there is a UI and we are not continuous listen
200
         # If there is a UI and we are not continuous listen
159
         if self.ui:
201
         if self.ui:
160
             if not self.continuous_listen:
202
             if not self.continuous_listen:
173
         sys.exit()
215
         sys.exit()
174
 
216
 
175
     def process_command(self, UI, command):
217
     def process_command(self, UI, command):
176
-        print command
218
+        print(command)
177
         if command == "listen":
219
         if command == "listen":
178
             self.recognizer.listen()
220
             self.recognizer.listen()
179
         elif command == "stop":
221
         elif command == "stop":
187
         elif command == "quit":
229
         elif command == "quit":
188
             self.quit()
230
             self.quit()
189
 
231
 
190
-    def load_resource(self,string):
232
+    def load_resource(self, string):
191
         local_data = os.path.join(os.path.dirname(__file__), 'data')
233
         local_data = os.path.join(os.path.dirname(__file__), 'data')
192
-        paths = ["/usr/share/blather/","/usr/local/share/blather", local_data]
234
+        paths = ["/usr/share/blather/", "/usr/local/share/blather", local_data]
193
         for path in paths:
235
         for path in paths:
194
             resource = os.path.join(path, string)
236
             resource = os.path.join(path, string)
195
             if os.path.exists( resource ):
237
             if os.path.exists( resource ):
247
     try:
289
     try:
248
         main_loop.run()
290
         main_loop.run()
249
     except:
291
     except:
250
-        print "time to quit"
292
+        print("time to quit")
251
         main_loop.quit()
293
         main_loop.quit()
252
         sys.exit()
294
         sys.exit()
253
 
295
 

+ 4
- 4
recognizer.py Visa fil

32
         cmd = audio_src+' ! audioconvert ! audioresample ! pocketsphinx name=asr ! appsink sync=false'
32
         cmd = audio_src+' ! audioconvert ! audioresample ! pocketsphinx name=asr ! appsink sync=false'
33
         try:
33
         try:
34
             self.pipeline=Gst.parse_launch( cmd )
34
             self.pipeline=Gst.parse_launch( cmd )
35
-        except Exception, e:
36
-            print e.message
37
-            print "You may need to install gstreamer1.0-pocketsphinx"
35
+        except Exception as e:
36
+            print(e.message)
37
+            print("You may need to install gstreamer1.0-pocketsphinx")
38
             raise e
38
             raise e
39
 
39
 
40
         bus = self.pipeline.get_bus()
40
         bus = self.pipeline.get_bus()
63
         # If we have a final command, send it for processing
63
         # If we have a final command, send it for processing
64
         command = msg_struct.get_string('hypothesis')
64
         command = msg_struct.get_string('hypothesis')
65
         if command != '' and msg_struct.get_boolean('final')[1]:
65
         if command != '' and msg_struct.get_boolean('final')[1]:
66
-	    self.emit("finished", command)
66
+            self.emit("finished", command)

Laddar…
Avbryt
Spara