## vim:ts=4:et:nowrap ## ##---------------------------------------------------------------------------## ## ## PySol -- a Python Solitaire game ## ## Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer ## Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer ## Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer ## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer ## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer ## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer ## All Rights Reserved. ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; see the file COPYING. ## If not, write to the Free Software Foundation, Inc., ## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ## ## Markus F.X.J. Oberhumer ## ## http://www.oberhumer.com/pysol ## ##---------------------------------------------------------------------------## # imports import sys, os, time, types #import traceback try: from cPickle import Pickler, Unpickler, UnpicklingError except ImportError: from pickle import Pickler, Unpickler, UnpicklingError try: import thread except: thread = None if os.name == "mac": # macfs module is deprecated, consider using Carbon.File or Carbon.Folder import macfs, MACFS win32api = shell = shellcon = None if sys.platform.startswith('win'): try: import win32api #from win32com.shell import shell, shellcon except ImportError: pass # /*********************************************************************** # // exceptions # ************************************************************************/ # work around a Mac problem ##EnvError = EnvironmentError EnvError = (IOError, OSError, os.error,) class SubclassResponsibility(Exception): pass # /*********************************************************************** # // misc. util # ************************************************************************/ ## def static(f, *args, **kw): ## if args: ## a = tuple([f.im_class()] + list(args)) ## else: ## a = (f.im_class(),) ## return apply(f, a, kw) ## def ifelse(expr, val1, val2): ## if expr: ## return val1 ## return val2 ## def merge_dict(dict1, dict2, merge_none=1): ## for k, v in dict2.items(): ## if dict1.has_key(k): ## if type(dict1[k]) is type(v): ## dict1[k] = v ## elif dict2[k] is None and merge_none: ## dict1[k] = v # this is a quick hack - we definitely need Unicode support... def latin1_to_ascii(n): #return n n = n.encode('iso8859-1', 'replace') ## FIXME: rewrite this for better speed n = (n.replace("\xc4", "Ae") .replace("\xd6", "Oe") .replace("\xdc", "Ue") .replace("\xe4", "ae") .replace("\xf6", "oe") .replace("\xfc", "ue")) return n ## import htmlentitydefs ## htmlentitydefs_i = {} ## def latin1_to_html(n): ## global htmlentitydefs_i ## if not htmlentitydefs_i: ## for k, v in htmlentitydefs.entitydefs.items(): ## htmlentitydefs_i[v] = "&" + k + ";" ## s, g = "", htmlentitydefs_i.get ## for c in n: ## s = s + g(c, c) ## return s ## def hexify(s): ## return "%02x"*len(s) % tuple(map(ord, s)) def format_time(t): ##print 'format_time:', t if t <= 0: return "0:00" if t < 3600: return "%d:%02d" % (t / 60, t % 60) return "%d:%02d:%02d" % (t / 3600, (t % 3600) / 60, t % 60) # /*********************************************************************** # // misc. portab stuff # ************************************************************************/ def getusername(): if os.name == "nt": return win32_getusername() user = os.environ.get("USER","").strip() if not user: user = os.environ.get("LOGNAME","").strip() return user def gethomedir(): if os.name == "nt": return win32_gethomedir() home = os.environ.get("HOME", "").strip() if not home or not os.path.isdir(home): home = os.curdir return os.path.abspath(home) def getprefdir(package, home=None): if os.name == "nt": return win32_getprefdir(package) if os.name == "mac": vrefnum, dirid = macfs.FindFolder(MACFS.kOnSystemDisk, MACFS.kPreferencesFolderType, 0) fss = macfs.FSSpec((vrefnum, dirid, ":" + "PySolFC")) return fss.as_pathname() if home is None: home = gethomedir() return os.path.join(home, ".PySolFC") # high resolution clock() and sleep() uclock = time.clock usleep = time.sleep if os.name == "posix": uclock = time.time # /*********************************************************************** # // MSWin util # ************************************************************************/ def win32_getusername(): user = os.environ.get('USERNAME','').strip() try: user = win32api.GetUserName().strip() except AttributeError: pass return user def win32_getprefdir(package): hd = win32_gethomedir() return os.path.join(hd, 'PySolFC') ## dname = os.path.expanduser("~\\.pysol") ## if not os.path.isdir(dname): ## try: ## dname = os.path.join( ## shell.SHGetFolderPath(0, shellcon.CSIDL_APPDATA, 0, 0), ## package, package) ## except AttributeError: ## pass ## return os.path.abspath(dname) def win32_gethomedir(): # %USERPROFILE%, %APPDATA% hd = os.environ.get('APPDATA') if hd: return hd hd = os.path.expanduser('~') if hd == '~': # win9x return os.path.abspath('/') return hd # /*********************************************************************** # // memory util # ************************************************************************/ def destruct(obj): # assist in breaking circular references if obj is not None: assert type(obj) is types.InstanceType for k in obj.__dict__.keys(): obj.__dict__[k] = None ##del obj.__dict__[k] # /*********************************************************************** # // # ************************************************************************/ class Struct: def __init__(self, **kw): self.__dict__.update(kw) def __str__(self): return str(self.__dict__) def __setattr__(self, key, value): if not self.__dict__.has_key(key): raise AttributeError, key self.__dict__[key] = value def addattr(self, **kw): for key in kw.keys(): if hasattr(self, key): raise AttributeError, key self.__dict__.update(kw) def update(self, dict): for key in dict.keys(): if not self.__dict__.has_key(key): raise AttributeError, key self.__dict__.update(dict) def clear(self): for key in self.__dict__.keys(): t = type(key) if t is types.ListType: self.__dict__[key] = [] elif t is types.TupleType: self.__dict__[key] = () elif t is types.DictType: self.__dict__[key] = {} else: self.__dict__[key] = None def copy(self): c = Struct() c.__class__ = self.__class__ c.__dict__.update(self.__dict__) return c # /*********************************************************************** # // keyword argument util # ************************************************************************/ # update keyword arguments with default arguments def kwdefault(kw, **defaults): for k, v in defaults.items(): if not kw.has_key(k): kw[k] = v class KwStruct: def __init__(self, kw={}, **defaults): if isinstance(kw, KwStruct): kw = kw.__dict__ if isinstance(defaults, KwStruct): defaults = defaults.__dict__ if defaults: kw = kw.copy() for k, v in defaults.items(): if not kw.has_key(k): kw[k] = v self.__dict__.update(kw) def __setattr__(self, key, value): if not self.__dict__.has_key(key): raise AttributeError, key self.__dict__[key] = value def __getitem__(self, key): return getattr(self, key) def get(self, key, default=None): return self.__dict__.get(key, default) def getKw(self): return self.__dict__ # /*********************************************************************** # // pickling support # ************************************************************************/ def pickle(obj, filename, binmode=0): f = None try: f = open(filename, "wb") p = Pickler(f, binmode) p.dump(obj) f.close(); f = None ##print "Pickled", filename finally: if f: f.close() def unpickle(filename): f, obj = None, None try: f = open(filename, "rb") p = Unpickler(f) x = p.load() f.close(); f = None obj = x ##print "Unpickled", filename finally: if f: f.close() return obj # /*********************************************************************** # // # ************************************************************************/ def spawnv(file, args=()): if not args: args = () args = (file,) + tuple(args) # if not os.path.isfile(file): raise os.error, str(file) mode = os.stat(file)[0] if not (mode & 0100): return 0 # if os.name == "posix": pid = os.fork() if pid == -1: raise os.error, "fork failed" if pid != 0: # parent try: os.waitpid(pid, 0) except: pass return 1 # child # 1) close all files for fd in range(255, -1, -1): try: os.close(fd) except: pass # 2) open stdin, stdout and stderr to /dev/null try: fd = os.open("/dev/null", os.O_RDWR) os.dup(fd) os.dup(fd) except: pass # 3) fork again and exec program try: if os.fork() == 0: try: os.setpgrp() except: pass os.execv(file, args) except: pass # 4) exit while 1: os._exit(0) return 0 def spawnvp(file, args=()): if file and os.path.isabs(file): try: if spawnv(file, args): return file except: ##if traceback: traceback.print_exc() pass return None # path = os.environ.get("PATH", "") path = path.split(os.pathsep) for dir in path: try: if dir and os.path.isdir(dir): f = os.path.join(dir, file) try: if spawnv(f, args): return f except: ##if traceback: traceback.print_exc() pass except: ##if traceback: traceback.print_exc() pass return None # /*********************************************************************** # // # ************************************************************************/ def openURL(url): try: import webbrowser webbrowser.open(url) return 1 except: return 0