Package conduit :: Package utils
[hide private]

Source Code for Package conduit.utils

  1  """ 
  2  Utility Functions 
  3   
  4  Part of this code copied from from Listen (c) 2006 Mehdi Abaakouk 
  5  (http://listengnome.free.fr/) 
  6   
  7  Copyright: John Stowers, 2006 
  8  License: GPLv2 
  9  """ 
 10  import sys 
 11  import os.path 
 12  import socket 
 13  import datetime 
 14  import time 
 15  import re 
 16  import logging 
 17  log = logging.getLogger("Utils") 
 18   
19 -def get_proportional_resize(desiredW, desiredH, currentW, currentH):
20 """ 21 Returns proportionally resized co-ordinates for an image 22 """ 23 #Account for 'dont care about this axis sizing' 24 if desiredH == -1: desiredH = currentH 25 if desiredW == -1: desiredW = currentW 26 27 #Calculate the axis of most change 28 dw = abs(currentW - desiredW) 29 dh = abs(currentH - desiredH) 30 31 if dh > dw: 32 newHeight = float(desiredH) 33 percentage = newHeight / currentH 34 newWidth = currentW * percentage 35 else: 36 newWidth = float(desiredW) 37 percentage = newWidth / currentW 38 newHeight = currentH * percentage 39 40 return int(newWidth), int(newHeight)
41
42 -def program_installed(app):
43 """ 44 Check if the given app is installed. 45 """ 46 path = os.environ['PATH'] 47 paths = path.split(os.pathsep) 48 for dir in paths: 49 if os.path.isdir(dir): 50 if os.path.isfile(os.path.join(dir,app)): 51 return True 52 return False
53 54 # 55 # Temporary file functions 56 #
57 -def new_tempfile(contents, contentsAreText=True):
58 """ 59 Returns a new File onject, which has been created in the 60 system temporary directory, and that has been filled with 61 contents 62 63 The file is closed when it is returned 64 65 @param contents: The data to write into the file 66 @param contentsAreText: Indicates to the OS if the file is text (as opposed 67 to a binary type file 68 @param contentsAreText: C{bool} 69 @returns: a L{conduit.datatypes.File} 70 """ 71 import conduit.datatypes.File as File 72 return File.TempFile(contents)
73
74 -def new_tempdir():
75 """ 76 Creates a new temporary directory 77 """ 78 import tempfile 79 return tempfile.mkdtemp("conduit")
80
81 -def unique_list(seq):
82 """ 83 The fastes way to unique-ify a list while retaining its order, from 84 http://www.peterbe.com/plog/uniqifiers-benchmark 85 """ 86 def _f10(listy): 87 seen = set() 88 for x in listy: 89 if x in seen: 90 continue 91 seen.add(x) 92 yield x
93 return list(_f10(seq)) 94
95 -def random_string(length=5):
96 """ 97 returns a random string of length 98 """ 99 import random 100 s = "" 101 for i in range(0,length): 102 s += str(random.randint(0,10)) 103 return s
104
105 -def dataprovider_add_dir_to_path(dataproviderfile, directory=""):
106 """ 107 Adds directory to the python search path. 108 109 From within a dataprovider (FooModule.py) 110 call with Utils.dataprovider_add_dir_to_path(__file__, some_dir): 111 """ 112 path = os.path.join(dataproviderfile, "..", directory) 113 path = os.path.abspath(path) 114 sys.path.insert(0,path)
115
116 -def dataprovider_glade_get_widget(dataproviderfile, gladefilename, widget):
117 """ 118 Gets a single gtk widget from a glad file 119 """ 120 import gtk.glade 121 path = os.path.join(dataproviderfile, "..", gladefilename) 122 path = os.path.abspath(path) 123 return gtk.glade.XML(path, widget)
124
125 -def run_dialog(dialog, window=None):
126 """ 127 Runs a given dialog, and makes it transient for 128 the given window if any 129 @param dialog: dialog 130 @param window: gtk window 131 @returns: True if the user clicked OK to exit the dialog 132 """ 133 import gtk 134 135 if window: 136 dialog.set_transient_for(window) 137 138 return dialog.run() == gtk.RESPONSE_OK
139
140 -def run_dialog_non_blocking(dialog, resp_cb, window=None):
141 """ 142 Runs a given dialog, and makes it transient for 143 the given window if any 144 @param dialog: dialog 145 @param window: gtk window 146 @returns: True if the user clicked OK to exit the dialog 147 """ 148 import gtk.gdk 149 150 dialog.connect("response", resp_cb) 151 dialog.connect("response", lambda dlg, resp: dlg.destroy()) 152 153 if window: 154 dialog.set_transient_for(window) 155 #FIXME: Doesnt work 156 #fake modality by making window ignore key events 157 #events = window.window.get_events() 158 #window.window.set_events( 159 # events & ~(gtk.gdk.KEY_PRESS_MASK | gtk.gdk.KEY_RELEASE_MASK)) 160 #connect to response signal to restore original events 161 #dialog.connect( 162 # "response", 163 # lambda dlg, resp, win, originalEvents: window.window.set_events(originalEvents), 164 # window,events) 165 166 dialog.show()
167
168 -def dialog_set_busy_cursor(dlg):
169 """ 170 Sets the dialog to display the busy cursor 171 """ 172 import gtk.gdk 173 dlg.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
174
175 -def dialog_reset_cursor(dlg):
176 """ 177 Resets the dialog to display the plain Gtk cursor 178 """ 179 dlg.window.set_cursor(None)
180
181 -def md5_string(string):
182 """ 183 Returns the md5 of the supplied string in readable hexdigest string format 184 """ 185 import md5 186 return md5.new(string).hexdigest()
187
188 -def uuid_string():
189 """ 190 Returns a uuid string 191 """ 192 try: 193 import uuid 194 return uuid.uuid4().hex 195 except ImportError: 196 import random, md5, socket 197 t = long( time.time() * 1000 ) 198 r = long( random.random()*100000000000000000L ) 199 try: 200 a = socket.gethostbyname( socket.gethostname() ) 201 except: 202 a = random.random()*100000000000000000L 203 data = str(t)+' '+str(r)+' '+str(a) 204 data = md5.md5(data).hexdigest() 205 return data
206
207 -def dbus_service_available(interface, bus=None):
208 """ 209 Checks if a dbus service is available on the given bus 210 @param interface: The interface to look for 211 @param bus: The bus to look on (optional) 212 """ 213 try: 214 import dbus 215 except: 216 return False 217 218 if bus == None: 219 bus = dbus.SessionBus() 220 221 obj = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus') 222 dbus_iface = dbus.Interface(obj, 'org.freedesktop.DBus') 223 avail = dbus_iface.ListNames() 224 return interface in avail
225
226 -def get_user_string():
227 """ 228 Makes a user and machine dependant string in the form 229 username@hostname 230 """ 231 hostname = socket.gethostname() 232 username = os.environ.get("USER","") 233 return "%s@%s" % (username, hostname)
234
235 -def datetime_from_timestamp(t):
236 """ 237 Makes a datetime object from a unix timestamp. 238 239 Note: For the sake of consistancy always drop the 240 fractional (microsecond) part of the timestamp 241 """ 242 if type(t) not in [long, int, float]: 243 raise Exception("Timestamp must be a number") 244 245 if t < 0: 246 raise Exception("Timestamps before 1970 are not valid") 247 248 return datetime.datetime.fromtimestamp(long(t))
249
250 -def datetime_get_timestamp(d):
251 """ 252 Returns the unix timestamp for a datetime 253 254 Note: For the sake of consistancy always drop the 255 fractional (microsecond) part of the timestamp 256 """ 257 if type(d) != datetime.datetime: 258 raise Exception("Must supply a datetime") 259 260 f = time.mktime(d.timetuple()) 261 if f < 0: 262 raise Exception("Timestamps before 1970 are not valid") 263 264 return long(f)
265
266 -def encode_conversion_args(args):
267 """ 268 encodes an args dictionary to a url string in the form 269 param=value&param2=val2 270 """ 271 import urllib 272 return urllib.urlencode(args)
273
274 -def decode_conversion_args(argString):
275 """ 276 FIXME: dont import cgi for just one function. Also it doesnt 277 even handle lists 278 """ 279 import cgi 280 args = {} 281 for key,val in cgi.parse_qsl(argString): 282 args[key] = val 283 return args
284
285 -def log_function_call(log):
286 """ 287 A decorator that prints debug message showing the function name and 288 argument types to the supplied logger instance. 289 290 Adapted from the accepts/returns decorators at 291 http://wiki.python.org/moin/PythonDecoratorLibrary 292 """ 293 def decorator(f): 294 def newf(*args): 295 #Ensure args are tuples with str args - necessart for CPython methods 296 argtypes = map(str,map(type, args)) 297 argnames = map(str,f.func_code.co_varnames[:f.func_code.co_argcount]) 298 argnamesandtypes = ["%s:%s" % (i,j) for i,j in zip(argnames,argtypes)] 299 msg = "Method Call %s(%s)" % ( 300 f.__name__, 301 ', '.join(argnamesandtypes) 302 ) 303 log.debug(msg) 304 return f(*args)
305 #Retain information about old function 306 newf.__name__ = f.__name__ 307 newf.__doc__ = f.__doc__ 308 newf.__dict__.update(f.__dict__) 309 return newf 310 return decorator 311
312 -def xml_extract_value_from_tag(tag, text):
313 """ 314 Returns the contents of the xml tag or None. Uses a simple regex. 315 316 Taken from: 317 http://immike.net/blog/2007/04/06/5-regular-expressions-every-web-programmer-should-know/ 318 """ 319 ans = re.compile("<%(tag)s[^>]*>(.*?)</%(tag)s>" % {"tag":tag}).findall(text) 320 if ans: 321 return ans[0] 322 else: 323 return None
324
325 -def get_module_information(module, versionAttributeName):
326 """ 327 Prints the name, location and version of the supplied module 328 """ 329 version = "" 330 if versionAttributeName: 331 try: 332 version = " v%s" % str(getattr(module, versionAttributeName)) 333 except: pass 334 335 path = "" 336 try: 337 path = " (%s)" % module.__file__ 338 except: pass 339 340 return "%s%s%s" % (module.__name__, version, path)
341