From 1d271d881502f5f600239253394809df053db4e2 Mon Sep 17 00:00:00 2001 From: Assim Date: Mon, 11 Aug 2008 12:37:36 +0000 Subject: configuration panel added --- diff --git a/las-gui.py b/ListenSpell.py index 4d833fa..68c8c80 100755 --- a/las-gui.py +++ b/ListenSpell.py @@ -1,44 +1,87 @@ #!/usr/bin/env python - - import pygtk pygtk.require('2.0') + import gtk +import os +import string from las import Listenspell +from sugar.activity import activity +from sugar.datastore import datastore +import logging +from gettext import gettext as _ -class LS_gui: - - # This is a callback function. The data arguments are ignored - # in this example. More on callbacks below. - def __init__(self, handle): - self.__init__() - - def __init__(self): +class ListenSpell(activity.Activity): + + def __init__(self, handle = None, is_stand_alone = False): + self.is_stand_alone = is_stand_alone + + if not self.is_stand_alone: + activity.Activity.__init__(self, handle) + self._name = handle + self._logger = logging.getLogger('listen-spell') + + path = __file__ + path = path.rpartition("/") + self.las = Listenspell() + self.las.set_path(path[0]) + DBname = "dict.db" + self.las.load_db(DBname) self.use_phoneme = False - self.las = Listenspell(DBname) + self.load_activity_interface() + self.las.play_sound("begin") + self.las.say_text("Welcome", wait = False) + self.ask_skill_level() self.play_game("start") gtk.main() - def destroy(self, widget, data=None): - #print "destroy signal occurred" - self.game_exit() - def load_activity_interface(self): - self.main_window = gtk.Window(gtk.WINDOW_TOPLEVEL) - self.main_window.connect("destroy", self.destroy) - - self.main_window.set_border_width(10) - - self.main_window.set_title("Listen and Spell") + #query = {'title':'listen-spell'} + #(result, count) = datastore.find(query) + #md = datastore.DSMetadata() + #if count > 0: + #dso = result[0] + #md = dso.get_metadata() + #md.get() + + + + if self.is_stand_alone: + self.main_window = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.main_window.connect("destroy", self.destroy) + self.main_window.set_border_width(10) + self.main_window.set_title("Listen and Spell") + + if not self.is_stand_alone: + toolbox = activity.ActivityToolbox(self) + #conf_toolbar = ConfigToolBar() + + #mytoolbar = gtk.Toolbar() + #helpbut = gtk.ToolButton(label = 'help') #Stock help icon + #helpbut.set_tooltip(_("Get help")) + #helpbut.connect('clicked', self.help_button_pressed) + #mytoolbar.insert(helpbut, -1) + #helpbut.show() + #mytoolbar.show() + + + #toolbox.add_toolbar("my toolbar",mytoolbar) + + self.set_toolbox(toolbox) + toolbox.show_all() + # Set title for our Activity + + self.set_title('Listen and Spell') self.Hcontainer = gtk.HBox() self.Hcontainer.show() - - self.main_window.add(self.Hcontainer) - + + if self.is_stand_alone: + self.main_window.add(self.Hcontainer) + self.vcontainer_left = gtk.VBox() self.vcontainer_left.set_border_width(10) self.vcontainer_left.show() @@ -53,36 +96,14 @@ class LS_gui: #####################Left Pane widgets########################## - #self.label_v_left_a = gtk.Label("Hello this is label 1") - #self.label_v_left_b = gtk.Label("label 2") - - #self.label_v_left_a.show() - #self.label_v_left_b.show() - - #self.main_output_view = gtk.TextView() - #self.main_output_buffer = gtk.TextBuffer() - #self.main_output_buffer.set_text("This is main output") - #self.main_output_view.set_editable(False) - #self.main_output_view.set_buffer(self.main_output_buffer) - - #self.display_main_output("This is main output") - - #self.main_output_view.show_all() self.text_input = gtk.Entry() - #self.text_input.set_text("Preset input text") - #self.text_input. self.text_input.show() self.text_input.connect("focus-in-event", self.text_input_focus, None) self.text_input.connect("activate", self.text_input_activate, None) self.console_text_view = gtk.TextView() - - #self.console_text_view.show() - #self.h_adj = gtk.Adjustment(value=0, lower=0, upper=4, step_incr=1, page_incr=0, page_size=0) - #self.console_text_sw = gtk.ScrolledWindow(vadjustment=self.h_adj) - self.console_text_sw = gtk.ScrolledWindow() self.console_text_sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) self.console_text_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) @@ -103,9 +124,6 @@ class LS_gui: self.console_text_frame.add(self.console_text_sw) self.console_text_frame.show_all() - #self.vcontainer_left.pack_start(self.main_output_view, True, True ) - #self.vcontainer_left.pack_start(self.label_v_left_b, True, False ) - self.vcontainer_left.pack_start(self.console_text_frame, True, True ) self.vcontainer_left.pack_start(self.text_input, False, True ) self.vcontainer_left.pack_start(self.text_submit_button, False, False ) @@ -128,10 +146,17 @@ class LS_gui: self.get_word_length_button = gtk.Button("Get Word Length") self.get_word_length_button.connect("clicked", self.get_word_length_button_clicked, None) + self.change_skill_level_button = gtk.Button("Change Skill Level") + self.change_skill_level_button.connect("clicked", self.change_skill_level_button_clicked, None) + + self.change_skill_level_button = gtk.Button("Speech Configuration") + self.change_skill_level_button.connect("clicked", self.speech_configuration_button_clicked, None) + self.v_buttonbox.add(self.repeat_word_button) self.v_buttonbox.add(self.get_def_button) self.v_buttonbox.add(self.get_usage_button) self.v_buttonbox.add(self.get_word_length_button) + self.v_buttonbox.add(self.change_skill_level_button) self.v_buttonbox.show_all() @@ -174,13 +199,125 @@ class LS_gui: self.stats_frame.add(self.stats_table) self.stats_frame.show_all() + if not self.is_stand_alone: + self._logger.debug('activity loaded') ################################################################ - - self.main_window.show() + if self.is_stand_alone: + self.main_window.show() + else: + self.set_canvas(self.Hcontainer) + self.show_all() ##################Call Backs#################################### + + + def _update_configuration(self, widget, attribute ): + if attribute == "voice": + self.las.speechd_config(attribute, widget.get_active_text()) + else: + self.las.speechd_config(attribute, widget.get_value()) + + + def _speech_test(self, widget, speech_text): + self.las.say_text(str(speech_text)) + + def speech_configuration_button_clicked(self, widget, data = None): + self.config_dialog = gtk.Dialog("Change Speech Configuration", self,0,(gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)) + #self.las.say_text("Skill Level") + #vbox = gtk.VBox(False, 8) + #Vbox.set_border_width(8) + + config_table = gtk.Table(4,2) + config_table.set_row_spacings(4) + config_table.set_col_spacings(4) + + speech_frame= gtk.Frame("Speech Configuration") + speech_frame.add(config_table) + + self.config_dialog.vbox.pack_start(speech_frame, False, False, 0) + + volume_adj = gtk.Adjustment(0, -100, 101, 1, 1, 1) + rate_adj = gtk.Adjustment(0, -100, 101, 1, 1, 1) + pitch_adj = gtk.Adjustment(0, -100, 101, 1, 1, 1) + + + volume_hscale = gtk.HScale(volume_adj) + rate_hscale = gtk.HScale(rate_adj) + pitch_hscale = gtk.HScale(pitch_adj) + + volume_hscale.set_digits(0) + rate_hscale.set_digits(0) + pitch_hscale.set_digits(0) + + + volume_hscale.set_update_policy(gtk.UPDATE_DISCONTINUOUS) + rate_hscale.set_update_policy(gtk.UPDATE_DISCONTINUOUS) + pitch_hscale.set_update_policy(gtk.UPDATE_DISCONTINUOUS) + + voice_box = gtk.combo_box_new_text() + voice_list = ["MALE1", "MALE2", "MALE3", "FEMALE1", "FEMALE2", "FEMALE3", "CHILD_MALE", "CHILD_FEMALE"] + #hscale4 = gtk.HScale(adj4) + for voice in voice_list: + voice_box.append_text(voice) + voice_box.set_active(0) + + volume_label = gtk.Label("Volume") + rate_label = gtk.Label("Rate") + pitch_label = gtk.Label("pitch") + voice_label = gtk.Label("Voice") + + volume_adj.connect('value_changed',self._update_configuration, "volume") + rate_adj.connect('value_changed',self._update_configuration, "rate") + pitch_adj.connect('value_changed',self._update_configuration, "pitch") + voice_box.connect('changed', self._update_configuration, "voice") + + + config_table.attach(volume_label, 0,1,0,1) + config_table.attach(rate_label, 0,1,1,2) + config_table.attach(pitch_label, 0,1,2,3) + config_table.attach(voice_label, 0,1,3,4) + + config_table.attach(volume_hscale, 1,2,0,1) + config_table.attach(rate_hscale, 1,2,1,2) + config_table.attach(pitch_hscale, 1,2,2,3) + config_table.attach(voice_box, 1,2,3,4) + + + speech_test_frame = gtk.Frame("Test Speech Setting") + + self.config_dialog.vbox.pack_start(speech_test_frame, False, False, 0) + + + + speech_test_table = gtk.Table(2,1) + speech_test_table.set_row_spacings(4) + speech_test_table.set_col_spacings(4) + + speech_test_frame.add(speech_test_table) + + speech_test_text_entry = gtk.Entry() + speech_test_text_entry.set_text("The quick brown fox jumps over the lazy dog") + + speech_test_button = gtk.Button("Test") + + speech_test_button.connect("clicked", self._speech_test, speech_test_text_entry.get_text()) + + speech_test_table.attach(speech_test_text_entry, 0,1,0,1) + speech_test_table.attach(speech_test_button, 0,1,1,2) + + + + self.config_dialog.show_all() + + response = self.config_dialog.run() + + + + def get_speechd_config(self): + pass + def submit_button_clicked(self, widget, data = None): answer = self.text_input.get_text() self.las.say_text("You typed") @@ -197,6 +334,8 @@ class LS_gui: self.shout(self.elem) self.update_all() self.play_game("next word") + if not self.is_stand_alone: + self._logger.debug('submit button clicked : ' + self.elem + '') return False def text_input_focus(self, widget, event, data= None): @@ -213,12 +352,16 @@ class LS_gui: self.las.say_text(self.pronounelem, is_phoneme = True) else: self.las.say_text(self.elem) + if not self.is_stand_alone: + self._logger.debug('repeat button clicked : ' + self.elem + '') def get_def_button_clicked(self, widget, data = None): def_list = self.las.get_word_info(self.wordid, "def") self.display_console("Definition: ") for (pos, definition, name) in def_list: self.display_console(pos + "(" + name + ") : " + definition) + if not self.is_stand_alone: + self._logger.debug('get defination button clicked : ' + self.elem + '') def get_usage_button_clicked(self, widget, data = None): if self.usage_used == 0: @@ -232,12 +375,16 @@ class LS_gui: (sample) = usage[self.usage_used] las.say_text(sample) self.usage_used = self.usage_used + 1 + if not self.is_stand_alone: + self._logger.debug('get usage button clicked : ' + self.elem + '') def get_word_length_button_clicked(self, widget, data = None): self.display_console("Word Length: " + str(len(self.elem))) + if not self.is_stand_alone: + self._logger.debug('get word length button clicked : ' + self.elem + '') def ask_skill_level(self): - self.skill_level_dialog = gtk.Dialog("Enter Skill Level", self.main_window, 0,(gtk.STOCK_OK, gtk.RESPONSE_OK, "Quit Game", gtk.RESPONSE_CANCEL)) + self.skill_level_dialog = gtk.Dialog("Enter Skill Level", self, 0,(gtk.STOCK_OK, gtk.RESPONSE_OK, "Quit Game", gtk.RESPONSE_CANCEL)) self.las.say_text("Skill Level") hbox = gtk.HBox(False, 8) hbox.set_border_width(8) @@ -262,10 +409,11 @@ class LS_gui: if response == gtk.RESPONSE_OK: skill_level = int (local_skill_level.get_text()) + if not self.is_stand_alone: + self._logger.debug('level set : ' + str(skill_level) + '') self.skill_level_dialog.destroy() self.las.set_skill_level(skill_level) self.update_all() - elif response == gtk.RESPONSE_CANCEL: self.game_exit() elif response == gtk.RESPONSE_NONE: @@ -278,6 +426,11 @@ class LS_gui: def local_skill_level_activate(self, widget, data=None): self.skill_level_dialog.response(gtk.RESPONSE_OK) + + def change_skill_level_button_clicked(self, widget, data=None): + self.ask_skill_level() + self.play_game("start") + def shout(self,string): self.display_console("") for char in string: @@ -335,12 +488,8 @@ class LS_gui: def play_game(self,mode = "start"): if mode == "start": - self.las.play_sound("begin") self.this_level_size = 7 self.this_level_max_error = 3 - #self.display_main_output("Welcome") - self.las.say_text("Welcome", wait = False) - self.ask_skill_level() self.wordid_list = self.las.load_wordid(self.this_level_size + self.this_level_max_error) self.this_level_num_words = len(self.wordid_list) self.this_level_words_left = self.this_level_num_words @@ -400,7 +549,7 @@ class LS_gui: # If the program is run directly or passed as an argument to the python # interpreter then create a HelloWorld instance and show it if __name__ == "__main__": - gui = LS_gui() + gui = ListenSpell(is_stand_alone = True) #gui.__init__() #gui.play_game("start") #gui.main() diff --git a/MANIFEST b/MANIFEST new file mode 100755 index 0000000..f1a29c8 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,12 @@ +activity/activity.info +activity/activity-listen-spell.svg +dict.db +correct.wav +ls.py +setup.py +dict.py +conv.sh +incorrect.wav +begin.wav +las.py +ListenSpell.py diff --git a/activity/activity-listen-spell.svg b/activity/activity-listen-spell.svg new file mode 100755 index 0000000..8d259ab --- /dev/null +++ b/activity/activity-listen-spell.svg @@ -0,0 +1,382 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/activity/activity.info b/activity/activity.info new file mode 100755 index 0000000..b108201 --- /dev/null +++ b/activity/activity.info @@ -0,0 +1,7 @@ +[Activity] +name = listen-spell +service_name = org.laptop.listen-spell +class = ListenSpell.ListenSpell +icon = activity-listen-spell +activity_version = 1 +show_launcher = yes diff --git a/begin.wav b/begin.wav index be6ba53..be6ba53 100644..100755 --- a/begin.wav +++ b/begin.wav Binary files differ diff --git a/correct.wav b/correct.wav index cb5d6bb..cb5d6bb 100644..100755 --- a/correct.wav +++ b/correct.wav Binary files differ diff --git a/dict.db b/dict.db index 913ad33..99dc47f 100644..100755 --- a/dict.db +++ b/dict.db Binary files differ diff --git a/dict.py b/dict.py index d202439..7a956a5 100755 --- a/dict.py +++ b/dict.py @@ -9,6 +9,8 @@ __debug = True class Dict: + + level_1 = () def __init__(self, sqliteDB = None): @@ -52,6 +54,10 @@ class Dict: def get_DB_name(self): return + def level_map(self, level): + level_1 = { 3:{s:30000000000, e:1460000000 }, 4:{s:23, e:312} } + pass + class Word: def __init__(self, identifier=None, value= None): @@ -75,16 +81,18 @@ class Word: self.wordid = None self.word = None self.length = None + self.freq = None self.synsetid_list = [] return None else: return "Invalid Usage" - (laswid, wordid, lemma, length) = self.cur.fetchone() + (laswid, wordid, lemma, length, freq) = self.cur.fetchone() self.las_word_id = laswid self.wordid = wordid self.word = lemma self.length = length + self.freq = freq self.synsetid_list = [] def get_word(self): @@ -107,6 +115,8 @@ class Word: return self.synsetid_list + def get_freq(self): + return self.freq def get_def(self): self.def_list = [] if self.synsetid_list == []: @@ -160,17 +170,23 @@ class Word: else:return None def update_phoneme(self, phoneme, is_correct = True): - #print phoneme + #try: + #if is_correct == True: + #self.cur.execute("UPDATE las_phoneme SET phoneme = ?, is_correct = ? where wordid = ?", (phoneme, 1, self.wordid,)) + #else: + #self.cur.execute("UPDATE las_phoneme SET phoneme = ?, is_correct = ? where wordid = ?", (phoneme, 0, self.wordid,)) + #except: try: if is_correct == True: - self.cur.execute("UPDATE las_phoneme SET phoneme = ?, is_correct = ? where wordid = ?", (phoneme, 1, self.wordid,)) - else: - self.cur.execute("UPDATE las_phoneme SET phoneme = ?, is_correct = ? where wordid = ?", (phoneme, 0, self.wordid,)) - except: - if is_correct == True: self.cur.execute("INSERT into las_phoneme (wordid, phoneme, is_correct ) VALUES (?,?,?) ", (self.wordid, phoneme, 1, )) else: self.cur.execute("INSERT into las_phoneme (wordid, phoneme, is_correct ) VALUES (?,?,?) ", (self.wordid, phoneme, 0, )) + except sqlite3.OperationalError: + if is_correct == True: + self.cur.execute("UPDATE las_phoneme SET phoneme = " + phoneme + ", is_correct = 1 where wordid = ?", (self.wordid,)) + else: + self.cur.execute("UPDATE las_phoneme SET phoneme = " + phoneme +", is_correct = 0 where wordid = ?", (self.wordid,)) + self.conn.commit() if __name__ == "__main__": diff --git a/dist/listen-spell-1.xo b/dist/listen-spell-1.xo new file mode 100755 index 0000000..a2cbd8f --- /dev/null +++ b/dist/listen-spell-1.xo Binary files differ diff --git a/incorrect.wav b/incorrect.wav index 359f147..359f147 100644..100755 --- a/incorrect.wav +++ b/incorrect.wav Binary files differ diff --git a/las.py b/las.py index 96fd52e..39afbb1 100755 --- a/las.py +++ b/las.py @@ -46,50 +46,44 @@ class _GetchWindows: class Listenspell(): - def __init__(self, SQLiteDB): - + def __init__(self): self.skill_level = 0 - self.level_threshold = 5 self.points = 0 self.words_played = 0 self.words_correct = 0 + self.path = "." self.speechd_init = False - self.dict_obj = Dict(SQLiteDB) #Always intitiate first Dict object then Word object + self.__speechd_default_config = {'pitch':0, 'rate':0, 'language':'en', 'volume':100, 'voice':'', + 'spelling':False, 'punctuation':speechd.PunctuationMode.SOME } + self.__speechd_config = {'pitch':0, 'rate':0, 'language':'en', 'volume':100, 'voice':'', + 'spelling':False, 'punctuation':speechd.PunctuationMode.SOME } + + def load_db(self, SQLiteDB): + if self.path == ".": + return False + #print self.path + SQLiteDB + self.dict_obj = Dict(self.path + SQLiteDB) #Always intitiate first Dict object then Word object self.word_obj = Word() - + + def set_path(self, path): + if path != "": + self.path = path + "/" + else: + self.path = path def play_sound(self,event): - #file= event + '.wav' - #from wave import open as waveOpen - #from ossaudiodev import open as ossOpen - #s = waveOpen(file,'rb') - #(nc,sw,fr,nf,comptype, compname) = s.getparams( ) - #dsp = ossOpen('/dev/dsp','w') - #try: - #from ossaudiodev import AFMT_S16_NE - #except ImportError: - #if byteorder == "little": - #AFMT_S16_NE = ossaudiodev.AFMT_S16_LE - #else: - #AFMT_S16_NE = ossaudiodev.AFMT_S16_BE - #dsp.setparameters(AFMT_S16_NE, nc, fr) - #data = s.readframes(nf) - #s.close() - #dsp.write(data) - #dsp.close() - - os.popen("aplay --quiet " + event + ".wav") - #if event == "begin": - #os.popen("aplay --quiet begin.wav") - #elif event == "correct": - #os.popen("aplay --quiet correct.wav") - #elif event == "incorrect": - #os.popen("aplay --quiet incorrect.wav") + os.popen("aplay --quiet " + self.path + event + ".wav") def set_skill_level(self,level): self.skill_level = level + self.reset_counters() + def reset_counters(self): + self.points = 0 + self.words_played = 0 + self.words_correct = 0 + def get_skill_level(self): return self.skill_level @@ -149,21 +143,28 @@ class Listenspell(): elif attribute == "phnm": phnm = self.word_obj.get_phoneme() if phnm == None: - phnm = self.get_phoneme(self.word_obj.get_word()) + phnm = self.__get_phoneme(self.word_obj.get_word()) return phnm else: (phoneme, is_correct) = phnm return phoneme else: return False - def get_phoneme(self, word = None): + def __get_phoneme(self, word = None): if word == None: return False phnm = commands.getoutput("/usr/bin/espeak -q -x " + word) self.word_obj.update_phoneme(phnm) return phnm - def start_speechd(self): + + def get_speechd_config(self, default =0): + if default == 1: + return self.__speechd_default_config + else: + return self.__speechd_config + + def __start_speechd(self): try: self.client = speechd.SSIPClient('spd-test') self.client.set_output_module('espeak') @@ -173,23 +174,51 @@ class Listenspell(): except dbus.exceptions.DBusException: print "Speech Dispatcher is not turned on." return False + self.speechd_init = True + + def speechd_config(self, attribute = None, data = None): + + if attribute == None or data == None: + return False - def callback(self,callback_type): + if self.speechd_init == False: + if self.__start_speechd() == False: + return False + + if attribute == "pitch": + self.client.set_pitch(data) #-100 to 100 + elif attribute == "rate": + self.client.set_rate(data) # -100 to 100 + elif attribute == "volume": + self.client.set_volume(data)#-100 to 100 + elif attribute == "voice": + self.client.set_voice(data)#(FE)MALE(1,2,3), CHILD_(FE)MALE + elif attribute == "output_module": + self.client.set_output_module(data) + elif attribute == "language": + self.client.set_language(data) + elif attribute == "punctuation": + self.client.set_punctuation(data) + elif attribute == "spelling": + self.client.set_spelling(data) # True or False + elif attribute == "synthesis_voice": + self.client.set_synthesis_voice(data)#self.client.list_synthesis_voices() + else: return False + + def __speechd_callback(self,callback_type): self.speech_state = callback_type - def say_text(self, text, wait= True, is_phoneme = False): + def say_text(self, text, wait= True): #wait: to wait for the text to be spoken or not #os.popen("espeak " + text) if self.speechd_init == False: - if self.start_speechd() == False: + if self.__start_speechd() == False: return False - self.speechd_init = True text = str(text) - if is_phoneme: - text = "[" + text + "]" - - self.client.speak(text, callback=self.callback,event_types=(speechd.CallbackType.BEGIN, + self.speech_state = None + + self.client.speak(text, callback=self.__speechd_callback,event_types=(speechd.CallbackType.BEGIN, speechd.CallbackType.CANCEL, speechd.CallbackType.END)) if wait == True: diff --git a/po/listen-spell.pot b/po/listen-spell.pot new file mode 100755 index 0000000..2aaba6e --- /dev/null +++ b/po/listen-spell.pot @@ -0,0 +1,21 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-07-29 14:59+0530\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: activity/activity.info:2 +msgid "listen-spell" +msgstr "" diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..6c8bbb8 --- /dev/null +++ b/setup.py @@ -0,0 +1,3 @@ +#!/usr/bin/python +from sugar.activity import bundlebuilder +bundlebuilder.start('listen-spell') diff --git a/sugar-speechd b/sugar-speechd deleted file mode 100755 index c5f271a..0000000 --- a/sugar-speechd +++ /dev/null Binary files differ -- cgit v0.9.1