source: telemeta/models/dublincore.py @ 66bbeee

cremcrem2crem3devdev2diademsdj1.6feature/breadcrumbsfeature/ts-0.5feature/ts-0.5.4feature/writecacheformagenericinstru_searchlamlam2mapsv3mergenlivemultiproductionrelease/1.4.4sabiodsearchsecurityserversocialstoragetelecastertestvideo
Last change on this file since 66bbeee was 66bbeee, checked in by yomguy <yomguy@…>, 3 years ago

fix item public_access

  • Property mode set to 100644
File size: 10.2 KB
Line 
1# -*- coding: utf-8 -*-
2# Copyright (C) 2007 Samalyse SARL
3
4# This software is a computer program whose purpose is to backup, analyse,
5# transcode and stream any audio content with its metadata over a web frontend.
6
7# This software is governed by the CeCILL  license under French law and
8# abiding by the rules of distribution of free software.  You can  use,
9# modify and/ or redistribute the software under the terms of the CeCILL
10# license as circulated by CEA, CNRS and INRIA at the following URL
11# "http://www.cecill.info".
12
13# As a counterpart to the access to the source code and  rights to copy,
14# modify and redistribute granted by the license, users are provided only
15# with a limited warranty  and the software's author,  the holder of the
16# economic rights,  and the successive licensors  have only  limited
17# liability.
18
19# In this respect, the user's attention is drawn to the risks associated
20# with loading,  using,  modifying and/or developing or reproducing the
21# software by the user in light of its specific status of free software,
22# that may mean  that it is complicated to manipulate,  and  that  also
23# therefore means  that it is reserved for developers  and  experienced
24# professionals having in-depth computer knowledge. Users are therefore
25# encouraged to load and test the software's suitability as regards their
26# requirements in conditions enabling the security of their systems and/or
27# data to be ensured and,  more generally, to use and operate it in the
28# same conditions as regards security.
29
30# The fact that you are presently reading this means that you have had
31# knowledge of the CeCILL license and that you accept its terms.
32#
33# Author: Olivier Guilyardi <olivier@samalyse.com>
34
35from telemeta.models.core import Duration
36from telemeta.models.media import MediaItem, MediaCollection, MediaItemAnalysis
37from django.contrib.sites.models import Site
38from django.conf import settings
39
40
41class Resource(object):
42    "Represent a Dublin Core resource"
43
44    def __init__(self, *args):
45        self.elements = []
46        self.add(*args)
47
48    def flatten(self):
49        """Convert the resource to a dictionary with element names as keys.
50
51        Warnings:
52        - refinements are lost during this conversion,
53        - if there are several occurences of the same element, only the first is
54        used, others are lost.
55        - all values are converted to strings
56        """
57        result = {}
58        for element in self.elements:
59            if not result.has_key(element.name):
60                result[element.name] = unicode(element.value)
61        return result
62
63    def to_list(self):
64        """Convert the resource to unqualified dublin core, as a list of the form:
65           [(key, value), ...]"""
66        result = []
67        for element in self.elements:
68            result.append((element.name, unicode(element.value)))
69        return result
70
71    def add(self, *elements):
72        for e in elements:
73            if isinstance(e, Element):
74                if not e in self.elements:
75                    self.elements.append(e)
76            else:
77                try:
78                    iter(e)
79                except TypeError: 
80                    raise Exception("add() only accepts elements or sequences of elements")
81
82                self.add(*e)
83
84    def __unicode__(self):
85        dump = u''
86        for e in self.elements:
87            key = unicode(e.name)
88            if e.refinement:
89                key += u'.' + unicode(e.refinement)
90            dump += u'%s:\t%s\n' % (key, unicode(e.value))
91        return dump           
92           
93
94class Element(object):
95    "Represent a Dublin Core element"
96
97    def __init__(self, name, value=None, refinement=None, related=None):
98        self.name = name
99        self.value = value
100        self.refinement = refinement
101        self.related = related
102
103    def __eq__(self, other):
104        return self.name == other.name and self.value == other.value and self.refinement == self.refinement
105
106    def __ne__(self, other):
107        return not (self == other)
108
109    @staticmethod
110    def multiple(name, values, refinement=None):
111        elements = []
112        if values:
113            for v in values:
114                elements.append(Element(name, v, refinement))
115        return elements
116
117class Date(Element):
118    "Dublin Core date element formatted according to W3C-DTF or DCMI Period"
119
120    def __init__(self, start, end=None, refinement=None):
121        value = ''
122        if start:
123            value = start
124        elif end:
125            value = end
126        else:
127            value = ''
128        if isinstance(value, long):
129            # start is a year
130            value = unicode(value) + '-01-01T00:00:00Z'
131        elif value:
132            value = value.strftime('%Y-%m-%dT%H:%M:%SZ')
133           
134        super(Date, self).__init__('date', value, refinement)           
135
136def media_access_rights(media):
137    if media.public_access == 'full':
138        return 'public'
139    if media.public_access == 'metadata':
140        return 'restricted'
141    return 'private'
142
143def media_identifier(media):
144    sites = Site.objects.all()
145    domain = sites[0].domain
146    return 'http://' + domain + '/' + media.element_type + 's/' + unicode(media.id)
147
148def express_collection(collection):
149    "Express a collection as a Dublin Core resource"
150
151    if collection.collector:
152        creator = (Element('creator', collection.collector), 
153                   Element('contributor', collection.creator))
154    else:                       
155        creator = Element('creator', collection.creator)
156
157    duration = max(collection.approx_duration, collection.computed_duration())
158    parts = []
159    for item in collection.items.all():
160        id = media_identifier(item)
161        if id:
162            parts.append(Element('relation', id, 'hasPart', item))
163
164    resource = Resource(
165        Element('identifier',       media_identifier(collection), related=collection),
166        Element('type',             'Collection'),
167        Element('title',            collection.title),
168        Element('title',            collection.alt_title),
169        creator,
170        Element('contributor',      collection.metadata_author),
171        Element.multiple('subject', settings.TELEMETA_SUBJECTS),
172        Element('publisher',        collection.publisher),
173        Element('publisher',        settings.TELEMETA_ORGANIZATION),
174        Date(collection.recorded_from_year, collection.recorded_to_year, refinement='created'),
175        Date(collection.year_published, refinement='issued'),
176        Element('rights',           collection.legal_rights, 'license'),
177        Element('rights',           media_access_rights(collection), 'accessRights'),
178        Element('format',           duration, 'extent'),
179        Element('format',           collection.physical_format, 'medium'),
180        parts
181    )
182
183    return resource
184
185def express_item(item):
186    "Express a media item as a Dublin Core resource"
187
188    if item.collector:
189        creator = (Element('creator', item.collector),
190                   Element('contributor', item.collection.creator))
191    elif item.collection.collector:                   
192        creator = (Element('creator', item.collection.collector),
193                   Element('contributor', item.collection.creator))
194    else:
195        creator = Element('creator', item.collection.creator)
196       
197    if item.recorded_from_date:
198        date = Date(item.recorded_from_date, item.recorded_to_date, refinement='created')
199    else:
200        date = Date(item.collection.recorded_from_year, item.collection.recorded_to_year, refinement='created'),
201       
202    if item.title:
203        title = item.title
204    else:
205        title = item.collection.title
206        if item.track:
207            title += u' - ' + item.track
208   
209    try:
210        analysis = MediaItemAnalysis(item=item, analyzer_id='mime_type')
211        mime_type = analysis.value
212    except:
213        mime_type = 'unknown'
214
215    resource = Resource(
216        Element('identifier',       media_identifier(item), related=item),
217        Element('type',             'Sound'),
218        Element('title',            title),
219        Element('title',            item.alt_title),
220        creator,
221        Element('contributor',      item.collection.metadata_author),
222        Element.multiple('subject', settings.TELEMETA_SUBJECTS),
223        Element.multiple('subject', item.keywords()),
224        Element('description',      item.context_comment, 'abstract'),
225        Element('publisher',        item.collection.publisher),
226        Element('publisher',        settings.TELEMETA_ORGANIZATION),
227        date,
228        Date(item.collection.year_published, refinement='issued'),
229        Element.multiple('coverage', item.location and item.location.fullnames(), 'spatial'),
230        Element('coverage',         item.location_comment, 'spatial'),
231        Element('rights',           item.collection.legal_rights, 'license'),
232        Element('rights',           media_access_rights(item.collection), 'accessRights'),
233        Element('format',           max(item.approx_duration, item.computed_duration()), 'extent'),
234        Element('format',           item.collection.physical_format, 'medium'),
235        Element('format',           mime_type, 'MIME type'),
236        Element('relation',         media_identifier(item.collection), 'isPartOf', item.collection)
237    )
238
239    return resource
240   
241def express_resource(res):
242    if isinstance(res, MediaItem):
243        return express_item(res)
244    elif isinstance(res, MediaCollection):
245        return express_collection(res)
246
247    raise Exception("Invalid resource type")       
248
249def lookup_resource(media_id):
250    try:
251        type, code = media_id.split(':', 1)
252    except ValueError:
253        raise MalformedMediaIdentifier("Media identifier must be in type:code format")
254   
255    if (type == 'collection'):
256        try:
257            return MediaCollection.objects.get(code=code)
258        except MediaCollection.DoesNotExist:
259            return None
260    elif (type == 'item'):
261        try:
262            return MediaItem.objects.get(code=code)
263        except MediaItem.DoesNotExist:
264            try:
265                return MediaItem.objects.get(old_code=code)
266            except MediaItem.DoesNotExist:
267                return None
268    else:
269        raise MalformedMediaIdentifier("No such type in media identifier: " + type)
270   
271class MalformedMediaIdentifier(Exception):
272    pass
Note: See TracBrowser for help on using the repository browser.