add media asset management package

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2928 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2008-10-21 13:02:40 +00:00
parent 13fe5fd4d8
commit 462f9aaa0b
14 changed files with 357 additions and 4 deletions

View file

@ -441,6 +441,7 @@
<include package=".integrator" />
<include package=".knowledge" />
<include package=".layout" />
<include package=".media" />
<include package=".organize" />
<include package=".rest" />
<include package=".search" />

18
media/README.txt Normal file
View file

@ -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

4
media/__init__.py Normal file
View file

@ -0,0 +1,4 @@
"""
$Id$
"""

81
media/asset.py Normal file
View file

@ -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)

View file

@ -0,0 +1,4 @@
"""
$Id$
"""

59
media/browser/admin.py Normal file
View file

@ -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.'

16
media/browser/asset.pt Normal file
View file

@ -0,0 +1,16 @@
<!-- ZPT macros for demo view -->
<metal:block define-macro="asset">
<h1 tal:content="item/adapted/title">Title</h1>
<h2>Content type</h2>
<p tal:content="item/adapted/getContentType">image/jpeg</p>
<div tal:define="descr item/adapted/description" tal:condition="descr">
<h2>Description</h2>
<p tal:content="item/adapted/description">Description</p>
</div>
<p><img tal:attributes="src string:${item/url}/@@mediaasset.html" /></p>
</metal:block>

66
media/browser/asset.py Normal file
View file

@ -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')

View file

@ -0,0 +1,25 @@
<!-- $Id$ -->
<configure
xmlns:zope="http://namespaces.zope.org/zope"
xmlns="http://namespaces.zope.org/browser"
i18n_domain="zope">
<page for="loops.interfaces.IResource"
name="mediaasset.html"
class="loops.media.browser.asset.MediaAssetView"
permission="zope.View"
attribute="show" />
<page for="loops.interfaces.INode"
name="mediaasset.html"
class="loops.media.browser.asset.MediaAssetNodeView"
permission="zope.View"
attribute="show" />
<page for="loops.interfaces.ILoopsObject"
name="regenerate_media_assets.html"
class="loops.media.browser.admin.RegenerationView"
permission="zope.View" />
</configure>

20
media/configure.zcml Normal file
View file

@ -0,0 +1,20 @@
<!-- $Id$ -->
<configure
xmlns:zope="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
i18n_domain="zope">
<zope:adapter factory="loops.media.asset.MediaAsset"
provides="loops.media.interfaces.IMediaAsset"
trusted="True" />
<zope:class class="loops.media.asset.MediaAsset">
<require permission="zope.View"
interface="loops.media.interfaces.IMediaAsset" />
<require permission="zope.ManageContent"
set_schema="loops.media.interfaces.IMediaAsset" />
</zope:class>
<include package=".browser" />
</configure>

32
media/interfaces.py Normal file
View file

@ -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

29
media/tests.py Normal file
View file

@ -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')

View file

@ -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

View file

@ -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