Author: jcater Date: 2007-02-22 19:29:03 -0600 (Thu, 22 Feb 2007) New Revision: 9404
Added: trunk/gnue-common/src/utils/file.py trunk/gnue-common/src/utils/importing.py Modified: trunk/gnue-common/src/utils/FileUtils.py trunk/gnue-common/src/utils/GMimeTypes.py trunk/gnue-common/src/utils/TextUtils.py trunk/gnue-common/src/utils/__init__.py Log: added propset Id; added a better module importer; split FileUtils up (but included imports in FileUtils for backwards compatability) Modified: trunk/gnue-common/src/utils/FileUtils.py =================================================================== --- trunk/gnue-common/src/utils/FileUtils.py 2007-02-22 22:44:30 UTC (rev 9403) +++ trunk/gnue-common/src/utils/FileUtils.py 2007-02-23 01:29:03 UTC (rev 9404) @@ -26,124 +26,18 @@ # Common file/url/resource related utilities # # NOTES: -# +# TODO: Deprecate -import os, urllib, urlparse, sys + +import os +import urllib +import urlparse +import sys import cStringIO -############################################################ -# -# Dynamically import a python module -# -def dyn_import(name): - try: - mod = __import__(name) - components = name.split('.') - for comp in components[1:]: - mod = getattr(mod, comp) - return mod - except (AttributeError,ValueError, ImportError), mesg: - raise ImportError, 'Unable to import %s: %s' % (name, mesg) - -############################################################ -# -# Try to turn a resource into a valid URI -# (because C:\ confuses some tools) -# -def urlize (resource): - if not resource.find(':'): - return 'file://%s' % resource - else: - drive = os.path.splitdrive(resource) - if len(drive[0]) and drive[0] == resource[:len(drive[0])]: - return 'file://%s' % resource - else: - return resource - - -############################################################ -# -# Open a string buffer as a normal file -# -def openBuffer(buffer): - return cStringIO.StringIO(buffer) - - -############################################################ -# -# Open a file or URL resource, -# properly handling drive letters. -# -def openResource(resource): - drive = os.path.splitdrive(resource) - if len(drive[0]): - return open(resource,'r') - else: - (urltype, host, path, param, query, frag) = urlparse.urlparse(resource) - - # check for .gear files - if resource[-5:]==".gear": - host=resource - path="" - urltype="gear" - - # normal files are directly passed to the application - if urltype!="gear": - return urllib.urlopen(resource) - - else: - - from gnue.common.gear.GearSystem import GearFileSystem - - # fix for a bug in URLPARSE - if host=="": - # path="//host/path" -> path=path host=host - host, path = path[2:].split('/', 1) - - # check if host ends in ".gear" - if host[-5:]!=".gear": - host += ".gear" - - # 1. search for gear in the local directory - try: - gear=GearFileSystem(urllib.unquote(host)) - - except: - # 2. search in the package directory - if sys.platform=="win32": - host=sys.prefix+"/packages/"+host - else: - host=os.environ["HOME"]+"/gnue/packages/"+host - - gear=GearFileSystem(urllib.unquote(host)) - - if len(path): - return gear.openFile(path) - - # if no path provided, create a navigator file for this archive - else: - - # check if the zip file contains a default navigator file - if gear.hasFile("default.gpd"): - # TODO: change navigator file and add relative paths - # i.e. in case of gear-resource="sample/test.gear" - # gear://test.gear/mypath/my.gfd -> - # gear://sample%2Ftest.gear/mypath/my.gfd - return gear.openFile("default.gpd") - - - # convert a single filename to a full gear url - if resource[:5] != "gear:": - resource="gear://"+urllib.quote(resource,"")+"/" - - gear._gearFileRes=resource - - filelist = gear.getArchiveListing() - - from gnue.common.gear.NavigationBuilder import buildNavigatorFile - - navi = buildNavigatorFile(filelist,host,1) - - return cStringIO.StringIO(navi) - +# For backwards compatability +from gnue.common.utils.importing import import_string as dyn_import +from gnue.common.utils.file import to_uri as urlize, \ + open_uri as openResource, \ + to_buffer as openBuffer Property changes on: trunk/gnue-common/src/utils/FileUtils.py ___________________________________________________________________ Name: svn:keywords + Id Property changes on: trunk/gnue-common/src/utils/GMimeTypes.py ___________________________________________________________________ Name: svn:keywords + Id Modified: trunk/gnue-common/src/utils/TextUtils.py =================================================================== --- trunk/gnue-common/src/utils/TextUtils.py 2007-02-22 22:44:30 UTC (rev 9403) +++ trunk/gnue-common/src/utils/TextUtils.py 2007-02-23 01:29:03 UTC (rev 9404) @@ -34,6 +34,7 @@ ALIGN_CENTER = 2 # very simple lineWrap +# TODO: Deprecate in favor of Python 2.3's textwrap module def lineWrap(message, maxWidth, preserveNewlines=1, alignment=ALIGN_LEFT, eol=1): """ Property changes on: trunk/gnue-common/src/utils/TextUtils.py ___________________________________________________________________ Name: svn:keywords + Id Property changes on: trunk/gnue-common/src/utils/__init__.py ___________________________________________________________________ Name: svn:keywords + Id Added: trunk/gnue-common/src/utils/file.py =================================================================== --- trunk/gnue-common/src/utils/file.py 2007-02-22 22:44:30 UTC (rev 9403) +++ trunk/gnue-common/src/utils/file.py 2007-02-23 01:29:03 UTC (rev 9404) @@ -0,0 +1,169 @@ +# GNU Enterprise Common Library - Utilities - File & URI reading/opening +# +# Copyright 2001-2007 Free Software Foundation +# +# This file is part of GNU Enterprise +# +# GNU Enterprise 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, or (at your option) any later version. +# +# GNU Enterprise 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 program; see the file COPYING. If not, +# write to the Free Software Foundation, Inc., 59 Temple Place +# - Suite 330, Boston, MA 02111-1307, USA. +# +# $Id$ +""" +Helper functions for opening/reading files or network resources. +""" + + +import os +import urllib +import urlparse +import sys +import cStringIO + + +# =================================================================== +# Convert a file name or URI into a URI (prepend file://) +# =================================================================== +def to_uri (resource): + """ + Try to turn a resource into a valid URI + (because C:\ confuses some tools). + + i.e., prepend file:// to an absolute file name. + """ + if not resource.find(':'): + return 'file://%s' % resource + else: + drive = os.path.splitdrive(resource) + if len(drive[0]) and drive[0] == resource[:len(drive[0])]: + return 'file://%s' % resource + else: + return resource + + +# =================================================================== +# string_to_buffer +# =================================================================== +def to_buffer(item): + """ + Convert a string to a file object if it is not already. + + Examples: + + >>> to_buffer('This is text\nFoo.').read() + + >>> my_file = open('/etc/passwd') + >>> to_buffer(my_file) == my_file + >>> myfile.read() + <<< True + + """ + if hasattr(resource, 'read'): + return resource + return cStringIO.StringIO(item) + + + +# =================================================================== +# Open a file or a URI as a file object +# =================================================================== +def open_uri(resource, mode='r'): + """ + Open a file or URI resource, + properly handling drive letters. + + For example, + + >>> resource = open_uri('/etc/passwd') + >>> resource = open_uri(r'A:\MyDir\MyFile') + >>> resource = open_uri('file:///etc/passwd') + >>> resource = open_uri('http://www.google.com/') + + """ + drive = os.path.splitdrive(resource) + if len(drive[0]): + return open(resource, mode) + else: + (urltype, host, path, param, query, frag) = urlparse.urlparse(resource) + + # check for .gear files + if resource[-5:] == ".gear": + host = resource + path = "" + urltype = "gear" + + # normal files are directly passed to the application + if urltype != "gear": + if urltype in ('file', ''): + return open(path, mode) + if not mode.startswith('r'): + raise IOError( + "Network resource '%s' can only be opened as read only." % ( + resource)) + return urllib.urlopen(resource) + + else: + + from gnue.common.gear.GearSystem import GearFileSystem + + # fix for a bug in URLPARSE + if host=="": + # path="//host/path" -> path=path host=host + host, path ="/".split(path[2:],1) + + # check if host ends in ".gear" + if host[-5:]!=".gear": + host += ".gear" + + # 1. search for gear in the local directory + try: + gear=GearFileSystem(urllib.unquote(host)) + + except: + # 2. search in the package directory + if sys.platform=="win32": + host=sys.prefix+"/packages/"+host + else: + host=os.environ["HOME"]+"/gnue/packages/"+host + + gear=GearFileSystem(urllib.unquote(host)) + + if len(path): + return gear.openFile(path) + + # if no path provided, create a navigator file for this archive + else: + + # check if the zip file contains a default navigator file + if gear.hasFile("default.gpd"): + # TODO: change navigator file and add relative paths + # i.e. in case of gear-resource="sample/test.gear" + # gear://test.gear/mypath/my.gfd -> + # gear://sample%2Ftest.gear/mypath/my.gfd + return gear.openFile("default.gpd") + + + # convert a single filename to a full gear url + if resource[:5] != "gear:": + resource="gear://"+urllib.quote(resource,"")+"/" + + gear._gearFileRes=resource + + filelist = gear.getArchiveListing() + + from gnue.common.gear.NavigationBuilder import buildNavigatorFile + + navi = buildNavigatorFile(filelist,host,1) + + return cStringIO.StringIO(navi) Property changes on: trunk/gnue-common/src/utils/file.py ___________________________________________________________________ Name: svn:keywords + Id Added: trunk/gnue-common/src/utils/importing.py =================================================================== --- trunk/gnue-common/src/utils/importing.py 2007-02-22 22:44:30 UTC (rev 9403) +++ trunk/gnue-common/src/utils/importing.py 2007-02-23 01:29:03 UTC (rev 9404) @@ -0,0 +1,99 @@ +# GNU Enterprise Common - Utilities - Importing +# +# Copyright 2001-2007 Free Software Foundation +# +# This file is part of GNU Enterprise +# +# GNU Enterprise 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, or (at your option) any later version. +# +# GNU Enterprise 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 program; see the file COPYING. If not, +# write to the Free Software Foundation, Inc., 59 Temple Place +# - Suite 330, Boston, MA 02111-1307, USA. +# +# $Id$ +# +""" +This module implements a dynamic module importer. +""" + +import sys + + +__all__ = ['import_string'] + +# =================================================================== +# Dynamically import a python module +# =================================================================== +_global_dict = globals() +def import_string(name): + """ + Import a module/item using a string name. + + This is adapted from PEAK's peak.utils.importString, licensed + under the Python license. + """ + parts = filter(None,name.split('.')) + item = __import__(parts.pop(0), _global_dict, _global_dict, ['__name__']) + + # Fast path for the common case, where everything is imported already + for attr in parts: + try: + item = getattr(item, attr) + except AttributeError: + break # either there's an error, or something needs importing + else: + return item + + # We couldn't get there with just getattrs from the base import. So now + # we loop *backwards* trying to import longer names, then shorter, until + # we find the longest possible name that can be handled with __import__, + # then loop forward again with getattr. This lets us give more meaningful + # error messages than if we only went forwards. + attrs = [] + exc = None + + try: + while True: + try: + # Exit as soon as we find a prefix of the original `name` + # that's an importable *module* or package + item = __import__(name, _global_dict, _global_dict, ['__name__']) + break + except ImportError: + if not exc: + # Save the first ImportError, as it's usually the most + # informative, especially w/Python < 2.4 + exc = sys.exc_info() + + if '.' not in name: + # We've backed up all the way to the beginning, so reraise + # the first ImportError we got + raise exc[0],exc[1],exc[2] + + # Otherwise back up one position and try again + parts = name.split('.') + attrs.append(parts[-1]) + name = '.'.join(parts[:-1]) + finally: + exc = None + + # Okay, the module object is now in 'item', so we can just loop forward + # to retrieving the desired attribute. + # + while attrs: + attr = attrs.pop() + try: + item = getattr(item,attr) + except AttributeError: + raise ImportError("%r has no %r attribute" % (item,attr)) + + return item Property changes on: trunk/gnue-common/src/utils/importing.py ___________________________________________________________________ Name: svn:keywords + Id _______________________________________________ commit-gnue mailing list commit-gnue@gnu.org http://lists.gnu.org/mailman/listinfo/commit-gnue