# # This file is part of Documancer (http://documancer.sf.net) # # Copyright (C) 2002-2005 Vaclav Slavik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # # 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; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # $Id: utils.py,v 1.15 2005/01/30 18:29:31 vaclavslavik Exp $ # # Misc utility functions # import os, os.path, string, urllib, pipes, sys def getConfigDir(): if sys.platform == 'win32': import pythoncom from win32com.shell import shell from win32com.shell import shellcon id = shellcon.CSIDL_APPDATA try: appdata = shell.SHGetSpecialFolderPath(0, id) except pythoncom.com_error: idl = shell.SHGetSpecialFolderLocation(0, id) appdata = shell.SHGetPathFromIDList(idl) return os.path.join(appdata, 'Documancer', '') else: cdir = os.path.expanduser('~/.documancer/') if not os.path.isdir(cdir): os.mkdir(cdir) return cdir def getBooksDir(): bookdir = getConfigDir() + 'books' if not os.path.isdir(bookdir): os.mkdir(bookdir) return bookdir def getDocumancerHome(): return os.environ['DOCUMANCER_HOME'] def mangleBookName(name): return urllib.quote(name, "") def demangleBookName(name): return urllib.unquote(name) def bookNameToFileName(name): """Converts book name into a 'nice' filename.""" x = name.lower() for i in ' `~@#$%^&*()\\|[]{}:;"\'<>,./?': # FIXME - use regex to do the substitution! x = x.replace(i, '-') return x DEFAULT_PORT_RANGE = '49152-65535' portsAvailable = None def findUnusedPort(): """Finds some currently unused port.""" import socket, errno, utils import random global portsAvailable def portUsed(port): used = 0 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.bind(('', port)) except socket.error, (err, desc): if err == errno.EADDRINUSE: used = 1 s.close() return used # Find out what the allowed ports range is: if portsAvailable == None: r = utils.config().Read('/Backend/ports_range', DEFAULT_PORT_RANGE) portFrom = int(r.split('-')[0]) portTo = int(r.split('-')[1]) portsAvailable = range(portFrom, portTo+1) while 1: i = random.randrange(0, len(portsAvailable)) p = portsAvailable[i] del portsAvailable[i] if not portUsed(p): return p return None usedPorts = {} def getServerPort(purpose = 'html_server'): global usedPorts if purpose not in usedPorts: usedPorts[purpose] = findUnusedPort() return usedPorts[purpose] __configObject = None def config(): global __configObject if __configObject == None: import wxPython.wx if sys.platform == 'win32': cfg = wxPython.wx.wxConfig('Documancer', 'Vaclav Slavik') else: cfg = wxPython.wx.wxConfig('Documancer', 'Vaclav Slavik', getConfigDir()+'config.ini', '/etc/documancer.conf') wxPython.wx.wxConfigBase_Set(cfg) __configObject = cfg return __configObject # -------------------------------------------------------------------------- # UI callback structure # -------------------------------------------------------------------------- class __UiCallbackNoop: def error(self, msg): pass def errorPrompt(self, msg): pass #create a GUI prompt for the error def showBusyIndicator(self): pass def hideBusyIndicator(self): pass def setBusyText(self, text): pass # This variable contains UI interface functions, so that UI elements can be # used by the backend (which doesn't know which UI is being used) uiCallback = __UiCallbackNoop()