Skip to content

Commit aa7202c

Browse files
committed
Google tts API and clipboard reading
1 parent 47569d6 commit aa7202c

File tree

6 files changed

+228
-115
lines changed

6 files changed

+228
-115
lines changed

google2ubuntu-manager.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -217,22 +217,27 @@ def create_toolbar(self,store):
217217
all_button.connect("clicked",self.removeall_clicked,store)
218218
all_button.set_tooltip_text(_('Remove all commands'))
219219
all_button.show()
220-
221-
# create a combobox to store user choice
222-
self.combo = self.get_combobox()
223-
toolcombo = Gtk.ToolItem()
224-
toolcombo.add(self.combo)
225-
toolcombo.show()
226-
toolbar.insert(toolcombo,4)
227-
220+
228221
# create a button for the "Help" action
229222
help_button = Gtk.ToolButton.new_from_stock(Gtk.STOCK_HELP)
230223
help_button.set_label(_("Help"))
231224
help_button.set_is_important(True)
232-
toolbar.insert(help_button,5)
225+
toolbar.insert(help_button,4)
233226
help_button.connect("clicked",self.help_clicked )
234227
help_button.set_tooltip_text(_("Display help message"))
235228
help_button.show()
229+
230+
# add a separator
231+
separator = Gtk.ToolItem()
232+
separator.set_expand(True)
233+
toolbar.insert(separator,5)
234+
235+
# create a combobox to store user choice
236+
self.combo = self.get_combobox()
237+
toolcombo = Gtk.ToolItem()
238+
toolcombo.add(self.combo)
239+
toolcombo.show()
240+
toolbar.insert(toolcombo,6)
236241

237242
# return the complete toolbar
238243
return toolbar

google2ubuntu.py

Lines changed: 94 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,76 @@
22
# -*- coding: utf-8 -*-
33
from subprocess import *
44
from gi.repository import Gtk
5+
from gi.repository import Gdk
56
from gi.repository import Notify
67
from os.path import expanduser
78
import sys
89
import subprocess
910
import os
1011
import json
1112
import urllib2
13+
import urllib
14+
import unicodedata
1215
import time
1316
import gettext
1417
import locale
18+
import re
19+
20+
PID = os.getpid()
1521
lang = locale.getlocale()[0]
1622
gettext.install('google2ubuntu',os.path.dirname(os.path.abspath(__file__))+'/i18n/')
1723

24+
class tts():
25+
def __init__(self,text):
26+
text = unicodedata.normalize('NFKD', unicode(text,"utf-8")).encode('ASCII', 'ignore')
27+
text = text.replace('\n','')
28+
text_list = re.split('(\,|\.)', text)
29+
combined_text = []
30+
output=open('/tmp/tts.mp3',"w")
31+
lc = lang.split('_')[0]
32+
33+
for idx, val in enumerate(text_list):
34+
if idx % 2 == 0:
35+
combined_text.append(val)
36+
else:
37+
joined_text = ''.join((combined_text.pop(),val))
38+
if len(joined_text) < 100:
39+
combined_text.append(joined_text)
40+
else:
41+
subparts = re.split('( )', joined_text)
42+
temp_string = ""
43+
temp_array = []
44+
for part in subparts:
45+
temp_string = temp_string + part
46+
if len(temp_string) > 80:
47+
temp_array.append(temp_string)
48+
temp_string = ""
49+
#append final part
50+
temp_array.append(temp_string)
51+
combined_text.extend(temp_array)
52+
#download chunks and write them to the output file
53+
for idx, val in enumerate(combined_text):
54+
mp3url = "http://translate.google.com/translate_tts?tl=%s&q=%s&total=%s&idx=%s" % (lc, urllib.quote(val), len(combined_text), idx)
55+
headers = {"Host":"translate.google.com",
56+
"Referer":"http://www.gstatic.com/translate/sound_player2.swf",
57+
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.163 Safari/535.19"}
58+
req = urllib2.Request(mp3url, '', headers)
59+
sys.stdout.write('.')
60+
sys.stdout.flush()
61+
if len(val) > 0:
62+
try:
63+
response = urllib2.urlopen(req)
64+
output.write(response.read())
65+
time.sleep(.5)
66+
except urllib2.HTTPError as e:
67+
print ('%s' % e)
68+
output.close()
69+
70+
71+
os.system("play /tmp/tts.mp3 &")
72+
73+
74+
1875

1976
# Cette classe utilis Notify pour alerter l'utilisateur
2077
class notification():
@@ -52,23 +109,27 @@ def close(self):
52109
class interface():
53110
def __init__(self):
54111
# on joue un son pour signaler le démarrage
55-
os.system('aplay '+os.path.dirname(os.path.abspath(__file__))+'/sound.wav')
112+
os.system('aplay '+os.path.dirname(os.path.abspath(__file__))+'/sound.wav &')
56113
notif.update(_('Recording')+':',_('Processing'),'RECORD')
57-
58114
# On lance le script d'enregistrement pour acquérir la voix pdt 5s
59-
command =os.path.dirname(os.path.abspath(__file__))+'/record.sh'
60-
p = subprocess.check_call([command])
61-
115+
command =os.path.dirname(os.path.abspath(__file__))+'/record.sh ' + str(PID)
116+
#p = subprocess.check_call([command])
117+
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
118+
output,error = p.communicate()
62119
notif.update(_("End of recording"),_('Sending to Google'),'NETWORK')
63120
self.sendto()
64121

65122
def sendto(self):
66123
# lecture du fichier audio
67-
filename='/tmp/voix.flac'
124+
filename='/tmp/voix_'+str(PID)+'.flac'
68125
f = open(filename)
69126
data = f.read()
70127
f.close()
71128

129+
# suppression du fichier audio
130+
if os.path.isfile('/tmp/voix_'+str(PID)+'.flac'):
131+
os.system('rm /tmp/voix_'+str(PID)+'.flac')
132+
72133
# envoi d'une requête à Google
73134
req = urllib2.Request('https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang='+lang, data=data, headers={'Content-type': 'audio/x-flac; rate=16000'})
74135
try:
@@ -98,22 +159,26 @@ def sendto(self):
98159
sp = stringParser(text,config_file)
99160
else:
100161
notif.update(_('Error'),_("I don't understand what you are saying"),'ERROR')
162+
tts(_('Error')+' '+_("I don't understand what you are saying"))
101163
time.sleep(3)
102164
notif.close()
103165
sys.exit(1)
104166

105167
except ValueError, IndexError:
106168
notif.update(_('Error'),_('Unable to translate'),'ERROR')
169+
tts(_('Error')+' '+_('Unable to translate'))
107170
time.sleep(3)
108171
notif.close()
109172
sys.exit(1)
110173

111174
except urllib2.URLError:
112-
notif.update(_('Error'),_('Unable to send to Google'),'ERROR')
175+
notif.update(_('Error'),_('Unable to send to Google'),'ERROR')
176+
tts(_('Error')+' '+_('Unable to send to Google'))
113177
time.sleep(3)
114178
notif.close()
115179
sys.exit(1)
116180

181+
117182
# Permet d'exécuter la commande associée à un mot prononcé
118183
class stringParser():
119184
def __init__(self,text,file):
@@ -168,13 +233,15 @@ def __init__(self,text,file):
168233
b = basicCommands(check[1])
169234
else:
170235
# on exécute directement l'action
236+
tts(_('Processing'))
171237
os.system(do)
172238

173239
time.sleep(1)
174240
notif.close()
175241

176242
except IOError:
177243
notif.update(_('Error'),_('Setup file missing'),'ERROR')
244+
tts(_('Error')+' '+_('Setup file missing'))
178245
time.sleep(3)
179246
notif.close()
180247
sys.exit(1)
@@ -234,21 +301,25 @@ def __init__(self,module_path,module_name,text):
234301
print text
235302
if text.count(linker) > 0:
236303
param =(text.split(linker)[1]).encode("utf-8")
237-
304+
238305
# on regarde si l'utilisateur veut transformer les ' ' en +
239306
if plus == 1:
240307
param=param.replace(' ','+')
241308

242309
# commande qui sera exécutée
310+
311+
tts (_('Search results for')+' '+param)
243312
execute = expanduser('~') +'/.config/google2ubuntu/modules/'+module_path+'/'+module_name+' '+param
244313
os.system(execute)
245314
else:
246315
notif.update(_('Error'),_("you didn't say the linking word")+'\n'+linker,'ERROR')
316+
tts(_('Error')+' '+_("you didn't say the linking word"))
247317
time.sleep(3)
248318
notif.close()
249319

250320
except IOError:
251321
notif.update(_('Error'),_('args file missing'),'ERROR')
322+
tts(_('Error')+' '+-('args file missing'))
252323
time.sleep(3)
253324
notif.close()
254325
sys.exit(1)
@@ -261,29 +332,22 @@ def __init__(self,text):
261332
self.getTime()
262333
elif text == _('power'):
263334
self.getPower()
335+
elif text == _('clipboard'):
336+
self.read_clipboard()
264337
else:
265338
print "no action found"
266339

267-
# en cours ...
268-
#def repeat(self, text):
269-
#path = '/tmp/previoux_command.txt'
270-
#if os.path.isfile(path):
271-
#try:
272-
#f = open(path,"r")
273-
#command_type = f.readline().rstrip('\n\r')
274-
#if command_type == _('module'):
275-
#name = f.readline().rstrip('\n\r')
276-
#lword = f.readline().rstrip('\n\r')
277-
#if lword in text:
278-
279-
280-
#command_args =
281-
#f.close()
282-
283-
284-
#except IOError:
285-
#print _('An error occured when I try to load previous commande')
286-
340+
def read_clipboard(self):
341+
clipboard = Gtk.Clipboard.get(Gdk.SELECTION_PRIMARY)
342+
343+
text = clipboard.wait_for_text()
344+
if text != None:
345+
text=text.replace("'",' ')
346+
print text
347+
tts(text)
348+
else:
349+
tts(_('Nothing in the clipboard'))
350+
287351
def getTime(self):
288352
var=time.strftime('%d/%m/%y %H:%M',time.localtime())
289353
notif.update(_('time'),var,'INFO')
@@ -298,13 +362,14 @@ def getPower(self):
298362
rtime = output.split(' ')[4]
299363

300364
if output.count('Charging') > 0:
301-
message = _('Charging')+': '+pcent+'\n'+rtime++' '+_('before charging')
365+
message = _('Charging')+': '+pcent+'\n'+rtime+' '+_('before charging')
302366
else:
303367
message = _('Discharging')+': '+pcent+'\n'+rtime+' '+_('remaining')
304368
else:
305369
message = _('battery is not plugged')
306370

307371
notif.update(_('Power'),message,'INFO')
372+
tts(message)
308373
time.sleep(3)
309374

310375
# Initialisation des notifications

0 commit comments

Comments
 (0)