-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathdfly-loader-wsr.py
148 lines (110 loc) · 4.29 KB
/
dfly-loader-wsr.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#
# This file is a command-module for Dragonfly.
# (c) Copyright 2008 by Christo Butcher
# Licensed under the LGPL, see <http://www.gnu.org/licenses/>
#
"""
Command-module loader for WSR
=============================
This script can be used to look Dragonfly command-modules
for use with Window Speech Recognition. It scans the
directory it's in and loads any ``*.py`` it finds.
"""
import time
import os.path
import logging
import pythoncom
from dragonfly.engines.backend_sapi5.engine import Sapi5InProcEngine
#---------------------------------------------------------------------------
# Set up basic logging.
logging.basicConfig(level=logging.DEBUG)
logging.getLogger("compound.parse").setLevel(logging.INFO)
#---------------------------------------------------------------------------
# Command module class; wraps a single command-module.
class CommandModule(object):
_log = logging.getLogger("module")
def __init__(self, path):
self._path = os.path.abspath(path)
self._namespace = None
self._loaded = False
def __str__(self):
return "%s(%r)" % (self.__class__.__name__,
os.path.basename(self._path))
def load(self):
self._log.info("%s: Loading module: '%s'" % (self, self._path))
# Prepare namespace in which to execute the
namespace = {}
namespace["__file__"] = self._path
# Attempt to execute the module; handle any exceptions.
try:
execfile(self._path, namespace)
except Exception, e:
self._log.error("%s: Error loading module: %s" % (self, e))
self._loaded = False
return
self._loaded = True
self._namespace = namespace
def unload(self):
self._log.info("%s: Unloading module: '%s'" % (self, self._path))
def check_freshness(self):
pass
#---------------------------------------------------------------------------
# Command module directory class.
class CommandModuleDirectory(object):
_log = logging.getLogger("directory")
def __init__(self, path, excludes=None):
self._path = os.path.abspath(path)
self._excludes = excludes
self._modules = {}
def load(self):
valid_paths = self._get_valid_paths()
# Remove any deleted modules.
for path, module in self._modules.items():
if path not in valid_paths:
del self._modules[path]
module.unload()
# Add any new modules.
for path in valid_paths:
if path not in self._modules:
module = CommandModule(path)
module.load()
self._modules[path] = module
else:
module = self._modules[path]
module.check_freshness()
def _get_valid_paths(self):
self._log.info("Looking for command modules here: %s" % (self._path,))
valid_paths = []
for filename in os.listdir(self._path):
path = os.path.abspath(os.path.join(self._path, filename))
if not os.path.isfile(path):
continue
if not os.path.splitext(path)[1] == ".py":
continue
if path in self._excludes:
continue
valid_paths.append(path)
self._log.info("Valid paths: %s" % (", ".join(valid_paths),))
return valid_paths
#---------------------------------------------------------------------------
# Main event driving loop.
def main():
logging.basicConfig(level=logging.INFO)
try:
path = os.path.dirname(__file__)
except NameError:
# The "__file__" name is not always available, for example
# when this module is run from PythonWin. In this case we
# simply use the current working directory.
path = os.getcwd()
__file__ = os.path.join(path, "dfly-loader-wsr.py")
engine = Sapi5InProcEngine()
engine.connect()
directory = CommandModuleDirectory(path, excludes=[__file__])
directory.load()
engine.speak('beginning loop!')
while 1:
pythoncom.PumpWaitingMessages()
time.sleep(.1)
if __name__ == "__main__":
main()