From 7223b08b5a243c0ced92e8d38e928c4971d34218 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Sun, 21 Aug 2011 15:52:21 +0200 Subject: [PATCH] - provide additional metaInfo field, e.g. for storing source and rights information for media assets; show this in info popup; link image to info popup in Lobo skin standard views - Lobo listings: allow for restriction of children listed to certain types --- CHANGES.txt | 4 ++++ browser/info.pt | 2 +- browser/lobo/standard.pt | 21 ++++++++++++++++----- browser/lobo/standard.py | 26 +++++++++++++++++--------- concept.py | 2 ++ interfaces.py | 13 +++++++++++-- locales/de/LC_MESSAGES/loops.mo | Bin 14729 -> 14927 bytes locales/de/LC_MESSAGES/loops.po | 14 +++++++++++++- media/asset.py | 1 + media/browser/asset.py | 9 +++++++++ media/interfaces.py | 13 +++++++++++-- resource.py | 2 ++ 12 files changed, 87 insertions(+), 20 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index ea091e2..b592d04 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -6,6 +6,10 @@ $Id$ 1.1 --- +- provide additional ``metaInfo`` field, e.g. for storing source and rights + information for media assets; show this in info popup; + link image to info popup in Lobo skin standard views +- Lobo listings: allow for restriction of children listed to certain types - media assets: allow for access restriction for viewing larger than a given maximum size (via option ``media.unauthorized_max_size``) - external editor functionality: include title field in data in order to diff --git a/browser/info.pt b/browser/info.pt index 61a503e..ed0d7db 100644 --- a/browser/info.pt +++ b/browser/info.pt @@ -39,7 +39,7 @@ Creators: - +
diff --git a/browser/lobo/standard.pt b/browser/lobo/standard.pt index c165ef8..59e6e93 100644 --- a/browser/lobo/standard.pt +++ b/browser/lobo/standard.pt @@ -48,7 +48,8 @@
-
+
@@ -65,7 +66,8 @@ -
+
@@ -76,9 +78,18 @@ - + + + + + diff --git a/browser/lobo/standard.py b/browser/lobo/standard.py index 6044ca7..5b3e3de 100644 --- a/browser/lobo/standard.py +++ b/browser/lobo/standard.py @@ -50,6 +50,11 @@ class Base(BaseConceptView): def macro(self): return self.macros[self.macroName] + @Lazy + def params(self): + ann = self.request.annotations.get('loops.view', {}) + return parse_qs(ann.get('params') or '') + class ConceptView(BaseConceptView): @@ -106,10 +111,10 @@ class ConceptView(BaseConceptView): @Lazy def img(self): for r in self.resources['images']: - src = ('%s/mediaasset.html?v=%s' % - (self.nodeView.getUrlForTarget(r), - self.parentView.imageSize)) - return dict(src=src, cssClass=self.parentView.imageCssClass) + url = self.nodeView.getUrlForTarget(r) + src = ('%s/mediaasset.html?v=%s' % (url, self.parentView.imageSize)) + return dict(src=src, url=url, + cssClass=self.parentView.imageCssClass) class ConceptRelationView(BaseConceptRelationView, ConceptView): @@ -127,9 +132,7 @@ class Layout(Base): def getParts(self): result = [] - ann = self.request.annotations.get('loops.view', {}) - params = parse_qs(ann.get('params') or '') - parts = (params.get('parts') or ['h1,g3'])[0].split(',') + parts = (self.params.get('parts') or ['h1,g3'])[0].split(',') for p in parts: viewName = 'lobo_' + p view = component.queryMultiAdapter((self.context, self.request), @@ -147,9 +150,14 @@ class BasePart(Base): gridPattern = [] def getChildren(self): + subtypeNames = (self.params.get('subtypes') or [''])[0].split(',') + subtypes = [self.conceptManager[st] for st in subtypeNames if st] result = [] - for idx, r in enumerate( - self.context.getChildRelations([self.defaultPredicate])): + childRels = self.context.getChildRelations([self.defaultPredicate]) + if subtypes: + childRels = [r for r in childRels + if r.second.conceptType in subtypes] + for idx, r in enumerate(childRels): result.append(ConceptRelationView(r, self.request, contextIsSecond=True, parent=self, idx=idx)) return result diff --git a/concept.py b/concept.py index efd9528..9a27490 100644 --- a/concept.py +++ b/concept.py @@ -107,6 +107,8 @@ class Concept(Contained, Persistent): workspaceInformation = None + metaInfo = u'' + def __init__(self, title=u''): self.title = title diff --git a/interfaces.py b/interfaces.py index e760c85..16b1d42 100644 --- a/interfaces.py +++ b/interfaces.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2010 Helmut Merz helmutm@cy55.de +# Copyright (c) 2011 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 @@ -90,6 +90,9 @@ class IConceptSchema(Interface): missing_value=u'', required=False) + metaInfo = Attribute('Optional additional information about the concept ' + 'provided as text.') + # let these fields always appear on top: IConceptSchema['title'].order = 1 IConceptSchema['description'].order = 2 @@ -291,6 +294,9 @@ class IBaseResource(ILoopsObject): missing_value='', required=False) + metaInfo = Attribute('Optional additional information about the resource ' + 'provided as text.') + def getType(): """ Return a concept that provides the object's type, i.e. the resourceType attribute. @@ -361,6 +367,9 @@ class IResourceSchema(Interface): missing_value='', required=False) + metaInfo = Attribute('Optional additional information about the resource ' + 'provided as text.') + class IResource(ILoopsObject, IPotentialTarget): """ A resource is an atomic information element that is made @@ -404,7 +413,7 @@ class IDocument(IDocumentSchema, IResource): # media asset is obsolete - replaced by plain Resource with -# resourceType = file. +# resourceType = file or the new media asset stuff in loops.media. class IMediaAssetView(IResourceSchema): """ Used for accessing a media asset via a node's target attribute""" diff --git a/locales/de/LC_MESSAGES/loops.mo b/locales/de/LC_MESSAGES/loops.mo index 8cda197bed722ba9db83a6749d7394c9037be436..5263c366ac0ad27fa7a01d996783c2b09d09792c 100644 GIT binary patch delta 6001 zcmZA533!cH9>?($xsg4x5CoMWL=qthB~nYP7}VBUI#OFwm!gtLqO_%VrfL^j7gPIQ z>x?CqnbMYyrAjBIv`jIKU1z3@t(2JW@4m;=dFFlQ?{m(1&wG~td)}KqGqtF!*mE}8 zHP>*(_!(0Zw*?uKPq|B!T8#;+YD^Cd#uUuPia5zyf`QcMpg%6cP+W$!aU(|J5e&vN z7=~An{vLCif*$zE-f&ejrV8~ajKxF@$JVF;x}X-&2U)A>Z|g(s{gD_$`xx6k9V=0v zjaujm?1}3!i1|%9g#a1?t2-USQ3F@8^`}q+*2iefviG~97Sso|!$GK>jk5ROK`nGL zs^3ghQa?oXUym`&Z+1~&^QO#pxPn^oeN@NbIAbbf9I9VqREBQWH&s4o^+g1M#SpC!x+pCMuQfP!GO<>es{C7d1gH zYKP-c{btzu2dMFuqZYgwm66YDl7FSJ%yv9yJKjL0@-ZqS(QH>cY=G+D61DKIw*E3| zg4a-~A7k4mq9&SW+gD-;^)0r(+e3k@n=er-zl7T99aKghqIPPYvS$I+FAjBRlTjH; zLoKK!s(%Mm2D;n!Ua0W~pvKR|rsx@F8T`M6~$ z>bXeN#BsJ>7d25T>ba(<1-C>kq%D$BkLf@`Da}T`n-QoTj<@v^)bGGjREl??Ud4V} zKZQEHS5cWT@y-UqP+vtHY9UQf6KA3NwMLh||IQS&&qb|#H0m9W$9gyo zwcyRD`+Kd2P&+(|%EWh=hUZWVh$4+TOVv6(O>`Qy@bjp7uAp{)%eI%-A^%ATGmG^~=Uo?2m~!9kt+6)Pl=U&z(dq-~#H0>>B!GxoxkIK>pPsh-K?gMW9kx z2Q^V+)T_uq7iOVS-3HaKH>zJQy3md4Kipb~n)of$f@Yx>xBy+a(nCQ5tVO-64X6pW zqaHYn4e?v7jsEqV4An&ql#JR@6WiV#HBM^`z>c=P8@8g}8?`_$>UqyX3QFxN)Pp-v zhj0(N@N3j7Ie~iMG-_d&FaU2@@1pKMMD-7-?@Sbi8mBTUW7Sd5)khZYF%9jFG*rh{ zs1>$F4cOV*)3*0Ro%+G3{)L$7$4@S{qrN%Om}l?~YQppe&VpK_#%qr{jNPz`zW;0r zI!pzqACe`glu=io@7wkj zsDs@kWLf2F7|4I!9|wQ(fsl$M|}@8zd?=n zJ%;0D)Ofd13wU7LqdkqBj`66Srl5B8oUQjmWu_37+KIM(5h{gSQ9C<`+Ua>)FGppd zT4U!GrDFv3=TXnSWc3WCpcRcnEnp5RHS1A3`_$IUkUtaV0%{=vY0ge-qCUd}YZB7M zG(s(W04jr{P!o^EP%J?*-(QTK?9ap=b;v~6xDGxDnsi~JKBqt@VKpCM5X#3 zs$XP=v#lo1+%q0jpql)bnmszXH^P#$ijGh5Aa4pkC2sh}?{H?t1)U(;tX2_K;roakxp>?8yAPM<-o>^am< zi){P5s0XH?&Vtw8UyYh*8!96^QDaguYy~1;-jNU-?dtlo={+Z5BVz4qdYM?TZ zhI*j2z26ZvQ4iDrJy8qlhdNY4kxiLm)Vtq+>URj$?-=UUoI#Cy&8d6LEeaaoF>2zl z7X0nUI8=)JqXuxJ7Epj1pa}Kcczb^us{dT;V)T8!sLZajZbD^bI|l0e-|s6J^A&1^ zCs02e=TQ@1Mh$cmmHIoVLm8OmOc;TBF4orTpca^nny4vioOZ~6rcB`QQyBV z9g_Qm{%;svnn>UFHKGr3o%n=^;{GjsMCe-P``7trJDex}Nn{g|^qqn_Pr4Qo4G4Y8 zF78c5-~4+h==vj3i5vQ4MiK#(*Wf^+DshF_OXylayhMCR=rw#xJh{$N(9U-gbBNy) zy5>8WTr76V&3vb{K9y}mzSC$5aHuW&vxoE+CIV?#56*ej;gMC#CT$fDqP2jFNv;1M?%-vM3^6`E2og57Ou`j z1Os2d&xvr#x?+j;zLN9LYp}uA7h@4|%GN967F!krY*{bq4WbV59q|w1j$YlrDEx(Z ziqJKY_?U1LTZvZ0E<(ro4Dl!82%+m)LO)e2h{nV_gucH{L@J@{3qnV|IkAe+#ZRXh zOnCLy|3ma6CVOwjRP}sMX%*@#M;(Fq^nU_!EnWpOu~x3O^FMHWGgJC8+)fqP5PAcTZ)Prw6sQL?NNCvKJgy znd^7NSYPRve?FjCiwLIgy?tvgcpfViA_Wxv6QGyL=d-$zZ1SY-C%j?-q`c5 zz(RLUaeiS@>9QJy{vqz-ocK<8L-GqpdP8fMN97K8zglb?a*BuL=amM=mjw6^a}V~; ztarqfnVOMaI-vf{iXm;?Ifc3IVa4vk(jOZ3c13q(pj2ld-*fJ~(l+Uh{Jgu;ss|Ot jcW2xY#ig%j%&8dhUfy7L;pn`fMT2vSN00QDXHNewYGPVH delta 5846 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 TZthl;R#{L|QM+Pw&+`8O?AJb| diff --git a/locales/de/LC_MESSAGES/loops.po b/locales/de/LC_MESSAGES/loops.po index 028544c..1c787c2 100644 --- a/locales/de/LC_MESSAGES/loops.po +++ b/locales/de/LC_MESSAGES/loops.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: $Id$\n" "POT-Creation-Date: 2007-05-22 12:00 CET\n" -"PO-Revision-Date: 2011-04-30 12:00 CET\n" +"PO-Revision-Date: 2011-08-21 12:00 CET\n" "Last-Translator: Helmut Merz \n" "Language-Team: loops developers \n" "MIME-Version: 1.0\n" @@ -233,6 +233,9 @@ msgstr "Aktionen" msgid "Print this page" msgstr "Diese Seite ausdrucken" +msgid "Object Information" +msgstr "Informationen über dieses Objekt" + msgid "Information about this object." msgstr "Informationen über dieses Objekt." @@ -245,6 +248,9 @@ msgstr "Mit 'External Editor' bearbeiten." msgid "Type" msgstr "Typ" +msgid "modified" +msgstr "Änderungsdatum" + msgid "Modification Date" msgstr "Änderungsdatum" @@ -254,6 +260,12 @@ msgstr "Größe" msgid "Author(s)" msgstr "Autor(en)" +msgid "Creators" +msgstr "Bearbeiter" + +msgid "Meta Information" +msgstr "Meta-Informationen" + msgid "Parents" msgstr "Oberbegriffe" diff --git a/media/asset.py b/media/asset.py index 2b0f503..1aa927a 100644 --- a/media/asset.py +++ b/media/asset.py @@ -52,6 +52,7 @@ class MediaAsset(MediaAssetFile, ExternalFileAdapter): implements(IMediaAsset) _adapterAttributes = ExternalFileAdapter._adapterAttributes + ('modified',) + _contextAttributes = list(IMediaAsset) isMediaAsset = True diff --git a/media/browser/asset.py b/media/browser/asset.py index 978f8b9..8797b46 100644 --- a/media/browser/asset.py +++ b/media/browser/asset.py @@ -31,6 +31,7 @@ from zope.security.interfaces import Unauthorized from loops.browser.node import NodeView from loops.browser.resource import ResourceView, resource_macros from loops.common import adapted +from loops.util import _ from loops import util template = ViewPageTemplateFile('asset.pt') @@ -81,6 +82,14 @@ class MediaAssetView(ResourceView): return False return True + @Lazy + def additionalInfos(self): + mi = self.adapted.metaInfo + if not mi: + return [] + return [dict(label=_(u'Meta Information'), + value=self.renderDescription(mi))] + class MediaAssetNodeView(NodeView): diff --git a/media/interfaces.py b/media/interfaces.py index 5cafe7e..6254977 100644 --- a/media/interfaces.py +++ b/media/interfaces.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2008 Helmut Merz helmutm@cy55.de +# Copyright (c) 2011 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 @@ -22,11 +22,20 @@ Media asset management interface definitions. $Id$ """ +from zope import schema + from cybertools.media.interfaces import IMediaAsset from loops.interfaces import IExternalFile +from loops.util import _ class IMediaAsset(IMediaAsset, IExternalFile): - pass + metaInfo = schema.Text( + title=_(u'Meta Information'), + description=_(u'A text giving some background information ' + u'about a media asset, like source, rights, etc.'), + default=u'', + missing_value=u'', + required=False) diff --git a/resource.py b/resource.py index bd90bbc..274fa5e 100644 --- a/resource.py +++ b/resource.py @@ -96,6 +96,8 @@ class Resource(Image, Contained): storageName = None + metaInfo = u'' + _size = _width = _height = 0 def __init__(self, title=u''):