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.session (c) RYX (Rico Pfaus) 2007 <ryx@ryxperience.com> 
  9  # 
 10  # INFO: 
 11  # The screenlets.utils module contains functions that are somehow needed 
 12  # by the Screenlet-class or parts of the framework, but don't necessarily 
 13  # have to be part of the Screenlet-class itself. 
 14  # 
 15  # TODO: move more functions here when possible 
 16  # 
 17   
 18  import screenlets 
 19  import dbus 
 20  import os 
 21  import sys 
 22  import stat 
 23  import gettext 
 24  import re 
 25   
 26  gettext.textdomain('screenlets') 
 27  gettext.bindtextdomain('screenlets', '/usr/share/locale') 
 28   
29 -def _(s):
30 return gettext.gettext(s)
31 32 33 # ------------------------------------------------------------------------------ 34 # FUNCTIONS 35 # ------------------------------------------------------------------------------ 36
37 -def find_first_screenlet_path (screenlet_name):
38 """Scan the SCREENLETS_PATH for the first occurence of screenlet "name" and 39 return the full path to it. This function is used to get the theme/data 40 directories for a Screenlet.""" 41 for dir in screenlets.SCREENLETS_PATH: 42 try: 43 for name in os.listdir(dir): 44 name_py = name + 'Screenlet.py' 45 path = dir + '/' + name 46 if not stat.S_ISDIR(os.stat(path).st_mode): 47 continue 48 # if path exists 49 if os.access(path + '/' + name_py, os.F_OK): 50 if name == screenlet_name: 51 return path 52 else: 53 #print "utils.find_first_screenlet_path: "+\ 54 # "LISTED PATH NOT EXISTS: " + path 55 pass 56 except OSError: # Raised by os.listdir: the directory doesn't exist 57 pass 58 # nothing found 59 return None
60
61 -def get_screenlet_metadata (screenlet_name):
62 """Returns a dict with name, info, author and version of the given 63 screenlet. Use with care because it always imports the screenlet 64 module and shouldn't be used too often due to performance issues.""" 65 # find path to file 66 path = find_first_screenlet_path(screenlet_name) 67 classname = screenlet_name + 'Screenlet' 68 # add path to PYTHONPATH 69 if sys.path.count(path) == 0: 70 sys.path.insert(0, path) 71 try: 72 slmod = __import__(classname) 73 cls = getattr(slmod, classname) 74 print cls 75 sys.path.remove(path) 76 return {'name' : cls.__name__, 77 'info' : cls.__desc__, 78 'author' : cls.__author__, 79 'version' : cls.__version__ 80 } 81 except Exception, ex: 82 print _("Unable to load '%s' from %s: %s ") % (screenlet_name, path, ex) 83 return None
84
85 -def list_available_screenlets ():
86 """Scan the SCREENLETS_PATHs for all existing screenlets and return their 87 names (without trailing "Screenlet") as a list of strings.""" 88 sls = [] 89 for dir in screenlets.SCREENLETS_PATH: 90 try: 91 for name in os.listdir(dir): 92 path = dir + '/' + name 93 # check if entry is a dir 94 if not stat.S_ISDIR(os.stat(path).st_mode): 95 continue 96 # if path exists, add it to list 97 if os.access(path + '/' + name + 'Screenlet.py', os.F_OK): 98 if not sls.count(name): 99 sls.append(name) 100 else: 101 print _("LISTED PATH NOT EXISTS: ") + path 102 except OSError: # Raised by os.listdir: the directory doesn't exist 103 pass 104 return sls
105 106 import session
107 -def list_running_screenlets ():
108 """Returns a list with names of running screenlets or None if no 109 Screenlet is currently running. Function returns False if an error 110 happened!""" 111 tempfile = session.TMP_DIR + '/' + session.TMP_FILE 112 if not os.path.isfile(tempfile): 113 return None 114 f = open(tempfile, 'r') 115 if f: 116 running = f.readlines() 117 f.close() 118 for i in xrange(len(running)): 119 running[i] = running[i][:-1] # strip trailing EOL 120 return running 121 return False
122
123 -def _contains_path (string):
124 """Internal function: Returns true if the given string contains one of the 125 SCREENLETS_PATH entries.""" 126 for p in screenlets.SCREENLETS_PATH: 127 if string.find(p) > -1: 128 return True 129 return False
130
131 -def list_running_screenlets2 ():
132 """Returns a list with names of running screenlets. The list can be empty if 133 no Screenlet is currently running.""" 134 p = os.popen("ps aux | awk '/Screenlet.py/{ print $11, $12, $13, $14, $15, $16 }'") 135 lst = [] 136 regex = re.compile('/([A-Za-z0-9]+)Screenlet.py ') 137 for line in p.readlines(): 138 if not line.endswith('awk /Screenlet.py/{\n') and line != 'sh -c\n' \ 139 and _contains_path(line): 140 slname = regex.findall(line) 141 if slname and type(slname) == list and len(slname) > 0: 142 lst.append(slname[0]) 143 p.close() 144 return lst
145
146 -def get_screenlet_process (name):
147 """Returns the PID of the given screenlet (if running) or None.""" 148 p = os.popen("ps aux | awk '/[" + name[0] + "]" + name[1:] + \ 149 "Screenlet.py/{ print $2, $11, $12, $13, $14, $15, $16 }'") 150 line = p.readlines() 151 p.close() 152 #print line 153 if len(line) and _contains_path(line[0]): 154 return int(line[0].split(' ')[0]) 155 return None
156 157 158 # ------------------------------------------------------------------------------ 159 # CLASSES 160 # ------------------------------------------------------------------------------ 161
162 -class IniReader:
163 """A simple config/ini-reader class. This is only used for reading the 164 theme.conf files yet, thus it only uses string-values. 165 TODO: add writing-functions and let backend use this, too""" 166
167 - def __init__ (self):
168 self.options = [] 169 self.sections = {}
170
171 - def list_options (self, section=''):
172 """Return all options (alternatively only from the given section).""" 173 if section != '': 174 return self.sections[section] 175 else: 176 return self.options
177
178 - def get_option (self, name, section=''):
179 """Get a variable from the config (optional: only get vars from the 180 specified section).""" 181 if section != '': 182 l = self.sections[section] 183 else: 184 l = self.options 185 for o in l: 186 if o[0] == name: 187 return o[1] 188 return None
189
190 - def has_section (self, name):
191 """Returns true if the given section exists.""" 192 return self.sections.has_key(name)
193
194 - def load (self, filename):
195 """Load a config/ini-file and save vars in internal list.""" 196 f=None 197 try: 198 f = open (filename, "r") 199 except: 200 print _("File %s not found") % str(filename) 201 if f: 202 section_name = '' 203 for line in f.readlines(): 204 # strip whitespace/tabs on the left 205 line = line.lstrip().lstrip('\t') 206 #print line 207 # ignore comment, EOL and too short lines 208 if len(line) < 4 or line[0] in ("#", "\n", ";"): 209 pass 210 else: 211 # split var/value and trim 212 tmp = line.split('=', 1) 213 # no '=' found? check for section name 214 if len(tmp) < 2 and len(line) > 5 and line[0] == '[': 215 section_name = line[:-1][1:-1] 216 self.sections[section_name] = [] 217 #print "Section found: %s" % section_name 218 else: 219 # two entries? split var/value 220 var = tmp[0].rstrip().rstrip('\t') 221 val = tmp[1][:-1].lstrip() # remove EOL 222 #print "VAR: %s=%s" % (var, val) 223 # and add them to lists 224 if var != '' and val != '': 225 o = [var, val] 226 self.options.append(o) 227 if section_name != '': 228 try: 229 self.sections[section_name].append(o) 230 except: 231 print _("Section %s not found!") % section_name 232 f.close() 233 return True 234 else: 235 return False
236
237 -class Notifier:
238 """A simple and conveniet wrapper for the notification-service. Allows 239 screenlets to easily pop up notes with their own icon (if any).""" 240
241 - def __init__ (self, screenlet=None):
242 self.bus = dbus.SessionBus() 243 self.notifications = dbus.Interface(\ 244 self.bus.get_object('org.freedesktop.Notifications', 245 '/org/freedesktop/Notifications'), 'org.freedesktop.Notifications') 246 self.screenlet = screenlet
247
248 - def notify (self, message, title='', icon='', timeout=-1, screenlet=None):
249 """Send a notification to org.freedesktop.Notifications. The message 250 should contain the text you want to display, title may define a title 251 (summary) for the message, icon can be the full path to an icon, 252 timeout can be set to the desired displaying time in milliseconds.""" 253 if self.bus and self.notifications: 254 if not screenlet: 255 screenlet = self.screenlet 256 if screenlet: 257 p = find_first_screenlet_path(screenlet.__class__.__name__[:-9]) 258 if p: 259 icon = p + '/icon.svg' 260 title = screenlet.__name__ 261 self.notifications.Notify('Screenlets', 0, icon, title, message, 262 [], {}, timeout) 263 return True 264 else: 265 print _("Notify: No DBus running or notifications-daemon unavailable.") 266 return False
267 268 269 if __name__ == '__main__': 270 271 # get info about screenlet 272 print get_screenlet_metadata('Clock') 273 274 # find first path 275 print "Find first occurence of a Screenlet:" 276 print find_first_screenlet_path('Clock') 277 print find_first_screenlet_path('Orloj') 278 print find_first_screenlet_path('Weather') 279 print find_first_screenlet_path('Foo') 280 281 # list available 282 print "\nList all installed Screenlets:" 283 avail = list_available_screenlets() 284 avail.sort() 285 print avail 286 287 # IniReader 288 print "\nTest INI-reader:" 289 ini = IniReader() 290 if not ini.load('/usr/share/screenlets/CPUMeter/themes/default/theme.conf'): 291 print "Error while loading ini-file" 292 else: 293 # check for section 294 if ini.has_section('Theme'): 295 # get option-values from within a section 296 print ini.get_option('name', section='Theme') 297 print ini.get_option('info', section='Theme') 298 # check for existence of a section 299 if ini.has_section('Options'): 300 for o in ini.list_options(section='Options'): 301 print o[0] 302 303 # notify 304 print "\nNotify-test:" 305 n = Notifier() 306 n.notify('Hi there! This is sent through screenlets.utils.Notifier.notify', 307 title='Test') 308 n.notify('A second note ..', title='Another note', timeout=2000) 309 n.notify('A second note ..', title='Another note', icon='/usr/share/screenlets/Notes/icon.svg') 310 311 # some tests of the list/find screenlets functions 312 print "\nRunning screenlets: " 313 print list_running_screenlets2() 314 print "\n" 315 print get_screenlet_process('Clock') 316 print get_screenlet_process('Ruler') 317 print get_screenlet_process('Webtest') 318