[Erp5-report] r12788 - in /spec/debian/unstable/erp5-pluginregistry: ./ PluginRegistry/ Plu...

nobody at svn.erp5.org nobody at svn.erp5.org
Thu Feb 15 18:28:38 CET 2007


Author: yusei
Date: Thu Feb 15 18:28:34 2007
New Revision: 12788

URL: http://svn.erp5.org?rev=12788&view=rev
Log:
added debian package and workspace.

Added:
    spec/debian/unstable/erp5-pluginregistry/
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/PluginRegistry.py
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/__init__.py
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/changelog
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/compat
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/control
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/copyright
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/dzproduct
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/postinst
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/rules   (with props)
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/interfaces/
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/interfaces/__init__.py
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/interfaces/plugins.py
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/tests/
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/tests/__init__.py
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/tests/test_PluginRegistry.py
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/utils.py
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/PluginRegistry.png   (with props)
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-down.gif   (with props)
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-left.gif   (with props)
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-right.gif   (with props)
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-up.gif   (with props)
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/plugins.zpt
    spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/two_lists.zpt
    spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1.diff.gz   (with props)
    spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1.dsc
    spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_all.deb   (with props)
    spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_i386.build
    spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_i386.changes
    spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0.orig.tar.gz   (with props)

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/PluginRegistry.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/PluginRegistry.py?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/PluginRegistry.py (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/PluginRegistry.py Thu Feb 15 18:28:34 2007
@@ -1,0 +1,325 @@
+""" Classes: PluginRegistry
+
+$Id: PluginRegistry.py,v 1.1.1.1 2004/04/28 19:19:54 urbanape Exp $
+"""
+
+from Globals import Persistent
+from App.ImageFile import ImageFile
+from Acquisition import Implicit, aq_parent, aq_inner
+from AccessControl import ClassSecurityInfo
+from AccessControl.Permissions import manage_users as ManageUsers
+from Persistence import PersistentMapping
+from OFS.SimpleItem import SimpleItem
+from App.class_init import default__class_init__ as InitializeClass
+from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from Products.PageTemplates.Expressions import getEngine
+from Products.PageTemplates.Expressions import SecureModuleImporter
+
+from interfaces.plugins import IPluginRegistry
+from utils import _wwwdir
+
+class PluginRegistry( SimpleItem ):
+
+    """ Implement IPluginRegistry as an independent, ZMI-manageable object.
+
+    o Each plugin type holds an ordered list of ( id, wrapper ) tuples.
+    """
+    __implements__ = ( IPluginRegistry, )
+
+    security = ClassSecurityInfo()
+
+    meta_type = 'Plugin Registry'
+
+    _plugins = None
+
+    def __init__( self, plugin_type_info ):
+
+        self._plugin_types = [x[0] for x in plugin_type_info]
+        self._plugin_type_info = PersistentMapping()
+        for interface in plugin_type_info:
+            self._plugin_type_info[interface[0]] = { 
+                  'id': interface[1]
+                , 'title': interface[2]
+                , 'description': interface[3]
+                }
+
+    #
+    #   IPluginRegistry implementation
+    #
+    security.declareProtected( ManageUsers, 'listPluginTypeInfo' )
+    def listPluginTypeInfo( self ):
+
+        """ See IPluginRegistry.
+        """
+        result = []
+
+        for ptype in self._plugin_types:
+
+            info = self._plugin_type_info[ptype].copy()
+            info['interface'] = ptype
+            info['methods'] = ptype.names()
+
+            result.append( info )
+
+        return result
+
+    security.declareProtected( ManageUsers, 'listPlugins' )
+    def listPlugins( self, plugin_type ):
+
+        """ See IPluginRegistry.
+        """
+        result = []
+
+        parent = aq_parent( aq_inner( self ) )
+
+        for plugin_id in self._getPlugins( plugin_type ):
+
+            plugin = parent._getOb( plugin_id )
+            result.append( ( plugin_id, plugin ) )
+
+        return result
+
+    security.declareProtected( ManageUsers, 'getPluginInfo' )
+    def getPluginInfo( self, plugin_type ):
+
+        """ See IPluginRegistry.
+        """
+        plugin_type = self._getInterfaceFromName( plugin_type )
+        return self._plugin_type_info[plugin_type]
+
+    security.declareProtected( ManageUsers, 'listPluginInfo' )
+    def listPluginIds( self, plugin_type ):
+
+        """ See IPluginRegistry.
+        """
+
+        return self._getPlugins( plugin_type )
+
+    security.declareProtected( ManageUsers, 'activatePlugin' )
+    def activatePlugin( self, plugin_type, plugin_id ):
+
+        """ See IPluginRegistry.
+        """
+        plugins = list( self._getPlugins( plugin_type ) )
+
+        if plugin_id in plugins:
+            raise KeyError, 'Duplicate plugin id: %s' % plugin_id
+
+        parent = aq_parent( aq_inner( self ) )
+        plugin = parent._getOb( plugin_id ) 
+
+        if not plugin_type.isImplementedBy(plugin):
+            raise ValueError, 'Plugin does not implement %s' % plugin_type 
+        
+        plugins.append( plugin_id )
+        self._plugins[ plugin_type ] = tuple( plugins )
+
+    security.declareProtected( ManageUsers, 'deactivatePlugin' )
+    def deactivatePlugin( self, plugin_type, plugin_id ):
+
+        """ See IPluginRegistry.
+        """
+        plugins = list( self._getPlugins( plugin_type ) )
+
+        if not plugin_id in plugins:
+            raise KeyError, 'Invalid plugin id: %s' % plugin_id
+
+        plugins = [ x for x in plugins if x != plugin_id ]
+        self._plugins[ plugin_type ] = tuple( plugins )
+
+    security.declareProtected( ManageUsers, 'movePluginsUp' )
+    def movePluginsUp( self, plugin_type, ids_to_move ):
+
+        """ See IPluginRegistry.
+        """
+        ids = list( self._getPlugins( plugin_type ) )
+        count = len( ids )
+
+        indexes = list( map( ids.index, ids_to_move ) )
+        indexes.sort()
+
+        for i1 in indexes:
+
+            if i1 < 0 or i1 >= count:
+                raise IndexError, i1
+
+            i2 = i1 - 1
+            if i2 < 0:      # wrap to bottom
+                i2 = len( ids ) - 1
+
+            ids[ i2 ], ids[ i1 ] = ids[ i1 ], ids[ i2 ]
+
+        self._plugins[ plugin_type ] = tuple( ids )
+
+    security.declareProtected( ManageUsers, 'movePluginsDown' )
+    def movePluginsDown( self, plugin_type, ids_to_move ):
+
+        """ See IPluginRegistry.
+        """
+        ids = list( self._getPlugins( plugin_type ) )
+        count = len( ids )
+
+        indexes = list( map( ids.index, ids_to_move ) )
+        indexes.sort()
+        indexes.reverse()
+
+        for i1 in indexes:
+
+            if i1 < 0 or i1 >= count:
+                raise IndexError, i1
+
+            i2 = i1 + 1
+            if i2 == len( ids ):      # wrap to top
+                i2 = 0
+
+            ids[ i2 ], ids[ i1 ] = ids[ i1 ], ids[ i2 ]
+
+        self._plugins[ plugin_type ] = tuple( ids )
+
+    #
+    #   ZMI
+    #
+    arrow_right_gif = ImageFile( 'www/arrow-right.gif', globals() )
+    arrow_left_gif = ImageFile( 'www/arrow-left.gif', globals() )
+    arrow_up_gif = ImageFile( 'www/arrow-up.gif', globals() )
+    arrow_down_gif = ImageFile( 'www/arrow-down.gif', globals() )
+
+    security.declareProtected( ManageUsers, 'manage_activatePlugins' )
+    def manage_activatePlugins( self
+                             , plugin_type
+                             , plugin_ids
+                             , RESPONSE
+                             ):
+        """ Shim into ZMI.
+        """
+        interface = self._getInterfaceFromName( plugin_type )
+        for id in plugin_ids:
+            self.activatePlugin( interface, id )
+        RESPONSE.redirect( '%s/manage_plugins?plugin_type=%s'
+                         % ( self.absolute_url(), plugin_type )
+                         )
+
+    security.declareProtected( ManageUsers, 'manage_deactivatePlugins' )
+    def manage_deactivatePlugins( self
+                                , plugin_type
+                                , plugin_ids
+                                , RESPONSE
+                                ):
+        """ Shim into ZMI.
+        """
+        interface = self._getInterfaceFromName( plugin_type )
+        for id in plugin_ids:
+            self.deactivatePlugin( interface, id )
+
+        RESPONSE.redirect( '%s/manage_plugins?plugin_type=%s'
+                         % ( self.absolute_url(), plugin_type )
+                         )
+
+    security.declareProtected( ManageUsers, 'manage_movePluginsUp' )
+    def manage_movePluginsUp( self
+                            , plugin_type
+                            , plugin_ids
+                            , RESPONSE
+                            ):
+        """ Shim into ZMI.
+        """
+        interface = self._getInterfaceFromName( plugin_type )
+        self.movePluginsUp( interface, plugin_ids )
+
+        RESPONSE.redirect( '%s/manage_plugins?plugin_type=%s'
+                         % ( self.absolute_url(), plugin_type )
+                         )
+
+    security.declareProtected( ManageUsers, 'manage_movePluginsDown' )
+    def manage_movePluginsDown( self
+                              , plugin_type
+                              , plugin_ids
+                              , RESPONSE
+                              ):
+        """ Shim into ZMI.
+        """
+        interface = self._getInterfaceFromName( plugin_type )
+        self.movePluginsDown( interface, plugin_ids )
+
+        RESPONSE.redirect( '%s/manage_plugins?plugin_type=%s'
+                         % ( self.absolute_url(), plugin_type )
+                         )
+
+    security.declareProtected( ManageUsers, 'getAllPlugins' )
+    def getAllPlugins( self, plugin_type ):
+
+        """ Return a mapping segregating active / available plugins.
+
+        'plugin_type' is the __name__ of the interface.
+        """
+        interface = self._getInterfaceFromName( plugin_type )
+
+        active = self._getPlugins( interface )
+        available = []
+
+        for id, value in aq_parent( aq_inner( self ) ).objectItems():
+            if interface.isImplementedBy( value ):
+                if id not in active:
+                    available.append( id )
+
+        return { 'active' : active, 'available' : available }
+
+
+    security.declareProtected( ManageUsers, 'removePluginById' )
+    def removePluginById( self, plugin_id ):
+
+        """ Remove a plugin from any plugin types which have it configured.
+        """
+        for plugin_type in self._plugin_types:
+
+            if plugin_id in self._getPlugins( plugin_type ):
+                self.deactivatePlugin( plugin_type, plugin_id )
+
+    security.declareProtected( ManageUsers, 'manage_plugins' )
+    manage_plugins = PageTemplateFile( 'plugins', _wwwdir )
+    manage_twoLists = PageTemplateFile( 'two_lists', _wwwdir )
+
+    manage_options=( ( { 'label'        : 'Plugins'
+                       , 'action'       : 'manage_plugins'
+                     # , 'help'         : ( 'PluggableAuthService'
+                     #                    , 'plugins.stx')
+                       }
+                     ,
+                     )
+                   + SimpleItem.manage_options
+                   )
+
+    #
+    #   Helper methods
+    #
+    security.declarePrivate( '_getPlugins' )
+    def _getPlugins( self, plugin_type ):
+
+        parent = aq_parent( aq_inner( self ) )
+
+        if plugin_type not in self._plugin_types:
+            raise KeyError, plugin_type
+
+        if self._plugins is None:
+            self._plugins = PersistentMapping()
+
+        return self._plugins.setdefault( plugin_type, () )
+
+    security.declarePrivate( '_getInterfaceFromName' )
+    def _getInterfaceFromName( self, plugin_type_name ):
+
+        """ Convert the string name to an interface.
+
+        o Raise KeyError is no such interface is known.
+        """
+        found = [ x[0] for x in self._plugin_type_info.items()
+                                if x[1][ 'id' ] == plugin_type_name ]
+        if not found:
+            raise KeyError, plugin_type_name
+
+        if len( found ) > 1:
+            raise KeyError, 'Waaa!:  %s' % plugin_type_name
+
+        return found[ 0 ]
+
+InitializeClass( PluginRegistry )

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/__init__.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/__init__.py?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/__init__.py (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/__init__.py Thu Feb 15 18:28:34 2007
@@ -1,0 +1,17 @@
+""" PluginRegistry product initialization.
+
+$Id: __init__.py,v 1.1.1.1 2004/04/28 19:19:54 urbanape Exp $
+"""
+
+from utils import allTests
+
+import PluginRegistry
+
+def initialize(context):
+
+    context.registerClass( PluginRegistry.PluginRegistry
+                         , constructors=[ ( 'Dummy', lambda: None ) ]
+                         , visibility=None
+                         , icon='www/PluginRegistry.png'
+                         )
+

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/changelog
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/changelog?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/changelog (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/changelog Thu Feb 15 18:28:34 2007
@@ -1,0 +1,6 @@
+erp5-pluginregistry (1.0-1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Yusei TAHARA <yusei at domen.cx>  Wed, 14 Feb 2007 03:27:56 +0900
+

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/compat
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/compat?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/compat (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/compat Thu Feb 15 18:28:34 2007
@@ -1,0 +1,1 @@
+5

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/control
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/control?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/control (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/control Thu Feb 15 18:28:34 2007
@@ -1,0 +1,19 @@
+Source: erp5-pluginregistry
+Section: web
+Priority: optional
+Maintainer: Yusei TAHARA
+Build-Depends: debhelper (>= 5.0)
+Build-Depends-Indep: zope-debhelper (>= 0.3.6)
+Standards-Version: 3.7.2
+
+Package: erp5-pluginregistry
+Architecture: all
+Depends: erp5-zope
+Description: This Zope product defines a fully-pluggable user folder, intended for use in all sites
+ PluggableAuthService is a highly extensible replacement user folder for
+ Zope 2. It can manage arbitrary user, group, role, and property
+ definitions with ease, and works best in very heterogeneous environments
+ (users stored in MySQL, groups in LDAP, properties from the filesystem, etc).
+ .
+ For authentication, it supports HTTP Basic Auth, Cookie Auth, Domain Auth,
+ and can be extended to support just about any other mechanism.

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/copyright
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/copyright?rev=12788&view=auto
==============================================================================
    (empty)

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/dzproduct
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/dzproduct?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/dzproduct (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/dzproduct Thu Feb 15 18:28:34 2007
@@ -1,0 +1,3 @@
+Name: PluginRegistry
+Package: erp5-pluginregistry
+ZopeVersions: >= 2.7

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/postinst
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/postinst?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/postinst (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/postinst Thu Feb 15 18:28:34 2007
@@ -1,0 +1,7 @@
+#!/bin/sh -e
+
+. /usr/share/debconf/confmodule
+
+#DEBHELPER#
+
+db_stop

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/rules
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/rules?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/rules (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/rules Thu Feb 15 18:28:34 2007
@@ -1,0 +1,44 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper.
+# GNU copyright 1997 to 1999 by Joey Hess.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+pwd        := $(shell pwd)
+debian     := $(pwd)/debian/erp5-pluginregistry
+
+build: build-stamp
+build-stamp:
+	touch build-stamp
+
+clean:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp configure-stamp
+	dh_clean
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k
+	dh_installdirs
+	dh_installerp5zope .
+
+binary-indep: build install
+	dh_testdir
+	dh_testroot
+	dh_installdocs
+	dh_installexamples
+	dh_installchangelogs
+	dh_compress
+	dh_fixperms
+	dh_installdeb
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary-arch:
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary install

Propchange: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/debian/rules
------------------------------------------------------------------------------
    svn:executable = 

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/interfaces/__init__.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/interfaces/__init__.py?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/interfaces/__init__.py (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/interfaces/__init__.py Thu Feb 15 18:28:34 2007
@@ -1,0 +1,4 @@
+""" PluginRegistry interface declarations
+
+$Id: __init__.py,v 1.1.1.1 2004/04/28 19:19:54 urbanape Exp $
+"""

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/interfaces/plugins.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/interfaces/plugins.py?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/interfaces/plugins.py (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/interfaces/plugins.py Thu Feb 15 18:28:34 2007
@@ -1,0 +1,95 @@
+""" Interfaces:  IPluginRegistry
+
+$Id: plugins.py,v 1.1.1.1 2004/04/28 19:19:54 urbanape Exp $
+"""
+
+from Interface import Interface
+
+class IPluginRegistry( Interface ):
+
+
+    """ Manage a set of plugin definitions, grouped by type.
+    """
+
+    def listPluginTypeInfo():
+
+        """ Return a sequence of mappings describing our plugin types.
+
+        o Keys for the mappings must include:
+
+          'id' -- a string used to identify the plugin type (should be
+            the __name__ of the interface)
+
+          'interface' -- the plugin type interface
+
+          'methods' -- the methods expected by the plugin type interface
+
+          'title' -- a display title for the plugin type
+
+          'description' -- a description of what the plugins do
+        """
+
+    def listPlugins( plugin_type ):
+
+        """ Return a sequence of tuples, one for each plugin of the given type.
+
+        o 'plugin_type' must be one of the known types, else raise KeyError.
+
+        o Tuples will be of the form, '( plugin_id, plugin )'.
+        """
+
+    def listPluginIds( plugin_type ):
+
+        """ Return a sequence of plugin ids
+        
+        o Return ids for each active plugin of the given type.
+
+        o 'plugin_type' must be one of the known types, else raise KeyError.
+        """
+
+    def activatePlugin( plugin_type, plugin_id ):
+
+        """ Activate a plugin of the given type.
+
+        o 'plugin_type' must be one of the known types, else raise KeyError.
+
+        o 'plugin_id' must be the ID of an available plugin, else raise
+          KeyError.
+
+        o Append 'plugin_id' to the list of active plugins for the given
+          'plugin_type'.
+        """
+
+    def deactivatePlugin( plugin_type, plugin_id ):
+
+        """ Deactivate a plugin of the given type.
+
+        o 'plugin_type' must be one of the known types, else raise KeyError.
+
+        o 'plugin_id' must be an ID of an existing plugin of that type,
+          else raise KeyError.
+        """
+
+    def movePluginsUp( plugin_type, ids_to_move ):
+
+        """ Move a set of plugins "up" in their list.
+
+        o 'plugin_type' must be one of the known types, else raise KeyError.
+
+        o 'ids_to_move' must be a sequence of ids of current plugins
+          for that type.
+          
+          - If any item is not the ID of a current plugin, raise ValueError.
+        """
+
+    def movePluginsDown( plugin_type, ids_to_move ):
+
+        """ Move a set of plugins "down" in their list.
+
+        o 'plugin_type' must be one of the known types, else raise KeyError.
+
+        o 'ids_to_move' must be a sequence of indexes of items in the current
+          list of plugins for that type.
+          
+          - If any item is not the ID of a current plugin, raise ValueError.
+        """

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/tests/__init__.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/tests/__init__.py?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/tests/__init__.py (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/tests/__init__.py Thu Feb 15 18:28:34 2007
@@ -1,0 +1,4 @@
+""" PluginRegistry unit tests
+
+$Id: __init__.py,v 1.1.1.1 2004/04/28 19:19:54 urbanape Exp $
+"""

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/tests/test_PluginRegistry.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/tests/test_PluginRegistry.py?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/tests/test_PluginRegistry.py (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/tests/test_PluginRegistry.py Thu Feb 15 18:28:34 2007
@@ -1,0 +1,288 @@
+from OFS.Folder import Folder
+from Interface import Interface
+from Acquisition import Implicit
+import unittest
+
+from Products.PluginRegistry.utils import directlyProvides
+
+class INonesuch(Interface):
+    pass
+
+class IFoo(Interface):
+    def foo():
+        """ Foo. """
+
+class IBar(Interface):
+    def bar():
+        """ Bar. """
+
+class DummyFolder(Folder):
+    pass
+
+class DummyPlugin(Implicit):
+    pass
+
+_PLUGIN_INFO = ( ( IFoo, 'IFoo', 'foo', 'Foo test' )
+               , ( IBar, 'IBar', 'bar', 'Bar test' )
+               )
+
+class PluginRegistryTests( unittest.TestCase ):
+
+    def _getTargetClass( self ):
+
+        from Products.PluginRegistry.PluginRegistry import PluginRegistry
+
+        return PluginRegistry
+
+    def _makeOne( self, plugin_info=_PLUGIN_INFO, *args, **kw ):
+
+        return self._getTargetClass()( plugin_info, *args, **kw )
+
+    def test_conformance_IPluginRegistry( self ):
+
+        from Products.PluginRegistry.interfaces.plugins \
+            import IPluginRegistry
+
+        from Interface.Verify import verifyClass
+
+        verifyClass( IPluginRegistry, self._getTargetClass() )
+
+
+    def test_empty( self ):
+
+        preg = self._makeOne()
+
+        self.assertRaises( KeyError, preg.listPlugins, INonesuch )
+        self.assertEqual( len( preg.listPlugins( IFoo ) ), 0 )
+        self.assertEqual( len( preg.listPluginIds( IFoo ) ), 0 )
+
+    def test_listPluginTypeInfo( self ):
+
+        pref = self._makeOne()
+
+        pti = pref.listPluginTypeInfo()
+        self.assertEqual( pti[0]['interface'], IFoo )
+        self.assertEqual( pti[1]['title'], 'bar' )
+
+    def test_activatePluginNoChild( self ):
+
+        parent = DummyFolder()
+
+        preg = self._makeOne().__of__(parent)
+
+        self.assertRaises( AttributeError, preg.activatePlugin, IFoo,
+                           'foo_plugin' )
+
+    def test_activatePluginInterfaceNonconformance( self ):
+
+        parent = DummyFolder()
+        foo_plugin = DummyPlugin()
+        parent._setObject( 'foo_plugin', foo_plugin )
+
+        preg = self._makeOne().__of__(parent)
+
+        self.assertRaises( ValueError, preg.activatePlugin, IFoo,
+                           'foo_plugin' )
+
+    def test_activatePlugin( self ):
+
+        parent = DummyFolder()
+        foo_plugin = DummyPlugin()
+        directlyProvides( foo_plugin,  ( IFoo, ) )
+        parent._setObject( 'foo_plugin', foo_plugin )
+
+        preg = self._makeOne().__of__(parent)
+
+        preg.activatePlugin( IFoo, 'foo_plugin')
+
+        idlist = preg.listPluginIds( IFoo )
+        self.assertEqual( len( idlist ), 1 )
+        self.assertEqual( idlist[0], 'foo_plugin' )
+
+        # XXX:  Note that we aren't testing 'listPlugins' here, as it
+        #       requires that we have TALES wired up.
+        #
+        #plugins = preg.listPlugins( 'foo' )
+        #self.assertEqual( len( plugins ), 1 )
+        #plugin = plugins[0]
+        #self.assertEqual( plugin[0], 'test' )
+        #self.assertEqual( plugin[1], preg.test_foo )
+
+    def test_deactivatePlugin( self ):
+
+        parent = DummyFolder()
+        foo_plugin = DummyPlugin()
+        directlyProvides( foo_plugin, ( IFoo, ) )
+        parent._setObject( 'foo_plugin', foo_plugin )
+
+        bar_plugin = DummyPlugin()
+        directlyProvides( bar_plugin, ( IFoo, ) )
+        parent._setObject( 'bar_plugin', bar_plugin )
+
+        baz_plugin = DummyPlugin()
+        directlyProvides( baz_plugin, ( IFoo, ) )
+        parent._setObject( 'baz_plugin', baz_plugin )
+
+        preg = self._makeOne().__of__(parent)
+
+        preg.activatePlugin( IFoo, 'foo_plugin' )
+        preg.activatePlugin( IFoo, 'bar_plugin' )
+        preg.activatePlugin( IFoo, 'baz_plugin' )
+
+        preg.deactivatePlugin( IFoo, 'bar_plugin' )
+
+        idlist = preg.listPluginIds( IFoo )
+        self.assertEqual( len( idlist ), 2 )
+        self.assertEqual( idlist[0], 'foo_plugin' )
+        self.assertEqual( idlist[1], 'baz_plugin' )
+
+    def test_movePluginsUp( self ):
+
+        parent = DummyFolder()
+        foo_plugin = DummyPlugin()
+        directlyProvides( foo_plugin, ( IFoo, ) )
+        parent._setObject( 'foo_plugin', foo_plugin )
+
+        bar_plugin = DummyPlugin()
+        directlyProvides( bar_plugin, ( IFoo, ) )
+        parent._setObject( 'bar_plugin', bar_plugin )
+
+        baz_plugin = DummyPlugin()
+        directlyProvides( baz_plugin, ( IFoo, ) )
+        parent._setObject( 'baz_plugin', baz_plugin )
+
+        preg = self._makeOne().__of__(parent)
+
+        preg.activatePlugin( IFoo, 'foo_plugin' )
+        preg.activatePlugin( IFoo, 'bar_plugin' )
+        preg.activatePlugin( IFoo, 'baz_plugin' )
+
+        self.assertRaises( ValueError, preg.movePluginsUp
+                         , IFoo, ( 'quux_plugin', ) )
+
+        preg.movePluginsUp( IFoo, ( 'bar_plugin', 'baz_plugin' ) )
+
+        idlist = preg.listPluginIds( IFoo )
+        self.assertEqual( len( idlist ), 3 )
+
+        self.assertEqual( idlist[0], 'bar_plugin' )
+        self.assertEqual( idlist[1], 'baz_plugin' )
+        self.assertEqual( idlist[2], 'foo_plugin' )
+
+    def test_movePluginsDown( self ):
+
+        parent = DummyFolder()
+        foo_plugin = DummyPlugin()
+        directlyProvides( foo_plugin, ( IFoo, ) )
+        parent._setObject( 'foo_plugin', foo_plugin )
+
+        bar_plugin = DummyPlugin()
+        directlyProvides( bar_plugin, ( IFoo, ) )
+        parent._setObject( 'bar_plugin', bar_plugin )
+
+        baz_plugin = DummyPlugin()
+        directlyProvides( baz_plugin, ( IFoo, ) )
+        parent._setObject( 'baz_plugin', baz_plugin )
+
+        preg = self._makeOne().__of__(parent)
+
+        preg.activatePlugin( IFoo, 'foo_plugin' )
+        preg.activatePlugin( IFoo, 'bar_plugin' )
+        preg.activatePlugin( IFoo, 'baz_plugin' )
+
+        self.assertRaises( ValueError, preg.movePluginsDown
+                         , IFoo, ( 'quux_plugin', ) )
+
+        preg.movePluginsDown( IFoo, ( 'foo_plugin', 'bar_plugin' ) )
+
+        idlist = preg.listPluginIds( IFoo )
+        self.assertEqual( len( idlist ), 3 )
+
+        self.assertEqual( idlist[0], 'baz_plugin' )
+        self.assertEqual( idlist[1], 'foo_plugin' )
+        self.assertEqual( idlist[2], 'bar_plugin' )
+
+    def test_getAllPlugins( self ):
+
+        parent = DummyFolder()
+        foo_plugin = DummyPlugin()
+        directlyProvides( foo_plugin, ( IFoo, ) )
+        parent._setObject( 'foo_plugin', foo_plugin )
+
+        bar_plugin = DummyPlugin()
+        directlyProvides( bar_plugin, ( IFoo, ) )
+        parent._setObject( 'bar_plugin', bar_plugin )
+
+        baz_plugin = DummyPlugin()
+        directlyProvides( baz_plugin, ( IFoo, ) )
+        parent._setObject( 'baz_plugin', baz_plugin )
+
+        preg = self._makeOne().__of__( parent )
+
+        first = preg.getAllPlugins( 'IFoo' )
+
+        self.assertEqual( len( first[ 'active' ] ), 0 )
+
+        self.assertEqual( len( first[ 'available' ] ), 3 )
+        self.failUnless( 'foo_plugin' in first[ 'available' ] )
+        self.failUnless( 'bar_plugin' in first[ 'available' ] )
+        self.failUnless( 'baz_plugin' in first[ 'available' ] )
+
+        preg.activatePlugin( IFoo, 'foo_plugin' )
+
+        second = preg.getAllPlugins( 'IFoo' )
+
+        self.assertEqual( len( second[ 'active' ] ), 1 )
+        self.failUnless( 'foo_plugin' in second[ 'active' ] )
+
+        self.assertEqual( len( second[ 'available' ] ), 2 )
+        self.failIf( 'foo_plugin' in second[ 'available' ] )
+        self.failUnless( 'bar_plugin' in second[ 'available' ] )
+        self.failUnless( 'baz_plugin' in second[ 'available' ] )
+
+        preg.activatePlugin( IFoo, 'bar_plugin' )
+        preg.activatePlugin( IFoo, 'baz_plugin' )
+
+        third = preg.getAllPlugins( 'IFoo' )
+
+        self.assertEqual( len( third[ 'active' ] ), 3 )
+        self.failUnless( 'foo_plugin' in third[ 'active' ] )
+        self.failUnless( 'bar_plugin' in third[ 'active' ] )
+        self.failUnless( 'baz_plugin' in third[ 'active' ] )
+
+        self.assertEqual( len( third[ 'available' ] ), 0 )
+
+    def test_removePluginById( self ):
+
+        parent = DummyFolder()
+        foo_plugin = DummyPlugin()
+        directlyProvides( foo_plugin, ( IFoo, IBar ) )
+        parent._setObject( 'foo_plugin', foo_plugin )
+
+        bar_plugin = DummyPlugin()
+        directlyProvides( bar_plugin, ( IFoo, ) )
+        parent._setObject( 'bar_plugin', bar_plugin )
+
+        baz_plugin = DummyPlugin()
+        directlyProvides( baz_plugin, ( IBar, ) )
+        parent._setObject( 'baz_plugin', baz_plugin )
+
+        preg = self._makeOne().__of__(parent)
+
+        preg.activatePlugin( IFoo, 'foo_plugin' )
+        preg.activatePlugin( IBar, 'foo_plugin' )
+        preg.activatePlugin( IFoo, 'bar_plugin' )
+        preg.activatePlugin( IBar, 'baz_plugin' )
+
+        preg.removePluginById( 'foo_plugin' )
+
+        idlist = preg.listPluginIds( IFoo )
+        self.assertEqual( len( idlist ), 1 )
+        self.assertEqual( idlist[0], 'bar_plugin' )
+
+        idlist = preg.listPluginIds( IBar )
+        self.assertEqual( len( idlist ), 1 )
+        self.assertEqual( idlist[0], 'baz_plugin' )
+
+if __name__ == "__main__":
+    unittest.main()

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/utils.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/utils.py?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/utils.py (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/utils.py Thu Feb 15 18:28:34 2007
@@ -1,0 +1,130 @@
+import os
+import unittest
+
+try:
+    from zope.interface import directlyProvides
+except ImportError:
+    def directlyProvides(obj, *interfaces):
+        obj.__implements__ = ( getattr( obj.__class__, '__implements__', () ) +
+                               tuple( interfaces )
+                             )
+
+product_dir, utils_module_file = os.path.split( __file__ )
+
+product_prefix = product_dir
+while product_prefix:
+    product_prefix, module = os.path.split( product_prefix )
+    if module == 'Products':
+        break
+
+
+_wwwdir = os.path.join( product_dir, 'www' )
+
+#
+#   Most of this module is shamelessly ripped off from Zope3.test
+#
+def remove_stale_bytecode( arg, dirname, names ):
+    """
+        Troll product, removing compiled turds whose source is now gone.
+    """
+    names = map( os.path.normcase, names )
+
+    for name in names:
+
+        if name.endswith( ".pyc" ) or name.endswith( ".pyo" ):
+
+            srcname = name[:-1]
+
+            if srcname not in names:
+
+                fullname = os.path.join( dirname, name )
+
+                if __debug__:
+                    print "Removing stale bytecode file", fullname
+
+                os.unlink( fullname )
+
+class TestFileFinder:
+
+    def __init__( self ):
+        self.files = []
+
+    def visit( self, prefix, dir, files ):
+        """
+            Visitor for os.path.walk:  accumulates filenamse of unittests.
+        """
+        #if dir[-5:] != "tests":
+        #    return
+
+        # ignore tests that aren't in packages
+        if not "__init__.py" in files:
+
+            if not files or files == ['CVS']:
+                return
+
+            if 0 and __debug__: # XXX: don't care!
+                print "not a package", dir
+
+            return
+
+        for file in files:
+
+            if file.startswith( prefix ) and file.endswith( ".py" ):
+                path = os.path.join(dir, file)
+                self.files.append(path)
+
+def find_unit_test_files( from_dir=product_dir, test_prefix='test' ):
+    """
+        Walk the product, return a list of all unittest files.
+    """
+    finder = TestFileFinder()
+    os.path.walk( from_dir, finder.visit, test_prefix )
+    return finder.files
+
+def module_name_from_path( path ):
+    """
+        Return the dotted module name matching the filesystem path.
+    """
+    assert path.endswith( '.py' )
+    path = path[:-3]
+    path = path[ len(product_prefix) + 1: ] # strip extraneous crap
+    dirs = []
+    while path:
+        path, end = os.path.split( path )
+        dirs.insert( 0, end )
+    return ".".join( dirs )
+
+def get_suite( file ):
+    """
+        Retrieve a TestSuite from 'file'.
+    """
+    module_name = module_name_from_path( file )
+    loader = unittest.defaultTestLoader
+    try:
+        suite = loader.loadTestsFromName( '%s.test_suite' % module_name )
+    except AttributeError:
+
+        try:
+            suite = loader.loadTestsFromName(  module_name )
+        except ImportError, err:
+            print "Error importing %s\n%s" % (module_name, err)
+            raise
+    return suite
+
+def allTests( from_dir=product_dir, test_prefix='test' ):
+    """
+        Walk the product and build a unittest.TestSuite aggregating tests.
+    """
+    os.path.walk( from_dir, remove_stale_bytecode, None )
+    test_files = find_unit_test_files( from_dir, test_prefix )
+    test_files.sort()
+
+    suite = unittest.TestSuite()
+
+    for test_file in test_files:
+
+        s = get_suite( test_file )
+        if s is not None:
+            suite.addTest( s )
+
+    return suite

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/PluginRegistry.png
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/PluginRegistry.png?rev=12788&view=auto
==============================================================================
Binary file - no diff available.

Propchange: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/PluginRegistry.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-down.gif
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-down.gif?rev=12788&view=auto
==============================================================================
Binary file - no diff available.

Propchange: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-down.gif
------------------------------------------------------------------------------
    svn:executable = 

Propchange: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-down.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-left.gif
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-left.gif?rev=12788&view=auto
==============================================================================
Binary file - no diff available.

Propchange: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-left.gif
------------------------------------------------------------------------------
    svn:executable = 

Propchange: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-left.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-right.gif
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-right.gif?rev=12788&view=auto
==============================================================================
Binary file - no diff available.

Propchange: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-right.gif
------------------------------------------------------------------------------
    svn:executable = 

Propchange: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-right.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-up.gif
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-up.gif?rev=12788&view=auto
==============================================================================
Binary file - no diff available.

Propchange: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-up.gif
------------------------------------------------------------------------------
    svn:executable = 

Propchange: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/arrow-up.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/plugins.zpt
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/plugins.zpt?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/plugins.zpt (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/plugins.zpt Thu Feb 15 18:28:34 2007
@@ -1,0 +1,68 @@
+<h1 tal:replace="structure here/manage_page_header"> PAGE HEADER </h1>
+<h2 tal:replace="structure here/manage_tabs"> TABS </h2>
+
+<div tal:define="plugin_type request/plugin_type | nothing">
+
+<div tal:condition="not: plugin_type">
+
+<h3> Plugin Types </h3>
+
+<dl>
+
+ <div tal:repeat="info here/listPluginTypeInfo"
+      tal:omit-tag="python: 1"
+ >
+ <dt class="form-label">
+   <a href="?plugin_type=PTYPE"
+      tal:attributes="href string:?plugin_type=${info/id}"
+      tal:content="string: ${info/title/title} Plugins"
+   >PLUGIN TYPE DESCRIPTION</a>
+ </dt>
+
+ <dd class="form-help" tal:content="info/description" />
+
+ </div>
+
+</dl>
+
+</div>
+
+<div tal:condition="plugin_type">
+<tal:info tal:define="plugin_info python:here.getPluginInfo( plugin_type )">
+
+<h3> <span tal:replace="plugin_info/title/capitalize">PluginType</span> 
+    Plugins </h3>
+
+
+<form action="."
+      tal:define="plugins python:here.getAllPlugins( plugin_type );
+                  left_name string:plugin_ids;
+                  left_list python: [(x, x) for x in plugins['available']];
+                  right_name string:plugin_ids;
+                  right_list python: [(x, x) for x in plugins['active']];
+                  left_to_right string:manage_activatePlugins;
+                  right_to_left string:manage_deactivatePlugins;
+                  right_is_ordered python:1;
+                  move_up string:manage_movePluginsUp;
+                  move_down string:manage_movePluginsDown;
+                 "
+>
+<table width="100%"
+       metal:use-macro="here/manage_twoLists/macros/two_lists"
+>
+ <input metal:fill-slot="hidden_vars"
+        type="hidden" name="plugin_type" value="PLUGIN_TYPE"
+        tal:attributes="value plugin_type" />
+
+ <span metal:fill-slot="left_title">Available Plugins</span>
+ <span metal:fill-slot="right_title">Active Plugins</span>
+
+</table>
+</form>
+
+</tal:info>
+</div>
+
+</div>
+
+<h1 tal:replace="structure here/manage_page_footer"> PAGE FOOTER </h1>

Added: spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/two_lists.zpt
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/two_lists.zpt?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/two_lists.zpt (added)
+++ spec/debian/unstable/erp5-pluginregistry/PluginRegistry/www/two_lists.zpt Thu Feb 15 18:28:34 2007
@@ -1,0 +1,94 @@
+<html>
+<body>
+<form action=".">
+
+<tal:comment>
+Macro for generic two-list UI.  Expects to have the following names defined
+by the including template:
+
+  - left_name: the name of the select widget for the left-hand side list.
+
+  - left_list: a list of tuples of strings for the left-hand side:
+    [ ( item_value, item_text ), ... ]
+
+  - right_name: the name of the select widget for the right-hand side list.
+
+  - right_list: is a list of tuples of strings for the right hand side:
+    [ ( item_value, item_text ), ... ]
+
+  - left_to_right: the name of the :method to move an item from left to
+    right lists.
+
+  - right_to_left: the name of the :method to move an item from left to
+    right lists.
+
+  - right_is_ordered:  if defined, then order matters, and the next two
+    names are required:
+
+    o move_up:  the name of a :method to move an item up in the right list.
+
+    o move_down:  the name of a :method to move an item down in the right list.
+
+</tal:comment>
+
+<table width="100%"
+       metal:define-macro="two_lists"
+>
+
+ <tal:block metal:define-slot="hidden_vars" />
+
+ <tr>
+    <td valign="top">
+      <div align="center">
+        <span metal:define-slot="left_title">Available</span>
+      </div>
+      <select size="10" name="items:list" style="width: 100%;"
+              multiple="multiple"
+              tal:attributes="name string:${left_name}:list" >
+        <option tal:repeat="item left_list"
+                tal:attributes="value python:item[0]" 
+                tal:content="python: item[1]"/>
+      </select>
+    </td>
+    <td align="center" valign="middle">
+      <input type="image" src="arrow_right_gif" 
+             width="29" height="30" border="0"
+             name="left_to_right:method"
+             tal:attributes="name string:${left_to_right}:method"/>
+      <br><br>
+      <input type="image" src="arrow_left_gif" 
+             width="29" height="30" border="0"
+             name="right_to_left:method"
+             tal:attributes="name string:${right_to_left}:method"/>
+    </td>
+    <td valign="top">
+      <div align="center">
+        <span metal:define-slot="right_title">Active</span>
+      </div>
+      <select size="10" name="items:list" style="width: 100%;"
+              multiple="multiple"
+              tal:attributes="name string:${right_name}:list" >
+        <option tal:repeat="item right_list"
+                tal:attributes="value python:item[0]" 
+                tal:content="python: item[1]"/>
+      </select>
+    </td>
+    <td align="center" valign="middle"
+        tal:condition="right_is_ordered | nothing"
+    >
+      <input type="image" src="arrow_up_gif" 
+             width="29" height="30" border="0"
+             name="move_up:method"
+             tal:attributes="name string:${move_up}:method"/>
+      <br><br>
+      <input type="image" src="arrow_down_gif" 
+             width="29" height="30" border="0"
+             name="move_down:method"
+             tal:attributes="name string:${move_down}:method"/>
+    </td>
+ </tr>
+</table>
+</form>
+
+</body>
+</html>

Added: spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1.diff.gz
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1.diff.gz?rev=12788&view=auto
==============================================================================
Binary file - no diff available.

Propchange: spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1.diff.gz
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1.dsc
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1.dsc?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1.dsc (added)
+++ spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1.dsc Thu Feb 15 18:28:34 2007
@@ -1,0 +1,12 @@
+Format: 1.0
+Source: erp5-pluginregistry
+Version: 1.0-1
+Binary: erp5-pluginregistry
+Maintainer: Yusei TAHARA
+Architecture: all
+Standards-Version: 3.7.2
+Build-Depends: debhelper (>= 5.0)
+Build-Depends-Indep: zope-debhelper (>= 0.3.6)
+Files: 
+ 9879dcd6c111656a9cdff9b1bffc0763 9152 erp5-pluginregistry_1.0.orig.tar.gz
+ c3fb74cead1cd682e753335e93fecb6e 1117 erp5-pluginregistry_1.0-1.diff.gz

Added: spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_all.deb
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_all.deb?rev=12788&view=auto
==============================================================================
Binary file - no diff available.

Propchange: spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_all.deb
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_i386.build
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_i386.build?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_i386.build (added)
+++ spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_i386.build Thu Feb 15 18:28:34 2007
@@ -1,0 +1,34 @@
+ fakeroot debian/rules clean
+dh_testdir
+dh_testroot
+rm -f build-stamp configure-stamp
+dh_clean
+ dpkg-source -b PluginRegistry
+dpkg-source: warning: source directory `./PluginRegistry' is not <sourcepackage>-<upstreamversion> `erp5-pluginregistry-1.0'
+dpkg-source: warning: .orig directory name PluginRegistry.orig is not <package>-<upstreamversion> (wanted erp5-pluginregistry-1.0.orig)
+dpkg-source: building erp5-pluginregistry using existing erp5-pluginregistry_1.0.orig.tar.gz
+dpkg-source: building erp5-pluginregistry in erp5-pluginregistry_1.0-1.diff.gz
+dpkg-source: building erp5-pluginregistry in erp5-pluginregistry_1.0-1.dsc
+ debian/rules build
+touch build-stamp
+ fakeroot debian/rules binary
+dh_testdir
+dh_testroot
+dh_clean -k
+dh_installdirs
+dh_installerp5zope .
+dh_testdir
+dh_testroot
+dh_installdocs
+dh_installexamples
+dh_installchangelogs
+dh_compress
+dh_fixperms
+dh_installdeb
+dh_gencontrol
+dh_md5sums
+dh_builddeb
+dpkg-deb: `../erp5-pluginregistry_1.0-1_all.deb' ¤Ë¥Ñ¥Ã¥±¡¼¥¸ `erp5-pluginregistry' ¤ò¹½ÃÛ¤·¤Æ¤¤¤Þ¤¹¡£
+ dpkg-genchanges
+dpkg-genchanges: including full source code in upload
+dpkg-buildpackage (debuild emulation): full upload (original source is included)

Added: spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_i386.changes
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_i386.changes?rev=12788&view=auto
==============================================================================
--- spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_i386.changes (added)
+++ spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0-1_i386.changes Thu Feb 15 18:28:34 2007
@@ -1,0 +1,21 @@
+Format: 1.7
+Date: Wed, 14 Feb 2007 03:27:56 +0900
+Source: erp5-pluginregistry
+Binary: erp5-pluginregistry
+Architecture: source all
+Version: 1.0-1
+Distribution: unstable
+Urgency: low
+Maintainer: Yusei TAHARA
+Changed-By: Yusei TAHARA <yusei at domen.cx>
+Description: 
+ erp5-pluginregistry - This Zope product defines a fully-pluggable user folder, intended
+Changes: 
+ erp5-pluginregistry (1.0-1) unstable; urgency=low
+ .
+   * Initial Release.
+Files: 
+ de5ad25c8d1aa34c4e4bb14c0b35464a 388 web optional erp5-pluginregistry_1.0-1.dsc
+ 9879dcd6c111656a9cdff9b1bffc0763 9152 web optional erp5-pluginregistry_1.0.orig.tar.gz
+ c3fb74cead1cd682e753335e93fecb6e 1117 web optional erp5-pluginregistry_1.0-1.diff.gz
+ 5978d0842e95cb2789336af18b0b10a0 11608 web optional erp5-pluginregistry_1.0-1_all.deb

Added: spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0.orig.tar.gz
URL: http://svn.erp5.org/spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0.orig.tar.gz?rev=12788&view=auto
==============================================================================
Binary file - no diff available.

Propchange: spec/debian/unstable/erp5-pluginregistry/erp5-pluginregistry_1.0.orig.tar.gz
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream




More information about the Erp5-report mailing list