[(dublin core element, element value), ...],
change time
)
- or None if the record doesn't exist.
+ or None if the record doesn't exist. In case the id isn't wellformed
+ a BadArgumentError should be raised.
The dublin core data must contain an 'identifier' element, which is the same
as the id parameter."""
def get_record(self, id):
"""Append GetRecord result"""
- record = self.datasource.get_record(id)
+ try:
+ record = self.datasource.get_record(id)
+ except BadArgumentError, e:
+ self.error('badArgument', e.message)
+ return
if not record:
self.error('idDoesNotExist')
else:
except AttributeError:
# Apparently no free/unlink method in libxml2dom
pass
+
+class BadArgumentError(Exception):
+ pass
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license and that you accept its terms.
-from telemeta.models import MediaCollection, MediaItem, Revision
+from telemeta.models import MediaCollection, MediaItem, Revision, dublincore
+from telemeta.interop.oai import BadArgumentError
from datetime import datetime
class TelemetaOAIDataSource(object):
except IndexError:
return datetime.now()
- def prepare_record(self, type, record):
+ def prepare_record(self, record):
ctime = record.get_revision().time
- dc = []
- _dc = record.to_dublincore().to_list()
- for k, v in _dc:
- if k == 'identifier':
- dc.append((k, type + ':' + v)) # FIXME: type prepended by CREM model
- else:
- dc.append((k, v))
- return (dc, ctime)
+ return dublincore.express_resource(record).to_list(), ctime
def get_record(self, id):
"""Return a specific record"""
try:
- type, id = id.split(':')
- except ValueError:
- return None
-
- #FIXME: search by code
- if (type == 'collection'):
- try:
- record = MediaCollection.objects.get(id=id)
- except MediaCollection.DoesNotExist:
- return None
- elif (type == 'item'):
- try:
- #FIXME: also search by old_code if code is not found
- record = MediaItem.objects.get(id=id)
- except MediaItem.DoesNotExist:
- return None
- else:
- return None
-
- return self.prepare_record(type, record)
-
+ record = dublincore.lookup_resource(id)
+ except dublincore.MalformedMediaIdentifier, e:
+ raise BadArgumentError(e.message)
+ return record and self.prepare_record(record)
def count_records(self, from_time = None, until_time = None):
"""Must return the number of records between (optional) from and until change time."""
if (offset < nitems):
set = query[offset:offset + limit]
for record in set:
- result.append(self.prepare_record('item', record))
+ result.append(self.prepare_record(record))
limit -= len(set)
offset = 0
else:
query = MediaCollection.objects.by_change_time(from_time, until_time)
set = query[offset:offset + limit]
for record in set:
- result.append(self.prepare_record('collection', record))
+ result.append(self.prepare_record(record))
return result
def _by_change_time(self, type, from_time = None, until_time = None):
"Search between two revision dates"
- where = ["element_type = '%s'" % type]
+ table = self.model._meta.db_table
+ where = []
if from_time:
- where.append("time >= '%s'" % from_time.strftime('%Y-%m-%d %H:%M:%S'))
+ where.append("revisions.time >= '%s'" % from_time.strftime('%Y-%m-%d %H:%M:%S'))
if until_time:
- where.append("time <= '%s'" % until_time.strftime('%Y-%m-%d %H:%M:%S'))
- return self.extra(
- where = ["id IN (SELECT DISTINCT element_id FROM revisions WHERE %s)" % " AND ".join(where)]);
+ where.append("revisions.time <= '%s'" % until_time.strftime('%Y-%m-%d %H:%M:%S'))
+
+ qs = self
+ if where:
+ where.extend(["revisions.element_type = '%s'" % type, "revisions.element_id = %s.id" % table])
+ qs = qs.extra(where = [" AND ".join(where)],
+ tables = ['revisions']).distinct()
+ return qs
class CoreManager(EnhancedManager):
"Base class for all models managers"
# Author: Olivier Guilyardi <olivier@samalyse.com>
from telemeta.models.core import Duration
+from telemeta.models.media import MediaItem, MediaCollection
from django.conf import settings
class Resource(object):
@staticmethod
def multiple(name, values, refinement=None):
elements = []
- for v in values:
- elements.append(Element(name, v, refinement))
+ if values:
+ for v in values:
+ elements.append(Element(name, v, refinement))
return elements
class Date(Element):
Element('publisher', settings.TELEMETA_ORGANIZATION),
date,
Date(item.collection.year_published, refinement='issued'),
- Element.multiple('coverage', item.location.fullnames(), 'spatial'),
+ Element.multiple('coverage', item.location and item.location.fullnames(), 'spatial'),
Element('coverage', item.location_comment, 'spatial'),
Element('rights', item.collection.legal_rights, 'license'),
Element('rights', media_access_rights(item.collection), 'accessRights'),
return resource
-
+def express_resource(res):
+ if isinstance(res, MediaItem):
+ return express_item(res)
+ elif isinstance(res, MediaCollection):
+ return express_collection(res)
+
+ raise Exception("Invalid resource type")
+
+def lookup_resource(media_id):
+ try:
+ type, code = media_id.split(':', 1)
+ except ValueError:
+ raise MalformedMediaIdentifier("Media identifier must be in type:code format")
+
+ if (type == 'collection'):
+ try:
+ return MediaCollection.objects.get(code=code)
+ except MediaCollection.DoesNotExist:
+ return None
+ elif (type == 'item'):
+ try:
+ return MediaItem.objects.get(code=code)
+ except MediaItem.DoesNotExist:
+ try:
+ return MediaItem.objects.get(old_code=code)
+ except MediaItem.DoesNotExist:
+ return None
+ else:
+ raise MalformedMediaIdentifier("No such type in media identifier: " + type)
+
+class MalformedMediaIdentifier(Exception):
+ pass