screenlets.utils

Package screenlets :: Module utils |
[hide private]
[frames] | no frames]

# Source Code for Module screenlets.utils

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