[Zope-CVS] CVS: Packages/zpkgtools/zpkgtools - locationmap.py:1.1

Fred L. Drake, Jr. fred at zope.com
Tue Mar 9 10:20:38 EST 2004


Update of /cvs-repository/Packages/zpkgtools/zpkgtools
In directory cvs.zope.org:/tmp/cvs-serv10752

Added Files:
	locationmap.py 
Log Message:
- rename zpkgtools.cvsmap to zpkgtools.locationmap
- add mapping object with an interface that closely supports the
  strings actually found in the packages files
- add a function to normalize feature names found in packages lists
  (dealing with typed entries)


=== Added File Packages/zpkgtools/zpkgtools/locationmap.py ===
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tools to deal with the mapping of resources to CVS URLs."""

import os.path
import posixpath
import urllib
import urllib2
import urlparse
import UserDict

from zpkgtools import cvsloader


DEFAULT_TYPE = "package"


class MapLoadingError(ValueError):
    def __init__(self, message, lineno):
        self.lineno = lineno
        ValueError.__init__(self, message)


class LocationMap(UserDict.UserDict):

    def __getitem__(self, key):
        return self.data[normalizeResourceId(key)]

    def __setitem__(self, key, item):
        self.data[normalizeResourceId(key)] = item

    def __delitem__(self, key):
        del self.data[normalizeResourceId(key)]

    def has_key(self, key):
        return normalizeResourceId(key) in self.data

    def update(self, dict=None, **kwargs):
        if dict:
            for key, value in dict.iteritems():
                self.data[normalizeResourceId(key)] = value
        if len(kwargs):
            self.update(kwargs)

    def pop(self, key, *args):
        return self.data.pop(normalizeResourceId(key), *args)

    def __contains__(self, key):
        return normalizeResourceId(key) in self.data


def load(f, base=None, mapping=None):
    cvsbase = None
    if base is not None:
        try:
            cvsbase = cvsloader.parse(base)
        except ValueError:
            pass
    if mapping is None:
        mapping = LocationMap()
    lineno = 0
    for line in f:
        lineno += 1
        line = line.strip()
        if line[:1] in ("", "#"):
            continue

        parts = line.split()
        if len(parts) != 2:
            raise MapLoadingError("malformed package specification", lineno)
        resource, url = parts
        resource = normalizeResourceId(resource)
        try:
            cvsurl = cvsloader.parse(url)
        except ValueError:
            # conventional URL
            if base is not None:
                url = urlparse.urljoin(base, url)
        else:
            if isinstance(cvsurl, cvsloader.RepositoryUrl):
                if cvsbase is None:
                    raise MapLoadingError(
                        "repository: URLs are not supported"
                        " without a cvs: base URL",
                        lineno)
                cvsurl = cvsurl.join(cvsbase)
            url = cvsurl.getUrl()

        # We only want to add it once, so that loading several
        # mappings causes the first defining a resource to "win":
        if resource not in mapping:
            mapping[resource] = url
        # else tell the user of the conflict?

    return mapping


def fromPathOrUrl(path, mapping=None):
    if os.path.isfile(path):
        # prefer a cvs: URL over a local path if possible:
        try:
            cvsurl = cvsloader.fromPath(path)
        except IOError, e:
            print "IOError:", e
            base = os.path.dirname(path)
        else:
            cvsurl.path = posixpath.dirname(cvsurl.path)
            base = cvsurl.getUrl()
        f = open(path, "rU")
    else:
        f = urllib2.urlopen(path)
    try:
        return load(f, base, mapping)
    finally:
        f.close()


def normalizeResourceId(resource):
    if resource[:1] == ":":
        return resource
    type, rest = urllib.splittype(resource)
    if not type:
        type = DEFAULT_TYPE
    return "%s:%s" % (type, rest)




More information about the Zope-CVS mailing list