Package screenlets :: Module utils

[hide private]
[frames] | no frames]

# Source Code for Module screenlets.utils

      1  # This application is released under the GNU General Public License
      2  # v3 (or, at your option, any later version). You can find the full
      3  # text of the license under http://www.gnu.org/licenses/gpl.txt.
      4  # By using, editing and/or distributing this software you agree to
      5  # the terms and conditions of this license.
      6  # Thank you for using free software!
      7
      8  #  screenlets.utils (c) Whise (Helder Fraga) 2008 <helder.fraga@hotmail.com>
      9  #  Originaly by RYX (Rico Pfaus) 2007 <ryx@ryxperience.com>
     10  #
     11  # TODO: move more functions here when possible
     12  #
     13
     14  import screenlets
     15  import gtk
     16  import dbus
     17  import os
     18  import sys
     19  import stat
     20  import gettext
     21  import re
     22  import urllib
     23  gettext.textdomain('screenlets')
     24  gettext.bindtextdomain('screenlets', screenlets.INSTALL_PREFIX +  '/share/locale')
     25  import gobject
     26  try:
     27          import gnomevfs
     28  except:
     29          pass
     30 -def _(s):
     31          return gettext.gettext(s)
     32
     33  # ------------------------------------------------------------------------------
     34  # FUNCTIONS
     35  # ------------------------------------------------------------------------------
     36
     37
     38 -def get_autostart_dir():
     39          """Returns the system autostart directory"""
     40          desktop_environment = 'gnome'
     41
     42          if os.environ.get('KDE_FULL_SESSION') == 'true':
     43              desktop_environment = 'kde'
     44          elif os.environ.get('GNOME_DESKTOP_SESSION_ID'):
     45              desktop_environment = 'gnome'
     46          else:
     47              try:
     48                  import commands
     49                  info = commands.getoutput('xprop -root _DT_SAVE_MODE')
     50                  if ' = "xfce4"' in info:
     51                      desktop_environment = 'xfce'
     52              except (OSError, RuntimeError):
     53                  pass
     54
     55
     56
     57          if desktop_environment == 'kde':
     58                  return os.environ['HOME'] + '/.kde/Autostart/'
     59          elif desktop_environment == 'gnome':
     60                  return os.environ['HOME'] + '/.config/autostart/'
     61          elif desktop_environment == 'xfce':
     62                  return os.environ['HOME'] + '/.config/autostart/'
     63
     64  if os.geteuid()==0:
     65          # we run as root, install system-wide
     66          USER = 0
     67          DIR_USER                = screenlets.INSTALL_PREFIX + '/share/screenlets'
     68          DIR_AUTOSTART   = '/etc/xdg/autostart'                  # TODO: use pyxdg here
     69  else:
     70          # we run as normal user, install into $HOME
     71          USER = 1
     72          DIR_USER                = os.environ['HOME'] + '/.screenlets'
     73          DIR_AUTOSTART = get_autostart_dir()
     74
     75
     76
     77 -def is_manager_running_me():
     78          """checks if the one starting the screenlet is the screenlets manager"""
     79          if str(sys.argv[0]).find('screenlets-manager') != -1:
     80                  return True
     81          else:
     82                  return False
     83
     84 -def containsAll(str, set):
     85          """Check whether 'str' contains ALL of the chars in 'set'"""
     86          for c in set:
     87                  if c not in str: return 0;
     88          return 1;
     89 -def containsAny(str, set):
     90          """Check whether 'str' contains ANY of the chars in 'set'"""
     91          return 1 in [c in str for c in set]
     92
     93 -def create_autostarter (name):
     94          """Create a .desktop-file for the screenlet with the given name in
     95          $HOME/.config/autostart."""
     96          if not os.path.isdir(DIR_AUTOSTART):
     97                  # create autostart directory, if not existent
     98                  if screenlets.show_question(None,
     99                          _("There is no existing autostart directory for your user account yet. Do you want me to automatically create it for you?"),
    100                          _('Error')):
    101                          print _("Auto-create autostart dir ...")
    102                          os.system('mkdir %s' % DIR_AUTOSTART)
    103                          if not os.path.isdir(DIR_AUTOSTART):
    104                                  screenlets.show_error(None, _("Automatic creation failed. Please manually create the directory:\n%s") % DIR_AUTOSTART, _('Error'))
    105                                  return False
    106                  else:
    107                          screenlets.show_message(None, _("Please manually create the directory:\n%s") % DIR_AUTOSTART)
    108                          return False
    109          if name.endswith('Screenlet'):
    110                  name = name[:-9]
    111          starter = '%s%sScreenlet.desktop' % (DIR_AUTOSTART, name)
    112
    113          for f in os.listdir(DIR_AUTOSTART):
    114                  a = f.find(name + 'Screenlet')
    115                  if a != -1:
    116                          print str(f) + ' duplicate entry'
    117                          os.system('rm %s%s' % (chr(34)+DIR_AUTOSTART,f+chr(34)))
    118                          print _('Removed duplicate entry')
    119          if not os.path.isfile(starter) and not os.path.exists(os.environ['HOME'] + '/.config/autostart/CalendarScreenlet'):
    120                  path = find_first_screenlet_path(name)
    121                  if path:
    122                          print _("Create autostarter for: %s/%sScreenlet.py") % (path, name)
    123                          code = ['[Desktop Entry]']
    124                          code.append('Name=%sScreenlet' % name)
    125                          code.append('Encoding=UTF-8')
    126                          code.append('Version=1.0')
    127                          code.append('Type=Application')
    128                          code.append('Exec= python -u %s/%sScreenlet.py' % (path, name))
    129                          code.append('X-GNOME-Autostart-enabled=true')
    130                          #print code
    131                          f = open(starter, 'w')
    132                          if f:
    133                                  for l in code:
    134                                          f.write(l + '\n')
    135                                  f.close()
    136                                  return True
    137                          print _('Failed to create autostarter for %s.') % name
    138                          return False
    139          else:
    140                  print _("Starter already exists.")
    141                  return True
    142
    143 -def delete_autostarter ( name):
    144          """Delete the autostart for the given screenlet."""
    145          if name.endswith('Screenlet'):
    146                  name = name[:-9]
    147          print _('Delete autostarter for %s.') % name
    148          os.system('rm %s%sScreenlet.desktop' % (DIR_AUTOSTART, name))
    149          for f in os.listdir(DIR_AUTOSTART):
    150                  a = f.find(name + 'Screenlet')
    151                  if a != -1:
    152                          print str(f) + ' duplicate entry'
    153                          os.system('rm %s%s' % (chr(34)+DIR_AUTOSTART,f+chr(34)))
    154                          print _('Removed duplicate entry')
    155
    156 -def _contains_path (string):
    157          """Internal function: Returns true if the given string contains one of the
    158          SCREENLETS_PATH entries."""
    159          for p in screenlets.SCREENLETS_PATH:
    160                  if string.find(p) > -1:
    161                          return True
    162          return False
    163
    164 -def create_user_dir ():
    165          """Create the userdir for the screenlets."""
    166          if not os.path.isdir(os.environ['HOME'] + '/.screenlets'):
    167                  try:
    168                          os.mkdir(os.environ['HOME'] + '/.screenlets')
    169                  except:
    170                          print 'coulnt create user dir'
    171
    172
    173 -def find_first_screenlet_path (screenlet_name):
    174          """Scan the SCREENLETS_PATH for the first occurence of screenlet "name" and
    175          return the full path to it. This function is used to get the theme/data
    176          directories for a Screenlet."""
    177          for dir in screenlets.SCREENLETS_PATH:
    178                  try:
    179                          for name in os.listdir(dir):
    180                                  name_py = name + 'Screenlet.py'
    181                                  path = dir + '/' + name
    182                                  if not stat.S_ISDIR(os.stat(path).st_mode):
    183                                          continue
    184                                  # if path exists
    185                                  if os.access(path + '/' + name_py, os.F_OK):
    186                                          if name == screenlet_name:
    187                                                  return path
    188                                  else:
    189                                          #print "utils.find_first_screenlet_path: "+\
    190                                          #       "LISTED PATH NOT EXISTS: " + path
    191                                          pass
    192                  except OSError: # Raised by os.listdir: the directory doesn't exist
    193                          pass
    194          # nothing found
    195          return None
    196
    197 -def get_screenlet_icon (screenlet_name,width,height):
    198          img = gtk.gdk.pixbuf_new_from_file_at_size(\
    199                          screenlets.INSTALL_PREFIX + '/share/screenlets-manager/noimage.svg',width,height)
    200          for path in screenlets.SCREENLETS_PATH:
    201                  for ext in ['svg', 'png']:
    202                          img_path = "%s/%s/icon.%s" % (path, screenlet_name, ext)
    203                          if os.path.isfile(img_path):
    204                                  try:
    205                                          img = gtk.gdk.pixbuf_new_from_file_at_size(img_path,width,height)
    206                                  except Exception, ex:
    207                                          pass
    208          return img
    209
    210 -def getBetween(data, first, last):
    211          x = len(first)
    212          begin = data.find(first) +x
    213          end = data.find(last, begin)
    214          return data[begin:end]
    215
    216 -def get_screenlet_metadata (screenlet_name):
    217          """Returns a dict with name, info, author and version of the given
    218          screenlet. Use with care because it always imports the screenlet
    219          module and shouldn't be used too often due to performance issues."""
    220          # find path to file
    221          path = find_first_screenlet_path(screenlet_name)
    222          classname = screenlet_name + 'Screenlet'
    223
    224          try:
    225                  slfile = open(path + '/'+ classname + '.py','r')
    226                  sldata = slfile.read()
    227                  slfile.close()
    228                  name = getBetween(sldata,'__name__','\n')
    229                  name1 = getBetween(name ,"'","'")
    230                  if name1.find(' = ') != -1: name1 = getBetween(name ,chr(34),chr(34))
    231                  info = getBetween(sldata,'__desc__','\n')
    232                  info1 = getBetween(info ,"'","'")
    233                  if info1.find(' = ') != -1: info1 = getBetween(info ,chr(34),chr(34))
    234                  if info1.find('_doc_') != -1:
    235                          info1 = getBetween(sldata ,'class ' + classname,'__name__')
    236                          info1 = getBetween(info1 ,chr(34) +chr(34)+chr(34),chr(34)+chr(34)+chr(34))
    237                  author = getBetween(sldata,'__author__','\n')
    238                  author1 = getBetween(author ,"'","'")
    239                  if author1.find(' = ') != -1: author1 = getBetween(author ,chr(34),chr(34))
    240                  version = getBetween(sldata,'__version__','\n')
    241                  version1 = getBetween(version ,"'","'")
    242                  if version1.find(' = ') != -1: version1 = getBetween(version ,chr(34),chr(34))
    243                  return {'name'  : name1,
    244                          'info'          : info1,
    245                          'author'        : author1,
    246                          'version'       : version1
    247                          }
    248          except:
    249                  try:
    250          # add path to PYTHONPATH
    251                          if sys.path.count(path) == 0:
    252                                  sys.path.insert(0, path)
    253                          slmod = __import__(classname)
    254                          cls = getattr(slmod, classname)
    255                          sys.path.remove(path)
    256                          return {'name'  : cls.__name__,
    257                                  'info'          : cls.__desc__,
    258                                  'author'        : cls.__author__,
    259                                  'version'       : cls.__version__
    260                                  }
    261                  except Exception, ex:
    262                          print _("Unable to load '%s' from %s: %s ") % (screenlet_name, path, ex)
    263                          return None
    264
    265 -def list_available_screenlets ():
    266          """Scan the SCREENLETS_PATHs for all existing screenlets and return their
    267          names (without trailing "Screenlet") as a list of strings."""
    268          sls = []
    269          for dir in screenlets.SCREENLETS_PATH:
    270                  try:
    271                          for name in os.listdir(dir):
    272                                  path = dir + '/' + name
    273                                  # check if entry is a dir
    274                                  if not stat.S_ISDIR(os.stat(path).st_mode):
    275                                          continue
    276                                  # if path exists, add it to list
    277                                  if os.access(path + '/' + name + 'Screenlet.py', os.F_OK):
    278                                          if not sls.count(name):
    279                                                  sls.append(name)
    280                                  else:
    281                                          pass
    282                  except OSError: # Raised by os.listdir: the directory doesn't exist
    283                          pass
    284          return sls
    285
    286  import session
    287 -def list_running_screenlets ():
    288          """Returns a list with names of running screenlets or None if no
    289          Screenlet is currently running. Function returns False if an error
    290          happened!"""
    291          running = []
    292          tempfile = screenlets.TMP_DIR + '/' + screenlets.TMP_FILE
    293          if not os.path.isfile(tempfile):
    294                  return None
    295          f = open(tempfile, 'r')
    296          if f:
    297                  running = f.readlines()
    298                  f.close()
    299                  for i in xrange(len(running)):
    300                          running[i] = running[i][:-1]    # strip trailing EOL
    301
    302          p = os.popen("ps aux | awk '/Screenlet.py/{ print $11, $12, $13, $14, $15, $16 }'")
    303          lst = []
    304          regex = re.compile('/([A-Za-z0-9]+)Screenlet.py ')
    305          for line in p.readlines():
    306                  if not line.endswith('awk /Screenlet.py/{\n') and line != 'sh -c\n' \
    307                          and _contains_path(line):
    308                          slname = regex.findall(line)
    309                          if slname and type(slname) == list and len(slname) > 0:
    310                                  lst.append(slname[0]+'Screenlet')
    311          p.close()
    312          for a in lst:
    313                  if a not in running:
    314                          running.append(a)
    315          return running
    316
    317
    318
    319 -def list_running_screenlets2 ():
    320          """Returns a list with names of running screenlets. The list can be empty if
    321          no Screenlet is currently running."""
    322          p = os.popen("ps aux | awk '/Screenlet.py/{ print $11, $12, $13, $14, $15, $16 }'")
    323          lst = []
    324          regex = re.compile('/([A-Za-z0-9]+)Screenlet.py ')
    325          for line in p.readlines():
    326                  if not line.endswith('awk /Screenlet.py/{\n') and line != 'sh -c\n' \
    327                          and _contains_path(line):
    328                          slname = regex.findall(line)
    329                          if slname and type(slname) == list and len(slname) > 0:
    330                                  lst.append(slname[0]+'Screenlet')
    331          p.close()
    332          return lst
    333
    334
    335
    336
    337 -def get_screenlet_process (name):
    338          """Returns the PID of the given screenlet (if running) or None."""
    339          p = os.popen("ps aux | awk '/[" + name[0] + "]" + name[1:] + \
    340                  "Screenlet.py/{ print $2, $11, $12, $13, $14, $15, $16 }'")
    341          line = p.readlines()
    342          p.close()
    343          #print line
    344          if len(line) and _contains_path(line[0]):
    345                  return int(line[0].split(' ')[0])
    346          return None
    347
    348 -def get_user_dir(key, default):
    349          """http://www.freedesktop.org/wiki/Software/xdg-user-dirs"""
    350
    351          user_dirs_dirs = os.path.expanduser("~/.config/user-dirs.dirs")
    352          if os.path.exists(user_dirs_dirs):
    353                  f = open(user_dirs_dirs, "r")
    354                  for line in f.readlines():
    355                          if line.startswith(key):
    356                                  return os.path.expandvars(line[len(key)+2:-2])
    357          return default
    358
    359 -def get_daemon_iface ():
    360          """Check if the daemon is already running and return its interface."""
    361          bus = dbus.SessionBus()
    362          if bus:
    363                  try:
    364                          proxy_obj = bus.get_object(screenlets.DAEMON_BUS, screenlets.DAEMON_PATH)
    365                          if proxy_obj:
    366                                  return dbus.Interface(proxy_obj, screenlets.DAEMON_IFACE)
    367
    368                  except Exception, ex:
    369                          print _("Error in ScreenletsManager.connect_daemon: %s") % ex
    370          return None
    371
    372 -def get_desktop_dir():
    373          """Returns desktop dir"""
    374          desktop_dir =  get_user_dir("XDG_DESKTOP_DIR", os.path.expanduser("~/Desktop"))
    375          desktop_dir = urllib.unquote(desktop_dir)
    376          return desktop_dir
    377
    378 -def get_filename_on_drop(sel_data):
    379          """Returns filenames of window droped files"""
    380          filename = ''
    381          filenames = []
    382          # get text-elements in selection data
    383          try:
    384                  txt = unicode.encode(sel_data.get_text(), 'utf-8')
    385          except:
    386                  txt = sel_data.get_text()
    387          txta = urllib.unquote(txt)
    388          txta = str(txta).split('\n')
    389
    390          for txt in txta:
    391                  if txt and txt != '':
    392                          # if it is a filename, use it
    393                          if txt.startswith('file://'):
    394                                  filename = txt[7:]
    395                          else:
    396                                  print 'Invalid string: %s.' % txt
    397                  else:
    398                          # else get uri-part of selection
    399                          uris = sel_data.get_uris()
    400                          if uris and len(uris)>0:
    401                                  #print "URIS: "+str(uris        )
    402                                  filename = uris[0][7:]
    403                  if filename != '':
    404                          filenames.append(chr(34) +filename + chr(34))
    405
    406          return filenames
    407
    408 -def LoadPlaces():
    409          """Returns mount points in media"""
    410          mountlist = os.popen('mount -l').read()
    411          prog = re.compile("^/dev/.*?\son\s/media/(.*?) .*?(\[(.*?)\])?$", re.MULTILINE)
    412          return prog.findall(mountlist)
    413
    414 -def LoadBookmarks():
    415          """Returns gtk bookmarks """
    416          _bookmarks_path = os.path.expanduser("~/.gtk-bookmarks")
    417          _places = []
    418          try:
    419                  for line in file(_bookmarks_path):
    420                          line = line.strip()
    421
    422                          if " " in line:
    423                                  uri, name = line.split(" ", 1)
    424
    425                          else:
    426                                  uri = line
    427
    428                                  path = urllib.splittype(uri)[1]
    429                                  name = urllib.unquote(os.path.split(path)[1])
    430
    431                          try:
    432                                  if os.path.exists(uri):
    433                                          continue
    434                  # Protect against a broken bookmarks file
    435                          except TypeError:
    436                                  continue
    437
    438                          _places.append((uri, name))
    439                  return _places
    440          except IOError, err:
    441              print "Error loading GTK bookmarks:", err
    442
    443 -def quit_screenlet_by_name ( name):
    444          """Quit all instances of the given screenlet type."""
    445          # get service for instance and call quit method
    446          service = screenlets.services.get_service_by_name(name)
    447          if service:
    448                  service.quit()
    449
    450 -def quit_all_screenlets():
    451
    452          a = list_running_screenlets()
    453          if a != None:
    454                  for s in a:
    455                          if s.endswith('Screenlet'):
    456                                  s = s[:-9]
    457                          try:
    458                                  quit_screenlet_by_name(s)
    459                          except:
    460                                  pass
    461
    462 -def restart_all_screenlets():
    463          quit_all_screenlets()
    464          for s in os.listdir(DIR_AUTOSTART):
    465                  if s.lower().endswith('screenlet.desktop'):
    466                          #s = s[:-17]
    467                          os.system('sh '+ DIR_AUTOSTART + s + ' &')
    468
    469 -def readMountFile( filename):
    470          """Reads fstab file"""
    471          fstab = []
    472          f = open(filename, 'r')
    473          for line in f:
    474                  if (not line.isspace() and not line.startswith('#') and not line.lower().startswith('none')) :
    475                          fstabline = line.split()
    476                          if fstabline[1] != 'none' and fstabline[1] != '/proc': fstab.append(fstabline[1])
    477
    478          fstab.sort()
    479          return fstab
    480
    481 -def read_file( filename):
    482          """Reads a file"""
    483          f = open(filename, 'r')
    484          t = f.read()
    485          f.close()
    486          return t
    487
    488
    489 -def strip_html(string):
    490          """Strips HTML tags of a string"""
    491          return re.sub(r"<.*?>|</.*?>","",string)
    492
    493
    494
    495 -def lookup_daemon_autostart ():
    496          """Adds Screenlets-daemon to autostart if not already"""
    497          if not os.path.isdir(DIR_AUTOSTART):
    498          # create autostart directory, if not existent
    499                  if screenlets.show_question(None, _("There is no existing autostart directory for your user account yet. Do you want me to automatically create it for you?"), _('Error')):
    500                          print _("Auto-create autostart dir ...")
    501                          os.system('mkdir %s' % DIR_AUTOSTART)
    502                          if not os.path.isdir(DIR_AUTOSTART):
    503                                  screenlets.show_error(None, _("Automatic creation failed. Please manually create the directory:\n%s") % DIR_AUTOSTART, _('Error'))
    504                                  return False
    505                  else:
    506                          screenlets.show_message(None, _("Please manually create the directory:\n%s") % DIR_AUTOSTART)
    507                          return False
    508          starter = '%sScreenlets Daemon.desktop' % (DIR_AUTOSTART)
    509
    510          if not os.path.isfile(starter) and os.path.isfile('%sscreenlets-daemon.desktop' % (DIR_AUTOSTART)) == False:
    511                  print _("Create autostarter for: Screenlets Daemon")
    512                  code = ['[Desktop Entry]']
    513                  code.append('Encoding=UTF-8')
    514                  code.append('Version=1.0')
    515                  code.append('Name=Screenlets Daemon')
    516                  code.append('Type=Application')
    517                  code.append('Exec=%s/share/screenlets-manager/screenlets-daemon.py' % (screenlets.INSTALL_PREFIX))
    518                  code.append('X-GNOME-Autostart-enabled=true')
    519                  f = open(starter, 'w')
    520                  if f:
    521                          for l in code:
    522                                  f.write(l + '\n')
    523                          f.close()
    524                          return True
    525                  print _('Failed to create autostarter for %s.') % name
    526                  return False
    527          else:
    528                  print _("Starter already exists.")
    529                  return True
    530
    531 -def launch_screenlet(screenlet):
    532          """Launches a screenlet"""
    533          name = str(screenlet)
    534          if not screenlets.launch_screenlet(name):
    535                  screenlets.show_error(None, _('Failed to add %sScreenlet.') % name)
    536
    537
    538
    539 -def xdg_open(name):
    540          """Opens anything"""
    541          os.system('xdg-open ' + name + ' &')
    542
    543  # ------------------------------------------------------------------------------
    544  # CLASSES
    545  # ------------------------------------------------------------------------------
    546
    547 -class ScreenletInfo:
    548          """A container with info about a screenlet."""
    549
    550 -        def __init__ (self, name, lname, info, author, version, icon):
    551                  self.name               = name
    552                  self.lname              = lname
    553                  self.info               = info.replace("\n", '').replace('\t', ' ')
    554                  self.author             = author
    555                  self.version    = version
    556                  self.icon               = icon
    557                  self.active             = False
    558                  self.system             = not os.path.isfile('%s/%s/%sScreenlet.py' % (DIR_USER, name, name))
    559                  self.autostart  = os.path.isfile(DIR_AUTOSTART + '/' + name + 'Screenlet.desktop')
    560
    561
    562
    563 -class FileMonitor(gobject.GObject):
    564          '''
    565          A simple wrapper around Gnome VFS file monitors.  Emits created, deleted,
    566          and changed events.  Incoming events are queued, with the latest event
    567          cancelling prior undelivered events.
    568          '''
    569
    570
    571          __gsignals__ = {
    572                  "event" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
    573                     (gobject.TYPE_STRING, gobject.TYPE_INT)),
    574                  "created" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)),
    575                  "deleted" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)),
    576                  "changed" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,))
    577          }
    578
    579 -        def __init__(self, path):
    580                  gobject.GObject.__init__(self)
    581
    582                  if os.path.isabs(path):
    583                          self.path = "file://" + path
    584                  else:
    585                          self.path = path
    586                  try:
    587                          self.type = gnomevfs.get_file_info(path).type
    588                  except gnomevfs.Error:
    589                          self.type = gnomevfs.MONITOR_FILE
    590
    591                  self.monitor = None
    592                  self.pending_timeouts = {}
    593
    594 -        def open(self):
    595                  if not self.monitor:
    596                          if self.type == gnomevfs.FILE_TYPE_DIRECTORY:
    597                                  monitor_type = gnomevfs.MONITOR_DIRECTORY
    598                          else:
    599                                  monitor_type = gnomevfs.MONITOR_FILE
    600                          self.monitor = gnomevfs.monitor_add(self.path, monitor_type, self._queue_event)
    601
    602 -        def _clear_timeout(self, info_uri):
    603                  try:
    604                          gobject.source_remove(self.pending_timeouts[info_uri])
    605                          del self.pending_timeouts[info_uri]
    606                  except KeyError:
    607                          pass
    608
    609 -        def _queue_event(self, monitor_uri, info_uri, event):
    610                  self._clear_timeout(info_uri)
    611                  self.pending_timeouts[info_uri] = \
    612                          gobject.timeout_add(250, self._timeout_cb, monitor_uri, info_uri, event)
    613
    614 -        def queue_changed(self, info_uri):
    615                  self._queue_event(self.path, info_uri, gnomevfs.MONITOR_EVENT_CHANGED)
    616
    617 -        def close(self):
    618                  gnomevfs.monitor_cancel(self.monitor)
    619                  self.monitor = None
    620
    621 -        def _timeout_cb(self, monitor_uri, info_uri, event):
    622                  if event in (gnomevfs.MONITOR_EVENT_METADATA_CHANGED,
    623                       gnomevfs.MONITOR_EVENT_CHANGED):
    624                          self.emit("changed", info_uri)
    625                  elif event == gnomevfs.MONITOR_EVENT_CREATED:
    626                          self.emit("created", info_uri)
    627                  elif event == gnomevfs.MONITOR_EVENT_DELETED:
    628                          self.emit("deleted", info_uri)
    629                  self.emit("event", info_uri, event)
    630
    631                  self._clear_timeout(info_uri)
    632                  return False
    633
    634
    635 -class IniReader:
    636          """A simple config/ini-reader class. This is only used for reading the
    637          theme.conf files yet, thus it only uses string-values.
    638          TODO: add writing-functions and let backend use this, too"""
    639
    640 -        def __init__ (self):
    641                  self.options    = []
    642                  self.sections   = {}
    643
    644 -        def list_options (self, section=''):
    645                  """Return all options (alternatively only from the given section)."""
    646                  if section != '':
    647                          return self.sections[section]
    648                  else:
    649                          return self.options
    650
    651 -        def get_option (self, name, section=''):
    652                  """Get a variable from the config (optional: only get vars from the
    653                  specified section)."""
    654                  if section != '':
    655                          l = self.sections[section]
    656                  else:
    657                          l = self.options
    658                  for o in l:
    659                          if o[0] == name:
    660                                  return o[1]
    661                  return None
    662
    663 -        def has_section (self, name):
    664                  """Returns true if the given section exists."""
    665                  return self.sections.has_key(name)
    666
    667 -        def load (self, filename):
    668                  """Load a config/ini-file and save vars in internal list."""
    669                  f=None
    670                  try:
    671                          f = open (filename, "r")
    672                  except:
    673                          print _("File %s not found") % str(filename)
    674                  if f:
    675                          section_name = ''
    676                          for line in f.readlines():
    677                                  # strip whitespace/tabs on the left
    678                                  line = line.lstrip().lstrip('\t')
    679                                  #print line
    680                                  # ignore comment, EOL and too short lines
    681                                  if len(line) < 4 or line[0] in ("#", "\n", ";"):
    682                                          pass
    683                                  else:
    684                                          # split var/value and trim
    685                                          tmp = line.split('=', 1)
    686                                          # no '=' found? check for section name
    687                                          if len(tmp) < 2 and len(line) > 5 and line[0] == '[':
    688                                                  section_name = line[:-1][1:-1]
    689                                                  self.sections[section_name] =  []
    690                                                  #print "Section found: %s" % section_name
    691                                          else:
    692                                                  # two entries? split var/value
    693                                                  var = tmp[0].rstrip().rstrip('\t')
    694                                                  val = tmp[1][:-1].lstrip()      # remove EOL
    695                                                  #print "VAR: %s=%s" % (var, val)
    696                                                  # and add them to lists
    697                                                  if var != '' and val != '':
    698                                                          o = [var, val]
    699                                                          self.options.append(o)
    700                                                          if section_name != '':
    701                                                                  try:
    702                                                                          self.sections[section_name].append(o)
    703                                                                  except:
    704                                                                          print _("Section %s not found!") % section_name
    705                          f.close()
    706                          return True
    707                  else:
    708                          return False
    709
    710
    711
    712 -class Notifier:
    713          """A simple and conveniet wrapper for the notification-service. Allows
    714          screenlets to easily pop up notes with their own icon (if any)."""
    715
    716 -        def __init__ (self, screenlet=None):
    717                  self.bus = dbus.SessionBus()
    718                  self.notifications = dbus.Interface(\
    719                          self.bus.get_object('org.freedesktop.Notifications',
    720                          '/org/freedesktop/Notifications'), 'org.freedesktop.Notifications')
    721                  self.screenlet = screenlet
    722
    723 -        def notify (self, message, title='', icon='', timeout=-1, screenlet=None):
    724                  """Send a notification to org.freedesktop.Notifications. The message
    725                  should contain the text you want to display, title may define a title
    726                  (summary) for the message, icon can be the full path to an icon,
    727                  timeout can be set to the desired displaying time in milliseconds."""
    728                  if self.bus and self.notifications:
    729                          if not screenlet:
    730                                  screenlet = self.screenlet
    731                          if screenlet:
    732                                  p = find_first_screenlet_path(screenlet.__class__.__name__[:-9])
    733                                  if p:
    734                                          icon = p + '/icon.svg'
    735                                  title = screenlet.__name__
    736                          self.notifications.Notify('Screenlets', 0, icon, title, message,
    737                                  [], {}, timeout)
    738                          return True
    739                  else:
    740                          print _("Notify: No DBus running or notifications-daemon unavailable.")
    741                  return False
    742
    743
    744  if __name__ == '__main__':
    745
    746          # get info about screenlet
    747          print get_screenlet_metadata('Clock')
    748
    749          # find first path
    750          print "Find first occurence of a Screenlet:"
    751          print find_first_screenlet_path('Clock')
    752          print find_first_screenlet_path('Orloj')
    753          print find_first_screenlet_path('Weather')
    754          print find_first_screenlet_path('Foo')
    755
    756          # list available
    757          print "\nList all installed Screenlets:"
    758          avail = list_available_screenlets()
    759          avail.sort()
    760          print avail
    761
    762          # IniReader
    763          print "\nTest INI-reader:"
    764          ini = IniReader()
    765          if not ini.load('/usr/share/screenlets/CPUMeter/themes/default/theme.conf'):
    766                  print "Error while loading ini-file"
    767          else:
    768                  # check for section
    769                  if ini.has_section('Theme'):
    770                          # get option-values from within a section
    771                          print ini.get_option('name', section='Theme')
    772                          print ini.get_option('info', section='Theme')
    773                  # check for existence of a section
    774                  if ini.has_section('Options'):
    775                          for o in ini.list_options(section='Options'):
    776                                  print o[0]
    777
    778          # notify
    779          print "\nNotify-test:"
    780          n = Notifier()
    781          n.notify('Hi there! This is sent through screenlets.utils.Notifier.notify',
    782                  title='Test')
    783          n.notify('A second note ..', title='Another note', timeout=2000)
    784          n.notify('A second note ..', title='Another note', icon='/usr/share/screenlets/Notes/icon.svg')
    785
    786          # some tests of the list/find screenlets functions
    787          print "\nRunning screenlets: "
    788          print list_running_screenlets2()
    789          print "\n"
    790          print get_screenlet_process('Clock')
    791          print get_screenlet_process('Ruler')
    792          print get_screenlet_process('Webtest')
    793