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
				
			
		
							
								
								
									
										10
									
								
								README.txt
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								README.txt
									
										
									
									
									
								
							|  | @ -230,7 +230,7 @@ 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: | ||||||
| 
 | 
 | ||||||
|  | @ -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: | ||||||
| 
 | 
 | ||||||
|  | @ -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', | ||||||
|  |  | ||||||
|  | @ -201,7 +201,8 @@ class LoopsTerms(object): | ||||||
|         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) | ||||||
|  |  | ||||||
|  | @ -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" | ||||||
|  |  | ||||||
|  | @ -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,7 +159,9 @@ 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" | ||||||
|       /> |       /> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  | @ -178,7 +179,7 @@ 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. | ||||||
|  | @ -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. | ||||||
|  | @ -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. | ||||||
|  | @ -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') | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										115
									
								
								resource.py
									
										
									
									
									
								
							
							
						
						
									
										115
									
								
								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, IFileSystemResource, IControlledResource, |     implements(IBaseResource, IResource, IResourceManagerContained, IRelatable, ISized) | ||||||
|                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: | ||||||
|  | @ -86,26 +94,26 @@ class Resource(Contained, Persistent): | ||||||
|     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() | ||||||
| 
 | 
 | ||||||
|  | @ -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): | ||||||
|  | @ -193,12 +186,14 @@ class ResourceManager(BTreeContainer): | ||||||
| # 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