dataobject.py 9.62 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# copyright 2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr -- mailto:contact@logilab.fr
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 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 Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""cubicweb-seda views for data objects (BinaryDataObject / PhysicalDataObject)"""

18
19
import json

20
21
from logilab.mtconverter import xml_escape

22
from cubicweb import tags
23
24
from cubicweb.predicates import match_form_params, is_instance
from cubicweb.web.views import uicfg, tabs
25
26
27

from cubes.relationwidget import views as rwdg

28
from cubes.seda.xsd2yams import RDEF_CONSTRAINTS
29
30
from cubes.seda.views import rtags_from_xsd_element, add_subobject_link, parent_and_container
from cubes.seda.views import viewlib
31

32
33
_ = unicode

34
35
36
pvs = uicfg.primaryview_section
rec = uicfg.reledit_ctrl
afs = uicfg.autoform_section
37
38
affk = uicfg.autoform_field_kwargs

39
40
41
42
43
44
45
46
47

class ContainedRelationFacetWidget(rwdg.RelationFacetWidget):

    def trigger_search_url(self, entity, url_params):
        """Overriden to add information about who is the container

        This information will be used later for proper vocabulary computation.
        """
        # first retrieve the container entity
48
        _, container = parent_and_container(entity)
49
        # and put it as an extra url param
50
51
        if container is not None:
            url_params['container'] = unicode(container.eid)
52
53
54
55
56
57
        return super(ContainedRelationFacetWidget, self).trigger_search_url(entity, url_params)


class ContainedSearchForRelatedEntitiesView(rwdg.SearchForRelatedEntitiesView):
    __select__ = rwdg.SearchForRelatedEntitiesView.__select__ & match_form_params('container')

58
59
    has_creation_form = False

60
61
62
63
64
65
66
67
68
69
70
71
72
73
    def linkable_rset(self):
        """Return rset of entities to be displayed as possible values for the
        edited relation. You may want to override this.
        """
        entity = self.compute_entity()
        rtype, tetype, role = self.rdef
        rdef = entity.e_schema.rdef(rtype, role, tetype)
        assert len(rdef.constraints) == 1 and 'S container AT' in rdef.constraints[0].expression
        baserql = rdef.constraints[0].expression
        baserql.replace('S container AT', 'AT eid %(at)s')
        rql = 'Any O WHERE ' + baserql
        return self._cw.execute(rql, {'at': int(self._cw.form['container'])})


74
75
# hide some relation from autoform because of limitation of _container_eid
afs.tag_object_of(('*', 'seda_compressed', 'SEDABinaryDataObject'), 'main', 'hidden')
76
pvs.tag_object_of(('*', 'seda_compressed', 'SEDABinaryDataObject'), 'attributes')
77
78
79
80
81
82
83
84
85
rec.tag_object_of(('*', 'seda_compressed', 'SEDABinaryDataObject'),
                  {'rvid': 'seda.reledit.complexlink',
                   'novalue_label': _('<unauthorized>')})

rec.tag_subject_of(('SEDABinaryDataObject', 'seda_alt_binary_data_object_attachment', '*'),
                   {'rvid': 'seda.reledit.alternative',
                    'novalue_label': _('<unauthorized>')})

for etype in ('SEDABinaryDataObject', 'SEDAPhysicalDataObject'):
86
87
    afs.tag_object_of(('*', 'seda_data_object_version_from', etype), 'main', 'hidden')
    pvs.tag_object_of(('*', 'seda_data_object_version_from', etype), 'attributes')
88
89
90
91
92
    rec.tag_object_of(('*', 'seda_data_object_version_from', etype),
                      {'rvid': 'seda.reledit.complexlink',
                       'novalue_label': _('<unauthorized>')})


93
94
def uri_cardinality_vocabulary(form, field):
    req = form._cw
95
96
97
98
99
100
101
102
103
104
    if form.edited_entity.has_eid():
        parent_type = form.edited_entity.cw_adapt_to('IContained').parent.cw_etype
    else:
        try:
            # inlined creation form
            parent_type = json.loads(req.form['arg'][1])
        except KeyError:
            # edition through reledit
            parent_eid = req.form['eid']
            parent_type = req.describe(int(parent_eid))[0]
105
106
107
108
109
110
111
112
    if parent_type in ('SEDABinaryDataObject', 'SEDAAltBinaryDataObjectAttachment'):
        return [u'1']
    return [u'0..1', u'1']

affk.tag_attribute(('SEDAUri', 'user_cardinality'),
                   {'choices': uri_cardinality_vocabulary})


113
114
115
116
117
118
119
for key, rql_expr in RDEF_CONSTRAINTS.items():
    if 'S container AT' in rql_expr:
        try:
            etype, rtype = key
        except ValueError:
            etype = '*'
            rtype = key
120
121
        if rtype == 'seda_rule':
            continue  # managed in mgmt_rules module
122
123
        affk.tag_subject_of((etype, rtype, '*'),
                            {'widget': ContainedRelationFacetWidget(dialog_options={'width': 800})})
124
125
126
127
128
129


class BinaryDataObjectTabbedPrimaryView(tabs.TabbedPrimaryView):
    __select__ = tabs.TabbedPrimaryView.__select__ & is_instance('SEDABinaryDataObject')
    tabs = [
        'main_tab',
130
        _('seda_bdo_format_identification'),
131
        _('seda_bdo_file_information'),
132
        _('seda_do_relations'),
133
134
135
    ]


136
137
138
139
140
141
142
143
class BinaryDataObjectFormatIdentificationTab(tabs.PrimaryTab):
    """Display format identification information of a binary data object"""
    __regid__ = 'seda_bdo_format_identification'
    __select__ = tabs.PrimaryTab.__select__ & is_instance('SEDABinaryDataObject')

    rsection, display_ctrl = rtags_from_xsd_element('SEDABinaryDataObject', 'FormatIdentification')


144
145
146
147
148
149
150
151
class BinaryDataObjectFileInfoTab(tabs.PrimaryTab):
    """Display file information of a binary data object"""
    __regid__ = 'seda_bdo_file_information'
    __select__ = tabs.PrimaryTab.__select__ & is_instance('SEDABinaryDataObject')

    rsection, display_ctrl = rtags_from_xsd_element('SEDABinaryDataObject', 'FileInfo')


152
153
154
155
class PhysicalDataObjectTabbedPrimaryView(tabs.TabbedPrimaryView):
    __select__ = tabs.TabbedPrimaryView.__select__ & is_instance('SEDAPhysicalDataObject')
    tabs = [
        'main_tab',
156
        _('seda_pdo_dimensions'),
157
        _('seda_do_relations'),
158
    ]
159
160


161
162
163
164
165
166
167
168
class PhysicalDataObjectDimensionsTab(tabs.PrimaryTab):
    """Display physical dimensions of a physical data object"""
    __regid__ = 'seda_pdo_dimensions'
    __select__ = tabs.PrimaryTab.__select__ & is_instance('SEDAPhysicalDataObject')

    rsection, display_ctrl = rtags_from_xsd_element('SEDAPhysicalDataObject', 'PhysicalDimensions')


Sylvain Thénault's avatar
Sylvain Thénault committed
169
class DataObjectRelationsTab(tabs.PrimaryTab):
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
    """Display relations of a binary or physical data object"""
    __regid__ = 'seda_do_relations'
    __select__ = tabs.PrimaryTab.__select__ & is_instance('SEDABinaryDataObject',
                                                          'SEDAPhysicalDataObject')

    def entity_call(self, entity):
        rschema = self._cw.vreg.schema.rschema('seda_relationship')
        if rschema.has_perm(self._cw, 'add', toeid=entity.eid):
            urlparams = {'__redirectparams': 'tab=' + self.__regid__}
            self.w(add_subobject_link(entity, 'seda_relationship', 'object', urlparams,
                                      msg=self._cw._('add a SEDARelationship'),
                                      klass='btn btn-success pull-right'))
            self.w(tags.div(klass='clearfix'))
        rset = entity.related('seda_relationship', 'object')
        if rset:
            self._cw.view('list', rset=rset, parent=entity, w=self.w, tabid=self.__regid__,
                          subvid='seda.listitem')


class RelationshipBusinessValueLinkEntityView(viewlib.BusinessValueLinkEntityView):
    __select__ = viewlib.BusinessValueLinkEntityView.__select__ & is_instance('SEDARelationship')

192
193
194
195
196
197
    def entity_value(self, entity):
        target = entity.seda_target[0] if entity.seda_target else None
        if target:
            value = tags.a(target.dc_title(), href=target.absolute_url())
        else:
            value = xml_escape(self._cw._('<no data-object specified>'))
198
199
        if entity.seda_type_relationship:
            concept = entity.seda_type_relationship[0]
200
            msg = self._cw._(', of relationship type %s') % concept.label()
201
        else:
202
203
204
            msg = self._cw._(', no relationship type specified')
        value += xml_escape(msg)
        return value
205
206


Sylvain Thénault's avatar
Sylvain Thénault committed
207
class AttachmentBusinessValueEntityView(viewlib.BusinessValueEntityView):
208
209
210
    __select__ = is_instance('SEDAAttachment')

    def entity_call(self, entity):
Sylvain Thénault's avatar
Sylvain Thénault committed
211
        super(AttachmentBusinessValueEntityView, self).entity_call(entity)
212
213
214
215
216
217
218
219
220
221
222
        attributes = []
        for rtype in ('reverse_seda_uri', 'reverse_seda_filename'):
            values = getattr(entity, rtype)
            if values:
                value = values[0]
                display = value.dc_type()
                if value.user_cardinality == '0..1':
                    display += ' <i>%s</i>' % self._cw._('optional')
                attributes.append(display)
        if attributes:
            self.w(self._cw._(' (attributes: %s)') % ', '.join(attributes))
223
224
225
226
227
228
229
230
231
232
233
234
235


class UnitBusinessValueEntityView(viewlib.BusinessValueEntityView):
    __select__ = is_instance('SEDAWidth', 'SEDAHeight', 'SEDADepth', 'SEDAShape',
                             'SEDADiameter', 'SEDALength', 'SEDAThickness', 'SEDAWeight')

    def entity_call(self, entity):
        super(UnitBusinessValueEntityView, self).entity_call(entity)
        if entity.seda_unit:
            unit = self._cw._('unit: {0}').format(entity.seda_unit[0].label())
        else:
            unit = self._cw._('<no unit specified>')
        self.w(u' (%s)' % xml_escape(unit))