diff --git a/browser/common.py b/browser/common.py
index 571df48..77b8080 100644
--- a/browser/common.py
+++ b/browser/common.py
@@ -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)
diff --git a/browser/concept_macros.pt b/browser/concept_macros.pt
index eb4faf4..c201d19 100644
--- a/browser/concept_macros.pt
+++ b/browser/concept_macros.pt
@@ -3,12 +3,14 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
@@ -154,7 +156,10 @@
- Resource Title
+
+ Resource Title
Type |
diff --git a/browser/resource.py b/browser/resource.py
index b38876a..8ed2ff8 100644
--- a/browser/resource.py
+++ b/browser/resource.py
@@ -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:
diff --git a/integrator/collection.py b/integrator/collection.py
index 0adfd8f..1ab8bf1 100644
--- a/integrator/collection.py
+++ b/integrator/collection.py
@@ -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):
diff --git a/integrator/collection_macros.pt b/integrator/collection_macros.pt
index e824484..4ba39b3 100644
--- a/integrator/collection_macros.pt
+++ b/integrator/collection_macros.pt
@@ -1,11 +1,19 @@
-
+
-
-
+
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/integrator/interfaces.py b/integrator/interfaces.py
index ba2c0b5..32e9b16 100644
--- a/integrator/interfaces.py
+++ b/integrator/interfaces.py
@@ -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/*', '*/*'.
"""
diff --git a/media/asset.py b/media/asset.py
index e576113..32e823b 100644
--- a/media/asset.py
+++ b/media/asset.py
@@ -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)
diff --git a/resource.py b/resource.py
index e678496..0cfe549 100644
--- a/resource.py
+++ b/resource.py
@@ -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
diff --git a/search/search.pt b/search/search.pt
index eecffe8..0fdfe35 100644
--- a/search/search.pt
+++ b/search/search.pt
@@ -72,9 +72,13 @@
description row/description">
-
+
+
+
|
Type |