__init__.py revision 305
49N/A#!/usr/bin/python
49N/A#
49N/A# CDDL HEADER START
49N/A#
49N/A# The contents of this file are subject to the terms of the
49N/A# Common Development and Distribution License (the "License").
49N/A# You may not use this file except in compliance with the License.
49N/A#
49N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
49N/A# or http://www.opensolaris.org/os/licensing.
49N/A# See the License for the specific language governing permissions
49N/A# and limitations under the License.
49N/A#
49N/A# When distributing Covered Code, include this CDDL HEADER in each
49N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
49N/A# If applicable, add the following below this CDDL HEADER, with the
49N/A# fields enclosed by brackets "[]" replaced with your own identifying
49N/A# information: Portions Copyright [yyyy] [name of copyright owner]
49N/A#
49N/A# CDDL HEADER END
49N/A#
49N/A
49N/A#
49N/A# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
49N/A# Use is subject to license terms.
49N/A#
49N/A
49N/A"""
49N/Apackage containing packaging action (file type) modules
49N/A
49N/AThis package contains modules describing packaging actions, or file types. The
49N/Aactions are dynamically discovered, so that new modules can be placed in this
49N/Apackage directory and they'll just be picked up. The current package contents
49N/Acan be seen in the section "PACKAGE CONTENTS", below.
49N/A
51N/AThis package has one data member: "types". This is a dictionary which maps the
51N/Aaction names to the classes that represent them.
51N/A
51N/AThis package also has one function: "fromstr", which creates an action instance
51N/Abased on a str() representation of an action.
49N/A"""
49N/A
49N/Aimport inspect
49N/Aimport os
49N/A
49N/A# All modules in this package (all python files except __init__.py with their
49N/A# extensions stripped off).
49N/A__all__ = [
49N/A f[:-3]
49N/A for f in os.listdir(__path__[0])
49N/A if f.endswith(".py") and f != "__init__.py"
49N/A]
49N/A
49N/A# A dictionary of all the types in this package, mapping to the classes that
49N/A# define them.
49N/Atypes = {}
49N/Afor modname in __all__:
49N/A module = __import__("%s.%s" % (__name__, modname),
49N/A globals(), locals(), [modname])
49N/A
49N/A nvlist = inspect.getmembers(module, inspect.isclass)
49N/A
49N/A # Pull the class objects out of nvlist, keeping only those that are
49N/A # actually defined in this package.
49N/A classes = [
49N/A c[1]
49N/A for c in nvlist
49N/A if '.'.join(c[1].__module__.split('.')[:-1]) == __name__
49N/A ]
49N/A for cls in classes:
51N/A types[cls.name] = cls
49N/A
49N/A# Clean up after ourselves
49N/Adel f, modname, module, nvlist, classes, c, cls
51N/A
51N/Adef fromstr(str):
51N/A """Create an action instance based on a str() representation of an action.
279N/A
279N/A Raises KeyError if the action type is unknown.
51N/A """
51N/A
305N/A list = str.split(' ')
305N/A type = list.pop(0)
51N/A if type not in types:
305N/A raise KeyError, "Bad action type '%s' in action '%s'" % \
305N/A (type, str)
51N/A
51N/A # That is, if the first attribute is a hash
305N/A if list[0].find("=") == -1:
305N/A hash = list.pop(0)
131N/A else:
131N/A hash = None
57N/A
57N/A # Simple state machine to reconnect the elements that shouldn't have
57N/A # been split. Put the results into a new list since we can't modify the
57N/A # list we're iterating over.
57N/A state = 0
57N/A nlist = []
305N/A n = ""
57N/A for i in list:
57N/A if '="' in i:
57N/A n = i.replace('="', '=')
57N/A state = 1
57N/A elif i.endswith('"'):
57N/A n += " " + i[:-1]
57N/A nlist += [ n ]
305N/A n = ""
57N/A state = 0
57N/A elif state == 1:
57N/A n += " " + i
305N/A elif i:
57N/A nlist += [ i ]
57N/A
305N/A if n != "":
305N/A raise ValueError("Unmatched \" in action '%s'" % str)
57N/A
132N/A return fromlist(type, nlist, hash)
57N/A
131N/Adef fromlist(type, args, hash = None):
279N/A """Create an action instance based on a sequence of "key=value" strings.
279N/A
279N/A Raises ValueError if the attribute strings are malformed.
279N/A """
305N/A
305N/A attrs = {}
305N/A
305N/A saw_error = False
305N/A try:
305N/A for a, v in [kv.split("=", 1) for kv in args]:
305N/A if v == '' or a == '':
305N/A saw_error = True
305N/A raise ValueError(
305N/A "Malformed action attribute: '%s=%s'" %
305N/A (a, v))
57N/A
305N/A # This is by far the common case-- an attribute with
305N/A # a single value.
305N/A if a not in attrs:
305N/A attrs[a] = v
305N/A else:
305N/A av = attrs[a]
305N/A if isinstance(av, list):
305N/A attrs[a].append(v)
305N/A else:
305N/A attrs[a] = [ av, v ]
305N/A except ValueError, v:
305N/A if saw_error:
305N/A raise
305N/A
305N/A #
305N/A # We're only here if the for: statement above throws a
305N/A # ValueError. That can happen if split yields a single element,
305N/A # which is possible if e.g. an attribute lacks an =.
305N/A #
305N/A raise ValueError("Malformed action string: %s", args)
51N/A
51N/A action = types[type](**attrs)
131N/A if hash:
51N/A action.hash = hash
51N/A
51N/A return action