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