[Checkins] SVN: grokcore.content/trunk/ Initial population
Souheil CHELFOUH
souheil at chelfouh.com
Sun Jan 3 10:05:38 EST 2010
Log message for revision 107586:
Initial population
Changed:
A grokcore.content/trunk/CHANGES.txt
A grokcore.content/trunk/README.txt
A grokcore.content/trunk/bootstrap.py
A grokcore.content/trunk/buildout.cfg
A grokcore.content/trunk/setup.py
A grokcore.content/trunk/src/
A grokcore.content/trunk/src/grokcore/
A grokcore.content/trunk/src/grokcore/content/
A grokcore.content/trunk/src/grokcore/content/components.py
-=-
Added: grokcore.content/trunk/CHANGES.txt
===================================================================
--- grokcore.content/trunk/CHANGES.txt (rev 0)
+++ grokcore.content/trunk/CHANGES.txt 2010-01-03 15:05:37 UTC (rev 107586)
@@ -0,0 +1,8 @@
+Changes
+=======
+
+1.0 (unreleased)
+----------------
+
+* Created ``grokcore.content`` in January 2010 by factoring basic
+ component base classes out of Grok.
Added: grokcore.content/trunk/README.txt
===================================================================
--- grokcore.content/trunk/README.txt (rev 0)
+++ grokcore.content/trunk/README.txt 2010-01-03 15:05:37 UTC (rev 107586)
@@ -0,0 +1,8 @@
+This package provides base classes of basic content types.
+
+.. contents::
+
+Examples
+========
+
+TODO
Added: grokcore.content/trunk/bootstrap.py
===================================================================
--- grokcore.content/trunk/bootstrap.py (rev 0)
+++ grokcore.content/trunk/bootstrap.py 2010-01-03 15:05:37 UTC (rev 107586)
@@ -0,0 +1,77 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id: bootstrap.py 90478 2008-08-27 22:44:46Z georgyberdyshev $
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+is_jython = sys.platform.startswith('java')
+
+try:
+ import pkg_resources
+except ImportError:
+ ez = {}
+ exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+ import pkg_resources
+
+if sys.platform == 'win32':
+ def quote(c):
+ if ' ' in c:
+ return '"%s"' % c # work around spawn lamosity on windows
+ else:
+ return c
+else:
+ def quote (c):
+ return c
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+ws = pkg_resources.working_set
+
+if is_jython:
+ import subprocess
+
+ assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd',
+ quote(tmpeggs), 'zc.buildout'],
+ env=dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ).wait() == 0
+
+else:
+ assert os.spawnle(
+ os.P_WAIT, sys.executable, quote (sys.executable),
+ '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Added: grokcore.content/trunk/buildout.cfg
===================================================================
--- grokcore.content/trunk/buildout.cfg (rev 0)
+++ grokcore.content/trunk/buildout.cfg 2010-01-03 15:05:37 UTC (rev 107586)
@@ -0,0 +1,20 @@
+[buildout]
+develop = .
+parts = interpreter test releaser
+extends = http://grok.zope.org/releaseinfo/grok-1.1a2.cfg
+versions = versions
+newest = false
+
+[interpreter]
+recipe = zc.recipe.egg
+eggs = grokcore.content
+interpreter = python
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = grokcore.content [test]
+defaults = ['--tests-pattern', '^f?tests$', '-v', '-c']
+
+[releaser]
+recipe = zc.recipe.egg
+eggs = zest.releaser
Added: grokcore.content/trunk/setup.py
===================================================================
--- grokcore.content/trunk/setup.py (rev 0)
+++ grokcore.content/trunk/setup.py 2010-01-03 15:05:37 UTC (rev 107586)
@@ -0,0 +1,37 @@
+from setuptools import setup, find_packages
+import os
+
+def read(*rnames):
+ return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+long_description = "%s\n%s\n" % (read('README.txt'), read('CHANGES.txt'))
+
+install_requires = [
+ 'setuptools',
+ 'grokcore.component >= 1.5, < 2.0',
+ 'zope.annotation'
+ ],
+
+setup(
+ name='grokcore.content',
+ version = '1.0dev',
+ author='Grok Team',
+ author_email='grok-dev at zope.org',
+ url='http://grok.zope.org',
+ download_url='http://pypi.python.org/pypi/grokcore.content',
+ description='Base content types for Grok',
+ long_description=long_description,
+ license='ZPL',
+ install_requires = install_requires
+ packages=find_packages('src'),
+ package_dir = {'': 'src'},
+ namespace_packages=['grokcore'],
+ include_package_data = True,
+ zip_safe=False,
+ classifiers=[
+ 'Environment :: Web Environment',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Zope Public License',
+ 'Programming Language :: Python',
+ 'Framework :: Zope3'],
+)
Added: grokcore.content/trunk/src/grokcore/content/components.py
===================================================================
--- grokcore.content/trunk/src/grokcore/content/components.py (rev 0)
+++ grokcore.content/trunk/src/grokcore/content/components.py 2010-01-03 15:05:37 UTC (rev 107586)
@@ -0,0 +1,110 @@
+# -*- coding: utf-8 -*-
+
+import persistent
+from persistent.list import PersistentList
+from grokcore.component.interfaces import IContext
+from zope.annotation.interfaces import IAttributeAnnotatable
+from zope.container.btree import BTreeContainer
+from zope.container.interfaces import IContainer, IOrderedContainer
+from zope.container.contained import Contained, notifyContainerModified
+from zope.interface import implements
+
+
+class Model(Contained, persistent.Persistent):
+ # XXX Inheritance order is important here. If we reverse this,
+ # then containers can't be models anymore because no unambigous MRO
+ # can be established.
+ """The base class for models in Grok applications.
+
+ When an application class inherits from `grok.Model`, it gains the
+ ability to persist itself in the Zope object database along with all
+ of its attributes, and to remember the container in which it has
+ been placed (its "parent") so that its URL can be computed. It also
+ inherits the `IContext` marker interface, which can make it the
+ default context for views in its module; the rule is that if a
+ module contains `grok.View` classes or other adapters that do not
+ define a `grok.context()`, but the module also defines exactly one
+ class that provides the `IContext` interface, then that class will
+ automatically be made the `grok.context()` of each of the views.
+
+ """
+ implements(IAttributeAnnotatable, IContext)
+
+
+class Container(BTreeContainer):
+ """The base class for containers in Grok applications.
+
+ When an application class inherits from `grok.Container`, it not
+ only has the features of a `grok.Model` (persistance, location, and
+ the ability to serve as a default context for other classes), but it
+ also behaves like a persistent dictionary. To store items inside a
+ container, simply use the standard Python getitem/setitem protocol::
+
+ mycontainer['counter'] = 72
+ mycontainer['address'] = mymodel
+ mycontainer['subfolder'] = another_container
+
+ By default, the URL of each item inside a container is the
+ container's own URL followed by a slash and the key (like 'counter'
+ or 'address') under which that item has been stored.
+
+ """
+ implements(IAttributeAnnotatable, IContainer)
+
+
+class OrderedContainer(Container):
+ """A Grok container that remembers the order of its items.
+
+ This straightforward extension of the basic `grok.Container`
+ remembers the order in which items have been inserted, so that
+ `keys()`, `values()`, `items()`, and iteration across the container
+ can all return the items in the order they were inserted. The only
+ way of changing the order is to call the `updateOrder()` method.
+
+ """
+ implements(IOrderedContainer)
+
+ def __init__(self):
+ super(OrderedContainer, self).__init__()
+ self._order = PersistentList()
+
+ def keys(self):
+ # Return a copy of the list to prevent accidental modifications.
+ return self._order[:]
+
+ def __iter__(self):
+ return iter(self.keys())
+
+ def values(self):
+ return (self[key] for key in self._order)
+
+ def items(self):
+ return ((key, self[key]) for key in self._order)
+
+ def __setitem__(self, key, object):
+ foo = self.has_key(key)
+ # Then do whatever containers normally do.
+ super(OrderedContainer, self).__setitem__(key, object)
+ if not foo:
+ self._order.append(key)
+
+ def __delitem__(self, key):
+ # First do whatever containers normally do.
+ super(OrderedContainer, self).__delitem__(key)
+ self._order.remove(key)
+
+ def updateOrder(self, order):
+ """Impose a new order on the items in this container.
+
+ Items in this container are, by default, returned in the order
+ in which they were inserted. To change the order, provide an
+ argument to this method that is a sequence containing every key
+ already in the container, but in a new order.
+
+ """
+ if set(order) != set(self._order):
+ raise ValueError("Incompatible key set.")
+
+ self._order = PersistentList()
+ self._order.extend(order)
+ notifyContainerModified(self)
More information about the checkins
mailing list