reorganize resource stuff - dynamic typing, first type is 'file'
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1289 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
		
							parent
							
								
									89ae9aeab0
								
							
						
					
					
						commit
						e860cf5a07
					
				
					 16 changed files with 349 additions and 298 deletions
				
			
		
							
								
								
									
										46
									
								
								README.txt
									
										
									
									
									
								
							
							
						
						
									
										46
									
								
								README.txt
									
										
									
									
									
								
							|  | @ -17,12 +17,12 @@ with lower-level aspects like type or state management. | ||||||
| 
 | 
 | ||||||
|   >>> from zope.app.testing.setup import placefulSetUp, placefulTearDown |   >>> from zope.app.testing.setup import placefulSetUp, placefulTearDown | ||||||
|   >>> site = placefulSetUp(True) |   >>> site = placefulSetUp(True) | ||||||
|    | 
 | ||||||
|   >>> from zope.app import zapi |   >>> from zope.app import zapi | ||||||
|   >>> from zope.app.tests import ztapi |   >>> from zope.app.tests import ztapi | ||||||
|   >>> from zope.interface import Interface |   >>> from zope.interface import Interface | ||||||
|   >>> from zope.publisher.browser import TestRequest |   >>> from zope.publisher.browser import TestRequest | ||||||
|    | 
 | ||||||
| 
 | 
 | ||||||
| Concepts and Relations | Concepts and Relations | ||||||
| ====================== | ====================== | ||||||
|  | @ -73,7 +73,7 @@ also need a default predicate concept; the default name for this is | ||||||
| 
 | 
 | ||||||
| Now we can assign the concept c2 as a child to c1 (using the standard | Now we can assign the concept c2 as a child to c1 (using the standard | ||||||
| ConceptRelation): | ConceptRelation): | ||||||
|          | 
 | ||||||
|   >>> cc1.assignChild(cc2) |   >>> cc1.assignChild(cc2) | ||||||
| 
 | 
 | ||||||
| We can now ask our concepts for their related child and parent concepts: | We can now ask our concepts for their related child and parent concepts: | ||||||
|  | @ -163,7 +163,7 @@ The token attribute provided with the items returned by the children() and | ||||||
| parents() methods identifies identifies not only the item itself but | parents() methods identifies identifies not only the item itself but | ||||||
| also the relationship to the context object using a combination | also the relationship to the context object using a combination | ||||||
| of URIs to item and the predicate of the relationship: | of URIs to item and the predicate of the relationship: | ||||||
|    | 
 | ||||||
|   >>> [c.token for c in children] |   >>> [c.token for c in children] | ||||||
|   ['.loops/concepts/cc2:.loops/concepts/standard'] |   ['.loops/concepts/cc2:.loops/concepts/standard'] | ||||||
| 
 | 
 | ||||||
|  | @ -207,11 +207,11 @@ types and predicates. | ||||||
|   >>> from zope.schema.interfaces import IIterableSource |   >>> from zope.schema.interfaces import IIterableSource | ||||||
|   >>> ztapi.provideAdapter(IIterableSource, ITerms, LoopsTerms, |   >>> ztapi.provideAdapter(IIterableSource, ITerms, LoopsTerms, | ||||||
|   ...                      with=(IBrowserRequest,)) |   ...                      with=(IBrowserRequest,)) | ||||||
|        | 
 | ||||||
|   >>> sorted((t.title, t.token) for t in view.conceptTypes()) |   >>> sorted((t.title, t.token) for t in view.conceptTypes()) | ||||||
|   [(u'Topic', '.loops/concepts/topic'), (u'Type', '.loops/concepts/type'), |   [(u'Topic', '.loops/concepts/topic'), (u'Type', '.loops/concepts/type'), | ||||||
|       (u'Unknown Type', '.loops/concepts/unknown')] |       (u'Unknown Type', '.loops/concepts/unknown')] | ||||||
|            | 
 | ||||||
|   >>> sorted((t.title, t.token) for t in view.predicates()) |   >>> sorted((t.title, t.token) for t in view.predicates()) | ||||||
|   [(u'subconcept', '.loops/concepts/standard')] |   [(u'subconcept', '.loops/concepts/standard')] | ||||||
| 
 | 
 | ||||||
|  | @ -222,7 +222,7 @@ Index attributes adapter | ||||||
|   >>> idx = IndexAttributes(cc2) |   >>> idx = IndexAttributes(cc2) | ||||||
|   >>> idx.text() |   >>> idx.text() | ||||||
|   u'cc2 Zope 3' |   u'cc2 Zope 3' | ||||||
|    | 
 | ||||||
|   >>> idx.title() |   >>> idx.title() | ||||||
|   u'cc2 Zope 3' |   u'cc2 Zope 3' | ||||||
| 
 | 
 | ||||||
|  | @ -230,16 +230,16 @@ Index attributes adapter | ||||||
| Resources and what they have to do with Concepts | Resources and what they have to do with Concepts | ||||||
| ================================================ | ================================================ | ||||||
| 
 | 
 | ||||||
|   >>> from loops.interfaces import IDocument, IMediaAsset |   >>> from loops.interfaces import IResource, IDocument, IMediaAsset | ||||||
| 
 | 
 | ||||||
| We first need a resource manager: | We first need a resource manager: | ||||||
|      | 
 | ||||||
|   >>> from loops.resource import ResourceManager |   >>> from loops.resource import ResourceManager | ||||||
|   >>> loopsRoot['resources'] = ResourceManager() |   >>> loopsRoot['resources'] = ResourceManager() | ||||||
|   >>> resources = loopsRoot['resources'] |   >>> resources = loopsRoot['resources'] | ||||||
| 
 | 
 | ||||||
| A common type of resource is a document: | A common type of resource is a document: | ||||||
|        | 
 | ||||||
|   >>> from loops.interfaces import IDocument |   >>> from loops.interfaces import IDocument | ||||||
|   >>> from loops.resource import Document |   >>> from loops.resource import Document | ||||||
|   >>> doc1 = Document(u'Zope Info') |   >>> doc1 = Document(u'Zope Info') | ||||||
|  | @ -247,9 +247,9 @@ A common type of resource is a document: | ||||||
|   >>> doc1.title |   >>> doc1.title | ||||||
|   u'Zope Info' |   u'Zope Info' | ||||||
|   >>> doc1.data |   >>> doc1.data | ||||||
|   u'' |  | ||||||
|   >>> doc1.contentType |  | ||||||
|   '' |   '' | ||||||
|  |   >>> doc1.contentType | ||||||
|  |   u'' | ||||||
| 
 | 
 | ||||||
| Another one is a media asset: | Another one is a media asset: | ||||||
| 
 | 
 | ||||||
|  | @ -258,7 +258,7 @@ Another one is a media asset: | ||||||
|   >>> img = MediaAsset(u'A png Image') |   >>> img = MediaAsset(u'A png Image') | ||||||
| 
 | 
 | ||||||
| For testing we use some simple files from the tests directory: | For testing we use some simple files from the tests directory: | ||||||
|        | 
 | ||||||
|   >>> from loops import tests |   >>> from loops import tests | ||||||
|   >>> import os |   >>> import os | ||||||
|   >>> path = os.path.join(*tests.__path__) |   >>> path = os.path.join(*tests.__path__) | ||||||
|  | @ -312,7 +312,7 @@ These relations may also be managed starting from a resource using | ||||||
| the resource configuration view: | the resource configuration view: | ||||||
| 
 | 
 | ||||||
|   >>> from loops.browser.resource import ResourceConfigureView |   >>> from loops.browser.resource import ResourceConfigureView | ||||||
|      | 
 | ||||||
| Index attributes adapter | Index attributes adapter | ||||||
| ------------------------ | ------------------------ | ||||||
| 
 | 
 | ||||||
|  | @ -320,7 +320,7 @@ Index attributes adapter | ||||||
|   >>> idx = IndexAttributes(doc1) |   >>> idx = IndexAttributes(doc1) | ||||||
|   >>> idx.text() |   >>> idx.text() | ||||||
|   u'doc1 Zope Info' |   u'doc1 Zope Info' | ||||||
|    | 
 | ||||||
|   >>> idx.title() |   >>> idx.title() | ||||||
|   u'doc1 Zope Info' |   u'doc1 Zope Info' | ||||||
| 
 | 
 | ||||||
|  | @ -340,7 +340,7 @@ the views or nodes, however, present informations coming from the concepts | ||||||
| or resources they are related to. | or resources they are related to. | ||||||
| 
 | 
 | ||||||
| We first need a view manager: | We first need a view manager: | ||||||
|      | 
 | ||||||
|   >>> from loops.view import ViewManager, Node |   >>> from loops.view import ViewManager, Node | ||||||
|   >>> from zope.security.checker import NamesChecker, defineChecker |   >>> from zope.security.checker import NamesChecker, defineChecker | ||||||
|   >>> nodeChecker = NamesChecker(('body',)) |   >>> nodeChecker = NamesChecker(('body',)) | ||||||
|  | @ -351,7 +351,7 @@ We first need a view manager: | ||||||
| 
 | 
 | ||||||
| The view space is typically built up with nodes; a node may be a top-level | The view space is typically built up with nodes; a node may be a top-level | ||||||
| menu that may contain other nodes as menu or content items: | menu that may contain other nodes as menu or content items: | ||||||
|        | 
 | ||||||
|   >>> m1 = Node(u'Menu') |   >>> m1 = Node(u'Menu') | ||||||
|   >>> views['m1'] = m1 |   >>> views['m1'] = m1 | ||||||
|   >>> m11 = Node(u'Zope') |   >>> m11 = Node(u'Zope') | ||||||
|  | @ -426,7 +426,7 @@ out - this is usually done through ZCML.) | ||||||
|   >>> from cybertools.relation.interfaces import IRelationInvalidatedEvent |   >>> from cybertools.relation.interfaces import IRelationInvalidatedEvent | ||||||
|   >>> ztapi.subscribe([ITargetRelation, IRelationInvalidatedEvent], None, |   >>> ztapi.subscribe([ITargetRelation, IRelationInvalidatedEvent], None, | ||||||
|   ...                 removeTargetRelation) |   ...                 removeTargetRelation) | ||||||
|    | 
 | ||||||
|   >>> m111.target = cc1 |   >>> m111.target = cc1 | ||||||
|   >>> m111.target is cc1 |   >>> m111.target is cc1 | ||||||
|   True |   True | ||||||
|  | @ -487,10 +487,10 @@ accessing a target via a node view it is usually wrapped in a corresponding | ||||||
| view; these views we have to provide as multi-adapters: | view; these views we have to provide as multi-adapters: | ||||||
| 
 | 
 | ||||||
|   >>> from loops.browser.node import ConfigureView |   >>> from loops.browser.node import ConfigureView | ||||||
|   >>> from loops.browser.resource import DocumentView, MediaAssetView |   >>> from loops.browser.resource import DocumentView, ResourceView | ||||||
|   >>> ztapi.provideAdapter(IDocument, Interface, DocumentView, |   >>> ztapi.provideAdapter(IDocument, Interface, DocumentView, | ||||||
|   ...                      with=(IBrowserRequest,)) |   ...                      with=(IBrowserRequest,)) | ||||||
|   >>> ztapi.provideAdapter(IMediaAsset, Interface, MediaAssetView, |   >>> ztapi.provideAdapter(IResource, Interface, ResourceView, | ||||||
|   ...                      with=(IBrowserRequest,)) |   ...                      with=(IBrowserRequest,)) | ||||||
| 
 | 
 | ||||||
|   >>> form = {'action': 'create', 'create.title': 'New Resource', |   >>> form = {'action': 'create', 'create.title': 'New Resource', | ||||||
|  | @ -592,10 +592,10 @@ Let's add some more nodes and reorder them: | ||||||
|   >>> m11['m114'] = m114 |   >>> m11['m114'] = m114 | ||||||
|   >>> m11.keys() |   >>> m11.keys() | ||||||
|   ['m111', 'm112', 'm113', 'm114'] |   ['m111', 'm112', 'm113', 'm114'] | ||||||
|        | 
 | ||||||
| A special management view provides methods for moving objects down, up, | A special management view provides methods for moving objects down, up, | ||||||
| to the bottom, and to the top. | to the bottom, and to the top. | ||||||
|        | 
 | ||||||
|   >>> from cybertools.container.ordered import OrderedContainerView |   >>> from cybertools.container.ordered import OrderedContainerView | ||||||
|   >>> view = OrderedContainerView(m11, TestRequest()) |   >>> view = OrderedContainerView(m11, TestRequest()) | ||||||
|   >>> view.move_bottom(('m113',)) |   >>> view.move_bottom(('m113',)) | ||||||
|  | @ -641,7 +641,7 @@ instance to another. | ||||||
|   >>> exporter.dumpData() |   >>> exporter.dumpData() | ||||||
| 
 | 
 | ||||||
| Load them again from the exported file: | Load them again from the exported file: | ||||||
|    | 
 | ||||||
|   >>> importer = NodesImporter(views) |   >>> importer = NodesImporter(views) | ||||||
|   >>> importer.filename = dumpname |   >>> importer.filename = dumpname | ||||||
|   >>> imported = importer.getData() |   >>> imported = importer.getData() | ||||||
|  |  | ||||||
|  | @ -117,7 +117,7 @@ class BaseView(object): | ||||||
|     @Lazy |     @Lazy | ||||||
|     def loopsRoot(self): |     def loopsRoot(self): | ||||||
|         return self.context.getLoopsRoot() |         return self.context.getLoopsRoot() | ||||||
|      | 
 | ||||||
|     @Lazy |     @Lazy | ||||||
|     def url(self): |     def url(self): | ||||||
|         return zapi.absoluteURL(self.context, self.request) |         return zapi.absoluteURL(self.context, self.request) | ||||||
|  | @ -199,9 +199,10 @@ class LoopsTerms(object): | ||||||
|     @Lazy |     @Lazy | ||||||
|     def loopsRoot(self): |     def loopsRoot(self): | ||||||
|         return self.context.getLoopsRoot() |         return self.context.getLoopsRoot() | ||||||
|      | 
 | ||||||
|     def getTerm(self, value): |     def getTerm(self, value): | ||||||
|         #return BaseView(value, self.request) |         #if value is None: | ||||||
|  |         #    return SimpleTerm(None, '', u'not assigned') | ||||||
|         title = value.title or zapi.getName(value) |         title = value.title or zapi.getName(value) | ||||||
|         token = self.loopsRoot.getLoopsUri(value) |         token = self.loopsRoot.getLoopsUri(value) | ||||||
|         return SimpleTerm(value, token, title) |         return SimpleTerm(value, token, title) | ||||||
|  |  | ||||||
|  | @ -66,14 +66,14 @@ class ConceptEditForm(EditForm): | ||||||
| class ConceptView(BaseView): | class ConceptView(BaseView): | ||||||
| 
 | 
 | ||||||
|     template = NamedTemplate('loops.concept_macros') |     template = NamedTemplate('loops.concept_macros') | ||||||
|      | 
 | ||||||
|     @Lazy |     @Lazy | ||||||
|     def macro(self): |     def macro(self): | ||||||
|         return self.template.macros['conceptdata'] |         return self.template.macros['conceptdata'] | ||||||
| 
 | 
 | ||||||
|     def fieldData(self): |     def fieldData(self): | ||||||
|         ti = IType(self.context).typeInterface |         ti = IType(self.context).typeInterface | ||||||
|         if not ti: return  |         if not ti: return | ||||||
|         adapter = ti(self.context) |         adapter = ti(self.context) | ||||||
|         for n, f in schema.getFieldsInOrder(ti): |         for n, f in schema.getFieldsInOrder(ti): | ||||||
|             value = getattr(adapter, n, '') |             value = getattr(adapter, n, '') | ||||||
|  |  | ||||||
|  | @ -233,6 +233,21 @@ | ||||||
| 
 | 
 | ||||||
|   <!-- resource in general --> |   <!-- resource in general --> | ||||||
| 
 | 
 | ||||||
|  |   <page | ||||||
|  |       for="loops.interfaces.IResource" | ||||||
|  |       name="index.html" | ||||||
|  |       permission="zope.View" | ||||||
|  |       class=".resource.ResourceView" | ||||||
|  |       attribute="show" /> | ||||||
|  | 
 | ||||||
|  |   <zope:adapter | ||||||
|  |       for="loops.interfaces.IResource | ||||||
|  |            zope.publisher.interfaces.browser.IBrowserRequest" | ||||||
|  |       provides="zope.interface.Interface" | ||||||
|  |       factory="loops.browser.resource.ResourceView" | ||||||
|  |       permission="zope.View" | ||||||
|  |       /> | ||||||
|  | 
 | ||||||
|   <pages |   <pages | ||||||
|       for="loops.interfaces.IResource" |       for="loops.interfaces.IResource" | ||||||
|       class=".resource.ResourceConfigureView" |       class=".resource.ResourceConfigureView" | ||||||
|  | @ -246,12 +261,19 @@ | ||||||
| 
 | 
 | ||||||
|   </pages> |   </pages> | ||||||
| 
 | 
 | ||||||
|   <zope:adapter |   <page | ||||||
|       for="loops.interfaces.IResource |       name="edit.html" | ||||||
|            zope.publisher.interfaces.browser.IBrowserRequest" |       for="loops.interfaces.IResource" | ||||||
|       provides="zope.interface.Interface" |       class="loops.browser.resource.ResourceEditForm" | ||||||
|       factory="loops.browser.resource.ResourceView" |       permission="zope.ManageContent" | ||||||
|       permission="zope.View" |       menu="zmi_views" title="Edit" | ||||||
|  |       /> | ||||||
|  | 
 | ||||||
|  |   <!-- suppress the upload menu item: --> | ||||||
|  |   <menuItem | ||||||
|  |       for="loops.interfaces.IResource" | ||||||
|  |       menu="zmi_views" action="upload.html" title="Upload" | ||||||
|  |       filter="nothing" | ||||||
|       /> |       /> | ||||||
| 
 | 
 | ||||||
|   <!-- document --> |   <!-- document --> | ||||||
|  | @ -263,33 +285,6 @@ | ||||||
|       class=".resource.DocumentView" |       class=".resource.DocumentView" | ||||||
|       attribute="show" /> |       attribute="show" /> | ||||||
| 
 | 
 | ||||||
|   <addform |  | ||||||
|       label="Add Document" |  | ||||||
|       name="AddLoopsDocument.html" |  | ||||||
|       schema="loops.interfaces.IDocumentSchema" |  | ||||||
|       fields="title data contentType" |  | ||||||
|       content_factory="loops.resource.Document" |  | ||||||
|       template="add.pt" |  | ||||||
|       permission="zope.ManageContent" /> |  | ||||||
| 
 |  | ||||||
|   <addMenuItem |  | ||||||
|       class="loops.resource.Document" |  | ||||||
|       title="Document" |  | ||||||
|       description="A document is an editable information unit" |  | ||||||
|       permission="zope.ManageContent" |  | ||||||
|       view="AddLoopsDocument.html" |  | ||||||
|       /> |  | ||||||
| 
 |  | ||||||
| <!--  <editform |  | ||||||
|       label="Edit Document" |  | ||||||
|       name="edit.html" |  | ||||||
|       schema="loops.interfaces.IDocumentSchema" |  | ||||||
|       fields="title data contentType" |  | ||||||
|       for="loops.interfaces.IDocument" |  | ||||||
|       template="edit.pt" |  | ||||||
|       permission="zope.ManageContent" |  | ||||||
|       menu="zmi_views" title="Edit" />--> |  | ||||||
| 
 |  | ||||||
|   <page |   <page | ||||||
|       name="edit.html" |       name="edit.html" | ||||||
|       for="loops.interfaces.IDocument" |       for="loops.interfaces.IDocument" | ||||||
|  | @ -322,25 +317,7 @@ | ||||||
| 
 | 
 | ||||||
|   <!-- media asset --> |   <!-- media asset --> | ||||||
| 
 | 
 | ||||||
|   <addform |   <!--<editform | ||||||
|       label="Add Media Asset" |  | ||||||
|       name="AddLoopsMediaAsset.html" |  | ||||||
|       schema="loops.interfaces.IMediaAssetSchema" |  | ||||||
|       fields="title data contentType" |  | ||||||
|       content_factory="loops.resource.MediaAsset" |  | ||||||
|       template="add.pt" |  | ||||||
|       permission="zope.ManageContent" |  | ||||||
|       /> |  | ||||||
| 
 |  | ||||||
|   <addMenuItem |  | ||||||
|       class="loops.resource.MediaAsset" |  | ||||||
|       title="Media Asset" |  | ||||||
|       description="A media asset is a binary file, image, video or audio file" |  | ||||||
|       permission="zope.ManageContent" |  | ||||||
|       view="AddLoopsMediaAsset.html" |  | ||||||
|       /> |  | ||||||
| 
 |  | ||||||
|   <editform |  | ||||||
|       label="Edit Media Asset" |       label="Edit Media Asset" | ||||||
|       name="edit.html" |       name="edit.html" | ||||||
|       schema="loops.interfaces.IMediaAssetSchema" |       schema="loops.interfaces.IMediaAssetSchema" | ||||||
|  | @ -349,7 +326,7 @@ | ||||||
|       template="edit.pt" |       template="edit.pt" | ||||||
|       permission="zope.ManageContent" |       permission="zope.ManageContent" | ||||||
|       menu="zmi_views" title="Edit Media Asset" |       menu="zmi_views" title="Edit Media Asset" | ||||||
|       /> |       />--> | ||||||
| 
 | 
 | ||||||
|   <!--<page |   <!--<page | ||||||
|       name="edit.html" |       name="edit.html" | ||||||
|  | @ -359,21 +336,6 @@ | ||||||
|       menu="zmi_views" title="Edit" |       menu="zmi_views" title="Edit" | ||||||
|       />--> |       />--> | ||||||
| 
 | 
 | ||||||
|   <!-- suppress the upload menu item: --> |  | ||||||
|   <menuItem |  | ||||||
|       for="loops.interfaces.IMediaAsset" |  | ||||||
|       menu="zmi_views" action="upload.html" title="Upload" |  | ||||||
|       filter="nothing" |  | ||||||
|       /> |  | ||||||
| 
 |  | ||||||
|   <zope:adapter |  | ||||||
|       for="loops.interfaces.IMediaAsset |  | ||||||
|            zope.publisher.interfaces.browser.IBrowserRequest" |  | ||||||
|       provides="zope.interface.Interface" |  | ||||||
|       factory="loops.browser.resource.MediaAssetView" |  | ||||||
|       permission="zope.View" |  | ||||||
|       /> |  | ||||||
| 
 |  | ||||||
|   <!-- view manager --> |   <!-- view manager --> | ||||||
| 
 | 
 | ||||||
|   <addform |   <addform | ||||||
|  | @ -584,6 +546,10 @@ | ||||||
|            for="loops.type.TypeInterfaceSourceList |            for="loops.type.TypeInterfaceSourceList | ||||||
|                 zope.publisher.interfaces.browser.IBrowserRequest" /> |                 zope.publisher.interfaces.browser.IBrowserRequest" /> | ||||||
| 
 | 
 | ||||||
|  |   <zope:adapter factory="loops.browser.common.LoopsTerms" | ||||||
|  |            for="loops.resource.ResourceTypeSourceList | ||||||
|  |                 zope.publisher.interfaces.browser.IBrowserRequest" /> | ||||||
|  | 
 | ||||||
|   <zope:view factory="loops.view.NodeTraverser" |   <zope:view factory="loops.view.NodeTraverser" | ||||||
|         for="loops.interfaces.INode" |         for="loops.interfaces.INode" | ||||||
|         type="zope.publisher.interfaces.browser.IBrowserRequest" |         type="zope.publisher.interfaces.browser.IBrowserRequest" | ||||||
|  |  | ||||||
|  | @ -204,7 +204,7 @@ class NodeView(BaseView): | ||||||
| 
 | 
 | ||||||
|     def active(self, item): |     def active(self, item): | ||||||
|         return item.context == self.context or item.context in self.parents |         return item.context == self.context or item.context in self.parents | ||||||
|              | 
 | ||||||
|     def targetDefaultView(self): |     def targetDefaultView(self): | ||||||
|         target = self.request.annotations.get('loops.view', {}).get('target') |         target = self.request.annotations.get('loops.view', {}).get('target') | ||||||
|         if target is None: |         if target is None: | ||||||
|  | @ -250,7 +250,7 @@ class ConfigureView(NodeView): | ||||||
|         obj = self.targetObject |         obj = self.targetObject | ||||||
|         if obj is not None: |         if obj is not None: | ||||||
|             return zapi.getMultiAdapter((obj, self.request)) |             return zapi.getMultiAdapter((obj, self.request)) | ||||||
|      | 
 | ||||||
|     def update(self): |     def update(self): | ||||||
|         request = self.request |         request = self.request | ||||||
|         action = request.get('action') |         action = request.get('action') | ||||||
|  | @ -291,6 +291,8 @@ class ConfigureView(NodeView): | ||||||
|         target.title = form.get('create.title', u'') |         target.title = form.get('create.title', u'') | ||||||
|         if IConcept.providedBy(target): |         if IConcept.providedBy(target): | ||||||
|             target.conceptType = type.typeProvider |             target.conceptType = type.typeProvider | ||||||
|  |         elif IResource.providedBy(target): | ||||||
|  |             target.resourceType = type.typeProvider | ||||||
|         notify(ObjectCreatedEvent(target)) |         notify(ObjectCreatedEvent(target)) | ||||||
|         notify(ObjectModifiedEvent(target)) |         notify(ObjectModifiedEvent(target)) | ||||||
|         self.context.target = target |         self.context.target = target | ||||||
|  |  | ||||||
|  | @ -33,8 +33,8 @@ from zope.proxy import removeAllProxies | ||||||
| from zope.security import canAccess, canWrite | from zope.security import canAccess, canWrite | ||||||
| from zope.security.proxy import removeSecurityProxy | from zope.security.proxy import removeSecurityProxy | ||||||
| 
 | 
 | ||||||
| from loops.interfaces import IDocument, IMediaAsset | from cybertools.typology.interfaces import IType | ||||||
| from loops.interfaces import IFileSystemResource, IControlledResource | from loops.interfaces import IBaseResource, IDocument, IMediaAsset | ||||||
| from loops.browser.common import EditForm, BaseView | from loops.browser.common import EditForm, BaseView | ||||||
| from loops.browser.concept import ConceptRelationView, ConceptConfigureView | from loops.browser.concept import ConceptRelationView, ConceptConfigureView | ||||||
| from loops.browser.node import NodeView | from loops.browser.node import NodeView | ||||||
|  | @ -48,12 +48,27 @@ renderingFactories = { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class ResourceEditForm(EditForm): | ||||||
|  | 
 | ||||||
|  |     @Lazy | ||||||
|  |     def typeInterface(self): | ||||||
|  |         return IType(self.context).typeInterface | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def form_fields(self): | ||||||
|  |         fields = FormFields(IBaseResource) | ||||||
|  |         typeInterface = self.typeInterface | ||||||
|  |         if typeInterface is not None: | ||||||
|  |             fields = FormFields(fields, typeInterface) | ||||||
|  |         return fields | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class DocumentEditForm(EditForm): | class DocumentEditForm(EditForm): | ||||||
|     #form_fields = FormFields(IDocument, IFileSystemResource, IControlledResource) |  | ||||||
|     form_fields = FormFields(IDocument) |     form_fields = FormFields(IDocument) | ||||||
|     for f in form_fields: |     for f in form_fields: | ||||||
|         f.render_context |= DISPLAY_UNWRITEABLE |         f.render_context |= DISPLAY_UNWRITEABLE | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| class MediaAssetEditForm(EditForm): | class MediaAssetEditForm(EditForm): | ||||||
|     form_fields = FormFields(IMediaAsset) |     form_fields = FormFields(IMediaAsset) | ||||||
| 
 | 
 | ||||||
|  | @ -62,6 +77,20 @@ class ResourceView(BaseView): | ||||||
| 
 | 
 | ||||||
|     template = ViewPageTemplateFile('resource_macros.pt') |     template = ViewPageTemplateFile('resource_macros.pt') | ||||||
| 
 | 
 | ||||||
|  |     @property | ||||||
|  |     def macro(self): | ||||||
|  |         if 'image/' in self.context.contentType: | ||||||
|  |             return self.template.macros['image'] | ||||||
|  |         else: | ||||||
|  |             return self.template.macros['download'] | ||||||
|  | 
 | ||||||
|  |     def show(self): | ||||||
|  |         data = self.context.data | ||||||
|  |         response = self.request.response | ||||||
|  |         response.setHeader('Content-Type', self.context.contentType) | ||||||
|  |         response.setHeader('Content-Length', len(data)) | ||||||
|  |         return data | ||||||
|  | 
 | ||||||
|     def concepts(self): |     def concepts(self): | ||||||
|         for r in self.context.getConceptRelations(): |         for r in self.context.getConceptRelations(): | ||||||
|             yield ConceptRelationView(r, self.request) |             yield ConceptRelationView(r, self.request) | ||||||
|  | @ -130,8 +159,10 @@ class ResourceConfigureView(ResourceView, ConceptConfigureView): | ||||||
| 
 | 
 | ||||||
| class DocumentView(ResourceView): | class DocumentView(ResourceView): | ||||||
| 
 | 
 | ||||||
|     macro = ResourceView.template.macros['render'] |     @property | ||||||
|      |     def macro(self): | ||||||
|  |         return ResourceView.template.macros['render'] | ||||||
|  | 
 | ||||||
|     def render(self): |     def render(self): | ||||||
|         """ Return the rendered content (data) of the context object. |         """ Return the rendered content (data) of the context object. | ||||||
|         """ |         """ | ||||||
|  | @ -143,19 +174,3 @@ class DocumentView(ResourceView): | ||||||
|         view = zapi.getMultiAdapter((removeAllProxies(source), self.request)) |         view = zapi.getMultiAdapter((removeAllProxies(source), self.request)) | ||||||
|         return view.render() |         return view.render() | ||||||
| 
 | 
 | ||||||
|     def show(self): |  | ||||||
|         data = self.context.data |  | ||||||
|         response = self.request.response |  | ||||||
|         response.setHeader('Content-Type', self.context.contentType) |  | ||||||
|         response.setHeader('Content-Length', len(data)) |  | ||||||
|         return data |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| class MediaAssetView(ResourceView): |  | ||||||
| 
 |  | ||||||
|     @property |  | ||||||
|     def macro(self): |  | ||||||
|         if 'image/' in self.context.contentType: |  | ||||||
|             return self.template.macros['image'] |  | ||||||
|         else: |  | ||||||
|             return self.template.macros['download'] |  | ||||||
|  |  | ||||||
							
								
								
									
										47
									
								
								common.py
									
										
									
									
									
								
							
							
						
						
									
										47
									
								
								common.py
									
										
									
									
									
								
							|  | @ -29,9 +29,54 @@ from zope.app.dublincore.zopedublincore import ScalarProperty | ||||||
| from zope.component import adapts | from zope.component import adapts | ||||||
| from zope.interface import implements | from zope.interface import implements | ||||||
| from zope.cachedescriptors.property import Lazy | from zope.cachedescriptors.property import Lazy | ||||||
| from loops.interfaces import ILoopsObject | from loops.interfaces import ILoopsObject, IConcept, IResource | ||||||
|  | from loops.interfaces import IResourceAdapter | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | # type interface adapters | ||||||
|  | 
 | ||||||
|  | class AdapterBase(object): | ||||||
|  |     """ (Mix-in) Class for concept adapters that provide editing of fields | ||||||
|  |         defined by the type interface. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     adapts(IConcept) | ||||||
|  | 
 | ||||||
|  |     _attributes = ('context', '__parent__', ) | ||||||
|  |     _schemas = list(IConcept) | ||||||
|  | 
 | ||||||
|  |     def __init__(self, context): | ||||||
|  |         self.context = context # to get the permission stuff right | ||||||
|  |         self.__parent__ = context | ||||||
|  | 
 | ||||||
|  |     def __getattr__(self, attr): | ||||||
|  |         self.checkAttr(attr) | ||||||
|  |         return getattr(self.context, '_' + attr, None) | ||||||
|  | 
 | ||||||
|  |     def __setattr__(self, attr, value): | ||||||
|  |         if attr in self._attributes: | ||||||
|  |             object.__setattr__(self, attr, value) | ||||||
|  |         else: | ||||||
|  |             self.checkAttr(attr) | ||||||
|  |             setattr(self.context, '_' + attr, value) | ||||||
|  | 
 | ||||||
|  |     def checkAttr(self, attr): | ||||||
|  |         if attr not in self._schemas: | ||||||
|  |             raise AttributeError(attr) | ||||||
|  | 
 | ||||||
|  |     def __eq__(self, other): | ||||||
|  |         return self.context == other.context | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ResourceAdapterBase(AdapterBase): | ||||||
|  | 
 | ||||||
|  |     adapts(IResource) | ||||||
|  | 
 | ||||||
|  |     _schemas = list(IResourceAdapter) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # other adapters | ||||||
|  | 
 | ||||||
| class LoopsDCAdapter(ZDCAnnotatableAdapter): | class LoopsDCAdapter(ZDCAnnotatableAdapter): | ||||||
| 
 | 
 | ||||||
|     implements(IZopeDublinCore) |     implements(IZopeDublinCore) | ||||||
|  |  | ||||||
|  | @ -125,6 +125,30 @@ | ||||||
| 
 | 
 | ||||||
|   </content> |   </content> | ||||||
| 
 | 
 | ||||||
|  |   <interface | ||||||
|  |       interface=".interfaces.IResource" | ||||||
|  |       type="zope.app.content.interfaces.IContentType" /> | ||||||
|  | 
 | ||||||
|  |   <class class=".resource.Resource"> | ||||||
|  | 
 | ||||||
|  |     <implements | ||||||
|  |        interface="zope.app.annotation.interfaces.IAttributeAnnotatable" /> | ||||||
|  | 
 | ||||||
|  |     <factory | ||||||
|  |         id="loops.Resource" | ||||||
|  |         description="Document" /> | ||||||
|  | 
 | ||||||
|  |     <require | ||||||
|  |         permission="zope.View" | ||||||
|  |         interface=".interfaces.IBaseResource | ||||||
|  |                    zope.app.size.interfaces.ISized" /> | ||||||
|  | 
 | ||||||
|  |     <require | ||||||
|  |         permission="zope.ManageContent" | ||||||
|  |         set_schema=".interfaces.IBaseResource" /> | ||||||
|  | 
 | ||||||
|  |   </class> | ||||||
|  | 
 | ||||||
|   <interface |   <interface | ||||||
|       interface=".interfaces.IDocument" |       interface=".interfaces.IDocument" | ||||||
|       type="zope.app.content.interfaces.IContentType" /> |       type="zope.app.content.interfaces.IContentType" /> | ||||||
|  | @ -141,19 +165,12 @@ | ||||||
|     <require |     <require | ||||||
|         permission="zope.View" |         permission="zope.View" | ||||||
|         interface=".interfaces.IDocument |         interface=".interfaces.IDocument | ||||||
|                    .interfaces.IFileSystemResource |  | ||||||
|                    .interfaces.IControlledResource |  | ||||||
|                    zope.app.size.interfaces.ISized" /> |                    zope.app.size.interfaces.ISized" /> | ||||||
| 
 | 
 | ||||||
|     <require |     <require | ||||||
|         permission="zope.ManageContent" |         permission="zope.ManageContent" | ||||||
|         set_schema=".interfaces.IDocument" /> |         set_schema=".interfaces.IDocument" /> | ||||||
| 
 | 
 | ||||||
|     <require |  | ||||||
|         permission="zope.ManageApplication" |  | ||||||
|         set_schema=".interfaces.IFileSystemResource |  | ||||||
|                     .interfaces.IControlledResource" /> |  | ||||||
| 
 |  | ||||||
|   </content> |   </content> | ||||||
| 
 | 
 | ||||||
|   <interface |   <interface | ||||||
|  | @ -171,11 +188,11 @@ | ||||||
| 
 | 
 | ||||||
|     <require |     <require | ||||||
|         permission="zope.View" |         permission="zope.View" | ||||||
|         interface=".interfaces.IMediaAsset" /> |         interface=".interfaces.IBaseResource" /> | ||||||
| 
 | 
 | ||||||
|     <require |     <require | ||||||
|         permission="zope.ManageContent" |         permission="zope.ManageContent" | ||||||
|         set_schema=".interfaces.IMediaAsset" /> |         set_schema=".interfaces.IBaseResource" /> | ||||||
| 
 | 
 | ||||||
|   </content> |   </content> | ||||||
| 
 | 
 | ||||||
|  | @ -249,12 +266,7 @@ | ||||||
|            trusted="True" /> |            trusted="True" /> | ||||||
| 
 | 
 | ||||||
|   <adapter factory="loops.common.LoopsDCAdapter" |   <adapter factory="loops.common.LoopsDCAdapter" | ||||||
|            for="loops.interfaces.IDocument" |            for="loops.interfaces.IResource" | ||||||
|            provides="zope.app.dublincore.interfaces.IZopeDublinCore" |  | ||||||
|            trusted="True" /> |  | ||||||
| 
 |  | ||||||
|   <adapter factory="loops.common.LoopsDCAdapter" |  | ||||||
|            for="loops.interfaces.IMediaAsset" |  | ||||||
|            provides="zope.app.dublincore.interfaces.IZopeDublinCore" |            provides="zope.app.dublincore.interfaces.IZopeDublinCore" | ||||||
|            trusted="True" /> |            trusted="True" /> | ||||||
| 
 | 
 | ||||||
|  | @ -264,16 +276,30 @@ | ||||||
| 
 | 
 | ||||||
|   <adapter factory="loops.concept.IndexAttributes" /> |   <adapter factory="loops.concept.IndexAttributes" /> | ||||||
|   <adapter factory="loops.resource.IndexAttributes" /> |   <adapter factory="loops.resource.IndexAttributes" /> | ||||||
|   <adapter factory="loops.resource.IndexableResource" /> |   <adapter factory="loops.resource.IndexableResource" trusted="True" /> | ||||||
|  |   <class class="loops.resource.IndexableResource"> | ||||||
|  |     <require permission="zope.View" | ||||||
|  |              interface="loops.interfaces.IBaseResourceSchema" /> | ||||||
|  |   </class> | ||||||
| 
 | 
 | ||||||
|   <adapter factory="loops.resource.DocumentReadFileAdapter" /> |   <adapter factory="loops.resource.DocumentReadFileAdapter" /> | ||||||
|   <adapter factory="loops.resource.DocumentWriteFileAdapter" /> |   <adapter factory="loops.resource.DocumentWriteFileAdapter" /> | ||||||
| 
 | 
 | ||||||
|  |   <adapter factory="loops.type.LoopsType" /> | ||||||
|   <adapter factory="loops.type.ConceptType" /> |   <adapter factory="loops.type.ConceptType" /> | ||||||
|   <adapter factory="loops.type.ResourceType" /> |   <adapter factory="loops.type.ResourceType" | ||||||
|  |            for="loops.interfaces.IDocument" /> | ||||||
|  |   <adapter factory="loops.type.ResourceType" | ||||||
|  |            for="loops.interfaces.IMediaAsset" /> | ||||||
|   <adapter factory="loops.type.LoopsTypeManager" /> |   <adapter factory="loops.type.LoopsTypeManager" /> | ||||||
| 
 | 
 | ||||||
|   <adapter factory="loops.type.TypeConcept" /> |   <adapter factory="loops.type.TypeConcept" trusted="True" /> | ||||||
|  |   <class class="loops.type.TypeConcept"> | ||||||
|  |     <require permission="zope.View" | ||||||
|  |              interface="loops.interfaces.ITypeConcept" /> | ||||||
|  |     <require permission="zope.ManageContent" | ||||||
|  |              set_schema="loops.interfaces.ITypeConcept" /> | ||||||
|  |   </class> | ||||||
| 
 | 
 | ||||||
|   <adapter factory="loops.query.QueryConcept" trusted="True" /> |   <adapter factory="loops.query.QueryConcept" trusted="True" /> | ||||||
|   <class class="loops.query.QueryConcept"> |   <class class="loops.query.QueryConcept"> | ||||||
|  | @ -283,6 +309,14 @@ | ||||||
|              set_schema="loops.query.IQueryConcept" /> |              set_schema="loops.query.IQueryConcept" /> | ||||||
|   </class> |   </class> | ||||||
| 
 | 
 | ||||||
|  |   <adapter factory="loops.resource.FileAdapter" trusted="True" /> | ||||||
|  |   <class class="loops.resource.FileAdapter"> | ||||||
|  |     <require permission="zope.View" | ||||||
|  |              interface="loops.interfaces.IFile" /> | ||||||
|  |     <require permission="zope.ManageContent" | ||||||
|  |              set_schema="loops.interfaces.IFile" /> | ||||||
|  |   </class> | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|   <adapter factory="loops.setup.SetupManager" /> |   <adapter factory="loops.setup.SetupManager" /> | ||||||
|   <adapter factory="loops.external.NodesLoader" /> |   <adapter factory="loops.external.NodesLoader" /> | ||||||
|  | @ -302,7 +336,7 @@ | ||||||
|       /> |       /> | ||||||
| 
 | 
 | ||||||
|   <vocabulary |   <vocabulary | ||||||
|       factory="loops.type.ResourceTypeSourceList" |       factory="loops.resource.ResourceTypeSourceList" | ||||||
|       name="loops.resourceTypeSource" |       name="loops.resourceTypeSource" | ||||||
|       /> |       /> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										100
									
								
								interfaces.py
									
										
									
									
									
								
							
							
						
						
									
										100
									
								
								interfaces.py
									
										
									
									
									
								
							|  | @ -29,6 +29,7 @@ from zope.app.container.constraints import contains, containers | ||||||
| from zope.app.container.interfaces import IContainer, IOrderedContainer | from zope.app.container.interfaces import IContainer, IOrderedContainer | ||||||
| from zope.app.file.interfaces import IImage as IBaseAsset | from zope.app.file.interfaces import IImage as IBaseAsset | ||||||
| from zope.app.folder.interfaces import IFolder | from zope.app.folder.interfaces import IFolder | ||||||
|  | from zope.app.size.interfaces import ISized | ||||||
| from cybertools.relation.interfaces import IRelation | from cybertools.relation.interfaces import IRelation | ||||||
| 
 | 
 | ||||||
| import util | import util | ||||||
|  | @ -62,7 +63,7 @@ class IPotentialTarget(Interface): | ||||||
| 
 | 
 | ||||||
| class IConcept(ILoopsObject, IPotentialTarget): | class IConcept(ILoopsObject, IPotentialTarget): | ||||||
|     """ The concept is the central element of the loops framework. |     """ The concept is the central element of the loops framework. | ||||||
|      | 
 | ||||||
|         A concept is related to other concepts, may have resources |         A concept is related to other concepts, may have resources | ||||||
|         associated with it and may be referenced by views. |         associated with it and may be referenced by views. | ||||||
|     """ |     """ | ||||||
|  | @ -130,7 +131,7 @@ class IConcept(ILoopsObject, IPotentialTarget): | ||||||
|     def getResources(predicates=None): |     def getResources(predicates=None): | ||||||
|         """ Return a sequence of resources assigned to self, |         """ Return a sequence of resources assigned to self, | ||||||
|             optionally restricted to the predicates given. |             optionally restricted to the predicates given. | ||||||
|         """         |         """ | ||||||
| 
 | 
 | ||||||
|     def getResourceRelations(predicates=None, resource=None): |     def getResourceRelations(predicates=None, resource=None): | ||||||
|         """ Return a sequence of relations to resources assigned to self, |         """ Return a sequence of relations to resources assigned to self, | ||||||
|  | @ -143,12 +144,12 @@ class IConcept(ILoopsObject, IPotentialTarget): | ||||||
| 
 | 
 | ||||||
|             The relationship defaults to ConceptResourceRelation. |             The relationship defaults to ConceptResourceRelation. | ||||||
|         """ |         """ | ||||||
|          | 
 | ||||||
|     def deassignResource(resource, predicates=None): |     def deassignResource(resource, predicates=None): | ||||||
|         """ Remove the relations to the resource given from self, optionally |         """ Remove the relations to the resource given from self, optionally | ||||||
|             restricting them to the predicates given. |             restricting them to the predicates given. | ||||||
|         """ |         """ | ||||||
|          | 
 | ||||||
| 
 | 
 | ||||||
| class IConceptView(Interface): | class IConceptView(Interface): | ||||||
|     """ Used for accessing a concept via a node's target attribute""" |     """ Used for accessing a concept via a node's target attribute""" | ||||||
|  | @ -178,12 +179,12 @@ class IConceptManagerContained(Interface): | ||||||
| # resource interfaces | # resource interfaces | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class IBaseResource(Interface): | class IBaseResource(ILoopsObject): | ||||||
|     """ New base interface for resources. Functionality beyond this simple |     """ New base interface for resources. Functionality beyond this simple | ||||||
|         interface is provided by adapters that are chosen via the |         interface is provided by adapters that are chosen via the | ||||||
|         resource type's typeInterface. |         resource type's typeInterface. | ||||||
|     """ |     """ | ||||||
|      | 
 | ||||||
|     title = schema.TextLine( |     title = schema.TextLine( | ||||||
|                 title=_(u'Title'), |                 title=_(u'Title'), | ||||||
|                 description=_(u'Title of the resource'), |                 description=_(u'Title of the resource'), | ||||||
|  | @ -199,6 +200,26 @@ class IBaseResource(Interface): | ||||||
|         source="loops.resourceTypeSource", |         source="loops.resourceTypeSource", | ||||||
|         required=False) |         required=False) | ||||||
| 
 | 
 | ||||||
|  |     data = schema.Bytes( | ||||||
|  |                 title=_(u'Data'), | ||||||
|  |                 description=_(u'Resource raw data'), | ||||||
|  |                 default='', | ||||||
|  |                 missing_value='', | ||||||
|  |                 required=False) | ||||||
|  | 
 | ||||||
|  |     contentType = schema.BytesLine( | ||||||
|  |                 title=_(u'Content Type'), | ||||||
|  |                 description=_(u'Content type (format) of the data field'), | ||||||
|  |                 default='', | ||||||
|  |                 missing_value='', | ||||||
|  |                 required=False) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class IBaseResourceSchema(Interface): | ||||||
|  |     """ New schema for resources; to be used by sub-interfaces that will | ||||||
|  |         be implemented by type adapters. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class IResourceSchema(Interface): | class IResourceSchema(Interface): | ||||||
| 
 | 
 | ||||||
|  | @ -224,29 +245,6 @@ class IResourceSchema(Interface): | ||||||
|                 required=False) |                 required=False) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # the next two interfaces are probably obsolete: |  | ||||||
| 
 |  | ||||||
| class IFileSystemResource(Interface): |  | ||||||
| 
 |  | ||||||
|     fsPath = schema.BytesLine( |  | ||||||
|                 title=_(u'Filesystem Path'), |  | ||||||
|                 description=_(u'Optional path to a file in the filesystem ' |  | ||||||
|                                'to be used for storing the resource'), |  | ||||||
|                 default='', |  | ||||||
|                 missing_value='', |  | ||||||
|                 required=False) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class IControlledResource(Interface): |  | ||||||
| 
 |  | ||||||
|     readOnly = schema.Bool( |  | ||||||
|                 title=_(u'Read only'), |  | ||||||
|                 description=_(u'Check this if resource may not be modified ' |  | ||||||
|                                'after being first filled with non-empty content'), |  | ||||||
|                 default=False, |  | ||||||
|                 required=False) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class IResource(ILoopsObject, IPotentialTarget): | class IResource(ILoopsObject, IPotentialTarget): | ||||||
|     """ A resource is an atomic information element that is made |     """ A resource is an atomic information element that is made | ||||||
|         available via a view or a concept. |         available via a view or a concept. | ||||||
|  | @ -323,10 +321,10 @@ class IMediaAssetView(IMediaAssetSchema): | ||||||
| 
 | 
 | ||||||
| class IMediaAsset(IMediaAssetSchema, IResource, IBaseAsset): | class IMediaAsset(IMediaAssetSchema, IResource, IBaseAsset): | ||||||
|     """ A resource containing a (typically binary) file-like content |     """ A resource containing a (typically binary) file-like content | ||||||
|         or an image.  |         or an image. | ||||||
|     """ |     """ | ||||||
|      | 
 | ||||||
|      | 
 | ||||||
| class IResourceManager(ILoopsObject, IContainer): | class IResourceManager(ILoopsObject, IContainer): | ||||||
|     """ A manager/container for resources. |     """ A manager/container for resources. | ||||||
|     """ |     """ | ||||||
|  | @ -475,7 +473,7 @@ class ILoops(ILoopsObject): | ||||||
|         """ Retrieve object specified by the loops uri (starting with |         """ Retrieve object specified by the loops uri (starting with | ||||||
|         '.loops/') given. |         '.loops/') given. | ||||||
|         """ |         """ | ||||||
|      | 
 | ||||||
|     def getConceptManager(): |     def getConceptManager(): | ||||||
|         """ Return the (default) concept manager. |         """ Return the (default) concept manager. | ||||||
|         """ |         """ | ||||||
|  | @ -545,7 +543,7 @@ class ITypeConcept(Interface): | ||||||
|     # storage = schema.Choice() |     # storage = schema.Choice() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class IResourceAdapter(Interface): | class IResourceAdapter(IBaseResourceSchema): | ||||||
|     """ Base interface for adapters for resources. This is the base interface |     """ Base interface for adapters for resources. This is the base interface | ||||||
|         of the interfaces to be used as typeInterface attribute on type concepts |         of the interfaces to be used as typeInterface attribute on type concepts | ||||||
|         specifying resource types. |         specifying resource types. | ||||||
|  | @ -556,15 +554,15 @@ class IFile(IResourceAdapter): | ||||||
|     """ A media asset that is not shown on a (web) page like an image but |     """ A media asset that is not shown on a (web) page like an image but | ||||||
|         may be downloaded instead. |         may be downloaded instead. | ||||||
|     """ |     """ | ||||||
|      | 
 | ||||||
|      | 
 | ||||||
| class IImage(IResourceAdapter): | class IImage(IResourceAdapter): | ||||||
|     """ A media asset that may be embedded in a (web) page as an image. |     """ A media asset that may be embedded in a (web) page as an image. | ||||||
|     """ |     """ | ||||||
|      | 
 | ||||||
|      | 
 | ||||||
| class ITextDocument(IResourceAdapter): | class ITextDocument(IResourceAdapter): | ||||||
|     """ A resource containing some sort of plain text that may be rendered and  |     """ A resource containing some sort of plain text that may be rendered and | ||||||
|         edited without necessarily involving a special external application |         edited without necessarily involving a special external application | ||||||
|         (like e.g. OpenOffice); typical content types are text/html, text/xml, |         (like e.g. OpenOffice); typical content types are text/html, text/xml, | ||||||
|         text/restructured, etc. |         text/restructured, etc. | ||||||
|  | @ -581,3 +579,27 @@ class IViewConfiguratorSchema(Interface): | ||||||
|         default=u'', |         default=u'', | ||||||
|         required=False) |         required=False) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | # the next two interfaces are obsolete, they will be replaced by IResourceStorage: | ||||||
|  | 
 | ||||||
|  | class IFileSystemResource(Interface): | ||||||
|  | 
 | ||||||
|  |     fsPath = schema.BytesLine( | ||||||
|  |                 title=_(u'Filesystem Path'), | ||||||
|  |                 description=_(u'Optional path to a file in the filesystem ' | ||||||
|  |                                'to be used for storing the resource'), | ||||||
|  |                 default='', | ||||||
|  |                 missing_value='', | ||||||
|  |                 required=False) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class IControlledResource(Interface): | ||||||
|  | 
 | ||||||
|  |     readOnly = schema.Bool( | ||||||
|  |                 title=_(u'Read only'), | ||||||
|  |                 description=_(u'Check this if resource may not be modified ' | ||||||
|  |                                'after being first filled with non-empty content'), | ||||||
|  |                 default=False, | ||||||
|  |                 required=False) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -36,7 +36,8 @@ from loops.interfaces import IConcept, IResource | ||||||
| from loops.knowledge.interfaces import IPerson, ITask | from loops.knowledge.interfaces import IPerson, ITask | ||||||
| from loops.organize.party import Person as BasePerson | from loops.organize.party import Person as BasePerson | ||||||
| from loops.organize.task import Task as BaseTask | from loops.organize.task import Task as BaseTask | ||||||
| from loops.type import TypeInterfaceSourceList, AdapterBase | from loops.common import AdapterBase | ||||||
|  | from loops.type import TypeInterfaceSourceList | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # register type interfaces - (TODO: use a function for this) | # register type interfaces - (TODO: use a function for this) | ||||||
|  |  | ||||||
|  | @ -41,7 +41,8 @@ from cybertools.typology.interfaces import IType | ||||||
| from loops.concept import Concept | from loops.concept import Concept | ||||||
| from loops.interfaces import IConcept | from loops.interfaces import IConcept | ||||||
| from loops.organize.interfaces import IPerson, ANNOTATION_KEY | from loops.organize.interfaces import IPerson, ANNOTATION_KEY | ||||||
| from loops.type import TypeInterfaceSourceList, AdapterBase | from loops.common import AdapterBase | ||||||
|  | from loops.type import TypeInterfaceSourceList | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # register type interfaces - (TODO: use a function for this) | # register type interfaces - (TODO: use a function for this) | ||||||
|  |  | ||||||
|  | @ -26,7 +26,8 @@ from zope.interface import implements | ||||||
| 
 | 
 | ||||||
| from cybertools.organize.interfaces import ITask | from cybertools.organize.interfaces import ITask | ||||||
| from loops.interfaces import IConcept | from loops.interfaces import IConcept | ||||||
| from loops.type import TypeInterfaceSourceList, AdapterBase | from loops.common import AdapterBase | ||||||
|  | from loops.type import TypeInterfaceSourceList | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| TypeInterfaceSourceList.typeInterfaces += (ITask,) | TypeInterfaceSourceList.typeInterfaces += (ITask,) | ||||||
|  |  | ||||||
|  | @ -33,7 +33,8 @@ from cybertools.typology.interfaces import IType | ||||||
| from cybertools.process.interfaces import IProcess | from cybertools.process.interfaces import IProcess | ||||||
| from cybertools.process.definition import Process as BaseProcess | from cybertools.process.definition import Process as BaseProcess | ||||||
| from loops.interfaces import IConcept | from loops.interfaces import IConcept | ||||||
| from loops.type import TypeInterfaceSourceList, AdapterBase | from loops.common import AdapterBase | ||||||
|  | from loops.type import TypeInterfaceSourceList | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # register type interfaces - (TODO: use a function for this) | # register type interfaces - (TODO: use a function for this) | ||||||
|  |  | ||||||
							
								
								
									
										3
									
								
								query.py
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								query.py
									
										
									
									
									
								
							|  | @ -32,7 +32,8 @@ from zope.security.proxy import removeSecurityProxy | ||||||
| 
 | 
 | ||||||
| from cybertools.typology.type import BaseType, TypeManager | from cybertools.typology.type import BaseType, TypeManager | ||||||
| from loops.interfaces import IConcept | from loops.interfaces import IConcept | ||||||
| from loops.type import AdapterBase, TypeInterfaceSourceList | from loops.common import AdapterBase | ||||||
|  | from loops.type import TypeInterfaceSourceList | ||||||
| 
 | 
 | ||||||
| _ = MessageFactory('loops') | _ = MessageFactory('loops') | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										127
									
								
								resource.py
									
										
									
									
									
								
							
							
						
						
									
										127
									
								
								resource.py
									
										
									
									
									
								
							|  | @ -25,13 +25,15 @@ $Id$ | ||||||
| from zope.app import zapi | from zope.app import zapi | ||||||
| from zope.app.container.btree import BTreeContainer | from zope.app.container.btree import BTreeContainer | ||||||
| from zope.app.container.contained import Contained | from zope.app.container.contained import Contained | ||||||
| from zope.app.file.image import Image as BaseMediaAsset | from zope.app.file.image import Image | ||||||
| from zope.app.file.interfaces import IFile | from zope.app.file.interfaces import IFile | ||||||
| from zope.app.filerepresentation.interfaces import IReadFile, IWriteFile | from zope.app.filerepresentation.interfaces import IReadFile, IWriteFile | ||||||
| from zope.app.size.interfaces import ISized | from zope.app.size.interfaces import ISized | ||||||
|  | from zope.cachedescriptors.property import Lazy | ||||||
| from zope.component import adapts | from zope.component import adapts | ||||||
| from zope.i18nmessageid import MessageFactory | from zope.i18nmessageid import MessageFactory | ||||||
| from zope.interface import implements | from zope.interface import implements | ||||||
|  | from zope import schema | ||||||
| from persistent import Persistent | from persistent import Persistent | ||||||
| from cStringIO import StringIO | from cStringIO import StringIO | ||||||
| 
 | 
 | ||||||
|  | @ -39,36 +41,42 @@ from textindexng.interfaces import IIndexableContent | ||||||
| from textindexng.content import IndexContentCollector | from textindexng.content import IndexContentCollector | ||||||
| from cybertools.relation.registry import getRelations | from cybertools.relation.registry import getRelations | ||||||
| from cybertools.relation.interfaces import IRelatable | from cybertools.relation.interfaces import IRelatable | ||||||
|  | from cybertools.typology.interfaces import ITypeManager | ||||||
| 
 | 
 | ||||||
| from interfaces import IBaseResource, IResource | from interfaces import IBaseResource, IResource | ||||||
|  | from interfaces import IFile | ||||||
| from interfaces import IDocument, IDocumentSchema, IDocumentView | from interfaces import IDocument, IDocumentSchema, IDocumentView | ||||||
| from interfaces import IMediaAsset, IMediaAssetSchema, IMediaAssetView | from interfaces import IMediaAsset, IMediaAssetSchema, IMediaAssetView | ||||||
| from interfaces import IFileSystemResource, IControlledResource |  | ||||||
| from interfaces import IResourceManager, IResourceManagerContained | from interfaces import IResourceManager, IResourceManagerContained | ||||||
| from interfaces import ILoopsContained | from interfaces import ILoopsContained | ||||||
| from interfaces import IIndexAttributes | from interfaces import IIndexAttributes | ||||||
| from concept import ResourceRelation | from concept import ResourceRelation | ||||||
|  | from common import ResourceAdapterBase | ||||||
| from view import TargetRelation | from view import TargetRelation | ||||||
| 
 | 
 | ||||||
| _ = MessageFactory('loops') | _ = MessageFactory('loops') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Resource(Contained, Persistent): | class Resource(Image, Contained): | ||||||
|  | 
 | ||||||
|  |     implements(IBaseResource, IResource, IResourceManagerContained, IRelatable, ISized) | ||||||
| 
 | 
 | ||||||
|     implements(IBaseResource, IResource, IFileSystemResource, IControlledResource, |  | ||||||
|                IResourceManagerContained, IRelatable) |  | ||||||
|                 |  | ||||||
|     proxyInterface = IMediaAssetView |     proxyInterface = IMediaAssetView | ||||||
| 
 | 
 | ||||||
|     _size = _width = _height = 0 |     _size = _width = _height = 0 | ||||||
| 
 | 
 | ||||||
|  |     def __init__(self, title=u''): | ||||||
|  |         super(Resource, self).__init__() | ||||||
|  |         self.title = title | ||||||
|  | 
 | ||||||
|     def getResourceType(self): |     def getResourceType(self): | ||||||
|         typePred = self.getLoopsRoot().getConceptManager().getTypePredicate() |         cm = self.getLoopsRoot().getConceptManager() | ||||||
|  |         typePred = cm.getTypePredicate() | ||||||
|         if typePred is None: |         if typePred is None: | ||||||
|             return None |             return None | ||||||
|         concepts = self.getConcepts([typePred]) |         concepts = self.getConcepts([typePred]) | ||||||
|         # TODO (?): check for multiple types (->Error) |         # TODO (?): check for multiple types (->Error) | ||||||
|         return concepts and concepts[0] or None |         return concepts and concepts[0] or cm.get('file', None) | ||||||
|     def setResourceType(self, concept): |     def setResourceType(self, concept): | ||||||
|         current = self.getResourceType() |         current = self.getResourceType() | ||||||
|         if current != concept: |         if current != concept: | ||||||
|  | @ -80,32 +88,32 @@ class Resource(Contained, Persistent): | ||||||
|                 self.deassignConcept(current, [typePred]) |                 self.deassignConcept(current, [typePred]) | ||||||
|             self.assignConcept(concept, typePred) |             self.assignConcept(concept, typePred) | ||||||
|     resourceType = property(getResourceType, setResourceType) |     resourceType = property(getResourceType, setResourceType) | ||||||
|      | 
 | ||||||
|     _title = u'' |     _title = u'' | ||||||
|     def getTitle(self): return self._title |     def getTitle(self): return self._title | ||||||
|     def setTitle(self, title): self._title = title |     def setTitle(self, title): self._title = title | ||||||
|     title = property(getTitle, setTitle) |     title = property(getTitle, setTitle) | ||||||
| 
 | 
 | ||||||
|     _contentType = '' |     def _setData(self, data): | ||||||
|  |         dataFile = StringIO(data)  # let File tear it into pieces | ||||||
|  |         super(Resource, self)._setData(dataFile) | ||||||
|  |         if not self.contentType: | ||||||
|  |             self.guessContentType(data) | ||||||
|  |     data = property(Image._getData, _setData) | ||||||
|  | 
 | ||||||
|  |     def guessContentType(self, data): | ||||||
|  |         if not isinstance(data, str): # seems to be a file object | ||||||
|  |             data = data.read(20) | ||||||
|  |         if data.startswith('%PDF'): | ||||||
|  |             self.contentType = 'application/pdf' | ||||||
|  | 
 | ||||||
|  |     _contentType = u'' | ||||||
|     def setContentType(self, contentType): |     def setContentType(self, contentType): | ||||||
|         if contentType: |         if contentType: | ||||||
|             self._contentType = contentType |             self._contentType = contentType | ||||||
|     def getContentType(self): return self._contentType |     def getContentType(self): return self._contentType | ||||||
|     contentType = property(getContentType, setContentType) |     contentType = property(getContentType, setContentType) | ||||||
| 
 | 
 | ||||||
|     _fsPath = '' |  | ||||||
|     def setFsPath(self, fsPath): self._fsPath = fsPath |  | ||||||
|     def getFsPath(self): return self._fsPath |  | ||||||
|     fsPath = property(getFsPath, setFsPath) |  | ||||||
| 
 |  | ||||||
|     _readOnly = '' |  | ||||||
|     def setReadOnly(self, readOnly): self._readOnly = readOnly |  | ||||||
|     def getReadOnly(self): return self._readOnly |  | ||||||
|     readOnly = property(getReadOnly, setReadOnly) |  | ||||||
| 
 |  | ||||||
|     def __init__(self, title=u''): |  | ||||||
|         self.title = title |  | ||||||
| 
 |  | ||||||
|     def getLoopsRoot(self): |     def getLoopsRoot(self): | ||||||
|         return zapi.getParent(self).getLoopsRoot() |         return zapi.getParent(self).getLoopsRoot() | ||||||
| 
 | 
 | ||||||
|  | @ -122,7 +130,7 @@ class Resource(Contained, Persistent): | ||||||
|         relationships = [ResourceRelation(None, self, p) for p in predicates] |         relationships = [ResourceRelation(None, self, p) for p in predicates] | ||||||
|         # TODO: sort... |         # TODO: sort... | ||||||
|         return getRelations(first=concept, second=self, relationships=relationships) |         return getRelations(first=concept, second=self, relationships=relationships) | ||||||
|          | 
 | ||||||
|     def getConcepts(self, predicates=None): |     def getConcepts(self, predicates=None): | ||||||
|         return [r.first for r in self.getConceptRelations(predicates)] |         return [r.first for r in self.getConceptRelations(predicates)] | ||||||
| 
 | 
 | ||||||
|  | @ -132,17 +140,7 @@ class Resource(Contained, Persistent): | ||||||
|     def deassignConcept(self, concept, predicates=None): |     def deassignConcept(self, concept, predicates=None): | ||||||
|         concept.deassignResource(self, predicates) |         concept.deassignResource(self, predicates) | ||||||
| 
 | 
 | ||||||
| 
 |     # ISized interface | ||||||
| class Document(Resource): |  | ||||||
| 
 |  | ||||||
|     implements(IDocument, ISized) |  | ||||||
| 
 |  | ||||||
|     proxyInterface = IDocumentView |  | ||||||
| 
 |  | ||||||
|     _data = u'' |  | ||||||
|     def setData(self, data): self._data = data |  | ||||||
|     def getData(self): return self._data |  | ||||||
|     data = property(getData, setData) |  | ||||||
| 
 | 
 | ||||||
|     def getSize(self): |     def getSize(self): | ||||||
|         return len(self.data) |         return len(self.data) | ||||||
|  | @ -154,29 +152,24 @@ class Document(Resource): | ||||||
|         return '%i Bytes' % self.getSize() |         return '%i Bytes' % self.getSize() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class MediaAsset(Resource, BaseMediaAsset): | class Document(Resource): | ||||||
| 
 | 
 | ||||||
|     implements(IMediaAsset) |     implements(IDocument) | ||||||
| 
 | 
 | ||||||
|     proxyInterface = IMediaAssetView |     proxyInterface = IDocumentView | ||||||
| 
 | 
 | ||||||
|     def __init__(self, title=u''): |     def __init__(self, title=u''): | ||||||
|         super(MediaAsset, self).__init__() |  | ||||||
|         self.title = title |         self.title = title | ||||||
| 
 | 
 | ||||||
|     def _setData(self, data): |     _data = '' | ||||||
|         dataFile = StringIO(data)  # let File tear it into pieces |     def setData(self, data): self._data = data | ||||||
|         super(MediaAsset, self)._setData(dataFile) |     def getData(self): return self._data | ||||||
|         if not self.contentType: |     data = property(getData, setData) | ||||||
|             self.guessContentType(data) |  | ||||||
| 
 | 
 | ||||||
|     data = property(BaseMediaAsset._getData, _setData) |  | ||||||
| 
 | 
 | ||||||
|     def guessContentType(self, data): | class MediaAsset(Resource): | ||||||
|         if not isinstance(data, str): # seems to be a file object | 
 | ||||||
|             data = data.read(20) |     implements(IMediaAsset) | ||||||
|         if data.startswith('%PDF'): |  | ||||||
|             self.contentType = 'application/pdf' |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class ResourceManager(BTreeContainer): | class ResourceManager(BTreeContainer): | ||||||
|  | @ -188,17 +181,19 @@ class ResourceManager(BTreeContainer): | ||||||
| 
 | 
 | ||||||
|     def getViewManager(self): |     def getViewManager(self): | ||||||
|         return self.getLoopsRoot().getViewManager() |         return self.getLoopsRoot().getViewManager() | ||||||
|      | 
 | ||||||
|      | 
 | ||||||
| # adapters and similar stuff | # adapters and similar stuff | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class FileAdapter(object): | class FileAdapter(ResourceAdapterBase): | ||||||
|     """ A type adapter for providing file functionality for resources. |     """ A type adapter for providing file functionality for resources. | ||||||
|     """ |     """ | ||||||
|      | 
 | ||||||
|     def __init__(self, context): |     implements(IFile) | ||||||
|         self.context = context | 
 | ||||||
|  |     # TODO: provide specialized access to data attribute analog to zope.app.file; | ||||||
|  |     #       automatically set contentType... | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class DocumentWriteFileAdapter(object): | class DocumentWriteFileAdapter(object): | ||||||
|  | @ -259,3 +254,23 @@ class IndexableResource(object): | ||||||
|         icc.addBinary(fields[0], context.data, context.contentType, language='de') |         icc.addBinary(fields[0], context.data, context.contentType, language='de') | ||||||
|         return icc |         return icc | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | class ResourceTypeSourceList(object): | ||||||
|  | 
 | ||||||
|  |     implements(schema.interfaces.IIterableSource) | ||||||
|  | 
 | ||||||
|  |     def __init__(self, context): | ||||||
|  |         self.context = context | ||||||
|  | 
 | ||||||
|  |     def __iter__(self): | ||||||
|  |         return iter(self.resourceTypes) | ||||||
|  | 
 | ||||||
|  |     @Lazy | ||||||
|  |     def resourceTypes(self): | ||||||
|  |         types = ITypeManager(self.context).listTypes(include=('resource',)) | ||||||
|  |         return [t.typeProvider for t in types if t.typeProvider is not None] | ||||||
|  | 
 | ||||||
|  |     def __len__(self): | ||||||
|  |         return len(self.resourceTypes) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |  | ||||||
							
								
								
									
										64
									
								
								type.py
									
										
									
									
									
								
							
							
						
						
									
										64
									
								
								type.py
									
										
									
									
									
								
							|  | @ -36,6 +36,7 @@ from loops.interfaces import ITypeConcept | ||||||
| from loops.interfaces import IResourceAdapter, IFile, IImage, ITextDocument | from loops.interfaces import IResourceAdapter, IFile, IImage, ITextDocument | ||||||
| from loops.concept import Concept | from loops.concept import Concept | ||||||
| from loops.resource import Resource, Document, MediaAsset | from loops.resource import Resource, Document, MediaAsset | ||||||
|  | from loops.common import AdapterBase | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class LoopsType(BaseType): | class LoopsType(BaseType): | ||||||
|  | @ -65,7 +66,7 @@ class LoopsType(BaseType): | ||||||
|     def typeInterface(self): |     def typeInterface(self): | ||||||
|         adapter = zapi.queryAdapter(self.typeProvider, ITypeConcept) |         adapter = zapi.queryAdapter(self.typeProvider, ITypeConcept) | ||||||
|         if adapter is not None: |         if adapter is not None: | ||||||
|             return adapter.typeInterface |             return removeSecurityProxy(adapter.typeInterface) | ||||||
|         else: |         else: | ||||||
|             conceptType = self.typeProvider |             conceptType = self.typeProvider | ||||||
|             typeConcept = self.root.getConceptManager().getTypeConcept() |             typeConcept = self.root.getConceptManager().getTypeConcept() | ||||||
|  | @ -130,7 +131,7 @@ class ResourceType(LoopsType): | ||||||
|         type concepts as is already the case for concepts. |         type concepts as is already the case for concepts. | ||||||
|     """ |     """ | ||||||
| 
 | 
 | ||||||
|     adapts(IResource) |     #adapts(IResource) | ||||||
| 
 | 
 | ||||||
|     typeTitles = {'MediaAsset': u'Media Asset'} |     typeTitles = {'MediaAsset': u'Media Asset'} | ||||||
| 
 | 
 | ||||||
|  | @ -214,15 +215,13 @@ class LoopsTypeManager(TypeManager): | ||||||
|                         for cls in (Document, MediaAsset)]) |                         for cls in (Document, MediaAsset)]) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TypeConcept(object): | class TypeConcept(AdapterBase): | ||||||
|     """ typeInterface adapter for concepts of type 'type'. |     """ typeInterface adapter for concepts of type 'type'. | ||||||
|     """ |     """ | ||||||
| 
 | 
 | ||||||
|     implements(ITypeConcept) |     implements(ITypeConcept) | ||||||
|     adapts(IConcept) |  | ||||||
| 
 | 
 | ||||||
|     def __init__(self, context): |     _schemas = list(ITypeConcept) + list(IConcept) | ||||||
|         self.context = removeSecurityProxy(context) |  | ||||||
| 
 | 
 | ||||||
|     def getTypeInterface(self): |     def getTypeInterface(self): | ||||||
|         ti = getattr(self.context, '_typeInterface', None) |         ti = getattr(self.context, '_typeInterface', None) | ||||||
|  | @ -251,56 +250,3 @@ class TypeInterfaceSourceList(object): | ||||||
|     def __len__(self): |     def __len__(self): | ||||||
|         return len(self.typeInterfaces) |         return len(self.typeInterfaces) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| class ResourceTypeSourceList(object): |  | ||||||
| 
 |  | ||||||
|     implements(schema.interfaces.IIterableSource) |  | ||||||
| 
 |  | ||||||
|     def __init__(self, context): |  | ||||||
|         self.context = context |  | ||||||
| 
 |  | ||||||
|     def __iter__(self): |  | ||||||
|         return iter(self.resourceTypes) |  | ||||||
| 
 |  | ||||||
|     @Lazy |  | ||||||
|     def resourceTypes(self): |  | ||||||
|         types = ITypeManager(self.context).listTypes(include=('resource',)) |  | ||||||
|         return [t.typeProvider for t in types] |  | ||||||
| 
 |  | ||||||
|     def __len__(self): |  | ||||||
|         return len(self.resourceTypes) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class AdapterBase(object): |  | ||||||
|     """ (Mix-in) Class for concept adapters that provide editing of fields |  | ||||||
|         defined by the type interface. |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     adapts(IConcept) |  | ||||||
| 
 |  | ||||||
|     _attributes = ('context', '__parent__', ) |  | ||||||
|     _schemas = list(IConcept) |  | ||||||
| 
 |  | ||||||
|     def __init__(self, context): |  | ||||||
|         self.context = context # to get the permission stuff right |  | ||||||
|         self.__parent__ = context |  | ||||||
| 
 |  | ||||||
|     def __getattr__(self, attr): |  | ||||||
|         self.checkAttr(attr) |  | ||||||
|         return getattr(self.context, '_' + attr, None) |  | ||||||
| 
 |  | ||||||
|     def __setattr__(self, attr, value): |  | ||||||
|         if attr in self._attributes: |  | ||||||
|             object.__setattr__(self, attr, value) |  | ||||||
|         else: |  | ||||||
|             self.checkAttr(attr) |  | ||||||
|             setattr(self.context, '_' + attr, value) |  | ||||||
| 
 |  | ||||||
|     def checkAttr(self, attr): |  | ||||||
|         if attr not in self._schemas: |  | ||||||
|             raise AttributeError(attr) |  | ||||||
| 
 |  | ||||||
|     def __eq__(self, other): |  | ||||||
|         return self.context == other.context |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 helmutm
						helmutm