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