import sys
from dbus.mainloop.glib import DBusGMainLoop
+# Would be truncated on every reboot, and shouldn't write
+# anythong if things go right way so it is OK not to have logrotate
+log = open("/var/log/ussd-widget.log")
+print >> sys.stderr, "Writing log to /var/log/ussd-widget.log"
+
try :
- t = gettext.translation('ussd-widget', '/usr/share/locale')
- _ = t.ugettext
+ t = gettext.translation('ussd-widget', '/usr/share/locale')
+ _ = t.ugettext
except IOError:
- print "Translation file for your language not found"
- def retme(arg):
- return arg
- _ = retme
+ print >> log, "Translation file for your language not found"
+ def retme(arg):
+ return arg
+ _ = retme
ussd_languages = ["German", "English", "Italian", "French", "Spanish", "Dutch", "Swedish", "Danish", "Portuguese", "Finnish", "Norwegian", "Greek", "Turkish", "Reserved1", "Reserved2", "Unspecified"]
ussd_languages_localized = [_("German"), _("English"), _("Italian"), _("French"), _("Spanish"), _("Dutch"), _("Swedish"), _("Danish"), _("Portuguese"), _("Finnish"), _("Norwegian"), _("Greek"), _("Turkish"), _("Reserved1"), _("Reserved2"), _("Unspecified")]
# how TODO widget vertical minimum size policy
class USSD_Controller:
- def __init__( self, widget ) :
- self.widget = widget
- # number, parser, chain, interval, regexp, width, execute_at_start, retry pattern, font, name, language, show_message_box, message_box_parser, additional arguments, regexp group, use SMS listener, SMS number, SMS regexp, SMS timeout
- self.default_config = ["", "", "", 0, "", 0, True, [], pango.FontDescription("Nokia Sans 18"), _("Click to update"), 15, False, "", "", 1, False, "", "", 60]
- self.config = self.default_config
- self.timeout_version = 0
- self.retry_version = 0
- self.retry_state = 0
- self.sms_counter = 0
- self.sms_reply = ""
-
- def save_config( self ) :
- configname = os.getenv("HOME")+"/.ussdWidget.conf"
- # Aquire lock
- lockf = open(configname+".lock", 'a')
- fcntl.flock(lockf,fcntl.LOCK_EX)
-
- oldconfig=""
- try:
- fconfig = open(configname,"r")
- #Read configuration of other instances
- my_section = False
- for line in fconfig :
- if line[0] == '%':
- my_section = line[1:].strip() == self.id
- if not my_section:
- oldconfig += line
- fconfig.close()
- except:
- print _("Couldn't read previous config")
-
- fconfig = open(configname,"w")
- fconfig.seek(0)
- fconfig.write(oldconfig)
- fconfig.write("%"+self.id+"\n");
- fconfig.writelines(["# USSD query to be run by widget\n", "number="+self.config[0], "\n"])
- fconfig.writelines(["#Parser command for widget\n", "parser="+self.config[1], "\n"])
- fconfig.writelines(["#Parser command for banner\n", "parser_box="+self.config[12], "\n"])
- fconfig.writelines(["#Chain command\n", "chain="+self.config[2], "\n"])
- fconfig.writelines(["#Update interval in minutes\n", "interval="+str(self.config[3]), "\n"])
- fconfig.writelines(["#RegExp pattern\n", "regexp="+self.config[4], "\n"])
- fconfig.writelines(["#Widget width\n", "width="+str(self.config[5]), "\n"])
- fconfig.writelines(["#Execute query at start\n", "query_at_start="+str(self.config[6]), "\n"])
- fconfig.writelines(["#Retry pattern\n"])
- fconfig.write("retry=")
- first = True
- for i in self.config[7]:
- if not first:
- fconfig.write ("-")
- fconfig.write(str(i))
- first = False
- fconfig.write("\n")
- fconfig.writelines(["#Font description\n", "font="+self.config[8].to_string(), "\n"])
- fconfig.writelines(["#Font color\n", "text_color="+self.widget.get_text_color().to_string(), "\n"])
- fconfig.writelines(["#Background color\n", "bg_color="+self.widget.get_bg_color().to_string(), "\n"])
- fconfig.writelines(["#Widget name\n", "name="+self.config[9], "\n"])
- fconfig.writelines(["#Show banner\n", "show_box="+str(self.config[11]), "\n"])
- fconfig.writelines(["#USSD reply language\n", "language="+str(self.config[10]), "\n"])
- fconfig.writelines(["#Additional ussdquery.py arguments\n", "args="+self.config[13], "\n"])
- fconfig.writelines(["#Regexp matching group\n", "reggroup="+str(self.config[14]), "\n"])
- fconfig.writelines(["#Use SMS listener\n", "listen_sms="+str(self.config[15]), "\n"])
- fconfig.writelines(["#Number,from which SMS should come\n", "sms_number="+self.config[16], "\n"])
- fconfig.writelines(["#SMS RegExp pattern\n", "sms_regexp="+self.config[17], "\n"])
- fconfig.writelines(["#SMS timeout\n", "sms_timeout="+str(self.config[18]), "\n"])
- fconfig.close()
-
- fcntl.flock(lockf,fcntl.LOCK_UN)
- lockf.close()
-
- def get_config(self):
- return self.config
-
- def read_config( self, id ):
- try :
- self.id = id
- config = open(os.getenv("HOME")+"/.ussdWidget.conf","r")
-
- error = False
- i = 0
- my_section = False
- for line in config :
- i += 1
- if line[0] == '#':
- continue
- if line[0] == '%':
- my_section = line[1:].strip() == id
- continue
-
- if not my_section:
- # This is config for another instace
- continue
-
- line=line.split('=', 1)
-
- if len(line) != 2 :
- error = True
- print _("Error reading config on line %(line)d. = or # expected.")%{"line":i}
- continue
- if line[0] == "number" :
- self.config[0] = line[1].strip()
- elif line[0] == "parser" :
- self.config[1] = line[1].strip()
- elif line[0] == "parser_box" :
- self.config[12] = line[1].strip()
- elif line[0] == "chain" :
- self.config[2] = line[1].strip()
- elif line[0] == "interval" :
- try:
- self.config[3] = int(line[1].strip())
- except:
- error = True
- print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
- continue
- elif line[0] == "regexp" :
- self.config[4] = line[1].strip()
- elif line[0] == "width" :
- try:
- self.config[5] = int(line[1].strip())
- except:
- error = True
- print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
- continue
- elif line[0] == "query_at_start" :
- if line[1].strip() == "True" :
- self.config[6] = True
- else :
- self.config[6] = False
- elif line[0] == "retry" :
- line[1] = line[1].strip()
- if line[1] != "":
- line[1] = line[1].split("-")
- i = 0
- while i < len(line[1]) :
- try:
- line[1][i] = int(line[1][i])
- except:
- error = True
- print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
- i += 1
- self.config[7] = line[1]
- else:
- self.config[7] = []
- continue
- elif line[0] == "font" :
- try:
- self.config[8] = pango.FontDescription(line[1].strip())
- except:
- error = True
- print _("Error reading config on line %(line)d. Pango font description expected.")%{"line":i}
- continue
- elif line[0] == "bg_color" :
- try:
- self.widget.set_bg_color(gtk.gdk.color_parse(line[1].strip()))
- except:
- error = True
- print _("Error reading config on line %(line)d. Expected color definition.")%{"line":i}
- elif line[0] == "text_color" :
- try:
- self.widget.set_text_color(gtk.gdk.color_parse(line[1].strip()))
- except:
- error = True
- print _("Error reading config on line %(line)d. Expected color definition.")%{"line":i}
- elif line[0] == "name" :
- self.config[9] = line[1].strip()
- elif line[0] == "show_box" :
- if line[1].strip() == "True" :
- self.config[11] = True
- else :
- self.config[11] = False
- elif line[0] == "language" :
- try:
- if int(line[1].strip()) >=0 and int(line[1].strip()) < len(ussd_languages):
- self.config[10] = int(line[1].strip())
- else:
- error = True
- print _("Error reading config on line %(line)d. Unknown language code.")%{"line":i}
- except:
- error = True
- print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
- elif line[0] == "args" :
- self.config[13] = line[1].strip()
- elif line[0] == "reggroup" :
- try:
- self.config[14] = int(line[1].strip())
- except:
- error = True
- print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
- continue
- elif line[0] == "listen_sms" :
- if line[1].strip() == "True" :
- self.config[15] = True
- else :
- self.config[15] = False
- elif line[0] == "sms_number" :
- self.config[16] = line[1].strip()
- elif line[0] == "sms_regexp" :
- self.config[17] = line[1].strip()
- elif line[0] == "sms_timeout" :
- try:
- self.config[18] = int(line[1].strip())
- except:
- error = True
- print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
- continue
- else :
- error = True
- print _("Error reading config on line %(line)d. Unexpected variable: ")%{"line":i}+line[0]
- continue
-
- config.close()
-
- if error :
- self.widget.error = 1
- self.widget.set_text (_("Config error"), 5000)
-
- return self.config
- except IOError:
- self.widget.error = 1
- self.widget.set_text (_("Config error"), 0)
- print _("IO error while reading config")
-
- return self.default_config
-
- def on_show_settings( self, widget ) :
- dialog = UssdConfigDialog(self.config, self.widget.get_bg_color(), self.widget.get_text_color(), self.id)
-
- while True:
- if dialog.run() != gtk.RESPONSE_OK :
- dialog.destroy()
- return
-
- test = check_regexp(dialog.regexp.get_text())
- if test :
- dialog.on_error_regexp(test)
- continue
-
- # Check, that we have ussd number
- if not check_number(dialog.ussdNumber.get_text()):
- dialog.on_error_ussd_number()
- continue
-
- if not check_number(dialog.sms_number.get_text()):
- dialog.on_error_sms_number()
- continue
-
- # Parse retry pattern
- retry = dialog.retryEdit.get_text().strip()
- if retry != "" :
- retry = retry.split("-")
- i = 0
- while i < len(retry) :
- try:
- retry[i] = int(retry[i])
- except:
- dialog.on_error_retry_pattern()
- break
- i += 1
-
- if i < len(retry):
- continue
- else :
- retry = []
-
- break
-
- self.config = [
- dialog.ussdNumber.get_text(),
- dialog.parser.get_text(),
- dialog.chain.get_text(),
- dialog.update_interval.get_value(),
- dialog.regexp.get_text(),
- dialog.widthEdit.get_value(),
- dialog.query_at_start.get_active(),
- retry,
- dialog.font,
- dialog.wname.get_text(),
- dialog.language.get_active(),
- dialog.show_box.get_active(),
- dialog.b_parser.get_text(),
- dialog.args.get_text(),
- dialog.reggroup.get_value(),
- dialog.sms_listener.get_active(),
- dialog.sms_number.get_text(),
- dialog.sms_regexp.get_text(),
- dialog.sms_timeout.get_value()
- ]
-
- widget.set_bg_color(dialog.bg_color)
- widget.set_text_color(dialog.text_color)
-
- self.save_config()
-
- widget.set_width(self.config[5])
- self.reset_timed_renew()
- self.widget.label.modify_font(self.config[8])
-
- dialog.destroy()
-
- # Before running this function widget wasn't configured
- if self.config == self.default_config:
- self.widget.set_text(_("Click to update"))
- return
-
- def handle_sms(self, pdumsg, msgcenter, message, sendernumber):
- # Timeout was recieved first
- if self.sms_ready:
- return
-
- if self.config[16] == "" or self.config[16] == sendernumber:
- pdu = gsmdecode.decode_pdu (pdumsg)
- if pdu != None :
- self.sms_reply += pdu['user_data']
- if not pdu['part']:
- if self.config[17] == "" or re.search( self.config[17], message, re.MULTILINE | re.UNICODE ):
- self.sms_ready = True
- self.sms_signal.remove()
- self.process_reply()
-
- def callback_ussd_data( self, source, condition ):
- if condition == gobject.IO_IN or condition == gobject.IO_PRI :
- data = source.read( )
- if len( data ) > 0 :
- self.cb_reply += data
- return True
- else :
- self.cb_ready = 1
- return False
-
- elif condition == gobject.IO_HUP or condition == gobject.IO_ERR :
- self.cb_ready = 1
- self.ussd_ready = True
- self.process_reply()
- return False
-
- print (_("serious problems in program logic"))
- # This will force widget to show error message
- self.cb_reply = ""
- self.cb_ready = 1
- self.process_reply()
- return False
-
-
- def call_external_script( self, ussd_code, language ):
- self.cb_ready = 0
- self.cb_reply = "";
- p = subprocess.Popen(['/usr/bin/ussdquery.py', ussd_code, "-l", ussd_languages[language]] + smart_split_string(self.config[13],"%","&"), stdout=subprocess.PIPE)
- gobject.io_add_watch( p.stdout, gobject.IO_IN | gobject.IO_PRI | gobject.IO_HUP | gobject.IO_ERR , self.callback_ussd_data )
-
- def ussd_renew(self, widget, event):
- if self.widget.processing == 0:
- if self.config :
- widget.processing = 1
- widget.set_text(_("Processing"), 0)
-
- self.ussd_ready = False
- self.sms_ready = False
- self.sms_reply = ""
-
- if self.config[15]:
- self.sms_counter += 1
- self.retry_timer = gobject.timeout_add (1000*self.config[18], self.sms_timeout, self.sms_counter)
-
- self.bus = dbus.SystemBus()
- self.sms_signal = self.bus.add_signal_receiver(self.handle_sms, path='/com/nokia/phone/SMS', dbus_interface='Phone.SMS', signal_name='IncomingSegment')
-
- self.call_external_script( self.config[0], self.config[10] )
- else :
- widget.processing = 0
- widget.error = 1
- widget.set_text(_("No config"), 0)
-
- def process_reply( self ):
- if not self.ussd_ready or not self.sms_ready and self.config[15]:
- return
-
- reply = self.cb_reply.strip()
- sms_reply = self.sms_reply.strip()
-
- if reply == "" or self.config[15] and sms_reply == "" :
- self.widget.error = 1
- self.widget.set_text (_("Error"), 5000)
- if self.retry_state == len(self.config[7]):
- self.retry_version += 1
- self.retry_state = 0
- else :
- self.retry_timer = gobject.timeout_add (1000*self.config[7][self.retry_state], self.retry_renew, self.retry_version)
- self.retry_state += 1
- else :
- self.widget.error = 0
- # Apply regexp
- reresult1 = reresult2 = None
- if self.config[4] != "":
- reresult1 = re.search( self.config[4], reply, re.MULTILINE | re.UNICODE )
- if self.config[17] != "":
- reresult2 = re.search( self.config[17], sms_reply, re.MULTILINE | re.UNICODE )
- w_reply = b_reply = reply
- if self.widget.error == 0:
- # Pass to box parser
- if self.config[12] != "" and self.config[11]:
- try:
- p = subprocess.Popen(smart_split_string(self.config[12], reply, sms_reply, reresult1, reresult2), stdout=subprocess.PIPE)
- b_reply = p.communicate()[0].strip()
- except Exception, e:
- print _("Couldn't exec banner parser:")+str(e)
- self.widget.error = 1
- else:
- if self.config[4] != "":
- try :
- b_reply = reresult1.group( self.config[14] )
- except Exception, e:
- self.widget.error = 1
- b_reply = _("Group not found: \n") + reply
-
- # Pass to widget parser
- if self.config[1] != "":
- try:
- p = subprocess.Popen(smart_split_string(self.config[1], reply, sms_reply, reresult1, reresult2), stdout=subprocess.PIPE)
- w_reply = p.communicate()[0].strip()
- except Exception, e:
- print _("Couldn't exec widget parser:")+str(e)
- self.widget.error = 1
- else:
- if self.config[4] != "":
- try :
- w_reply = reresult1.group( self.config[14] )
- except Exception, e:
- self.widget.error = 1
- w_reply = _("Group not found: \n") + reply
- # Pass to chain
- if self.config[2] != "":
- try:
- p = subprocess.Popen(smart_split_string(self.config[2], reply, sms_reply, reresult1, reresult2))
- except Exception, e:
- print _("Couldn't exec chain:")+str(e)
- self.widget.error = 1
- if self.config[11]:
- banner = hildon.hildon_banner_show_information (self.widget, "", b_reply)
- banner.set_timeout (5000)
- b_reply
- self.widget.set_text(w_reply)
- self.widget.processing = 0
-
- def sms_timeout(self, version):
- if version == self.sms_counter :
- self.sms_reply = ""
- self.sms_ready = True
- self.sms_signal.remove()
- self.process_reply()
- return False
-
- def timed_renew(self, version):
- if version < self.timeout_version :
- return False
- self.ussd_renew(self.widget, None)
- return True
-
- def retry_renew(self,version):
- if self.widget.error == 0 or self.widget.processing == 1 or version < self.retry_version :
- return False
- self.ussd_renew(self.widget, None)
- return False
-
- def reset_timed_renew (self) :
- self.timeout_version += 1
- if self.config[3] != 0 :
- self.timer = gobject.timeout_add (60000*self.config[3], self.timed_renew, self.timeout_version)
+ def __init__( self, widget ) :
+ self.widget = widget
+ # number, parser, chain, interval, regexp, width, execute_at_start,
+ # retry pattern, font, name, language, show_message_box,
+ # message_box_parser, additional arguments, regexp group,
+ # use SMS listener, SMS number, SMS regexp, SMS timeout
+ self.default_config = ["", "", "", 0, "", 0, True, [],\
+ pango.FontDescription("Nokia Sans 18"), _("Click to update"),\
+ 15, False, "", "", 1, False, "", "", 60]
+ self.config = self.default_config
+ self.timeout_version = 0
+ self.retry_version = 0
+ self.retry_state = 0
+ self.sms_counter = 0
+ self.sms_reply = ""
+
+ def save_config( self ) :
+ configname = os.getenv("HOME")+"/.ussdWidget.conf"
+ # Aquire lock
+ lockf = open(configname+".lock", 'a')
+ fcntl.flock(lockf,fcntl.LOCK_EX)
+
+ oldconfig=""
+ try:
+ fconfig = open(configname,"r")
+ #Read configuration of other instances
+ my_section = False
+ for line in fconfig :
+ if line[0] == '%':
+ my_section = line[1:].strip() == self.id
+ if not my_section:
+ oldconfig += line
+ fconfig.close()
+ except:
+ print >> log, _("Couldn't read previous config")
+
+ fconfig = open(configname,"w")
+ fconfig.seek(0)
+ fconfig.write(oldconfig)
+ fconfig.write("%"+self.id+"\n");
+ fconfig.writelines(["#USSD query to be run by widget\n", "number="+self.config[0], "\n"])
+ fconfig.writelines(["#Parser command for widget\n", "parser="+self.config[1], "\n"])
+ fconfig.writelines(["#Parser command for banner\n", "parser_box="+self.config[12], "\n"])
+ fconfig.writelines(["#Chain command\n", "chain="+self.config[2], "\n"])
+ fconfig.writelines(["#Update interval in minutes\n", "interval="+str(self.config[3]), "\n"])
+ fconfig.writelines(["#RegExp pattern\n", "regexp="+self.config[4], "\n"])
+ fconfig.writelines(["#Widget width\n", "width="+str(self.config[5]), "\n"])
+ fconfig.writelines(["#Execute query at start\n", "query_at_start="+str(self.config[6]), "\n"])
+ fconfig.writelines(["#Retry pattern\n"])
+ fconfig.write("retry=")
+ first = True
+ for i in self.config[7]:
+ if not first:
+ fconfig.write ("-")
+ fconfig.write(str(i))
+ first = False
+ fconfig.write("\n")
+ fconfig.writelines(["#Font description\n", "font="+self.config[8].to_string(), "\n"])
+ fconfig.writelines(["#Font color\n", "text_color="+self.widget.get_text_color().to_string(), "\n"])
+ fconfig.writelines(["#Background color\n", "bg_color="+self.widget.get_bg_color().to_string(), "\n"])
+ fconfig.writelines(["#Widget name\n", "name="+self.config[9], "\n"])
+ fconfig.writelines(["#Show banner\n", "show_box="+str(self.config[11]), "\n"])
+ fconfig.writelines(["#USSD reply language\n", "language="+str(self.config[10]), "\n"])
+ fconfig.writelines(["#Additional ussdquery.py arguments\n", "args="+self.config[13], "\n"])
+ fconfig.writelines(["#Regexp matching group\n", "reggroup="+str(self.config[14]), "\n"])
+ fconfig.writelines(["#Use SMS listener\n", "listen_sms="+str(self.config[15]), "\n"])
+ fconfig.writelines(["#Number,from which SMS should come\n", "sms_number="+self.config[16], "\n"])
+ fconfig.writelines(["#SMS RegExp pattern\n", "sms_regexp="+self.config[17], "\n"])
+ fconfig.writelines(["#SMS timeout\n", "sms_timeout="+str(self.config[18]), "\n"])
+ fconfig.close()
+
+ fcntl.flock(lockf,fcntl.LOCK_UN)
+ lockf.close()
+
+ def get_config(self):
+ return self.config
+
+ def read_config( self, id ):
+ try :
+ self.id = id
+ config = open(os.getenv("HOME")+"/.ussdWidget.conf","r")
+
+ error = False
+ i = 0
+ my_section = False
+ for line in config :
+ i += 1
+ if line[0] == '#':
+ continue
+ if line[0] == '%':
+ my_section = line[1:].strip() == id
+ continue
+
+ if not my_section:
+ # This is config for another instace
+ continue
+
+ line=line.split('=', 1)
+
+ if len(line) != 2 :
+ error = True
+ print >> log, _("Error reading config on line %(line)d. = or # expected.")%{"line":i}
+ continue
+ if line[0] == "number" :
+ self.config[0] = line[1].strip()
+ elif line[0] == "parser" :
+ self.config[1] = line[1].strip()
+ elif line[0] == "parser_box" :
+ self.config[12] = line[1].strip()
+ elif line[0] == "chain" :
+ self.config[2] = line[1].strip()
+ elif line[0] == "interval" :
+ try:
+ self.config[3] = int(line[1].strip())
+ except:
+ error = True
+ print >> log, _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
+ continue
+ elif line[0] == "regexp" :
+ self.config[4] = line[1].strip()
+ elif line[0] == "width" :
+ try:
+ self.config[5] = int(line[1].strip())
+ except:
+ error = True
+ print >> log, _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
+ continue
+ elif line[0] == "query_at_start" :
+ if line[1].strip() == "True" :
+ self.config[6] = True
+ else :
+ self.config[6] = False
+ elif line[0] == "retry" :
+ line[1] = line[1].strip()
+ if line[1] != "":
+ line[1] = line[1].split("-")
+ i = 0
+ while i < len(line[1]) :
+ try:
+ line[1][i] = int(line[1][i])
+ except:
+ error = True
+ print >> log, _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
+ i += 1
+ self.config[7] = line[1]
+ else:
+ self.config[7] = []
+ continue
+ elif line[0] == "font" :
+ try:
+ self.config[8] = pango.FontDescription(line[1].strip())
+ except:
+ error = True
+ print >> log, _("Error reading config on line %(line)d. Pango font description expected.")%{"line":i}
+ continue
+ elif line[0] == "bg_color" :
+ try:
+ self.widget.set_bg_color(gtk.gdk.color_parse(line[1].strip()))
+ except:
+ error = True
+ print >> log, _("Error reading config on line %(line)d. Expected color definition.")%{"line":i}
+ elif line[0] == "text_color" :
+ try:
+ self.widget.set_text_color(gtk.gdk.color_parse(line[1].strip()))
+ except:
+ error = True
+ print >> log, _("Error reading config on line %(line)d. Expected color definition.")%{"line":i}
+ elif line[0] == "name" :
+ self.config[9] = line[1].strip()
+ elif line[0] == "show_box" :
+ if line[1].strip() == "True" :
+ self.config[11] = True
+ else :
+ self.config[11] = False
+ elif line[0] == "language" :
+ try:
+ if int(line[1].strip()) >=0 and int(line[1].strip()) < len(ussd_languages):
+ self.config[10] = int(line[1].strip())
+ else:
+ error = True
+ print >> log, _("Error reading config on line %(line)d. Unknown language code.")%{"line":i}
+ except:
+ error = True
+ print >> log, _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
+ elif line[0] == "args" :
+ self.config[13] = line[1].strip()
+ elif line[0] == "reggroup" :
+ try:
+ self.config[14] = int(line[1].strip())
+ except:
+ error = True
+ print >> log, _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
+ continue
+ elif line[0] == "listen_sms" :
+ if line[1].strip() == "True" :
+ self.config[15] = True
+ else :
+ self.config[15] = False
+ elif line[0] == "sms_number" :
+ self.config[16] = line[1].strip()
+ elif line[0] == "sms_regexp" :
+ self.config[17] = line[1].strip()
+ elif line[0] == "sms_timeout" :
+ try:
+ self.config[18] = int(line[1].strip())
+ except:
+ error = True
+ print >> log, _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
+ continue
+ else :
+ error = True
+ print >> log, _("Error reading config on line %(line)d. Unexpected variable: ")%{"line":i}+line[0]
+ continue
+
+ config.close()
+
+ if error :
+ self.widget.error = 1
+ self.widget.set_text (_("Config error"), 5000)
+
+ return self.config
+ except IOError:
+ self.widget.error = 1
+ self.widget.set_text (_("Config error"), 0)
+ print >> log, _("IO error while reading config")
+
+ return self.default_config
+
+ def on_show_settings( self, widget ) :
+ dialog = UssdConfigDialog(self.config, self.widget.get_bg_color(), self.widget.get_text_color(), self.id)
+
+ while True:
+ if dialog.run() != gtk.RESPONSE_OK :
+ dialog.destroy()
+ return
+
+ test = check_regexp(dialog.regexp.get_text())
+ if test :
+ dialog.on_error_regexp(test)
+ continue
+
+ # Check, that we have ussd number
+ if not check_number(dialog.ussdNumber.get_text()):
+ dialog.on_error_ussd_number()
+ continue
+
+ if not check_number(dialog.sms_number.get_text()):
+ dialog.on_error_sms_number()
+ continue
+
+ # Parse retry pattern
+ retry = dialog.retryEdit.get_text().strip()
+ if retry != "" :
+ retry = retry.split("-")
+ i = 0
+ while i < len(retry) :
+ try:
+ retry[i] = int(retry[i])
+ except:
+ dialog.on_error_retry_pattern()
+ break
+ i += 1
+
+ if i < len(retry):
+ continue
+ else :
+ retry = []
+
+ break
+
+ self.config = [
+ dialog.ussdNumber.get_text(),
+ dialog.parser.get_text(),
+ dialog.chain.get_text(),
+ dialog.update_interval.get_value(),
+ dialog.regexp.get_text(),
+ dialog.widthEdit.get_value(),
+ dialog.query_at_start.get_active(),
+ retry,
+ dialog.font,
+ dialog.wname.get_text(),
+ dialog.language.get_active(),
+ dialog.show_box.get_active(),
+ dialog.b_parser.get_text(),
+ dialog.args.get_text(),
+ dialog.reggroup.get_value(),
+ dialog.sms_listener.get_active(),
+ dialog.sms_number.get_text(),
+ dialog.sms_regexp.get_text(),
+ dialog.sms_timeout.get_value()
+ ]
+
+ widget.set_bg_color(dialog.bg_color)
+ widget.set_text_color(dialog.text_color)
+
+ self.save_config()
+
+ widget.set_width(self.config[5])
+ self.reset_timed_renew()
+ self.widget.label.modify_font(self.config[8])
+
+ dialog.destroy()
+
+ # Before running this function widget wasn't configured
+ if self.config == self.default_config:
+ self.widget.set_text(_("Click to update"))
+ return
+
+ def handle_sms(self, pdumsg, msgcenter, message, sendernumber):
+ # Timeout was recieved first
+ if self.sms_ready:
+ return
+
+ if self.config[16] == "" or self.config[16] == sendernumber:
+ pdu = gsmdecode.decode_pdu (pdumsg)
+ if pdu != None :
+ self.sms_reply += pdu['user_data']
+ if not pdu['part']:
+ if self.config[17] == "" or re.search( self.config[17], message, re.MULTILINE | re.UNICODE ):
+ self.sms_ready = True
+ self.sms_signal.remove()
+ self.process_reply()
+
+ def callback_ussd_data(self, source, condition, process):
+ if condition == gobject.IO_IN or condition == gobject.IO_PRI:
+ data = source.read()
+ self.cb_reply += data
+ return True
+
+ if condition == gobject.IO_ERR:
+ print >> log, "Communication error occured"
+ # This will force widget to show error message
+ self.cb_reply = ""
+
+ if condition == gobject.IO_HUP:
+ # Pipe is broken, so ussd-query.py is already terminating
+ # and we wouldn't wait fot it too long
+ retcode = process.wait()
+ if retcode != 0:
+ self.cb_reply = ""
+
+ self.ussd_ready = True
+ self.process_reply()
+ return False
+
+ def callback_ussd_error(self, source, condition):
+ if condition == gobject.IO_IN or condition == gobject.IO_PRI:
+ self.error_message += source.read()
+ else:
+ if self.error_message != "":
+ print >> log, self.error_message
+
+ def call_external_script(self, ussd_code, language):
+ self.cb_reply = "";
+ process = subprocess.Popen(
+ ['/usr/bin/ussdquery.py', ussd_code, "-l", ussd_languages[language]] +\
+ smart_split_string(self.config[13],"%","&"),
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ process.stdin.close()
+ gobject.io_add_watch(
+ p.stdout, gobject.IO_IN | gobject.IO_PRI | gobject.IO_HUP | gobject.IO_ERR,
+ self.callback_ussd_data,
+ process)
+ self.error_message = "";
+ gobject.io_add_watch(
+ p.stderr, gobject.IO_IN | gobject.IO_PRI | gobject.IO_HUP | gobject.IO_ERR,
+ self.callback_ussd_error)
+
+ def ussd_renew(self, widget, event):
+ if self.widget.processing == 0:
+ if self.config :
+ widget.processing = 1
+ widget.set_text(_("Processing"), 0)
+
+ self.ussd_ready = False
+ self.sms_ready = False
+ self.sms_reply = ""
+
+ if self.config[15]:
+ self.sms_counter += 1
+ self.retry_timer = gobject.timeout_add (1000*self.config[18], self.sms_timeout, self.sms_counter)
+
+ self.bus = dbus.SystemBus()
+ self.sms_signal = self.bus.add_signal_receiver(self.handle_sms, path='/com/nokia/phone/SMS', dbus_interface='Phone.SMS', signal_name='IncomingSegment')
+
+ self.call_external_script( self.config[0], self.config[10] )
+ else :
+ widget.processing = 0
+ widget.error = 1
+ widget.set_text(_("No config"), 0)
+
+ def process_reply( self ):
+ if not self.ussd_ready or not self.sms_ready and self.config[15]:
+ return
+
+ reply = self.cb_reply.strip()
+ sms_reply = self.sms_reply.strip()
+
+ if reply == "" or self.config[15] and sms_reply == "" :
+ self.widget.error = 1
+ self.widget.set_text (_("Error"), 5000)
+ if self.retry_state == len(self.config[7]):
+ self.retry_version += 1
+ self.retry_state = 0
+ else :
+ self.retry_timer = gobject.timeout_add (1000*self.config[7][self.retry_state], self.retry_renew, self.retry_version)
+ self.retry_state += 1
+ else :
+ self.widget.error = 0
+ # Apply regexp
+ reresult1 = reresult2 = None
+ if self.config[4] != "":
+ reresult1 = re.search( self.config[4], reply, re.MULTILINE | re.UNICODE )
+ if self.config[17] != "":
+ reresult2 = re.search( self.config[17], sms_reply, re.MULTILINE | re.UNICODE )
+ w_reply = b_reply = reply
+ if self.widget.error == 0:
+ # Pass to box parser
+ if self.config[12] != "" and self.config[11]:
+ try:
+ p = subprocess.Popen(smart_split_string(self.config[12], reply, sms_reply, reresult1, reresult2), stdout=subprocess.PIPE)
+ b_reply = p.communicate()[0].strip()
+ except Exception, e:
+ print >> log, _("Couldn't exec banner parser:")+str(e)
+ self.widget.error = 1
+ else:
+ if self.config[4] != "":
+ try :
+ b_reply = reresult1.group( self.config[14] )
+ except Exception, e:
+ self.widget.error = 1
+ b_reply = _("Group not found: \n") + reply
+
+ # Pass to widget parser
+ if self.config[1] != "":
+ try:
+ p = subprocess.Popen(smart_split_string(self.config[1], reply, sms_reply, reresult1, reresult2), stdout=subprocess.PIPE)
+ w_reply = p.communicate()[0].strip()
+ except Exception, e:
+ print >> log, _("Couldn't exec widget parser:")+str(e)
+ self.widget.error = 1
+ else:
+ if self.config[4] != "":
+ try :
+ w_reply = reresult1.group( self.config[14] )
+ except Exception, e:
+ self.widget.error = 1
+ w_reply = _("Group not found: \n") + reply
+ # Pass to chain
+ if self.config[2] != "":
+ try:
+ p = subprocess.Popen(smart_split_string(self.config[2], reply, sms_reply, reresult1, reresult2))
+ except Exception, e:
+ print >> log, _("Couldn't exec chain:")+str(e)
+ self.widget.error = 1
+ if self.config[11]:
+ banner = hildon.hildon_banner_show_information (self.widget, "", b_reply)
+ banner.set_timeout (5000)
+ b_reply
+ self.widget.set_text(w_reply)
+ self.widget.processing = 0
+
+ def sms_timeout(self, version):
+ if version == self.sms_counter :
+ self.sms_reply = ""
+ self.sms_ready = True
+ self.sms_signal.remove()
+ self.process_reply()
+ return False
+
+ def timed_renew(self, version):
+ if version < self.timeout_version :
+ return False
+ self.ussd_renew(self.widget, None)
+ return True
+
+ def retry_renew(self,version):
+ if self.widget.error == 0 or self.widget.processing == 1 or version < self.retry_version :
+ return False
+ self.ussd_renew(self.widget, None)
+ return False
+
+ def reset_timed_renew (self) :
+ self.timeout_version += 1
+ if self.config[3] != 0 :
+ self.timer = gobject.timeout_add (60000*self.config[3], self.timed_renew, self.timeout_version)
class pHelpDialog(gtk.Dialog):
- def __init__(self, heading, text):
- gtk.Dialog.__init__(self, heading, None,
- gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR,
- (_("OK").encode("utf-8"), gtk.RESPONSE_OK))
- label = gtk.Label(text)
- label.set_line_wrap (True)
- self.vbox.add(label)
- self.show_all()
- self.parent
+ def __init__(self, heading, text):
+ gtk.Dialog.__init__(self, heading, None,
+ gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR,
+ (_("OK").encode("utf-8"), gtk.RESPONSE_OK))
+ label = gtk.Label(text)
+ label.set_line_wrap (True)
+ self.vbox.add(label)
+ self.show_all()
+ self.parent
class UssdConfigDialog(gtk.Dialog):
- def __init__(self, config, bg_color, text_color, id):
- gtk.Dialog.__init__(self, _("USSD widget : "+id), None,
- gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR,
- (_("Save").encode("utf-8"), gtk.RESPONSE_OK))
-
- self.font = config[8]
- self.bg_color = bg_color
- self.text_color = text_color
-
- self.set_size_request(-1, 400)
- self.ussdNumber = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.ussdNumber.set_text(config[0])
- self.parser = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.parser.set_text(config[1])
- self.b_parser = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.b_parser.set_text(config[12])
-
- self.chain = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.chain.set_text(config[2])
- self.update_interval = hildon.NumberEditor(0, 9999)
- self.update_interval.set_value(config[3])
- self.regexp = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.regexp.set_text(config[4])
- self.widthEdit = hildon.NumberEditor(0, 1000)
- self.widthEdit.set_value(config[5])
- self.retryEdit = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.args = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.args.set_text(config[13])
- self.reggroup = hildon.NumberEditor(0, 255)
- self.reggroup.set_value(config[14])
-
- selector = hildon.TouchSelector(text=True)
- for i in ussd_languages_localized:
- selector.append_text(i)
- self.language = hildon.PickerButton(gtk.HILDON_SIZE_AUTO, hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
- self.language.set_selector(selector)
- self.language.set_active(config[10])
- self.language.set_title(_("USSD reply language"))
- self.language.set_size_request(-1, -1)
-
- self.wname = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.wname.set_text(config[9])
- self.show_box = gtk.CheckButton(_("Enable banner. Parser:"))
- self.show_box.connect("toggled", self.show_box_changed)
- self.show_box.set_active(config[11])
-
- text = ""
- for i in config[7]:
- if text != "":
- text += "-"
- text += str(i)
- self.retryEdit.set_text(text)
-
- self.query_at_start = gtk.CheckButton(_("Execute query on start"))
- self.query_at_start.set_active(config[6])
-
- self.fontButton = gtk.Button(_("Font"))
- self.fontButton.connect("clicked", self.on_show_font_selection)
-
- self.colorButton = gtk.Button(_("Background color"))
- self.colorButton.connect("clicked", self.on_show_color_selection)
- self.textColorButton = gtk.Button(_("Text color"))
- self.textColorButton.connect("clicked", self.on_show_text_color_selection)
-
- phelp = gtk.Button("?")
- phelp.connect("clicked", self.on_show_phelp)
-
- bphelp = gtk.Button("?")
- bphelp.connect("clicked", self.on_show_bphelp)
-
- chelp = gtk.Button("?")
- chelp.connect("clicked", self.on_show_chelp)
-
- reghelp = gtk.Button("?")
- reghelp.connect("clicked", self.on_show_reghelp)
-
- retryhelp = gtk.Button("?")
- retryhelp.connect("clicked", self.on_show_retryhelp)
-
- numberhelp = gtk.Button("?")
- numberhelp.connect("clicked", self.on_show_number_help)
-
- area = hildon.PannableArea()
- self.vbox.add(area)
- vbox = gtk.VBox()
- area.add_with_viewport(vbox)
-
- numberBox = gtk.HBox()
- numberLabel = gtk.Label(_("USSD number"))
- numberLabel.set_alignment(0,0.6)
- numberLabel.set_size_request(100, -1)
- numberhelp.set_size_request(1, -1)
- self.ussdNumber.set_size_request(200, -1)
- numberBox.add(numberLabel)
- numberBox.add(numberhelp)
- numberBox.add(self.ussdNumber)
- vbox.add(numberBox)
-
- vbox.add(self.query_at_start)
-
- nameBox = gtk.HBox()
- nameLabel = gtk.Label(_("Name"))
- nameLabel.set_alignment(0,0.6)
- nameLabel.set_size_request(100, -1)
- self.wname.set_size_request(200, -1)
- nameBox.add(nameLabel)
- nameBox.add(self.wname)
- vbox.add(nameBox)
-
- parserBox = gtk.HBox()
- parserLabel = gtk.Label(_("Parser for widget"))
- parserLabel.set_alignment(0,0.6)
- parserLabel.set_size_request(200, -1)
- phelp.set_size_request(10, -1)
- parserBox.add(parserLabel)
- parserBox.add(phelp)
- vbox.add(parserBox)
- vbox.add(self.parser)
-
- b_parserBox = gtk.HBox()
- self.show_box.set_size_request(200, -1)
- bphelp.set_size_request(10, -1)
- b_parserBox.add(self.show_box)
- b_parserBox.add(bphelp)
- vbox.add(b_parserBox)
- vbox.add(self.b_parser)
-
- chainBox = gtk.HBox()
- chainLabel = gtk.Label(_("Chain"))
- chainLabel.set_alignment(0,0.6)
- chainLabel.set_size_request(200, -1)
- chelp.set_size_request(10, -1)
- chainBox.add(chainLabel)
- chainBox.add(chelp)
- vbox.add(chainBox)
- vbox.add(self.chain)
-
- regexpBox = gtk.HBox()
- regexpLabel = gtk.Label(_("Regular expression"))
- regexpLabel.set_alignment(0,0.6)
- regexpLabel.set_size_request(200, -1)
- regexpGroupLabel = gtk.Label(_("Group"))
- regexpGroupLabel.set_size_request(1, -1)
- reghelp.set_size_request(10, -1)
- regexpBox.add(regexpLabel)
- regexpBox.add(reghelp)
- regexpBox.add(regexpGroupLabel)
- vbox.add(regexpBox)
- self.reggroup.set_size_request(1,-1);
- self.regexp.set_size_request(250,-1);
- regexpInputBox = gtk.HBox()
- regexpInputBox.add(self.regexp)
- regexpInputBox.add(self.reggroup)
- vbox.add(regexpInputBox)
-
- widthBox = gtk.HBox()
- widthLabel = gtk.Label(_("Max. width"))
- widthLabel.set_alignment(0,0.6)
- symbolsLabel = gtk.Label(_("symbols"))
- widthLabel.set_size_request(140, -1)
- self.widthEdit.set_size_request(50, -1)
- symbolsLabel.set_size_request(40,-1)
- widthBox.add(widthLabel)
- widthBox.add(self.widthEdit)
- widthBox.add(symbolsLabel)
- vbox.add(widthBox)
-
- updateBox = gtk.HBox()
- updateLabel = gtk.Label(_("Update every"))
- updateLabel.set_alignment(0,0.6)
- minutesLabel = gtk.Label(_("minutes"))
- updateLabel.set_size_request(140, -1)
- self.update_interval.set_size_request(50, -1)
- minutesLabel.set_size_request(40, -1)
- updateBox.add(updateLabel)
- updateBox.add(self.update_interval)
- updateBox.add(minutesLabel)
- vbox.add(updateBox)
-
- retryBox = gtk.HBox()
- retryLabel = gtk.Label(_("Retry pattern"))
- retryLabel.set_alignment(0,0.6)
- retryLabel.set_size_request(200, -1)
- retryhelp.set_size_request(10, -1)
- retryBox.add(retryLabel)
- retryBox.add(retryhelp)
- vbox.add(retryBox)
- vbox.add(self.retryEdit)
-
- argsLabel = gtk.Label(_("Additional ussdquery.py options"))
- argsLabel.set_alignment(0,0.6)
- vbox.add(argsLabel)
- vbox.add(self.args)
-
- viewBox = gtk.HBox()
- viewBox.add(self.fontButton)
- viewBox.add(self.textColorButton)
- viewBox.add(self.colorButton)
- vbox.add(viewBox)
-
- self.sms_box = gtk.VBox()
- self.sms_listener = gtk.CheckButton(_("Enable SMS listener."))
- self.sms_listener.connect("toggled", self.sms_box_changed)
- self.sms_listener.set_active(config[15])
- vbox.add (self.sms_listener)
-
- self.sms_number = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.sms_number.set_text(config[16])
- smsNumberBox = gtk.HBox()
- smsNumberLabel = gtk.Label(_("SMS number"))
- smsNumberLabel.set_alignment(0,0.6)
- smsNumberLabel.set_size_request(100, -1)
- self.sms_number.set_size_request(200, -1)
- smsNumberBox.add(smsNumberLabel)
- smsNumberBox.add(self.sms_number)
- self.sms_box.add(smsNumberBox)
-
- smsRegexpLabel = gtk.Label(_("Regular expression"))
- smsRegexpLabel.set_alignment(0,0.6)
- self.sms_box.add(smsRegexpLabel)
-
- self.sms_regexp = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.sms_regexp.set_text(config[17])
- self.sms_box.add(self.sms_regexp)
-
- self.sms_timeout = hildon.NumberEditor(0, 9999)
- self.sms_timeout.set_value(config[18])
- sms_timeout_box = gtk.HBox()
- timeoutLabel = gtk.Label(_("Timeout"))
- timeoutLabel.set_alignment(0,0.6)
- secondsLabel = gtk.Label(_("seconds"))
- timeoutLabel.set_size_request(140, -1)
- self.sms_timeout.set_size_request(50, -1)
- secondsLabel.set_size_request(40, -1)
- sms_timeout_box.add(timeoutLabel)
- sms_timeout_box.add(self.sms_timeout)
- sms_timeout_box.add(secondsLabel)
- self.sms_box.add(sms_timeout_box)
-
- vbox.add(self.sms_box)
-
- vbox.add(gtk.Label(_("DO NOT CHANGE. Unspecified is what you want.")))
- vbox.add(self.language)
-
- self.show_all()
- self.show_box_changed(None)
- self.sms_box_changed(None)
- self.parent
-
- #============ Dialog helper functions =============
- def on_show_phelp(self, widget):
- dialog = pHelpDialog(_("Format help"), _("Reply would be passed to specified utility, output of utility would be shown to you on widget.\n Format:\n% would be replaced by reply\n%N with N'th regexp matching group\n& would be replaced with sms content\n&N with N'th sms regexp group\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility\n Hint: use echo \"Your string %\" to prepend your string to reply."))
- dialog.run()
- dialog.destroy()
-
- def on_show_bphelp(self, widget):
- dialog = pHelpDialog(_("Format help"), _("Reply would be passed to specified utility, output of utility would be shown to you on banner.\n Format:\n% would be replaced by reply\n%N with N'th regexp matching group\n& would be replaced with sms content\n&N with N'th sms regexp group\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility\n Hint: use echo \"Your string %\" to prepend your string to reply."))
- dialog.run()
- dialog.destroy()
-
- def on_show_chelp(self, widget):
- dialog = pHelpDialog(_("Format help"), _("Reply would be passed to specified utility after parser utility. May be used for logging, statistics etc.\n Format:\n% would be replaced by reply\n%N with N'th regexp matching group\n& would be replaced with sms content\n&N with N'th sms regexp group\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility\n"))
- dialog.run()
- dialog.destroy()
-
- def on_show_reghelp(self, widget):
- dialog = pHelpDialog(_("Format help"), _("Standard python regexps. Use\n (.+?[\d\,\.]+)\n to delete everything after first number."))
- dialog.run()
- dialog.destroy()
-
- def on_show_retryhelp(self, widget):
- dialog = pHelpDialog(_("Format help"), _("Pauses between attemps (in seconds), delimited by -. For example 15-15-300 means \"In case of failure wait 15 seconds, try again, on failure wait 15 more secodns and try again, on failure make last attempt after 5 minutes\""))
- dialog.run()
- dialog.destroy()
-
- def on_show_number_help(self, widget):
- dialog = pHelpDialog(_("Format help"), _("USSD number. To perform USSD menu navigation divide queries vith spacebars. For xample '*100# 1' means 1st entry in *100# menu."))
- dialog.run()
- dialog.destroy()
-
- def on_error_regexp(self, error):
- dialog = pHelpDialog(_("Regexp syntax error"), error )
- dialog.run()
- dialog.destroy()
-
- def on_error_ussd_number(self):
- dialog = pHelpDialog(_("Incorrect USSD number"), _("USSD number should contain only digits, +, * or #") )
- dialog.run()
- dialog.destroy()
-
- def on_error_retry_pattern(self):
- dialog = pHelpDialog(_("Incorrect retry pattern"), _("Retry pattern should contain only numbers, delimited by -") )
- dialog.run()
- dialog.destroy()
-
- def on_show_color_selection (self, event):
- colorDialog = gtk.ColorSelectionDialog(_("Choose background color"))
- colorDialog.colorsel.set_current_color(self.bg_color)
- if colorDialog.run() == gtk.RESPONSE_OK :
- self.bg_color = colorDialog.colorsel.get_current_color()
- colorDialog.destroy()
-
- def on_show_text_color_selection (self, event):
- colorDialog = gtk.ColorSelectionDialog(_("Choose text color"))
- colorDialog.colorsel.set_current_color(self.text_color)
- if colorDialog.run() == gtk.RESPONSE_OK :
- self.text_color = colorDialog.colorsel.get_current_color()
- colorDialog.destroy()
-
- def on_show_font_selection (self, event):
- fontDialog = gtk.FontSelectionDialog(_("Choose a font"))
- fontDialog.set_font_name(self.font.to_string())
-
- if fontDialog.run() != gtk.RESPONSE_OK :
- fontDialog.destroy()
- return
-
- self.font = pango.FontDescription (fontDialog.get_font_name())
- fontDialog.destroy()
-
- def show_box_changed (self, event):
- if self.show_box.get_active():
- self.b_parser.show()
- else:
- self.b_parser.hide()
-
- def sms_box_changed (self, event):
- if self.sms_listener.get_active():
- self.sms_box.show()
- else:
- self.sms_box.hide()
+ def __init__(self, config, bg_color, text_color, id):
+ gtk.Dialog.__init__(self, _("USSD widget : "+id), None,
+ gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR,
+ (_("Save").encode("utf-8"), gtk.RESPONSE_OK))
+
+ self.font = config[8]
+ self.bg_color = bg_color
+ self.text_color = text_color
+
+ self.set_size_request(-1, 400)
+ self.ussdNumber = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.ussdNumber.set_text(config[0])
+ self.parser = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.parser.set_text(config[1])
+ self.b_parser = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.b_parser.set_text(config[12])
+
+ self.chain = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.chain.set_text(config[2])
+ self.update_interval = hildon.NumberEditor(0, 9999)
+ self.update_interval.set_value(config[3])
+ self.regexp = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.regexp.set_text(config[4])
+ self.widthEdit = hildon.NumberEditor(0, 1000)
+ self.widthEdit.set_value(config[5])
+ self.retryEdit = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.args = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.args.set_text(config[13])
+ self.reggroup = hildon.NumberEditor(0, 255)
+ self.reggroup.set_value(config[14])
+
+ selector = hildon.TouchSelector(text=True)
+ for i in ussd_languages_localized:
+ selector.append_text(i)
+ self.language = hildon.PickerButton(gtk.HILDON_SIZE_AUTO, hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
+ self.language.set_selector(selector)
+ self.language.set_active(config[10])
+ self.language.set_title(_("USSD reply language"))
+ self.language.set_size_request(-1, -1)
+
+ self.wname = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.wname.set_text(config[9])
+ self.show_box = gtk.CheckButton(_("Enable banner. Parser:"))
+ self.show_box.connect("toggled", self.show_box_changed)
+ self.show_box.set_active(config[11])
+
+ text = ""
+ for i in config[7]:
+ if text != "":
+ text += "-"
+ text += str(i)
+ self.retryEdit.set_text(text)
+
+ self.query_at_start = gtk.CheckButton(_("Execute query on start"))
+ self.query_at_start.set_active(config[6])
+
+ self.fontButton = gtk.Button(_("Font"))
+ self.fontButton.connect("clicked", self.on_show_font_selection)
+
+ self.colorButton = gtk.Button(_("Background color"))
+ self.colorButton.connect("clicked", self.on_show_color_selection)
+ self.textColorButton = gtk.Button(_("Text color"))
+ self.textColorButton.connect("clicked", self.on_show_text_color_selection)
+
+ phelp = gtk.Button("?")
+ phelp.connect("clicked", self.on_show_phelp)
+
+ bphelp = gtk.Button("?")
+ bphelp.connect("clicked", self.on_show_bphelp)
+
+ chelp = gtk.Button("?")
+ chelp.connect("clicked", self.on_show_chelp)
+
+ reghelp = gtk.Button("?")
+ reghelp.connect("clicked", self.on_show_reghelp)
+
+ retryhelp = gtk.Button("?")
+ retryhelp.connect("clicked", self.on_show_retryhelp)
+
+ numberhelp = gtk.Button("?")
+ numberhelp.connect("clicked", self.on_show_number_help)
+
+ area = hildon.PannableArea()
+ self.vbox.add(area)
+ vbox = gtk.VBox()
+ area.add_with_viewport(vbox)
+
+ numberBox = gtk.HBox()
+ numberLabel = gtk.Label(_("USSD number"))
+ numberLabel.set_alignment(0,0.6)
+ numberLabel.set_size_request(100, -1)
+ numberhelp.set_size_request(1, -1)
+ self.ussdNumber.set_size_request(200, -1)
+ numberBox.add(numberLabel)
+ numberBox.add(numberhelp)
+ numberBox.add(self.ussdNumber)
+ vbox.add(numberBox)
+
+ vbox.add(self.query_at_start)
+
+ nameBox = gtk.HBox()
+ nameLabel = gtk.Label(_("Name"))
+ nameLabel.set_alignment(0,0.6)
+ nameLabel.set_size_request(100, -1)
+ self.wname.set_size_request(200, -1)
+ nameBox.add(nameLabel)
+ nameBox.add(self.wname)
+ vbox.add(nameBox)
+
+ parserBox = gtk.HBox()
+ parserLabel = gtk.Label(_("Parser for widget"))
+ parserLabel.set_alignment(0,0.6)
+ parserLabel.set_size_request(200, -1)
+ phelp.set_size_request(10, -1)
+ parserBox.add(parserLabel)
+ parserBox.add(phelp)
+ vbox.add(parserBox)
+ vbox.add(self.parser)
+
+ b_parserBox = gtk.HBox()
+ self.show_box.set_size_request(200, -1)
+ bphelp.set_size_request(10, -1)
+ b_parserBox.add(self.show_box)
+ b_parserBox.add(bphelp)
+ vbox.add(b_parserBox)
+ vbox.add(self.b_parser)
+
+ chainBox = gtk.HBox()
+ chainLabel = gtk.Label(_("Chain"))
+ chainLabel.set_alignment(0,0.6)
+ chainLabel.set_size_request(200, -1)
+ chelp.set_size_request(10, -1)
+ chainBox.add(chainLabel)
+ chainBox.add(chelp)
+ vbox.add(chainBox)
+ vbox.add(self.chain)
+
+ regexpBox = gtk.HBox()
+ regexpLabel = gtk.Label(_("Regular expression"))
+ regexpLabel.set_alignment(0,0.6)
+ regexpLabel.set_size_request(200, -1)
+ regexpGroupLabel = gtk.Label(_("Group"))
+ regexpGroupLabel.set_size_request(1, -1)
+ reghelp.set_size_request(10, -1)
+ regexpBox.add(regexpLabel)
+ regexpBox.add(reghelp)
+ regexpBox.add(regexpGroupLabel)
+ vbox.add(regexpBox)
+ self.reggroup.set_size_request(1,-1);
+ self.regexp.set_size_request(250,-1);
+ regexpInputBox = gtk.HBox()
+ regexpInputBox.add(self.regexp)
+ regexpInputBox.add(self.reggroup)
+ vbox.add(regexpInputBox)
+
+ widthBox = gtk.HBox()
+ widthLabel = gtk.Label(_("Max. width"))
+ widthLabel.set_alignment(0,0.6)
+ symbolsLabel = gtk.Label(_("symbols"))
+ widthLabel.set_size_request(140, -1)
+ self.widthEdit.set_size_request(50, -1)
+ symbolsLabel.set_size_request(40,-1)
+ widthBox.add(widthLabel)
+ widthBox.add(self.widthEdit)
+ widthBox.add(symbolsLabel)
+ vbox.add(widthBox)
+
+ updateBox = gtk.HBox()
+ updateLabel = gtk.Label(_("Update every"))
+ updateLabel.set_alignment(0,0.6)
+ minutesLabel = gtk.Label(_("minutes"))
+ updateLabel.set_size_request(140, -1)
+ self.update_interval.set_size_request(50, -1)
+ minutesLabel.set_size_request(40, -1)
+ updateBox.add(updateLabel)
+ updateBox.add(self.update_interval)
+ updateBox.add(minutesLabel)
+ vbox.add(updateBox)
+
+ retryBox = gtk.HBox()
+ retryLabel = gtk.Label(_("Retry pattern"))
+ retryLabel.set_alignment(0,0.6)
+ retryLabel.set_size_request(200, -1)
+ retryhelp.set_size_request(10, -1)
+ retryBox.add(retryLabel)
+ retryBox.add(retryhelp)
+ vbox.add(retryBox)
+ vbox.add(self.retryEdit)
+
+ argsLabel = gtk.Label(_("Additional ussdquery.py options"))
+ argsLabel.set_alignment(0,0.6)
+ vbox.add(argsLabel)
+ vbox.add(self.args)
+
+ viewBox = gtk.HBox()
+ viewBox.add(self.fontButton)
+ viewBox.add(self.textColorButton)
+ viewBox.add(self.colorButton)
+ vbox.add(viewBox)
+
+ self.sms_box = gtk.VBox()
+ self.sms_listener = gtk.CheckButton(_("Enable SMS listener."))
+ self.sms_listener.connect("toggled", self.sms_box_changed)
+ self.sms_listener.set_active(config[15])
+ vbox.add (self.sms_listener)
+
+ self.sms_number = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.sms_number.set_text(config[16])
+ smsNumberBox = gtk.HBox()
+ smsNumberLabel = gtk.Label(_("SMS number"))
+ smsNumberLabel.set_alignment(0,0.6)
+ smsNumberLabel.set_size_request(100, -1)
+ self.sms_number.set_size_request(200, -1)
+ smsNumberBox.add(smsNumberLabel)
+ smsNumberBox.add(self.sms_number)
+ self.sms_box.add(smsNumberBox)
+
+ smsRegexpLabel = gtk.Label(_("Regular expression"))
+ smsRegexpLabel.set_alignment(0,0.6)
+ self.sms_box.add(smsRegexpLabel)
+
+ self.sms_regexp = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.sms_regexp.set_text(config[17])
+ self.sms_box.add(self.sms_regexp)
+
+ self.sms_timeout = hildon.NumberEditor(0, 9999)
+ self.sms_timeout.set_value(config[18])
+ sms_timeout_box = gtk.HBox()
+ timeoutLabel = gtk.Label(_("Timeout"))
+ timeoutLabel.set_alignment(0,0.6)
+ secondsLabel = gtk.Label(_("seconds"))
+ timeoutLabel.set_size_request(140, -1)
+ self.sms_timeout.set_size_request(50, -1)
+ secondsLabel.set_size_request(40, -1)
+ sms_timeout_box.add(timeoutLabel)
+ sms_timeout_box.add(self.sms_timeout)
+ sms_timeout_box.add(secondsLabel)
+ self.sms_box.add(sms_timeout_box)
+
+ vbox.add(self.sms_box)
+
+ vbox.add(gtk.Label(_("DO NOT CHANGE. Unspecified is what you want.")))
+ vbox.add(self.language)
+
+ self.show_all()
+ self.show_box_changed(None)
+ self.sms_box_changed(None)
+ self.parent
+
+ #============ Dialog helper functions =============
+ def on_show_phelp(self, widget):
+ dialog = pHelpDialog(_("Format help"), _("Reply would be passed to specified utility, output of utility would be shown to you on widget.\n Format:\n% would be replaced by reply\n%N with N'th regexp matching group\n& would be replaced with sms content\n&N with N'th sms regexp group\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility\n Hint: use echo \"Your string %\" to prepend your string to reply."))
+ dialog.run()
+ dialog.destroy()
+
+ def on_show_bphelp(self, widget):
+ dialog = pHelpDialog(_("Format help"), _("Reply would be passed to specified utility, output of utility would be shown to you on banner.\n Format:\n% would be replaced by reply\n%N with N'th regexp matching group\n& would be replaced with sms content\n&N with N'th sms regexp group\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility\n Hint: use echo \"Your string %\" to prepend your string to reply."))
+ dialog.run()
+ dialog.destroy()
+
+ def on_show_chelp(self, widget):
+ dialog = pHelpDialog(_("Format help"), _("Reply would be passed to specified utility after parser utility. May be used for logging, statistics etc.\n Format:\n% would be replaced by reply\n%N with N'th regexp matching group\n& would be replaced with sms content\n&N with N'th sms regexp group\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility\n"))
+ dialog.run()
+ dialog.destroy()
+
+ def on_show_reghelp(self, widget):
+ dialog = pHelpDialog(_("Format help"), _("Standard python regexps. Use\n (.+?[\d\,\.]+)\n to delete everything after first number."))
+ dialog.run()
+ dialog.destroy()
+
+ def on_show_retryhelp(self, widget):
+ dialog = pHelpDialog(_("Format help"), _("Pauses between attemps (in seconds), delimited by -. For example 15-15-300 means \"In case of failure wait 15 seconds, try again, on failure wait 15 more secodns and try again, on failure make last attempt after 5 minutes\""))
+ dialog.run()
+ dialog.destroy()
+
+ def on_show_number_help(self, widget):
+ dialog = pHelpDialog(_("Format help"), _("USSD number. To perform USSD menu navigation divide queries vith spacebars. For xample '*100# 1' means 1st entry in *100# menu."))
+ dialog.run()
+ dialog.destroy()
+
+ def on_error_regexp(self, error):
+ dialog = pHelpDialog(_("Regexp syntax error"), error )
+ dialog.run()
+ dialog.destroy()
+
+ def on_error_ussd_number(self):
+ dialog = pHelpDialog(_("Incorrect USSD number"), _("USSD number should contain only digits, +, * or #") )
+ dialog.run()
+ dialog.destroy()
+
+ def on_error_retry_pattern(self):
+ dialog = pHelpDialog(_("Incorrect retry pattern"), _("Retry pattern should contain only numbers, delimited by -") )
+ dialog.run()
+ dialog.destroy()
+
+ def on_show_color_selection (self, event):
+ colorDialog = gtk.ColorSelectionDialog(_("Choose background color"))
+ colorDialog.colorsel.set_current_color(self.bg_color)
+ if colorDialog.run() == gtk.RESPONSE_OK :
+ self.bg_color = colorDialog.colorsel.get_current_color()
+ colorDialog.destroy()
+
+ def on_show_text_color_selection (self, event):
+ colorDialog = gtk.ColorSelectionDialog(_("Choose text color"))
+ colorDialog.colorsel.set_current_color(self.text_color)
+ if colorDialog.run() == gtk.RESPONSE_OK :
+ self.text_color = colorDialog.colorsel.get_current_color()
+ colorDialog.destroy()
+
+ def on_show_font_selection (self, event):
+ fontDialog = gtk.FontSelectionDialog(_("Choose a font"))
+ fontDialog.set_font_name(self.font.to_string())
+
+ if fontDialog.run() != gtk.RESPONSE_OK :
+ fontDialog.destroy()
+ return
+
+ self.font = pango.FontDescription (fontDialog.get_font_name())
+ fontDialog.destroy()
+
+ def show_box_changed (self, event):
+ if self.show_box.get_active():
+ self.b_parser.show()
+ else:
+ self.b_parser.hide()
+
+ def sms_box_changed (self, event):
+ if self.sms_listener.get_active():
+ self.sms_box.show()
+ else:
+ self.sms_box.hide()
def smart_split_string (str, reply1, reply2, reres1 = None, reres2 = None) :
- word = ""
- result = []
- # Is simbol backslashed?
- bs = 0
- # Quotes: 1 - ", 2 - ', 0 - no quotes
- qs = 0
- # Read out number
- num = -1
- # Current substitution simbol
- subst = ''
-
- for i in range(len(str)) :
- if num>= 0:
- if str[i] in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] :
- num *= 10
- num += int(str[i])
- continue
- else:
- if subst == '&':
- if reres2 != None and num != 0:
- word += reres2.group(num)
- else:
- word += reply2
- else:
- if reres1 != None and num != 0:
- word += reres1.group(num)
- else:
- word += reply1
- ws = 0
- num = -1
- subst = ''
- # Delete backslash if it delimites usual numbers from % or &
- if str[i] == '\\' and i < len(str)-1 and str[i+1] in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] :
- continue
- if bs == 0 and (str[i] == '"' and qs == 1 or str[i] == "'" and qs == 2) :
- qs = 0
- elif bs == 0 and qs == 0 and (str[i] == '"' or str[i] == "'") :
- if str[i] == '"':
- qs = 1
- else :
- qs = 2
- elif bs == 0 and str[i] == '\\' :
- bs = 1
- elif bs == 0 and (str[i] == '%' or str[i] == '&') :
- subst = str[i]
- num = 0
- else :
- if bs == 1 and str[i] != '\\' and str[i] != '"' and str[i] != "'" :
- word += "\\"
- if qs == 0 and (str[i] == " " or str[i] == "\t") :
- if word != "" :
- result.append(word)
- word = ""
- else :
- word += str[i]
- bs = 0
-
- if subst == '&':
- if reres2 != None and num != 0 and num != -1:
- word += reres2.group(num)
- else:
- word += reply2
- elif subst == '%':
- if reres1 != None and num != 0 and num != -1:
- word += reres1.group(num)
- else:
- word += reply1
- if word != "" :
- result.append(word)
- return result
+ word = ""
+ result = []
+ # Is simbol backslashed?
+ bs = 0
+ # Quotes: 1 - ", 2 - ', 0 - no quotes
+ qs = 0
+ # Read out number
+ num = -1
+ # Current substitution simbol
+ subst = ''
+
+ for i in range(len(str)) :
+ if num>= 0:
+ if str[i] in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] :
+ num *= 10
+ num += int(str[i])
+ continue
+ else:
+ if subst == '&':
+ if reres2 != None and num != 0:
+ word += reres2.group(num)
+ else:
+ word += reply2
+ else:
+ if reres1 != None and num != 0:
+ word += reres1.group(num)
+ else:
+ word += reply1
+ ws = 0
+ num = -1
+ subst = ''
+ # Delete backslash if it delimites usual numbers from % or &
+ if str[i] == '\\' and i < len(str)-1 and str[i+1] in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] :
+ continue
+ if bs == 0 and (str[i] == '"' and qs == 1 or str[i] == "'" and qs == 2) :
+ qs = 0
+ elif bs == 0 and qs == 0 and (str[i] == '"' or str[i] == "'") :
+ if str[i] == '"':
+ qs = 1
+ else :
+ qs = 2
+ elif bs == 0 and str[i] == '\\' :
+ bs = 1
+ elif bs == 0 and (str[i] == '%' or str[i] == '&') :
+ subst = str[i]
+ num = 0
+ else :
+ if bs == 1 and str[i] != '\\' and str[i] != '"' and str[i] != "'" :
+ word += "\\"
+ if qs == 0 and (str[i] == " " or str[i] == "\t") :
+ if word != "" :
+ result.append(word)
+ word = ""
+ else :
+ word += str[i]
+ bs = 0
+
+ if subst == '&':
+ if reres2 != None and num != 0 and num != -1:
+ word += reres2.group(num)
+ else:
+ word += reply2
+ elif subst == '%':
+ if reres1 != None and num != 0 and num != -1:
+ word += reres1.group(num)
+ else:
+ word += reply1
+ if word != "" :
+ result.append(word)
+ return result
def check_regexp(regexp):
- try :
- re.compile( regexp )
- except Exception, e:
- return str(e)
- return False
+ try :
+ re.compile( regexp )
+ except Exception, e:
+ return str(e)
+ return False
def check_number(number):
- for s in number :
- if not (s in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "+", "*", "#", " "]) :
- return False
- return True
+ for s in number :
+ if not (s in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "+", "*", "#", " "]) :
+ return False
+ return True
#=============== The widget itself ================
def get_color(logicalcolorname):
- settings = gtk.settings_get_default()
- color_style = gtk.rc_get_style_by_paths(settings, 'GtkButton', 'osso-logical-colors', gtk.Button)
- return color_style.lookup_color(logicalcolorname)
+ settings = gtk.settings_get_default()
+ color_style = gtk.rc_get_style_by_paths(settings, 'GtkButton', 'osso-logical-colors', gtk.Button)
+ return color_style.lookup_color(logicalcolorname)
class UssdWidgetPlugin(hildondesktop.HomePluginItem):
- def __init__(self):
- hildondesktop.HomePluginItem.__init__(self)
-
- self.processing = 0
- self.bg_color=gtk.gdk.color_parse('#000000')
- self.text_color=gtk.gdk.color_parse('#ffffff')
- self.error = 0
- self.timeout_version = 0
-
- colormap = self.get_screen().get_rgba_colormap()
- self.set_colormap (colormap)
-
- self.controller = USSD_Controller(self)
-
+ def __init__(self):
+ hildondesktop.HomePluginItem.__init__(self)
+
+ self.processing = 0
+ self.bg_color=gtk.gdk.color_parse('#000000')
+ self.text_color=gtk.gdk.color_parse('#ffffff')
+ self.error = 0
+ self.timeout_version = 0
+
+ colormap = self.get_screen().get_rgba_colormap()
+ self.set_colormap (colormap)
+
+ self.controller = USSD_Controller(self)
+
# TODO Click event would be better
- self.connect("button-press-event", self.controller.ussd_renew)
-
- self.vbox = gtk.HBox()
- self.add(self.vbox)
-
- self.set_settings(True)
- self.connect("show-settings", self.controller.on_show_settings)
- self.label = gtk.Label("")
-
- self.vbox.add(self.label)
- self.vbox.set_child_packing(self.label, False, False, 0, gtk.PACK_START)
- self.label.set_padding(15, 10)
- self.label.set_size_request(-1,-1)
- self.set_size_request(-1,-1)
- self.label.set_line_wrap (True)
-
- self.vbox.show_all()
-
- DBusGMainLoop(set_as_default=True)
- bus = dbus.SystemBus()
- signal = bus.add_signal_receiver(self.set_bg_color_text, path='/su/kibergus/ussd_widget', dbus_interface='su.kibergus.ussd_widget', signal_name='set_bg_color')
- signal = bus.add_signal_receiver(self.set_text_color_text, path='/su/kibergus/ussd_widget', dbus_interface='su.kibergus.ussd_widget', signal_name='set_text_color')
- signal = bus.add_signal_receiver(self.ussd_renew, path='/su/kibergus/ussd_widget', dbus_interface='su.kibergus.ussd_widget', signal_name='renew')
-
- def do_show(self):
- config = self.controller.read_config(self.get_applet_id())
- self.set_width(config[5])
- self.set_text(config[9])
- if config[6]:
- self.controller.ussd_renew(self, None)
-
- self.label.modify_font(config[8])
- self.controller.reset_timed_renew()
- hildondesktop.HomePluginItem.do_show(self)
-
- def error_return (self):
- if self.error == 1 and self.processing == 0:
- self.set_text(self.text)
- return False
-
- # showfor =
- # -1 - This is a permanent text message
- # 0 - This is service message, but it shouldn't be hidden automatically
- # >0 - This is service message, show permament message after showfor milliseconds
- def set_text(self, text, showfor=-1):
- if showfor > 0 :
- # Show previous text after 5 seconds
- gobject.timeout_add (showfor, self.error_return)
- else :
- if showfor == -1 :
- self.text = text
-
- config = self.controller.get_config()
- self.label.set_text(text)
-
- def get_text(self):
- return self.text
-
- def set_width(self, width):
- if width != 0:
- self.label.set_width_chars (width)
- else :
- self.label.set_width_chars(-1)
-
- def ussd_renew(self, id):
- if id == self.get_applet_id():
- self.controller.ussd_renew(self, None)
-
- def set_bg_color_text(self, id, color):
- if id == self.get_applet_id():
- try :
- self.set_bg_color(gtk.gdk.color_parse(color.strip()))
- except:
- print _("Unable to parse colour specification")
- self.queue_draw()
-
- def set_text_color_text(self, id, color):
- if id == self.get_applet_id():
- try:
- self.set_text_color(gtk.gdk.color_parse(color.strip()))
- except:
- print _("Unable to parse colour specification")
- self.queue_draw()
-
- def set_bg_color(self, color):
- self.bg_color = color
-
- def get_bg_color(self):
- return self.bg_color
-
- def set_text_color(self, color):
- self.label.modify_fg(gtk.STATE_NORMAL, color)
- self.text_color = color
-
- def get_text_color(self):
- return self.text_color
-
- def _expose(self, event):
- cr = self.window.cairo_create()
-
- # draw rounded rect
- width, height = self.label.allocation[2], self.label.allocation[3]
-
- #/* a custom shape, that could be wrapped in a function */
- x0 = 0 #/*< parameters like cairo_rectangle */
- y0 = 0
-
- radius = min(15, width/2, height/2) #/*< and an approximate curvature radius */
-
- x1 = x0 + width
- y1 = y0 + height
-
- cr.move_to (x0, y0 + radius)
- cr.arc (x0 + radius, y0 + radius, radius, 3.14, 1.5 * 3.14)
- cr.line_to (x1 - radius, y0)
- cr.arc (x1 - radius, y0 + radius, radius, 1.5 * 3.14, 0.0)
- cr.line_to (x1 , y1 - radius)
- cr.arc (x1 - radius, y1 - radius, radius, 0.0, 0.5 * 3.14)
- cr.line_to (x0 + radius, y1)
- cr.arc (x0 + radius, y1 - radius, radius, 0.5 * 3.14, 3.14)
-
- cr.close_path ()
-
- fg_color = get_color("ActiveTextColor")
-
- if self.processing :
- bg_color=fg_color
- else :
- bg_color=self.bg_color
-
- cr.set_source_rgba (bg_color.red / 65535.0, bg_color.green/65535.0, bg_color.blue/65535.0, 0.7)
- cr.fill_preserve ()
-
- if self.error :
- cr.set_source_rgba (1.0, 0.0, 0.0, 0.5)
- else :
- cr.set_source_rgba (fg_color.red / 65535.0, fg_color.green / 65535.0, fg_color.blue / 65535.0, 0.7)
- cr.stroke ()
-
- def do_expose_event(self, event):
- self.chain(event)
- self._expose (event)
- self.vbox.do_expose_event (self, event)
+ self.connect("button-press-event", self.controller.ussd_renew)
+
+ self.vbox = gtk.HBox()
+ self.add(self.vbox)
+
+ self.set_settings(True)
+ self.connect("show-settings", self.controller.on_show_settings)
+ self.label = gtk.Label("")
+
+ self.vbox.add(self.label)
+ self.vbox.set_child_packing(self.label, False, False, 0, gtk.PACK_START)
+ self.label.set_padding(15, 10)
+ self.label.set_size_request(-1,-1)
+ self.set_size_request(-1,-1)
+ self.label.set_line_wrap (True)
+
+ self.vbox.show_all()
+
+ DBusGMainLoop(set_as_default=True)
+ bus = dbus.SystemBus()
+ signal = bus.add_signal_receiver(self.set_bg_color_text, path='/su/kibergus/ussd_widget', dbus_interface='su.kibergus.ussd_widget', signal_name='set_bg_color')
+ signal = bus.add_signal_receiver(self.set_text_color_text, path='/su/kibergus/ussd_widget', dbus_interface='su.kibergus.ussd_widget', signal_name='set_text_color')
+ signal = bus.add_signal_receiver(self.ussd_renew, path='/su/kibergus/ussd_widget', dbus_interface='su.kibergus.ussd_widget', signal_name='renew')
+
+ def do_show(self):
+ config = self.controller.read_config(self.get_applet_id())
+ self.set_width(config[5])
+ self.set_text(config[9])
+ if config[6]:
+ self.controller.ussd_renew(self, None)
+
+ self.label.modify_font(config[8])
+ self.controller.reset_timed_renew()
+ hildondesktop.HomePluginItem.do_show(self)
+
+ def error_return (self):
+ if self.error == 1 and self.processing == 0:
+ self.set_text(self.text)
+ return False
+
+ # showfor =
+ # -1 - This is a permanent text message
+ # 0 - This is service message, but it shouldn't be hidden automatically
+ # >0 - This is service message, show permament message after showfor milliseconds
+ def set_text(self, text, showfor=-1):
+ if showfor > 0 :
+ # Show previous text after 5 seconds
+ gobject.timeout_add (showfor, self.error_return)
+ else :
+ if showfor == -1 :
+ self.text = text
+
+ config = self.controller.get_config()
+ self.label.set_text(text)
+
+ def get_text(self):
+ return self.text
+
+ def set_width(self, width):
+ if width != 0:
+ self.label.set_width_chars (width)
+ else :
+ self.label.set_width_chars(-1)
+
+ def ussd_renew(self, id):
+ if id == self.get_applet_id():
+ self.controller.ussd_renew(self, None)
+
+ def set_bg_color_text(self, id, color):
+ if id == self.get_applet_id():
+ try :
+ self.set_bg_color(gtk.gdk.color_parse(color.strip()))
+ except:
+ print >> log, _("Unable to parse colour specification")
+ self.queue_draw()
+
+ def set_text_color_text(self, id, color):
+ if id == self.get_applet_id():
+ try:
+ self.set_text_color(gtk.gdk.color_parse(color.strip()))
+ except:
+ print >> log, _("Unable to parse colour specification")
+ self.queue_draw()
+
+ def set_bg_color(self, color):
+ self.bg_color = color
+
+ def get_bg_color(self):
+ return self.bg_color
+
+ def set_text_color(self, color):
+ self.label.modify_fg(gtk.STATE_NORMAL, color)
+ self.text_color = color
+
+ def get_text_color(self):
+ return self.text_color
+
+ def _expose(self, event):
+ cr = self.window.cairo_create()
+
+ # draw rounded rect
+ width, height = self.label.allocation[2], self.label.allocation[3]
+
+ #/* a custom shape, that could be wrapped in a function */
+ x0 = 0 #/*< parameters like cairo_rectangle */
+ y0 = 0
+
+ radius = min(15, width/2, height/2) #/*< and an approximate curvature radius */
+
+ x1 = x0 + width
+ y1 = y0 + height
+
+ cr.move_to (x0, y0 + radius)
+ cr.arc (x0 + radius, y0 + radius, radius, 3.14, 1.5 * 3.14)
+ cr.line_to (x1 - radius, y0)
+ cr.arc (x1 - radius, y0 + radius, radius, 1.5 * 3.14, 0.0)
+ cr.line_to (x1 , y1 - radius)
+ cr.arc (x1 - radius, y1 - radius, radius, 0.0, 0.5 * 3.14)
+ cr.line_to (x0 + radius, y1)
+ cr.arc (x0 + radius, y1 - radius, radius, 0.5 * 3.14, 3.14)
+
+ cr.close_path ()
+
+ fg_color = get_color("ActiveTextColor")
+
+ if self.processing :
+ bg_color=fg_color
+ else :
+ bg_color=self.bg_color
+
+ cr.set_source_rgba (bg_color.red / 65535.0, bg_color.green/65535.0, bg_color.blue/65535.0, 0.7)
+ cr.fill_preserve ()
+
+ if self.error :
+ cr.set_source_rgba (1.0, 0.0, 0.0, 0.5)
+ else :
+ cr.set_source_rgba (fg_color.red / 65535.0, fg_color.green / 65535.0, fg_color.blue / 65535.0, 0.7)
+ cr.stroke ()
+
+ def do_expose_event(self, event):
+ self.chain(event)
+ self._expose (event)
+ self.vbox.do_expose_event (self, event)
hd_plugin_type = UssdWidgetPlugin
# The code below is just for testing purposes.
# It allows to run the widget as a standalone process.
if __name__ == "__main__":
- plugin_id = "ussd-widget.console"
- if len(sys.argv) == 2:
- try:
- plugin_id = "ussd-widget.desktop-"+str(int(sys.argv[1]))
- except:
- print "Plugin id must be integer"
- sys.exit(-1)
-
- import gobject
- gobject.type_register(hd_plugin_type)
- obj = gobject.new(hd_plugin_type, plugin_id=plugin_id)
- obj.show_all()
- gtk.main()
+ plugin_id = "ussd-widget.console"
+ if len(sys.argv) == 2:
+ try:
+ plugin_id = "ussd-widget.desktop-"+str(int(sys.argv[1]))
+ except:
+ print >> log, "Plugin id must be integer"
+ sys.exit(-1)
+
+ import gobject
+ gobject.type_register(hd_plugin_type)
+ obj = gobject.new(hd_plugin_type, plugin_id=plugin_id)
+ obj.show_all()
+ gtk.main()