open up media asset type for all kinds of external files
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3205 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
b3962aba0e
commit
1c1147cda9
13 changed files with 332 additions and 16 deletions
|
@ -403,6 +403,10 @@ class BaseView(GenericView, I18NView):
|
||||||
def globalOptions(self):
|
def globalOptions(self):
|
||||||
return IOptions(self.loopsRoot)
|
return IOptions(self.loopsRoot)
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def typeOptions(self):
|
||||||
|
return IOptions(adapted(self.typeProvider))
|
||||||
|
|
||||||
# versioning
|
# versioning
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
|
|
@ -140,9 +140,16 @@
|
||||||
<containerViews
|
<containerViews
|
||||||
for="loops.interfaces.IConceptManager"
|
for="loops.interfaces.IConceptManager"
|
||||||
index="loops.ManageSite"
|
index="loops.ManageSite"
|
||||||
contents="loops.ManageSite"
|
|
||||||
add="loops.ManageSite" />
|
add="loops.ManageSite" />
|
||||||
|
|
||||||
|
<page
|
||||||
|
for="loops.interfaces.IConceptManager"
|
||||||
|
name="contents.html"
|
||||||
|
template="contents.pt"
|
||||||
|
class="cybertools.container.ordered.ContainerView"
|
||||||
|
permission="loops.ManageSite"
|
||||||
|
menu="zmi_views" title="Contents" />
|
||||||
|
|
||||||
<!-- concept -->
|
<!-- concept -->
|
||||||
|
|
||||||
<addform
|
<addform
|
||||||
|
@ -237,15 +244,21 @@
|
||||||
schema="loops.interfaces.IResourceManager"
|
schema="loops.interfaces.IResourceManager"
|
||||||
content_factory="loops.resource.ResourceManager"
|
content_factory="loops.resource.ResourceManager"
|
||||||
template="add.pt"
|
template="add.pt"
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent" />
|
||||||
/>
|
|
||||||
|
|
||||||
<containerViews
|
<containerViews
|
||||||
for="loops.interfaces.IResourceManager"
|
for="loops.interfaces.IResourceManager"
|
||||||
index="loops.ManageSite"
|
index="loops.ManageSite"
|
||||||
contents="loops.ManageSite"
|
|
||||||
add="loops.ManageSite" />
|
add="loops.ManageSite" />
|
||||||
|
|
||||||
|
<page
|
||||||
|
for="loops.interfaces.IResourceManager"
|
||||||
|
name="contents.html"
|
||||||
|
template="contents.pt"
|
||||||
|
class="cybertools.container.ordered.ContainerView"
|
||||||
|
permission="loops.ManageSite"
|
||||||
|
menu="zmi_views" title="Contents" />
|
||||||
|
|
||||||
<!-- resource in general -->
|
<!-- resource in general -->
|
||||||
|
|
||||||
<page
|
<page
|
||||||
|
|
234
browser/contents.pt
Normal file
234
browser/contents.pt
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
<html metal:use-macro="context/@@standard_macros/view"
|
||||||
|
i18n:domain="zope">
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<metal:ecmascript fill-slot="ecmascript_slot">
|
||||||
|
<metal:use use-macro="views/ajax.dojo/main" />
|
||||||
|
</metal:ecmascript>
|
||||||
|
|
||||||
|
|
||||||
|
<div metal:fill-slot="body">
|
||||||
|
|
||||||
|
<div metal:define-macro="contents"
|
||||||
|
id="body.contents">
|
||||||
|
<tal:checkmove define="dummy view/checkMoveAction">
|
||||||
|
|
||||||
|
<form name="contents" method="post" action="."
|
||||||
|
tal:attributes="action request/URL"
|
||||||
|
tal:define="container_contents view/listContentInfo">
|
||||||
|
<metal:keep-batch define-macro="keep_batch_params">
|
||||||
|
<tal:param repeat="param python:('b_page', 'b_size', 'b_overlap', 'b_orphan')">
|
||||||
|
<input type="hidden"
|
||||||
|
tal:define="value request/?param|nothing"
|
||||||
|
tal:condition="value"
|
||||||
|
tal:attributes="name param;
|
||||||
|
value value" />
|
||||||
|
</tal:param>
|
||||||
|
</metal:keep-batch>
|
||||||
|
|
||||||
|
<input type="hidden" name="type_name" value=""
|
||||||
|
tal:attributes="value request/type_name"
|
||||||
|
tal:condition="request/type_name|nothing" />
|
||||||
|
<input type="hidden" name="retitle_id" value=""
|
||||||
|
tal:attributes="value request/retitle_id"
|
||||||
|
tal:condition="request/retitle_id|nothing" />
|
||||||
|
|
||||||
|
<div class="page_error"
|
||||||
|
tal:condition="view/error"
|
||||||
|
tal:content="view/error"
|
||||||
|
i18n:translate="">
|
||||||
|
Error message
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table id="sortable" class="listing" summary="Content listing"
|
||||||
|
i18n:attributes="summary">
|
||||||
|
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="margin:0; padding:0">
|
||||||
|
<input type="checkbox" class="noborder" title="Select all items"
|
||||||
|
i18n:attributes="title"
|
||||||
|
onclick="f = document.forms.contents['ids:list'];
|
||||||
|
for (i in f) f[i].checked=this.checked;" /></th>
|
||||||
|
<th i18n:translate="">Name</th>
|
||||||
|
<th i18n:translate="">Title</th>
|
||||||
|
<th i18n:translate="">Size</th>
|
||||||
|
<th i18n:translate="">Created</th>
|
||||||
|
<th i18n:translate="">Modified</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<metal:block tal:condition="view/hasAdding">
|
||||||
|
<tr tal:define="names_required context/@@+/nameAllowed"
|
||||||
|
tal:condition="python:names_required and request.has_key('type_name')">
|
||||||
|
<td></td>
|
||||||
|
<td><input name="new_value" id="focusid" value="" /></td>
|
||||||
|
<td></td><td></td><td></td>
|
||||||
|
</tr>
|
||||||
|
</metal:block>
|
||||||
|
|
||||||
|
<metal:block tal:define="supportsRename view/supportsRename;
|
||||||
|
batch nocall:context/@@cybertools.reporter.batch;
|
||||||
|
batch python:batch.setup(container_contents)">
|
||||||
|
<tal:list repeat="item batch/items">
|
||||||
|
<tr tal:define="oddrow repeat/item/odd;
|
||||||
|
url item/url;
|
||||||
|
id_quoted item/id/url:quote"
|
||||||
|
tal:attributes="class python:oddrow and 'even' or 'odd'" >
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" class="noborder" name="ids:list"
|
||||||
|
tal:attributes="value item/id;
|
||||||
|
id item/cb_id;
|
||||||
|
checked request/ids_checked|nothing;"/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="#"
|
||||||
|
tal:attributes="href string:${url}/@@SelectedManagementView.html"
|
||||||
|
tal:content="structure item/icon|default"></a>
|
||||||
|
<span tal:condition="item/rename">
|
||||||
|
<input name="new_value:list"
|
||||||
|
tal:attributes="value item/id"/>
|
||||||
|
<input type="hidden" name="rename_ids:list" value=""
|
||||||
|
tal:attributes="value item/rename" />
|
||||||
|
</span>
|
||||||
|
<span tal:condition="not:item/rename">
|
||||||
|
<a href="#"
|
||||||
|
tal:attributes="href
|
||||||
|
string:${url}/@@SelectedManagementView.html"
|
||||||
|
tal:content="item/id">foo</a>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="#"
|
||||||
|
tal:attributes="href string:${url}/@@SelectedManagementView.html"
|
||||||
|
tal:content="item/title|default">Title</a>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td><span tal:content="item/size/sizeForDisplay|nothing"
|
||||||
|
i18n:translate="">
|
||||||
|
</span></td>
|
||||||
|
<td><span tal:define="created item/created|default"
|
||||||
|
tal:content="created"
|
||||||
|
i18n:translate=""> </span></td>
|
||||||
|
<td><span tal:define="modified item/modified|default"
|
||||||
|
tal:content="modified"
|
||||||
|
i18n:translate=""> </span></td>
|
||||||
|
</tr>
|
||||||
|
</tal:list>
|
||||||
|
<metal:nav define-macro="batch_navigation_tr">
|
||||||
|
<tr class="batch_navigation"
|
||||||
|
style="border-top: 1px solid #ccc"
|
||||||
|
tal:condition="batch/showNavigation">
|
||||||
|
<td colspan="6"
|
||||||
|
style="text-align: center">
|
||||||
|
Pages:
|
||||||
|
<metal:nav define-macro="batch_navigation"
|
||||||
|
tal:define="first batch/first/title;
|
||||||
|
previous batch/previous/title;
|
||||||
|
current batch/current/title;
|
||||||
|
next batch/next/title;
|
||||||
|
last batch/last/title;">
|
||||||
|
<a href="#"
|
||||||
|
tal:attributes="href batch/first/url;"
|
||||||
|
tal:content="first"
|
||||||
|
tal:condition="python: first != current">1</a>
|
||||||
|
<span tal:condition="python: first < previous-1">...</span>
|
||||||
|
<a href="#"
|
||||||
|
tal:attributes="href batch/previous/url;"
|
||||||
|
tal:content="batch/previous/title"
|
||||||
|
tal:condition="python: first != previous and previous != current">2</a>
|
||||||
|
<b tal:content="batch/current/title">3</b>
|
||||||
|
<a href="#"
|
||||||
|
tal:attributes="href batch/next/url;"
|
||||||
|
tal:content="batch/next/title"
|
||||||
|
tal:condition="python: last != next and next != current">3</a>
|
||||||
|
<span tal:condition="python: last > next+1">...</span>
|
||||||
|
<a href="#"
|
||||||
|
tal:attributes="href batch/last/url;"
|
||||||
|
tal:content="batch/last/title"
|
||||||
|
tal:condition="python: last != current">5</a>
|
||||||
|
</metal:nav>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</metal:nav>
|
||||||
|
</metal:block>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div tal:condition="view/normalButtons">
|
||||||
|
<input type="submit" name="container_rename_button" value="Rename"
|
||||||
|
i18n:attributes="value container-rename-button"
|
||||||
|
tal:condition="view/supportsRename" />
|
||||||
|
<input type="submit" name="container_cut_button" value="Cut"
|
||||||
|
i18n:attributes="value container-cut-button"
|
||||||
|
tal:condition="view/supportsCut" />
|
||||||
|
<input type="submit" name="container_copy_button" value="Copy"
|
||||||
|
i18n:attributes="value container-copy-button"
|
||||||
|
tal:condition="view/supportsCopy" />
|
||||||
|
<input type="submit" name="container_paste_button" value="Paste"
|
||||||
|
tal:condition="view/hasClipboardContents"
|
||||||
|
i18n:attributes="value container-paste-button" />
|
||||||
|
<input type="submit" name="container_delete_button" value="Delete"
|
||||||
|
i18n:attributes="value container-delete-button"
|
||||||
|
tal:condition="view/supportsDelete"
|
||||||
|
i18n:domain="zope" />
|
||||||
|
<div tal:condition="view/hasAdding" tal:omit-tag="">
|
||||||
|
<div tal:omit-tag=""
|
||||||
|
tal:define="adding nocall:context/@@+;
|
||||||
|
addingInfo adding/addingInfo;
|
||||||
|
has_custom_add_view adding/hasCustomAddView;
|
||||||
|
names_required adding/nameAllowed"
|
||||||
|
tal:condition="adding/isSingleMenuItem">
|
||||||
|
<input type="submit" name="container_add_button" value="Add"
|
||||||
|
i18n:attributes="value add-button"
|
||||||
|
i18n:domain="zope" />
|
||||||
|
<input type="text" name="single_new_value" id="focusid"
|
||||||
|
tal:condition="python:names_required and not has_custom_add_view"
|
||||||
|
i18n:domain="zope" />
|
||||||
|
<input type="hidden" name="single_type_name"
|
||||||
|
tal:attributes="value python:addingInfo[0]['action']" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div tal:condition="view/orderable">
|
||||||
|
<input type="submit" name="move_top" value="Top"
|
||||||
|
i18n:attributes="value container-movetop-button"
|
||||||
|
i18n:domain="zope" />
|
||||||
|
<input type="submit" name="move_up" value="Up"
|
||||||
|
i18n:attributes="value container-moveup-button"
|
||||||
|
i18n:domain="zope" />
|
||||||
|
<input type="text" size="2" name="delta" value="1" />
|
||||||
|
<input type="submit" name="move_down" value="Down"
|
||||||
|
i18n:attributes="value container-moveup-button"
|
||||||
|
i18n:domain="zope" />
|
||||||
|
<input type="submit" name="move_bottom" value="Bottom"
|
||||||
|
i18n:attributes="value container-movebottom-button"
|
||||||
|
i18n:domain="zope" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div tal:condition="view/specialButtons">
|
||||||
|
<input type="submit" value="Apply"
|
||||||
|
i18n:attributes="value container-apply-button" />
|
||||||
|
<input type="submit" name="container_cancel_button" value="Cancel"
|
||||||
|
i18n:attributes="value container-cancel-button" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</tal:checkmove>
|
||||||
|
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
if (document.forms.contents.new_value)
|
||||||
|
document.forms.contents.new_value.focus();
|
||||||
|
//-->
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -283,6 +283,7 @@ class CreateObjectForm(ObjectForm):
|
||||||
def adapted(self):
|
def adapted(self):
|
||||||
ad = self.typeInterface(Resource())
|
ad = self.typeInterface(Resource())
|
||||||
ad.storageName = 'unknown' # hack for file objects: don't try to retrieve data
|
ad.storageName = 'unknown' # hack for file objects: don't try to retrieve data
|
||||||
|
ad.__type__ = adapted(self.typeConcept)
|
||||||
return ad
|
return ad
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
|
|
@ -58,6 +58,9 @@ from loops.versioning.interfaces import IVersionable
|
||||||
from loops.util import _
|
from loops.util import _
|
||||||
|
|
||||||
|
|
||||||
|
resource_macros = ViewPageTemplateFile('resource_macros.pt')
|
||||||
|
|
||||||
|
|
||||||
class CustomFileWidget(FileWidget):
|
class CustomFileWidget(FileWidget):
|
||||||
|
|
||||||
def hasInput(self):
|
def hasInput(self):
|
||||||
|
@ -103,7 +106,8 @@ class MediaAssetEditForm(EditForm):
|
||||||
|
|
||||||
class ResourceView(BaseView):
|
class ResourceView(BaseView):
|
||||||
|
|
||||||
template = ViewPageTemplateFile('resource_macros.pt')
|
#template = ViewPageTemplateFile('resource_macros.pt')
|
||||||
|
template = resource_macros
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def icon(self):
|
def icon(self):
|
||||||
|
|
|
@ -97,6 +97,7 @@ class AdapterBase(object):
|
||||||
_textIndexAttributes = ()
|
_textIndexAttributes = ()
|
||||||
|
|
||||||
__is_dummy__ = False
|
__is_dummy__ = False
|
||||||
|
__type__ = None
|
||||||
|
|
||||||
languageInfo = None
|
languageInfo = None
|
||||||
|
|
||||||
|
@ -138,6 +139,13 @@ class AdapterBase(object):
|
||||||
def name(self):
|
def name(self):
|
||||||
return getName(self.context)
|
return getName(self.context)
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def type(self):
|
||||||
|
return self.__type__ or self.getType()
|
||||||
|
|
||||||
|
def getType(self):
|
||||||
|
return adapted(self.context.getType())
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def uid(self):
|
def uid(self):
|
||||||
return util.getUidForObject(self.context)
|
return util.getUidForObject(self.context)
|
||||||
|
|
|
@ -33,7 +33,7 @@ from cybertools.meta.config import GlobalOptions as BaseGlobalOptions
|
||||||
from cybertools.meta.interfaces import IOptions
|
from cybertools.meta.interfaces import IOptions
|
||||||
from cybertools.meta.namespace import Executor, ExecutionError
|
from cybertools.meta.namespace import Executor, ExecutionError
|
||||||
from cybertools.typology.interfaces import IType
|
from cybertools.typology.interfaces import IType
|
||||||
from loops.interfaces import ILoops, ILoopsObject
|
from loops.interfaces import ILoops, ILoopsObject, ITypeConcept
|
||||||
#from loops.query import IQueryConcept
|
#from loops.query import IQueryConcept
|
||||||
from loops.expert.concept import IQueryConcept
|
from loops.expert.concept import IQueryConcept
|
||||||
from loops import util
|
from loops import util
|
||||||
|
@ -91,6 +91,11 @@ class LoopsOptions(Options):
|
||||||
raise ExecutionError('\n' + rc)
|
raise ExecutionError('\n' + rc)
|
||||||
|
|
||||||
|
|
||||||
|
class TypeOptions(LoopsOptions):
|
||||||
|
|
||||||
|
adapts(ITypeConcept)
|
||||||
|
|
||||||
|
|
||||||
class QueryOptions(LoopsOptions):
|
class QueryOptions(LoopsOptions):
|
||||||
|
|
||||||
adapts(IQueryConcept)
|
adapts(IQueryConcept)
|
||||||
|
|
|
@ -12,6 +12,11 @@
|
||||||
<allow interface="cybertools.meta.interfaces.IOptions" />
|
<allow interface="cybertools.meta.interfaces.IOptions" />
|
||||||
</zope:class>
|
</zope:class>
|
||||||
|
|
||||||
|
<zope:adapter factory="loops.config.base.TypeOptions" trusted="True" />
|
||||||
|
<zope:class class="loops.config.base.TypeOptions">
|
||||||
|
<allow interface="cybertools.meta.interfaces.IOptions" />
|
||||||
|
</zope:class>
|
||||||
|
|
||||||
<zope:adapter factory="loops.config.base.QueryOptions" trusted="True" />
|
<zope:adapter factory="loops.config.base.QueryOptions" trusted="True" />
|
||||||
<zope:class class="loops.config.base.QueryOptions">
|
<zope:class class="loops.config.base.QueryOptions">
|
||||||
<allow interface="cybertools.meta.interfaces.IOptions" />
|
<allow interface="cybertools.meta.interfaces.IOptions" />
|
||||||
|
|
|
@ -763,8 +763,13 @@ class IExternalFile(IFile):
|
||||||
missing_value='',
|
missing_value='',
|
||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
externalAddress = Attribute('The full address for accessing the object '
|
externalAddress = schema.BytesLine(
|
||||||
'on the external storage, e.g. a filename or path.')
|
title=_(u'External Address'),
|
||||||
|
description=_(u'The full address for accessing the object '
|
||||||
|
'on the external storage, e.g. a filename or path.'),
|
||||||
|
default='',
|
||||||
|
missing_value='',
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
|
||||||
class IAddressableExternalFile(IExternalFile):
|
class IAddressableExternalFile(IExternalFile):
|
||||||
|
|
|
@ -28,7 +28,7 @@ from zope.app.pagetemplate import ViewPageTemplateFile
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
|
|
||||||
from loops.browser.node import NodeView
|
from loops.browser.node import NodeView
|
||||||
from loops.browser.resource import ResourceView
|
from loops.browser.resource import ResourceView, resource_macros
|
||||||
from loops.common import adapted
|
from loops.common import adapted
|
||||||
from loops import util
|
from loops import util
|
||||||
|
|
||||||
|
@ -39,7 +39,11 @@ class MediaAssetView(ResourceView):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def macro(self):
|
def macro(self):
|
||||||
return template.macros['asset']
|
#return template.macros['asset']
|
||||||
|
if 'image/' in self.context.contentType:
|
||||||
|
return template.macros['asset']
|
||||||
|
else:
|
||||||
|
return resource_macros.macros['download']
|
||||||
|
|
||||||
def show(self, useAttachment=False):
|
def show(self, useAttachment=False):
|
||||||
versionId = self.request.get('v')
|
versionId = self.request.get('v')
|
||||||
|
|
22
resource.py
22
resource.py
|
@ -224,6 +224,11 @@ class Resource(Image, Contained):
|
||||||
def getSize(self):
|
def getSize(self):
|
||||||
if self._size:
|
if self._size:
|
||||||
return self._size
|
return self._size
|
||||||
|
size = getattr(adapted(self), 'size', None)
|
||||||
|
if size is None:
|
||||||
|
return len(adapted(self).data)
|
||||||
|
return size
|
||||||
|
|
||||||
tp = IType(self, None)
|
tp = IType(self, None)
|
||||||
if tp is not None:
|
if tp is not None:
|
||||||
ti = tp.typeInterface
|
ti = tp.typeInterface
|
||||||
|
@ -357,9 +362,15 @@ class ExternalFileAdapter(FileAdapter):
|
||||||
storageParams = property(getStorageParams, setStorageParams)
|
storageParams = property(getStorageParams, setStorageParams)
|
||||||
|
|
||||||
def getExternalAddress(self):
|
def getExternalAddress(self):
|
||||||
return getattr(self.context, '_externalAddress', self.context.__name__)
|
return getattr(self.context, '_externalAddress', None) or self.context.__name__
|
||||||
def setExternalAddress(self, addr):
|
def setExternalAddress(self, addr):
|
||||||
self.context._externalAddress = addr
|
self.context._externalAddress = addr
|
||||||
|
if addr:
|
||||||
|
data = self.data
|
||||||
|
self.context._size = len(data)
|
||||||
|
contentType = guess_content_type(addr, self.data[:100])
|
||||||
|
if contentType:
|
||||||
|
self.contentType = contentType[0]
|
||||||
externalAddress = property(getExternalAddress, setExternalAddress)
|
externalAddress = property(getExternalAddress, setExternalAddress)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -372,12 +383,14 @@ class ExternalFileAdapter(FileAdapter):
|
||||||
def setData(self, data):
|
def setData(self, data):
|
||||||
storageParams = self.storageParams
|
storageParams = self.storageParams
|
||||||
storageName = self.storageName
|
storageName = self.storageName
|
||||||
|
externalAddress = self.externalAddress
|
||||||
storage = component.getUtility(IExternalStorage, name=storageName)
|
storage = component.getUtility(IExternalStorage, name=storageName)
|
||||||
storage.setData(self.externalAddress, data, params=storageParams)
|
storage.setData(self.externalAddress, data, params=storageParams)
|
||||||
self.context._size = len(data)
|
self.context._size = len(data)
|
||||||
# remember storage settings:
|
# remember storage settings:
|
||||||
self.storageParams = storageParams
|
self.storageParams = storageParams
|
||||||
self.storageName = storageName
|
self.storageName = storageName
|
||||||
|
self.externalAddress = externalAddress
|
||||||
|
|
||||||
def getData(self):
|
def getData(self):
|
||||||
if self.storageName in ('unknown', None): # object not set up yet
|
if self.storageName in ('unknown', None): # object not set up yet
|
||||||
|
@ -387,6 +400,13 @@ class ExternalFileAdapter(FileAdapter):
|
||||||
|
|
||||||
data = property(getData, setData)
|
data = property(getData, setData)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def size(self):
|
||||||
|
if self.storageName in ('unknown', None): # object not set up yet
|
||||||
|
return ''
|
||||||
|
storage = component.getUtility(IExternalStorage, name=self.storageName)
|
||||||
|
return storage.getSize(self.externalAddress, params=self.storageParams)
|
||||||
|
|
||||||
|
|
||||||
class AddressableExternalFileAdapter(ExternalFileAdapter):
|
class AddressableExternalFileAdapter(ExternalFileAdapter):
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,10 @@ $Id$
|
||||||
from zope.component import adapts
|
from zope.component import adapts
|
||||||
|
|
||||||
from cybertools.composer.schema.factory import SchemaFactory
|
from cybertools.composer.schema.factory import SchemaFactory
|
||||||
|
from loops.common import adapted
|
||||||
from loops.interfaces import IResourceAdapter, IFile, INote, IAddressableExternalFile
|
from loops.interfaces import IResourceAdapter, IFile, INote, IAddressableExternalFile
|
||||||
|
from cybertools.meta.interfaces import IOptions
|
||||||
|
from cybertools.typology.interfaces import IType
|
||||||
|
|
||||||
|
|
||||||
class ResourceSchemaFactory(SchemaFactory):
|
class ResourceSchemaFactory(SchemaFactory):
|
||||||
|
@ -47,10 +50,19 @@ class FileSchemaFactory(SchemaFactory):
|
||||||
|
|
||||||
def __call__(self, interface, **kw):
|
def __call__(self, interface, **kw):
|
||||||
schema = super(FileSchemaFactory, self).__call__(interface, **kw)
|
schema = super(FileSchemaFactory, self).__call__(interface, **kw)
|
||||||
if 'request' in kw:
|
options = IOptions(self.context.type)
|
||||||
principal = kw['request'].principal
|
hide = options('hide_fields') or []
|
||||||
if not principal or principal.id != 'rootadmin':
|
show = options('show_fields') or []
|
||||||
schema.fields.remove('contentType')
|
for f in ('contentType', 'externalAddress',):
|
||||||
|
if f in schema.fields and f not in show:
|
||||||
|
schema.fields.remove(f)
|
||||||
|
for f in hide:
|
||||||
|
if f in schema.fields:
|
||||||
|
schema.fields.remove(f)
|
||||||
|
#if 'request' in kw:
|
||||||
|
# principal = kw['request'].principal
|
||||||
|
# if not principal or principal.id != 'rootadmin':
|
||||||
|
# schema.fields.remove('contentType')
|
||||||
return schema
|
return schema
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ from loops.browser.node import ViewPropertiesConfigurator
|
||||||
from loops.common import NameChooser
|
from loops.common import NameChooser
|
||||||
from loops.concept import Concept
|
from loops.concept import Concept
|
||||||
from loops.concept import IndexAttributes as ConceptIndexAttributes
|
from loops.concept import IndexAttributes as ConceptIndexAttributes
|
||||||
from loops.config.base import GlobalOptions, LoopsOptions, QueryOptions
|
from loops.config.base import GlobalOptions, LoopsOptions, QueryOptions, TypeOptions
|
||||||
from loops.interfaces import ILoopsObject, IIndexAttributes
|
from loops.interfaces import ILoopsObject, IIndexAttributes
|
||||||
from loops.interfaces import IDocument, IFile, ITextDocument
|
from loops.interfaces import IDocument, IFile, ITextDocument
|
||||||
from loops.layout.base import LayoutNode
|
from loops.layout.base import LayoutNode
|
||||||
|
@ -132,6 +132,7 @@ class TestSite(object):
|
||||||
component.provideAdapter(BaseSecuritySetter)
|
component.provideAdapter(BaseSecuritySetter)
|
||||||
component.provideAdapter(LoopsOptions)
|
component.provideAdapter(LoopsOptions)
|
||||||
component.provideAdapter(QueryOptions)
|
component.provideAdapter(QueryOptions)
|
||||||
|
component.provideAdapter(TypeOptions)
|
||||||
component.provideUtility(GlobalOptions())
|
component.provideUtility(GlobalOptions())
|
||||||
|
|
||||||
component.provideAdapter(Instance)
|
component.provideAdapter(Instance)
|
||||||
|
|
Loading…
Add table
Reference in a new issue