diff --git a/configure.zcml b/configure.zcml index b2e3506..5e04180 100644 --- a/configure.zcml +++ b/configure.zcml @@ -441,6 +441,7 @@ + diff --git a/media/README.txt b/media/README.txt new file mode 100644 index 0000000..6f8efcd --- /dev/null +++ b/media/README.txt @@ -0,0 +1,18 @@ +=============================================================== +loops - Linked Objects for Organization and Processing Services +=============================================================== + + ($Id$) + + +Media Asset Management +====================== + + >>> from loops.media.asset import MediaAsset + + +Browser Views +------------- + + >>> from loops.media.browser.asset import MediaAssetView, MediaAssetNodeView + diff --git a/media/__init__.py b/media/__init__.py new file mode 100644 index 0000000..4bc90fb --- /dev/null +++ b/media/__init__.py @@ -0,0 +1,4 @@ +""" +$Id$ +""" + diff --git a/media/asset.py b/media/asset.py new file mode 100644 index 0000000..11ebc20 --- /dev/null +++ b/media/asset.py @@ -0,0 +1,81 @@ +# +# Copyright (c) 2008 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Media asset file adapter. + +Original authors: Johann Schimpf, Erich Seifert. + +$Id$ +""" + +from logging import getLogger +import os + +from zope import component +from zope.cachedescriptors.property import Lazy +from zope.interface import implements + +from cybertools.media.asset import MediaAssetFile +from cybertools.storage.interfaces import IExternalStorage +from loops.media.interfaces import IMediaAsset +from loops.resource import ExternalFileAdapter +from loops.type import TypeInterfaceSourceList + +transformPrefix = 'asset_transform.' + +TypeInterfaceSourceList.typeInterfaces += (IMediaAsset,) + + +class MediaAsset(MediaAssetFile, ExternalFileAdapter): + """ Concept adapter for extracting metadata from assets and for creating + transformation variants. + """ + + implements(IMediaAsset) + + isMediaAsset = True + + def __init__(self, context): + ExternalFileAdapter.__init__(self, context) + + @Lazy + def rules(self): + result = {} + for key, value in self.options.items(): + if key.startswith(transformPrefix): + variant = key[len(transformPrefix):] + result[variant] = value + return result + + def setData(self, data): + ExternalFileAdapter.setData(self, data) + if data: + self.transform(self.rules) + data = property(ExternalFileAdapter.getData, setData) + + def getMimeType(self): + return self.context.contentType + + def getDataPath(self): + storage = component.getUtility(IExternalStorage, name=self.storageName) + return storage.getDir(self.externalAddress, + self.options['storage_parameters']) + + def getOriginalData(self): + return ExternalFileAdapter.getData(self) diff --git a/media/browser/__init__.py b/media/browser/__init__.py new file mode 100644 index 0000000..4bc90fb --- /dev/null +++ b/media/browser/__init__.py @@ -0,0 +1,4 @@ +""" +$Id$ +""" + diff --git a/media/browser/admin.py b/media/browser/admin.py new file mode 100644 index 0000000..968946a --- /dev/null +++ b/media/browser/admin.py @@ -0,0 +1,59 @@ +# +# Copyright (c) 2008 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +View for regenerating all transformed media assets. + +Authors: Johann Schimpf, Erich Seifert. + +$Id$ +""" + +from logging import getLogger +import traceback +from zope import component + +from cybertools.media.interfaces import IMediaAsset + + +class RegenerationView(object): + + def __call__(self): + conceptType = self.request.get('type') + if not conceptType: + return '*** No type given!' + tMediaAsset = self.context.getLoopsRoot().getConceptManager()[conceptType] + # Remove old transformed versions + #storageDir = assetManager.options.get("storage_parameters") + #print storageDir + # Regenerate all media asset transforations + resources = tMediaAsset.getResources() + logger = getLogger('Asset Manager') + errors = 0 + for res in resources: + logger.info('*** regenerating: ' + res.__name__) + asset = component.queryAdapter(res, IMediaAsset) + if asset != None: + try: + asset.transform() + except: + logger.warn(traceback.format_exc()) + errors += 1 + if errors: + return 'Done - there were %i errors.' % errors + return 'Done.' diff --git a/media/browser/asset.pt b/media/browser/asset.pt new file mode 100644 index 0000000..c003c62 --- /dev/null +++ b/media/browser/asset.pt @@ -0,0 +1,16 @@ + + + +

Title

+ +

Content type

+

image/jpeg

+ +
+

Description

+

Description

+
+ +

+
+ diff --git a/media/browser/asset.py b/media/browser/asset.py new file mode 100644 index 0000000..10f81bc --- /dev/null +++ b/media/browser/asset.py @@ -0,0 +1,66 @@ +# +# Copyright (c) 2008 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Views for displaying media assets. + +Authors: Johann Schimpf, Erich Seifert. + +$Id$ +""" + +from zope.app.pagetemplate import ViewPageTemplateFile +from zope.cachedescriptors.property import Lazy + +from loops.browser.node import NodeView +from loops.browser.resource import ResourceView +from loops.common import adapted +from loops import util + +template = ViewPageTemplateFile('asset.pt') + + +class MediaAssetView(ResourceView): + + @Lazy + def macro(self): + return template.macros['asset'] + + def show(self, useAttachment=False): + versionId = self.request.get('v') + obj = self.adapted + data = obj.getData(versionId) + contentType = obj.getContentType(versionId) + response = self.request.response + response.setHeader('Content-Type', contentType) + response.setHeader('Content-Length', len(data)) + #if useAttachment or ( + # not contentType.startswith('image/') and contentType != 'application/pdf'): + if useAttachment: + filename = obj.localFilename or getName(self.context) + #filename = urllib.quote(filename) + filename = NameChooser(getParent(self.context)).normalizeName(filename) + response.setHeader('Content-Disposition', + 'attachment; filename=%s' % filename) + return data + + +class MediaAssetNodeView(NodeView): + + def show(self): + return self.targetView('mediaasset.html') diff --git a/media/browser/configure.zcml b/media/browser/configure.zcml new file mode 100644 index 0000000..6f60056 --- /dev/null +++ b/media/browser/configure.zcml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/media/configure.zcml b/media/configure.zcml new file mode 100644 index 0000000..59fde62 --- /dev/null +++ b/media/configure.zcml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/media/interfaces.py b/media/interfaces.py new file mode 100644 index 0000000..5cafe7e --- /dev/null +++ b/media/interfaces.py @@ -0,0 +1,32 @@ +# +# Copyright (c) 2008 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Media asset management interface definitions. + +$Id$ +""" + +from cybertools.media.interfaces import IMediaAsset +from loops.interfaces import IExternalFile + + +class IMediaAsset(IMediaAsset, IExternalFile): + + pass + diff --git a/media/tests.py b/media/tests.py new file mode 100644 index 0000000..57fd700 --- /dev/null +++ b/media/tests.py @@ -0,0 +1,29 @@ +#! /usr/bin/python + +""" +Tests for the 'loops.media' package. + +$Id$ +""" + +import unittest, doctest +from zope.testing.doctestunit import DocFileSuite +from zope.interface.verify import verifyClass + + +class Test(unittest.TestCase): + "Basic tests for the media package." + + def testSomething(self): + pass + + +def test_suite(): + flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS + return unittest.TestSuite(( + unittest.makeSuite(Test), + DocFileSuite('README.txt', optionflags=flags), + )) + +if __name__ == '__main__': + unittest.main(defaultTest='test_suite') diff --git a/security/perm.py b/security/perm.py index ca402b8..3bbb3cf 100644 --- a/security/perm.py +++ b/security/perm.py @@ -31,8 +31,6 @@ from zope.app.securitypolicy.interfaces import IPrincipalRoleManager, IRolePermi from zope.app.securitypolicy.interfaces import IPrincipalPermissionManager, \ IPrincipalPermissionMap from zope.app.securitypolicy.zopepolicy import SettingAsBoolean -from zope.publisher.browser import BrowserView -from zope.security.proxy import removeSecurityProxy from zope.traversing.api import getParents diff --git a/type.py b/type.py index 51260d3..4e5f783 100644 --- a/type.py +++ b/type.py @@ -289,7 +289,7 @@ def getOptionsDict(options): for opt in options: if ':' in opt: key, value = opt.split(':', 1) - result[key] = value + result[key.strip()] = value.strip() else: - result['default'].append(opt) + result['default'].append(opt.strip()) return result