Included accessible_output2 fixed
This commit is contained in:
parent
33df4b5a39
commit
6e35d6b5d4
@ -1,19 +1,23 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
import ctypes
|
import ctypes
|
||||||
import os
|
import os
|
||||||
import types
|
import types
|
||||||
from platform_utils import paths
|
from platform_utils import paths
|
||||||
|
|
||||||
def load_library(libname):
|
def load_library(libname, cdll=False):
|
||||||
if paths.is_frozen():
|
if paths.is_frozen():
|
||||||
libfile = os.path.join(paths.embedded_data_path(), 'accessible_output2', 'lib', libname)
|
libfile = os.path.join(paths.embedded_data_path(), 'accessible_output2', 'lib', libname)
|
||||||
else:
|
else:
|
||||||
libfile = os.path.join(paths.module_path(), 'lib', libname)
|
libfile = os.path.join(paths.module_path(), 'lib', libname)
|
||||||
return ctypes.windll[libfile]
|
if cdll:
|
||||||
|
return ctypes.cdll[libfile]
|
||||||
|
else:
|
||||||
|
return ctypes.windll[libfile]
|
||||||
|
|
||||||
def get_output_classes():
|
def get_output_classes():
|
||||||
import outputs
|
from . import outputs
|
||||||
module_type = types.ModuleType
|
module_type = types.ModuleType
|
||||||
classes = [m.output_class for m in outputs.__dict__.itervalues() if type(m) == module_type and hasattr(m, 'output_class')]
|
classes = [m.output_class for m in outputs.__dict__.values() if type(m) == module_type and hasattr(m, 'output_class')]
|
||||||
return sorted(classes, key=lambda c: c.priority)
|
return sorted(classes, key=lambda c: c.priority)
|
||||||
|
|
||||||
def find_datafiles():
|
def find_datafiles():
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -1,14 +1,20 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
import platform
|
import platform
|
||||||
if platform.system() == 'Windows':
|
if platform.system() == 'Windows':
|
||||||
import nvda
|
from . import nvda
|
||||||
import jaws
|
from . import jaws
|
||||||
import window_eyes
|
from . import sapi5
|
||||||
import system_access
|
from . import window_eyes
|
||||||
import dolphin
|
from . import system_access
|
||||||
import pc_talker
|
from . import dolphin
|
||||||
elif platform.system() == "Darwin":
|
from . import pc_talker
|
||||||
import voiceover
|
#import sapi4
|
||||||
elif platform.system() == "Linux":
|
|
||||||
import speechDispatcher
|
|
||||||
|
|
||||||
import auto
|
if platform.system() == 'Darwin':
|
||||||
|
from . import voiceover
|
||||||
|
from . import say
|
||||||
|
|
||||||
|
if platform.system() == 'Linux':
|
||||||
|
from . import e_speak
|
||||||
|
|
||||||
|
from . import auto
|
||||||
|
@ -1,24 +1,17 @@
|
|||||||
import platform
|
from __future__ import absolute_import
|
||||||
import accessible_output2
|
import accessible_output2
|
||||||
from base import Output, OutputError
|
from .base import Output, OutputError
|
||||||
|
|
||||||
class Auto(Output):
|
class Auto(Output):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
if platform.system() == "Darwin":
|
output_classes = accessible_output2.get_output_classes()
|
||||||
import voiceover
|
self.outputs = []
|
||||||
self.outputs = [voiceover.VoiceOver()]
|
for output in output_classes:
|
||||||
elif platform.system() == "Linux":
|
try:
|
||||||
import speechDispatcher
|
self.outputs.append(output())
|
||||||
self.outputs = [speechDispatcher.SpeechDispatcher()]
|
except OutputError:
|
||||||
elif platform.system() == "Windows":
|
pass
|
||||||
output_classes = accessible_output2.get_output_classes()
|
|
||||||
self.outputs = []
|
|
||||||
for output in output_classes:
|
|
||||||
try:
|
|
||||||
self.outputs.append(output())
|
|
||||||
except OutputError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_first_available_output(self):
|
def get_first_available_output(self):
|
||||||
for output in self.outputs:
|
for output in self.outputs:
|
||||||
@ -40,3 +33,8 @@ class Auto(Output):
|
|||||||
output = self.get_first_available_output()
|
output = self.get_first_available_output()
|
||||||
if output:
|
if output:
|
||||||
output.speak(*args, **kwargs)
|
output.speak(*args, **kwargs)
|
||||||
|
|
||||||
|
def is_system_output(self):
|
||||||
|
output = self.get_first_available_output()
|
||||||
|
if output:
|
||||||
|
return output.is_system_output()
|
||||||
|
@ -5,27 +5,43 @@ class OutputError(Exception):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
class Output(object):
|
class Output(object):
|
||||||
name = "Unnamed Output" #The name of this output
|
name = "Unnamed Output"
|
||||||
lib32 = None #name of 32-bit lib
|
lib32 = None
|
||||||
lib64 = None #name of 64-bit lib
|
lib64 = None
|
||||||
priority = 100 #Where to sort in the list of available outputs for automaticly speaking
|
argtypes = {}
|
||||||
|
cdll = False
|
||||||
|
priority = 100
|
||||||
|
system_output = False
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
is_32bit = platform.architecture()[0] == "32bit"
|
self.is_32bit = platform.architecture()[0] == "32bit"
|
||||||
if self.lib32 and is_32bit:
|
if self.lib32 and self.is_32bit:
|
||||||
self.lib = load_library(self.lib32)
|
self.lib = load_library(self.lib32, cdll=self.cdll)
|
||||||
elif self.lib64:
|
elif self.lib64:
|
||||||
self.lib = load_library(self.lib64)
|
self.lib = load_library(self.lib64, cdll=self.cdll)
|
||||||
|
else:
|
||||||
|
self.lib = None
|
||||||
|
if self.lib is not None:
|
||||||
|
for func in self.argtypes:
|
||||||
|
try:
|
||||||
|
getattr(self.lib, func).argtypes = self.argtypes[func]
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
def output(self, text, **options):
|
def output(self, text, **options):
|
||||||
output = False
|
output = False
|
||||||
if hasattr(self, 'speak') and callable(self.speak):
|
if self.speak(text, **options):
|
||||||
self.speak(text, **options)
|
|
||||||
output = True
|
output = True
|
||||||
if hasattr(self, 'braille') and callable(self.braille):
|
if self.braille(text, **options):
|
||||||
self.braille(text, **options)
|
|
||||||
output = True
|
output = True
|
||||||
if not output:
|
if not output:
|
||||||
raise RuntimeError("Output %r does not have any method defined to output" % self)
|
raise RuntimeError("Output %r does not have any method defined to output" % self)
|
||||||
|
|
||||||
|
def is_system_output(self):
|
||||||
|
return self.system_output
|
||||||
|
|
||||||
|
def speak(self, **optiont):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def braille(self, *args, **options):
|
||||||
|
return False
|
||||||
|
@ -1,19 +1,25 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
import os
|
import os
|
||||||
|
import ctypes
|
||||||
|
|
||||||
from base import Output
|
from .base import Output
|
||||||
|
|
||||||
class Dolphin (Output):
|
class Dolphin (Output):
|
||||||
"""Supports dolphin products."""
|
"""Supports dolphin products."""
|
||||||
|
|
||||||
name = 'Dolphin'
|
name = 'Dolphin'
|
||||||
lib32 = 'dolapi.dll'
|
lib32 = 'dolapi.dll'
|
||||||
|
argtypes = {
|
||||||
|
'DolAccess_Command': (ctypes.c_wchar_p, ctypes.c_int, ctypes.c_int),
|
||||||
|
'DolAccess_Action': (ctypes.c_int,),
|
||||||
|
}
|
||||||
|
|
||||||
def speak(self, text, interrupt=0):
|
def speak(self, text, interrupt=0):
|
||||||
if interrupt:
|
if interrupt:
|
||||||
self.silence()
|
self.silence()
|
||||||
#If we don't call this, the API won't let us speak.
|
#If we don't call this, the API won't let us speak.
|
||||||
if self.is_active():
|
if self.is_active():
|
||||||
self.lib.DolAccess_Command(unicode(text), (len(text)*2)+2, 1)
|
self.lib.DolAccess_Command(text, (len(text)*2)+2, 1)
|
||||||
|
|
||||||
def silence(self):
|
def silence(self):
|
||||||
self.lib.DolAccess_Action(141)
|
self.lib.DolAccess_Action(141)
|
||||||
|
31
src/accessible_output2/outputs/e_speak.py
Normal file
31
src/accessible_output2/outputs/e_speak.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
|
from .base import Output
|
||||||
|
|
||||||
|
try:
|
||||||
|
import espeak.core
|
||||||
|
except:
|
||||||
|
raise RuntimeError("Cannot find espeak.core. Please install python-espeak")
|
||||||
|
|
||||||
|
class ESpeak(Output):
|
||||||
|
"""Speech output supporting ESpeak on Linux
|
||||||
|
Note this requires python-espeak to be installed
|
||||||
|
This can be done on Debian distros by using apt-get install python-espeak
|
||||||
|
Or through this tarball: https://launchpad.net/python-espeak
|
||||||
|
"""
|
||||||
|
name = "Linux ESpeak"
|
||||||
|
|
||||||
|
def is_active(self):
|
||||||
|
try:
|
||||||
|
import espeak.core
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def speak(self, text, interrupt = 0):
|
||||||
|
if interrupt:
|
||||||
|
self.silence()
|
||||||
|
espeak.core.synth(text)
|
||||||
|
def silence(self):
|
||||||
|
espeak.core.cancel()
|
||||||
|
|
||||||
|
output_class = ESpeak
|
@ -1,8 +1,9 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
import win32gui
|
import win32gui
|
||||||
from libloader.com import load_com
|
from libloader.com import load_com
|
||||||
import pywintypes
|
import pywintypes
|
||||||
|
|
||||||
from base import Output, OutputError
|
from .base import Output, OutputError
|
||||||
|
|
||||||
class Jaws (Output):
|
class Jaws (Output):
|
||||||
"""Output supporting the Jaws for Windows screen reader."""
|
"""Output supporting the Jaws for Windows screen reader."""
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
import ctypes
|
||||||
|
|
||||||
from platform_utils import paths
|
from platform_utils import paths
|
||||||
from libloader import load_library
|
from libloader import load_library
|
||||||
from base import Output
|
from .base import Output
|
||||||
|
|
||||||
class NVDA(Output):
|
class NVDA(Output):
|
||||||
"""Supports The NVDA screen reader"""
|
"""Supports The NVDA screen reader"""
|
||||||
name = "NVDA"
|
name = "NVDA"
|
||||||
lib32 = 'nvdaControllerClient32.dll'
|
lib32 = 'nvdaControllerClient32.dll'
|
||||||
lib64 = 'nvdaControllerClient64.dll'
|
lib64 = 'nvdaControllerClient64.dll'
|
||||||
|
argtypes = {
|
||||||
|
'nvdaController_brailleMessage': (ctypes.c_wchar_p,),
|
||||||
|
'nvdaController_speakText': (ctypes.c_wchar_p,),
|
||||||
|
}
|
||||||
|
|
||||||
def is_active(self):
|
def is_active(self):
|
||||||
try:
|
try:
|
||||||
@ -18,12 +24,12 @@ class NVDA(Output):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def braille(self, text, **options):
|
def braille(self, text, **options):
|
||||||
self.lib.nvdaController_brailleMessage(unicode(text))
|
self.lib.nvdaController_brailleMessage(text)
|
||||||
|
|
||||||
def speak(self, text, interrupt=False):
|
def speak(self, text, interrupt=False):
|
||||||
if interrupt:
|
if interrupt:
|
||||||
self.silence()
|
self.silence()
|
||||||
self.lib.nvdaController_speakText(unicode(text))
|
self.lib.nvdaController_speakText(text)
|
||||||
|
|
||||||
def silence(self):
|
def silence(self):
|
||||||
self.lib.nvdaController_cancelSpeech()
|
self.lib.nvdaController_cancelSpeech()
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
import ctypes
|
import ctypes
|
||||||
from base import Output
|
from .base import Output
|
||||||
|
|
||||||
class PCTalker(Output):
|
class PCTalker(Output):
|
||||||
lib32 = 'pctkusr.dll'
|
lib32 = 'pctkusr.dll'
|
||||||
lib64 = 'pctkusr64.dll'
|
lib64 = 'pctkusr64.dll'
|
||||||
|
cdll = True
|
||||||
|
argtypes = {
|
||||||
|
'PCTKPRead': (ctypes.c_char_p, ctypes.c_int, ctypes.c_int)
|
||||||
|
}
|
||||||
|
|
||||||
def speak(self, text, interrupt=False):
|
def speak(self, text, interrupt=False):
|
||||||
if interrupt:
|
if interrupt:
|
||||||
self.silence()
|
self.silence()
|
||||||
self.lib.PCTKPRead(text.encode('cp932', 'replace'))
|
self.lib.PCTKPRead(text.encode('cp932', 'replace'), 0, 1)
|
||||||
|
|
||||||
def silence(self):
|
def silence(self):
|
||||||
self.lib.PCTKVReset()
|
self.lib.PCTKVReset()
|
||||||
|
143
src/accessible_output2/outputs/sapi4.py
Normal file
143
src/accessible_output2/outputs/sapi4.py
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
|
from builtins import range
|
||||||
|
from libloader.com import load_com
|
||||||
|
from .base import Output
|
||||||
|
|
||||||
|
import logging
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class Sapi4(Output):
|
||||||
|
|
||||||
|
name = 'sapi4'
|
||||||
|
priority = 102
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
sapi4 = load_com("{EEE78591-FE22-11D0-8BEF-0060081841DE}")
|
||||||
|
self._voiceNo = sapi4.Find(0)
|
||||||
|
sapi4.Select(self._voiceNo)
|
||||||
|
sapi4.Speak(" ")
|
||||||
|
self.__object = sapi4
|
||||||
|
self._voice_list = self._available_voices()
|
||||||
|
|
||||||
|
def _set_capabilities(self):
|
||||||
|
sapi4 = self.__object
|
||||||
|
try:
|
||||||
|
sapi4.Pitch = sapi4.Pitch
|
||||||
|
self._min_pitch = sapi4.MinPitch
|
||||||
|
self._max_pitch = sapi4.MaxPitch
|
||||||
|
self._has_pitch = True
|
||||||
|
except:
|
||||||
|
self._min_pitch = 0
|
||||||
|
self._max_pitch = 0
|
||||||
|
self._has_pitch = False
|
||||||
|
try:
|
||||||
|
sapi4.Speed = sapi4.Speed
|
||||||
|
self._min_rate = sapi4.MinSpeed
|
||||||
|
self._max_rate = sapi4.MaxSpeed
|
||||||
|
self._has_rate = True
|
||||||
|
except:
|
||||||
|
self._min_rate = 0
|
||||||
|
self._max_rate = 0
|
||||||
|
self._has_rate = False
|
||||||
|
try:
|
||||||
|
sapi4.VolumeLeft = sapi4.VolumeLeft
|
||||||
|
self._min_volume = sapi4.MinVolumeLeft
|
||||||
|
self._max_volume = sapi4.MaxVolumeLeft
|
||||||
|
self._has_volume = True
|
||||||
|
except:
|
||||||
|
self._min_volume = 0
|
||||||
|
self._max_volume = 0
|
||||||
|
self._has_volume = False
|
||||||
|
|
||||||
|
def _available_voices(self):
|
||||||
|
voice_list = []
|
||||||
|
for voice_no in range(1, self.__object.CountEngines):
|
||||||
|
voice_list.append(self.__object.ModeName(voice_no))
|
||||||
|
return voice_list
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available_voices(self):
|
||||||
|
return self._voice_list
|
||||||
|
|
||||||
|
def list_voices(self):
|
||||||
|
return self.available_voices
|
||||||
|
|
||||||
|
def get_voice(self):
|
||||||
|
return self.__object.ModeName(self._voice_no)
|
||||||
|
|
||||||
|
def set_voice(self, value):
|
||||||
|
self._voice_no = self.list_voices().index(value) + 1
|
||||||
|
self.__object.Select(self._voice_no)
|
||||||
|
self.silence()
|
||||||
|
self.__object.Speak(" ")
|
||||||
|
self._set_capabilities()
|
||||||
|
|
||||||
|
def get_pitch(self):
|
||||||
|
if self.has_pitch:
|
||||||
|
return self.__object.Pitch
|
||||||
|
|
||||||
|
def set_pitch(self, value):
|
||||||
|
if self.has_pitch:
|
||||||
|
self.__object.Pitch = value
|
||||||
|
|
||||||
|
def get_rate(self):
|
||||||
|
if self.has_rate:
|
||||||
|
return self.__object.Speed
|
||||||
|
|
||||||
|
def set_rate(self, value):
|
||||||
|
if self.has_rate:
|
||||||
|
self.__object.Speed = value
|
||||||
|
|
||||||
|
def get_volume(self):
|
||||||
|
if self.has_volume:
|
||||||
|
return self.__object.VolumeLeft
|
||||||
|
|
||||||
|
def set_volume(self, value):
|
||||||
|
if self.has_volume:
|
||||||
|
self.__object.VolumeLeft = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def has_pitch(self):
|
||||||
|
return self._has_pitch
|
||||||
|
|
||||||
|
@property
|
||||||
|
def has_rate(self):
|
||||||
|
return self._has_rate
|
||||||
|
|
||||||
|
@property
|
||||||
|
def has_volume(self):
|
||||||
|
return self._has_volume
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_pitch(self):
|
||||||
|
return self._min_pitch
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_pitch(self):
|
||||||
|
return self._max_pitch
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_rate(self):
|
||||||
|
return self._min_rate
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_rate(self):
|
||||||
|
return self._max_rate
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_volume(self):
|
||||||
|
return self._min_volume
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_volume(self):
|
||||||
|
return self._max_volume
|
||||||
|
|
||||||
|
def speak(self, text, interrupt=False):
|
||||||
|
if interrupt:
|
||||||
|
self.silence()
|
||||||
|
self.__object.Speak(text)
|
||||||
|
|
||||||
|
def silence(self):
|
||||||
|
self.__object.AudioReset()
|
||||||
|
|
||||||
|
output_class = Sapi4
|
95
src/accessible_output2/outputs/sapi5.py
Normal file
95
src/accessible_output2/outputs/sapi5.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
|
from collections import OrderedDict
|
||||||
|
from libloader.com import load_com
|
||||||
|
from .base import Output, OutputError
|
||||||
|
import pywintypes
|
||||||
|
import logging
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
SVSFDefault = 0
|
||||||
|
SVSFlagsAsync = 1
|
||||||
|
SVSFPurgeBeforeSpeak = 2
|
||||||
|
SVSFIsFilename = 4
|
||||||
|
SVSFIsXML = 8
|
||||||
|
SVSFIsNotXML = 16
|
||||||
|
SVSFPersistXML = 32
|
||||||
|
|
||||||
|
class SAPI5(Output):
|
||||||
|
has_volume = True
|
||||||
|
has_rate = True
|
||||||
|
has_pitch = True
|
||||||
|
min_pitch = -10
|
||||||
|
max_pitch = 10
|
||||||
|
min_rate = -10
|
||||||
|
max_rate = 10
|
||||||
|
min_volume = 0
|
||||||
|
max_volume = 100
|
||||||
|
name = "sapi5"
|
||||||
|
priority = 101
|
||||||
|
system_output = True
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
try:
|
||||||
|
self.object = load_com("SAPI.SPVoice")
|
||||||
|
self._voices = self._available_voices()
|
||||||
|
except pywintypes.com_error:
|
||||||
|
raise OutputError
|
||||||
|
self._pitch = 0
|
||||||
|
|
||||||
|
def _available_voices(self):
|
||||||
|
_voices = OrderedDict()
|
||||||
|
for v in self.object.GetVoices():
|
||||||
|
_voices[v.GetDescription()] = v
|
||||||
|
return _voices
|
||||||
|
|
||||||
|
def list_voices(self):
|
||||||
|
return list(self._voices.keys())
|
||||||
|
|
||||||
|
def get_voice(self):
|
||||||
|
return self.object.Voice.GetDescription()
|
||||||
|
|
||||||
|
def set_voice(self, value):
|
||||||
|
log.debug("Setting SAPI5 voice to \"%s\"" % value)
|
||||||
|
self.object.Voice = self._voices[value]
|
||||||
|
# For some reason SAPI5 does not reset audio after changing the voice
|
||||||
|
# By setting the audio device after changing voices seems to fix this
|
||||||
|
# This was noted from information at:
|
||||||
|
# http://lists.nvaccess.org/pipermail/nvda-dev/2011-November/022464.html
|
||||||
|
self.object.AudioOutput = self.object.AudioOutput
|
||||||
|
|
||||||
|
def get_pitch(self):
|
||||||
|
return self._pitch
|
||||||
|
|
||||||
|
def set_pitch(self, value):
|
||||||
|
log.debug("Setting pitch to %d" % value)
|
||||||
|
self._pitch = value
|
||||||
|
|
||||||
|
def get_rate(self):
|
||||||
|
return self.object.Rate
|
||||||
|
|
||||||
|
def set_rate(self, value):
|
||||||
|
log.debug("Setting rate to %d" % value)
|
||||||
|
self.object.Rate = value
|
||||||
|
|
||||||
|
def get_volume(self):
|
||||||
|
return self.object.Volume
|
||||||
|
|
||||||
|
def set_volume(self, value):
|
||||||
|
self.object.Volume = value
|
||||||
|
|
||||||
|
def speak(self, text, interrupt=False):
|
||||||
|
if interrupt:
|
||||||
|
self.silence()
|
||||||
|
# We need to do the pitch in XML here
|
||||||
|
textOutput = "<pitch absmiddle=\"%d\">%s</pitch>" % (round(self._pitch), text.replace("<", "<"))
|
||||||
|
self.object.Speak(textOutput, SVSFlagsAsync | SVSFIsXML)
|
||||||
|
|
||||||
|
def silence(self):
|
||||||
|
self.object.Speak("", SVSFlagsAsync | SVSFPurgeBeforeSpeak)
|
||||||
|
|
||||||
|
def is_active(self):
|
||||||
|
if self.object:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
output_class = SAPI5
|
21
src/accessible_output2/outputs/say.py
Normal file
21
src/accessible_output2/outputs/say.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
|
import os
|
||||||
|
from .base import Output
|
||||||
|
|
||||||
|
class AppleSay(Output):
|
||||||
|
"""Speech output supporting the Apple Say subsystem."""
|
||||||
|
name = 'Apple Say'
|
||||||
|
def __init__(self, voice = 'Alex', rate = '300'):
|
||||||
|
self.voice = voice
|
||||||
|
self.rate = rate
|
||||||
|
super(AppleSay, self).__init__()
|
||||||
|
def is_active(self):
|
||||||
|
return not os.system('which say')
|
||||||
|
def speak(self, text, interrupt = 0):
|
||||||
|
if interrupt:
|
||||||
|
self.silence()
|
||||||
|
os.system('say -v %s -r %s "%s" &' % (self.voice, self.rate, text))
|
||||||
|
def silence(self):
|
||||||
|
os.system('killall say')
|
||||||
|
|
||||||
|
output_class = AppleSay
|
@ -1,29 +0,0 @@
|
|||||||
from base import Output, OutputError
|
|
||||||
import atexit
|
|
||||||
import application
|
|
||||||
class SpeechDispatcher(Output):
|
|
||||||
"""Supports speech dispatcher on Linux.
|
|
||||||
Note that this module will use the configuration of speech dispatcher, the user will need to configure the voice, language, punctuation and rate before using this module.
|
|
||||||
"""
|
|
||||||
name = 'SpeechDispatcher'
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(SpeechDispatcher, self).__init__(*args, **kwargs)
|
|
||||||
try:
|
|
||||||
import speechd
|
|
||||||
self.spd = speechd.SSIPClient(application.name)
|
|
||||||
except ImportError:
|
|
||||||
raise OutputError
|
|
||||||
atexit.register(self.on_exit_event)
|
|
||||||
|
|
||||||
def speak(self, text, interupt=False):
|
|
||||||
if interupt == True:
|
|
||||||
self.spd.cancel()
|
|
||||||
self.spd.speak(text)
|
|
||||||
|
|
||||||
def is_active(self):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def on_exit_event(self):
|
|
||||||
self.spd.close()
|
|
||||||
del self.spd
|
|
@ -1,18 +0,0 @@
|
|||||||
# Copyright (C) 2001, 2002 Brailcom, o.p.s.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
from .client import *
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
|||||||
SPD_SPAWN_CMD = "/usr/bin/speech-dispatcher"
|
|
@ -1,18 +1,24 @@
|
|||||||
from base import Output
|
from __future__ import absolute_import
|
||||||
|
import ctypes
|
||||||
|
from .base import Output
|
||||||
|
|
||||||
class SystemAccess (Output):
|
class SystemAccess (Output):
|
||||||
"""Supports System Access and System Access Mobile"""
|
"""Supports System Access and System Access Mobile"""
|
||||||
|
|
||||||
name = "System Access"
|
name = "System Access"
|
||||||
lib32 = 'saapi32.dll'
|
lib32 = 'saapi32.dll'
|
||||||
|
argtypes = {
|
||||||
|
'SA_BrlShowTextW': (ctypes.c_wchar_p,),
|
||||||
|
'SA_SayW': (ctypes.c_wchar_p,),
|
||||||
|
}
|
||||||
priority = 99
|
priority = 99
|
||||||
|
|
||||||
def braille(self, text, **options):
|
def braille(self, text, **options):
|
||||||
self.lib.SA_BrlShowTextW(unicode(text))
|
self.lib.SA_BrlShowTextW(text)
|
||||||
|
|
||||||
def speak(self, text, interrupt=False):
|
def speak(self, text, interrupt=False):
|
||||||
if self.is_active():
|
if self.is_active():
|
||||||
self.dll.SA_SayW(unicode(text))
|
self.dll.SA_SayW(str(text))
|
||||||
|
|
||||||
def is_active(self):
|
def is_active(self):
|
||||||
try:
|
try:
|
||||||
|
@ -1,23 +1 @@
|
|||||||
from base import Output, OutputError
|
from __future__ import absolute_import
from builtins import str
import subprocess, os
from .base import Output
class VoiceOver(Output):
"""Speech output supporting the Apple VoiceOver screen reader."""
def runAppleScript(self, command, process = 'voiceover'):
return subprocess.Popen(['osascript', '-e', 'tell application "' + process + '"\n' + command + '\nend tell'], stdout = subprocess.PIPE).communicate()[0]
name = 'VoiceOver'
def speak(self, text, interrupt=0):
if interrupt:
self.silence()
os.system('osascript -e \"tell application \\\"voiceover\\\" to output \\\"%s\\\"\" &' % text)
def silence (self):
self.runAppleScript('output ""')
def is_active(self):
return self.runAppleScript('return (name of processes) contains "VoiceOver"', 'system events').startswith('true') and not self.runAppleScript('try\nreturn bounds of vo cursor\non error\nreturn false\nend try').startswith('false')
output_class = VoiceOver
|
||||||
|
|
||||||
class VoiceOver (Output):
|
|
||||||
"""Supports the VoiceOver screenreader on the Mac.
|
|
||||||
|
|
||||||
Note that this will also output as a message to the braille display if VoiceOver is used with braille.
|
|
||||||
Calling this module could cause VoiceOver to be started.
|
|
||||||
"""
|
|
||||||
name = 'VoiceOver'
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(VoiceOver, self).__init__(*args, **kwargs)
|
|
||||||
try:
|
|
||||||
from appscript import app
|
|
||||||
self.app = app('VoiceOver')
|
|
||||||
except ImportError:
|
|
||||||
raise OutputError
|
|
||||||
|
|
||||||
def speak(self, text, interupt=False):
|
|
||||||
self.app.output(text)
|
|
||||||
|
|
||||||
def is_active(self):
|
|
||||||
return True
|
|
@ -1,6 +1,7 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
import win32gui
|
import win32gui
|
||||||
from libloader.com import load_com
|
from libloader.com import load_com
|
||||||
from base import Output, OutputError
|
from .base import Output, OutputError
|
||||||
import pywintypes
|
import pywintypes
|
||||||
|
|
||||||
class WindowEyes (Output):
|
class WindowEyes (Output):
|
||||||
|
@ -1,13 +1,26 @@
|
|||||||
from pywintypes import com_error
|
from pywintypes import com_error
|
||||||
|
import win32com
|
||||||
|
import paths
|
||||||
|
win32com.__gen_path__=paths.data_path(u"com_cache")
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
sys.path.append(os.path.join(win32com.__gen_path__, "."))
|
||||||
from win32com.client import gencache
|
from win32com.client import gencache
|
||||||
|
fixed=False
|
||||||
|
|
||||||
def prepare_gencache():
|
def prepare_gencache():
|
||||||
gencache.is_readonly = False
|
gencache.is_readonly = False
|
||||||
gencache.GetGeneratePath()
|
gencache.GetGeneratePath()
|
||||||
|
|
||||||
|
def patched_getmodule(modname):
|
||||||
|
mod=__import__(modname)
|
||||||
|
return sys.modules[modname]
|
||||||
|
|
||||||
def load_com(*names):
|
def load_com(*names):
|
||||||
|
global fixed
|
||||||
|
if fixed==False:
|
||||||
|
gencache._GetModule=patched_getmodule
|
||||||
|
fixed=True
|
||||||
result = None
|
result = None
|
||||||
for name in names:
|
for name in names:
|
||||||
try:
|
try:
|
||||||
|
@ -32,7 +32,7 @@ def load_library(library, x86_path='.', x64_path='.', *args, **kwargs):
|
|||||||
loaded = _do_load(lib, *args, **kwargs)
|
loaded = _do_load(lib, *args, **kwargs)
|
||||||
if loaded is not None:
|
if loaded is not None:
|
||||||
return loaded
|
return loaded
|
||||||
raise LibraryLoadError('unable to load %r. Provided library path: %r' % (library, path))
|
raise LibraryLoadError('unable to load %r. Provided library path: %r' % (library, lib))
|
||||||
|
|
||||||
def _do_load(file, *args, **kwargs):
|
def _do_load(file, *args, **kwargs):
|
||||||
loader = TYPES[platform.system()]['loader']
|
loader = TYPES[platform.system()]['loader']
|
||||||
|
@ -8,17 +8,26 @@ import sys
|
|||||||
speaker = None
|
speaker = None
|
||||||
|
|
||||||
def speak(text, interrupt=0):
|
def speak(text, interrupt=0):
|
||||||
global speaker
|
global speaker
|
||||||
if not speaker:
|
if not speaker:
|
||||||
setup()
|
setup()
|
||||||
speaker.speak(text, interrupt)
|
speaker.speak(text, interrupt)
|
||||||
speaker.braille(text)
|
speaker.braille(text)
|
||||||
|
|
||||||
def setup ():
|
def setup ():
|
||||||
global speaker
|
global speaker
|
||||||
logging.debug("Initializing output subsystem.")
|
logging.debug("Initializing output subsystem.")
|
||||||
try:
|
try:
|
||||||
speaker = outputs.auto.Auto()
|
# speaker = speech.Speaker(speech.outputs.Sapi5())
|
||||||
except:
|
# else:
|
||||||
return logging.exception("Output: Error during initialization.")
|
speaker = outputs.auto.Auto()
|
||||||
|
except:
|
||||||
|
return logging.exception("Output: Error during initialization.")
|
||||||
|
|
||||||
|
def copy(text):
|
||||||
|
import win32clipboard
|
||||||
|
#Copies text to the clipboard.
|
||||||
|
win32clipboard.OpenClipboard()
|
||||||
|
win32clipboard.EmptyClipboard()
|
||||||
|
win32clipboard.SetClipboardText(text)
|
||||||
|
win32clipboard.CloseClipboard()
|
||||||
|
Loading…
Reference in New Issue
Block a user