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