improvements for external collection and media asset: integration now working correctly, with generation of scal variants for media assets

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3105 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2008-12-31 13:46:18 +00:00
parent 60c7d22e61
commit be71f62a6e
9 changed files with 104 additions and 35 deletions

View file

@ -108,6 +108,7 @@ class EditForm(form.EditForm):
class BaseView(GenericView, I18NView):
actions = {}
icon = None
def __init__(self, context, request):
super(BaseView, self).__init__(context, request)
@ -127,6 +128,8 @@ class BaseView(GenericView, I18NView):
def conceptMacros(self):
return concept_macros.macros
concept_macros = conceptMacros
@Lazy
def name(self):
return getName(self.context)

View file

@ -3,12 +3,14 @@
<metal:data define-macro="conceptdata">
<div tal:attributes="class string:content-$level;">
<metal:fields use-macro="item/template/macros/concepttitle" />
<metal:fields use-macro="item/template/macros/conceptfields" />
<metal:fields use-macro="item/template/macros/conceptchildren" />
<metal:fields use-macro="item/template/macros/conceptresources" />
<metal:fields use-macro="view/work_macros/workitems" />
<metal:fields use-macro="view/comment_macros/comments" />
<metal:block use-macro="view/concept_macros/concepttitle" />
<metal:slot define-slot="fields">
<metal:block use-macro="view/concept_macros/conceptfields" />
</metal:slot>
<metal:block use-macro="view/concept_macros/conceptchildren" />
<metal:block use-macro="view/concept_macros/conceptresources" />
<metal:block use-macro="view/work_macros/workitems" />
<metal:block use-macro="view/comment_macros/comments" />
</div>
</metal:data>
@ -154,7 +156,10 @@
<a href="#"
tal:attributes="href string:${view/url}/.target${related/uniqueId};
title description">
<span tal:replace="related/title">Resource Title</span>
<img tal:define="icon related/icon"
tal:condition="icon"
tal:attributes="src icon/src" />
<div tal:content="related/title">Resource Title</div>
</a>
</td>
<td><span tal:replace="related/longTypeTitle">Type</span></td>

View file

@ -48,7 +48,9 @@ from loops.browser.concept import ConceptRelationView, ConceptConfigureView
from loops.browser.node import NodeView, node_macros
from loops.common import adapted, NameChooser
from loops.interfaces import IBaseResource, IDocument, IMediaAsset, ITextDocument
from loops.interfaces import IMediaAsset as legacy_IMediaAsset
from loops.interfaces import ITypeConcept
from loops.media.interfaces import IMediaAsset
from loops.organize.stateful.browser import statefulActions
from loops.versioning.browser import version_macros
from loops.versioning.interfaces import IVersionable
@ -95,13 +97,19 @@ class DocumentEditForm(EditForm):
class MediaAssetEditForm(EditForm):
form_fields = FormFields(IMediaAsset)
form_fields = FormFields(legacy_IMediaAsset)
class ResourceView(BaseView):
template = ViewPageTemplateFile('resource_macros.pt')
@Lazy
def icon(self):
if IMediaAsset.providedBy(self.adapted):
return dict(src='%s/mediaasset.html?v=minithumb' %
(self.nodeView.getUrlForTarget(self.context)))
@property
def macro(self):
if 'image/' in self.context.contentType:

View file

@ -59,9 +59,15 @@ class ExternalCollectionAdapter(AdapterBase):
implements(IExternalCollection)
adapts(IConcept)
_adapterAttributes = ('context', '__parent__',)
_adapterAttributes = ('context', '__parent__', 'exclude')
_contextAttributes = list(IExternalCollection) + list(IConcept)
def getExclude(self):
return getattr(self.context, '_exclude', None) or []
def setExclude(self, value):
self.context._exclude = value
exclude = property(getExclude, setExclude)
def update(self):
existing = self.context.getResources()
#old = dict((adapted(obj).uniqueAddress, obj) for obj in existing)
@ -109,26 +115,43 @@ class DirectoryCollectionProvider(object):
implements(IExternalCollectionProvider)
extFileTypeMapping = {
'image/*': 'media_asset',
'*/*': 'extfile',
}
def collect(self, client):
directory = self.getDirectory(client)
pattern = re.compile(client.pattern or '.*')
for path, dirs, files in os.walk(directory):
if '.svn' in dirs:
del dirs[dirs.index('.svn')]
for ex in client.exclude:
if ex in dirs:
del dirs[dirs.index(ex)]
for f in files:
if pattern.match(f):
mtime = os.stat(os.path.join(path, f))[stat.ST_MTIME]
yield (os.path.join(path[len(directory)+1:], f),
datetime.fromtimestamp(mtime))
def createExtFileObjects(self, client, addresses, extFileType=None):
if extFileType is None:
extFileType = client.context.getLoopsRoot().getConceptManager()['extfile']
def createExtFileObjects(self, client, addresses, extFileTypes=None):
if extFileTypes is None:
cm = client.context.getLoopsRoot().getConceptManager()
extFileTypes = dict((k, cm.get(v))
for k, v in self.extFileTypeMapping.items())
container = client.context.getLoopsRoot().getResourceManager()
directory = self.getDirectory(client)
for addr in addresses:
name = self.generateName(container, addr)
title = self.generateTitle(addr)
contentType = guess_content_type(addr,
default='application/octet-stream')[0]
extFileType = extFileTypes.get(contentType)
if extFileType is None:
extFileType = extFileTypes.get(contentType.split('/')[0] + '/*')
if extFileType is None:
extFileType = extFileTypes['*/*']
obj = addAndConfigureObject(
container, Resource, name,
title=title,
@ -136,9 +159,8 @@ class DirectoryCollectionProvider(object):
externalAddress=addr,
storageName='fullpath',
storageParams=dict(subdirectory=directory),
contentType = guess_content_type(addr,
default='application/octet-stream')[0]
)
contentType=contentType,
)
yield obj
def getDirectory(self, client):

View file

@ -1,11 +1,19 @@
<metal:resources define-macro="render_collection"
tal:define="dummy item/update">
<html i18n:domain="loops">
<metal:concept use-macro="item/template/macros/conceptdata" />
<form action="." method="post">
<input type="submit" name="update" value="Update Collection" />
</form>
<metal:block define-macro="render_collection"
tal:define="dummy item/update">
</metal:resources>
<metal:block use-macro="view/concept_macros/conceptdata">
<metal:fill fill-slot="fields">
<metal:block use-macro="view/concept_macros/conceptfields" />
<form action="." method="post">
<input type="submit" name="update" value="Update Collection" />
</form>
</metal:fill>
</metal:block>
</metal:block>
</html>

View file

@ -50,13 +50,13 @@ class IExternalCollection(IConceptSchema):
providerName = schema.TextLine(
title=_(u'Provider name'),
description=_(u'The name of a utility that provides the '
'external objects; default is a directory '
'collection provider'),
u'external objects; default is a directory '
u'collection provider'),
required=False)
baseAddress = schema.TextLine(
title=_(u'Base address'),
description=_(u'A base path or URL for accessing this collection '
'on the external system'),
u'on the external system'),
required=True)
address = schema.TextLine(
title=_(u'Relative address'),
@ -66,7 +66,13 @@ class IExternalCollection(IConceptSchema):
pattern = schema.TextLine(
title=_(u'Selection pattern'),
description=_(u'A regular expression for selecting external objects '
'that should belong to this collection'),
u'that should belong to this collection'),
required=False)
exclude = schema.List(
title=_(u'Exclude'),
description=_(u'Names of directories and files that should not '
u'be included.'),
value_type=schema.TextLine(),
required=False)
lastUpdated = Attribute('Date and time of last update.')
@ -93,9 +99,12 @@ class IExternalCollectionProvider(Interface):
IExternalCollection interface.
"""
def createExtFileObjects(clientCollection, addresses, extFileType=None):
""" Create a resource of type 'extFileType' (default is the
type with the name 'extfile') for each of the addresses
provided. Return the list of objects created.
def createExtFileObjects(clientCollection, addresses, extFileTypes=None):
""" Create a resource for each of the addresses provided.
Return the list of objects created.
The ``extFileTypes`` argument is a mapping of MIME types to
names of concept types. The MIME types may contain wildcards,
e.g. 'image/*', '*/*'.
"""

View file

@ -69,13 +69,22 @@ class MediaAsset(MediaAssetFile, ExternalFileAdapter):
self.transform(self.rules)
data = property(ExternalFileAdapter.getData, setData)
def setExternalAddress(self, addr):
ExternalFileAdapter.setExternalAddress(self, addr)
if addr and self.getMimeType().startswith('image/'):
self.transform(self.rules)
externalAddress = property(ExternalFileAdapter.getExternalAddress,
setExternalAddress)
def getMimeType(self):
return self.context.contentType or ''
def getDataPath(self):
storage = component.getUtility(IExternalStorage, name=self.storageName)
#print '***', self.storageName, self.storageParams, self.options
return storage.getDir(self.externalAddress,
self.options['storage_parameters'])
#self.options['storage_parameters'])
self.storageParams['subdirectory'])
def getOriginalData(self):
return ExternalFileAdapter.getData(self)

View file

@ -275,7 +275,8 @@ class Resource(Image, Contained):
oldAdapted.data = '' # clear old storage
context._storageName = None # let's take storage from new type options
context._storageParams = None # "
newAdapted.data = data
if data: # do not write empty files
newAdapted.data = data
# Document and MediaAsset are legacy classes, will become obsolete

View file

@ -72,9 +72,13 @@
description row/description">
<tr tal:attributes="class class">
<td>
<a tal:attributes="href string:${view/url}/.target${row/uniqueId}?version=this;
title description"
tal:content="row/title" />
<a tal:attributes="href
string:${view/url}/.target${row/uniqueId}?version=this;
title description">
<img tal:define="icon row/icon"
tal:condition="icon"
tal:attributes="src icon/src" />
<div tal:content="row/title" /></a>
</td>
<td i18n:translate=""
tal:content="row/longTypeTitle|row/typeTitle">Type</td>