Skip to content

Commit 684b984

Browse files
authored
Merge pull request #12 from zSeriesGuy/beta
v1.2.5
2 parents 1253c54 + f0e2379 commit 684b984

File tree

7 files changed

+141
-114
lines changed

7 files changed

+141
-114
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ data/**
3939
ehthumbs.db
4040
Icon?
4141
Thumbs.db
42+
pidfile
4243

4344
#Ignore files generated by PyCharm
4445
*.idea/*

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Changelog
22

3-
## v1.2.4.1 (2019-12-10)
3+
## v1.2.5 (2019-12-10)
44
* Upgrade packages, specifically grpcio, to fix an issue on Raspbian.
5+
* Modify pip_sync to output messages from process in realtime.
6+
* Modify loop to handle Google Cloud time limits on content.
7+
* Set GIT remote and branch based on what's installed.
58

69
## v1.2.4 (2019-12-09)
710
* Fix favicon handling.

INSTALLATION.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ SpeakReader will be installed to `/opt/SpeakReader`.
4141
* Install prerequisites:
4242
* Ubuntu/Debian:
4343
* `sudo apt-get install git-core`
44-
* `sudo apt-get install build-essential libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev zlib1g-dev alsa-utils portaudio19-dev`
44+
* `sudo apt-get install build-essential libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev zlib1g-dev alsa-utils libatlas-base-dev portaudio19-dev`
4545
* `sudo apt-get install python3 python3-venv python3-dev`
4646
* Type: `cd /opt`
4747
* Type: `sudo git clone https://github.com/zSeriesGuy/SpeakReader.git`

requirements.txt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,30 @@
55
# pip-compile
66
#
77
apscheduler==3.6.3
8-
azure-cognitiveservices-speech==1.7.0 ; sys_platform in "win32 macos" or (sys_platform == "linux" and platform_machine in "AMD64")
8+
azure-cognitiveservices-speech==1.8.0 ; sys_platform in "win32 macos" or (sys_platform == "linux" and platform_machine in "AMD64")
99
cachetools==3.1.1 # via google-auth
1010
certifi==2019.11.28 # via requests
1111
cffi==1.13.2 # via samplerate
1212
chardet==3.0.4 # via requests
1313
cheroot==8.2.1 # via cherrypy
14-
cherrypy==18.3.0
14+
cherrypy==18.5.0
1515
click==7.0 # via pip-tools
1616
configobj==5.0.6
1717
google-api-core[grpc]==1.14.3 # via google-cloud-speech
1818
google-api-python-client==1.7.11
1919
google-auth-httplib2==0.0.3 # via google-api-python-client
20-
google-auth==1.6.3 # via google-api-core, google-api-python-client, google-auth-httplib2
21-
google-cloud-speech==1.2.0
20+
google-auth==1.8.1 # via google-api-core, google-api-python-client, google-auth-httplib2
21+
google-cloud-speech==1.3.1
2222
googleapis-common-protos==1.6.0 # via google-api-core
2323
grpcio==1.25.0 # via google-api-core
2424
httplib2==0.14.0
25-
ibm-watson==4.0.1
25+
ibm-watson==4.1.0
2626
ibm_cloud_sdk_core==1.0.0 # via ibm-watson
2727
idna==2.8 # via requests
28-
jaraco.functools==2.0 # via cheroot, tempora
28+
jaraco.classes==2.0 # via jaraco.collections
29+
jaraco.collections==2.1 # via cherrypy
30+
jaraco.functools==2.0 # via cheroot, jaraco.text, tempora
31+
jaraco.text==3.2.0 # via jaraco.collections
2932
mako==1.1.0
3033
markupsafe==1.1.1 # via mako
3134
more-itertools==8.0.2 # via cheroot, cherrypy, jaraco.functools
@@ -46,7 +49,7 @@ pywin32==227 ; sys_platform == "win32"
4649
requests==2.22.0 # via google-api-core, ibm-cloud-sdk-core, ibm-watson
4750
rsa==4.0 # via google-auth
4851
samplerate==0.1.0
49-
six==1.13.0 # via apscheduler, cheroot, configobj, google-api-core, google-api-python-client, google-auth, grpcio, pip-tools, protobuf, python-dateutil, tempora, websocket-client
52+
six==1.13.0 # via apscheduler, cheroot, configobj, google-api-core, google-api-python-client, google-auth, grpcio, jaraco.classes, jaraco.collections, jaraco.text, pip-tools, protobuf, python-dateutil, tempora, websocket-client
5053
tempora==1.14.1 # via portend
5154
tzlocal==2.0.0
5255
uritemplate==3.0.0 # via google-api-python-client

speakreader/googleTranscribe.py

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,41 +40,51 @@ def __init__(self, audio_device):
4040
interim_results=True)
4141

4242
def transcribe(self):
43+
# Generator to return transcription results
44+
4345
if not self.is_supported:
4446
return
45-
# Generator to return transcription results
47+
4648
logger.debug("googleTranscribe.transcribe Entering")
47-
audio_generator = self.audio_device.streamGenerator()
4849

49-
requests = (speech.types.StreamingRecognizeRequest(
50-
audio_content=content)
51-
for content in audio_generator)
50+
while True:
51+
audio_generator = self.audio_device.streamGenerator()
52+
53+
requests = (speech.types.StreamingRecognizeRequest(
54+
audio_content=content)
55+
for content in audio_generator)
56+
57+
responses = self.client.streaming_recognize(self.streaming_config, requests)
58+
59+
try:
60+
for response in responses:
61+
if not response.results:
62+
continue
5263

53-
responses = self.client.streaming_recognize(self.streaming_config, requests)
64+
result = response.results[0]
5465

55-
try:
56-
for response in responses:
57-
if not response.results:
58-
continue
66+
if not result.is_final and not speakreader.CONFIG.SHOW_INTERIM_RESULTS:
67+
continue
5968

60-
result = response.results[0]
69+
if not result.alternatives:
70+
continue
6171

62-
if not result.is_final and not speakreader.CONFIG.SHOW_INTERIM_RESULTS:
63-
continue
72+
if not result.is_final and result.stability < 0.75:
73+
continue
6474

65-
if not result.alternatives:
66-
continue
75+
transcript = {
76+
'transcript': result.alternatives[0].transcript,
77+
'is_final': result.is_final,
78+
}
6779

68-
if not result.is_final and result.stability < 0.75:
69-
continue
80+
yield transcript
7081

71-
transcript = {
72-
'transcript': result.alternatives[0].transcript,
73-
'is_final': result.is_final,
74-
}
82+
logger.debug("googleTranscribe.transcribe Exiting")
83+
break
7584

76-
yield transcript
77-
logger.debug("googleTranscribe.transcribe Exiting")
78-
except exceptions.OutOfRange:
79-
logger.debug("googleTranscribe.transcribe OutOfRange Exception: Time Limit Exceeded. Restarting.")
80-
pass
85+
except exceptions.OutOfRange:
86+
""" Google Cloud limits stream to about 5 minutes. Just loop. """
87+
continue
88+
except exceptions.DeadlineExceeded:
89+
""" Google Cloud limits stream to about 5 minutes. Just loop. """
90+
continue

speakreader/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
PRODUCT = 'SpeakReader'
2-
VERSION_RELEASE = 'v1.2.4.1'
2+
VERSION_RELEASE = 'v1.2.5'
33
GITHUB_BRANCH = 'master'

speakreader/versionMgmt.py

Lines changed: 88 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import sys
2121
import re
2222
import subprocess
23+
import threading
2324
import tarfile
2425

2526
import speakreader
@@ -51,7 +52,7 @@ def __init__(self):
5152
if os.path.isdir(os.path.join(speakreader.PROG_DIR, '.git')):
5253
self.INSTALL_TYPE = 'git'
5354

54-
output, err = runGit('rev-parse HEAD')
55+
output, err = self.runGit('rev-parse HEAD')
5556
if output:
5657
if re.match('^[a-z0-9]+$', output):
5758
self.INSTALLED_VERSION_HASH = output
@@ -66,7 +67,7 @@ def __init__(self):
6667
if speakreader.CONFIG.DO_NOT_OVERRIDE_GIT_BRANCH and speakreader.CONFIG.GIT_BRANCH:
6768
self.BRANCH_NAME = speakreader.CONFIG.GIT_BRANCH
6869
else:
69-
remote_branch, err = runGit('rev-parse --abbrev-ref --symbolic-full-name @{u}')
70+
remote_branch, err = self.runGit('rev-parse --abbrev-ref --symbolic-full-name @{u}')
7071
remote_branch = remote_branch.rsplit('/', 1) if remote_branch else []
7172
if len(remote_branch) == 2:
7273
self.REMOTE_NAME, self.BRANCH_NAME = remote_branch
@@ -87,6 +88,9 @@ def __init__(self):
8788
logger.error('Could not retrieve branch name from git. Defaulting to master.')
8889
self.BRANCH_NAME = 'master'
8990

91+
speakreader.CONFIG.GIT_REMOTE = self.REMOTE_NAME
92+
speakreader.CONFIG.GIT_BRANCH = self.BRANCH_NAME
93+
9094
else:
9195
self.INSTALL_TYPE = 'source'
9296
self.REMOTE_NAME = 'origin'
@@ -273,20 +277,20 @@ def update(self):
273277

274278
if self.INSTALL_TYPE == 'git':
275279

276-
output, err = runGit('diff --name-only %s' % speakreader.CONFIG.GIT_REMOTE)
280+
output, err = self.runGit('diff --name-only %s/%s' % (speakreader.CONFIG.GIT_REMOTE, speakreader.CONFIG.GIT_BRANCH))
277281

278282
if output == '':
279283
logger.debug("No differences found from the origin")
280284

281285
elif output == 'requirements.txt':
282286
logger.warn('Requirements file is out of sync. Restoring to original.')
283-
output, err = runGit('checkout %s/%s requirements.txt' % (speakreader.CONFIG.GIT_REMOTE, speakreader.CONFIG.GIT_BRANCH))
287+
output, err = self.runGit('checkout %s/%s requirements.txt' % (speakreader.CONFIG.GIT_REMOTE, speakreader.CONFIG.GIT_BRANCH))
284288
else:
285289
logger.error("Differences Found. Unable to update.")
286290
logger.info('Output: ' + str(output))
287291
return False
288292

289-
output, err = runGit('pull ' + speakreader.CONFIG.GIT_REMOTE + ' ' + speakreader.CONFIG.GIT_BRANCH)
293+
output, err = self.runGit('pull ' + speakreader.CONFIG.GIT_REMOTE + ' ' + speakreader.CONFIG.GIT_BRANCH)
290294

291295
if not output:
292296
logger.error('Unable to download latest version')
@@ -362,14 +366,14 @@ def update(self):
362366
logger.error("Unable to write current version to version.txt, update not complete: %s" % e)
363367
return False
364368

365-
output, err = pip_sync()
369+
self.pip_sync()
366370
logger.info("Update Complete")
367371
return True
368372

369373
def checkout_git_branch(self):
370374
if self.INSTALL_TYPE == 'git':
371-
output, err = runGit('fetch %s' % speakreader.CONFIG.GIT_REMOTE)
372-
output, err = runGit('checkout %s' % speakreader.CONFIG.GIT_BRANCH)
375+
output, err = self.runGit('fetch %s' % speakreader.CONFIG.GIT_REMOTE)
376+
output, err = self.runGit('checkout %s' % speakreader.CONFIG.GIT_BRANCH)
373377

374378
if not output:
375379
logger.error('Unable to change git branch.')
@@ -380,8 +384,8 @@ def checkout_git_branch(self):
380384
logger.error('Unable to checkout from git: ' + line)
381385
logger.info('Output: ' + str(output))
382386

383-
output, err = runGit('pull %s %s' % (speakreader.CONFIG.GIT_REMOTE, speakreader.CONFIG.GIT_BRANCH))
384-
output, err = pip_sync()
387+
output, err = self.runGit('pull %s %s' % (speakreader.CONFIG.GIT_REMOTE, speakreader.CONFIG.GIT_BRANCH))
388+
self.pip_sync()
385389

386390

387391
def read_changelog(self, latest_only=False, since_prev_release=False):
@@ -449,76 +453,82 @@ def read_changelog(self, latest_only=False, since_prev_release=False):
449453
return '<h4>Unable to open changelog file</h4>'
450454

451455

452-
def runGit(args):
453-
if speakreader.CONFIG.GIT_PATH:
454-
git_locations = ['"' + speakreader.CONFIG.GIT_PATH + '"']
455-
else:
456-
git_locations = ['git']
456+
def runGit(self, args):
457+
if speakreader.CONFIG.GIT_PATH:
458+
git_locations = ['"' + speakreader.CONFIG.GIT_PATH + '"']
459+
else:
460+
git_locations = ['git']
457461

458-
output = err = None
462+
output = err = None
459463

460-
for cur_git in git_locations:
461-
cmd = cur_git + ' ' + args
464+
for cur_git in git_locations:
465+
cmd = cur_git + ' ' + args
462466

467+
try:
468+
logger.debug('Trying to execute: "' + cmd + '" with shell in ' + speakreader.PROG_DIR)
469+
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True,
470+
cwd=speakreader.PROG_DIR)
471+
output, err = p.communicate()
472+
output = output.decode('utf-8').strip()
473+
474+
for line in output.split('\n'):
475+
if line:
476+
logger.debug('Git output: ' + line)
477+
478+
except OSError:
479+
logger.debug('Command failed: %s', cmd)
480+
continue
481+
482+
if 'not found' in output or "not recognized as an internal or external command" in output:
483+
logger.debug('Unable to find git with command ' + cmd)
484+
output = None
485+
elif 'fatal:' in output or err:
486+
logger.error('Git returned bad info. Are you sure this is a git installation?')
487+
output = None
488+
elif output:
489+
break
490+
491+
return (output, err)
492+
493+
494+
def pip_sync(self):
495+
"""
496+
Run pip install requirements first because running pip-sync will fail if pip-tools gets updated.
497+
"""
463498
try:
464-
logger.debug('Trying to execute: "' + cmd + '" with shell in ' + speakreader.PROG_DIR)
465-
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True,
466-
cwd=speakreader.PROG_DIR)
467-
output, err = p.communicate()
468-
output = output.decode('utf-8').strip()
499+
logger.info("Running pip install requirements to update the environment.")
500+
cmd = sys.executable + ' -m pip install -r requirements.txt'
501+
output = self._exec_command(cmd)
502+
for line in output:
503+
logger.info('pip output: %s' % line)
504+
505+
logger.info("Running pip-sync to synchronize the environment.")
506+
cmd = sys.executable + ' -m piptools sync requirements.txt'
507+
output = self._exec_command(cmd)
508+
for line in output:
509+
logger.info('pip-sync output: %s' % line)
469510

470-
for line in output.split('\n'):
471-
if line:
472-
logger.debug('Git output: ' + line)
473-
474-
except OSError:
475-
logger.debug('Command failed: %s', cmd)
476-
continue
477-
478-
if 'not found' in output or "not recognized as an internal or external command" in output:
479-
logger.debug('Unable to find git with command ' + cmd)
480-
output = None
481-
elif 'fatal:' in output or err:
482-
logger.error('Git returned bad info. Are you sure this is a git installation?')
483-
output = None
484-
elif output:
485-
break
486-
487-
return (output, err)
488-
489-
490-
def pip_sync():
491-
"""
492-
Run pip install requirements first because running pip-sync will fail if pip-tools gets updated.
493-
"""
494-
logger.info("Running pip install for requirements update to synchronize the environment.")
495-
cmd = sys.executable + ' -m pip install -r requirements.txt'
496-
try:
497-
logger.debug('Trying to execute: "' + cmd + '" with shell in ' + speakreader.PROG_DIR)
498-
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True,
499-
cwd=speakreader.PROG_DIR)
500-
output, err = p.communicate()
501-
for line in output.decode('utf-8').split('\n'):
502-
if line:
503-
logger.info('pip output: ' + str(line))
504-
505-
except Exception as e:
506-
logger.error('Command failed: %s' % e)
507-
return None, None
508-
509-
logger.info("Running pip-sync to synchronize the environment.")
510-
cmd = sys.executable + ' -m piptools sync requirements.txt'
511-
try:
512-
logger.debug('Trying to execute: "' + cmd + '" with shell in ' + speakreader.PROG_DIR)
513-
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True,
514-
cwd=speakreader.PROG_DIR)
515-
output, err = p.communicate()
516-
for line in output.decode('utf-8').split('\n'):
517-
if line:
518-
logger.info('pip-sync output: ' + str(line))
519-
520-
except Exception as e:
521-
logger.error('Command failed: %s' % e)
522-
return None, None
523-
524-
return (output, err)
511+
except Exception as e:
512+
logger.error('Command failed: %s' % e)
513+
return None, None
514+
515+
516+
def _exec_command(self, cmd, cwd=None):
517+
if cwd is None:
518+
cwd = speakreader.PROG_DIR
519+
logger.debug('Trying to execute: "' + cmd + '" with shell in ' + cwd)
520+
p = subprocess.Popen(
521+
cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=cwd, shell=True
522+
)
523+
524+
while True:
525+
out = p.stdout.readline().decode('utf-8').replace('\r', '').replace('\n', '')
526+
return_code = p.poll()
527+
if out == '' and return_code is not None:
528+
break
529+
530+
if out != '':
531+
yield out
532+
533+
if return_code:
534+
raise subprocess.CalledProcessError(return_code, cmd)

0 commit comments

Comments
 (0)