--- /dev/null
+from telemeta.models import MediaCollection, MediaItem, Revision
+from datetime import datetime
+
+class TelemetaOAIDataSource(object):
+ """Telemeta OAI datasource adapter. This class implements the oai.IDataSource interface."""
+
+ def get_earliest_time(self):
+ """Return the change time of the oldest record(s) as a datetime object"""
+ try:
+ rev = Revision.objects.order_by('time')[0]
+ return rev.time
+ except IndexError:
+ return datetime.now()
+
+ def prepare_record(self, type, 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))
+ else:
+ dc.append((k, v))
+ return (dc, ctime)
+
+ def get_record(self, id):
+ """Return a specific record"""
+ type, id = id.split(':')
+ if (type == 'collection'):
+ record = MediaCollection.objects.get(id=id)
+ elif (type == 'item'):
+ record = MediaItem.objects.get(id=id)
+ else:
+ raise Exception("No such record type: %s" % type)
+
+ return self.prepare_record(type, record)
+
+
+ def count_records(self, from_time = None, until_time = None):
+ """Must return the number of records between (optional) from and until change time."""
+ nitems = MediaItem.objects.by_change_time(from_time, until_time).count()
+ ncolls = MediaCollection.objects.by_change_time(from_time, until_time).count()
+ return nitems + ncolls
+
+ def list_records(self, offset, limit, from_time = None, until_time = None):
+ """Return a list of records"""
+
+ result = []
+
+ query = MediaItem.objects.by_change_time(from_time, until_time)
+ nitems = query.count()
+ if (offset < nitems):
+ set = query[offset:offset + limit]
+ for record in set:
+ result.append(self.prepare_record('item', record))
+ limit -= len(set)
+ offset = 0
+ else:
+ offset -= nitems
+
+ if limit > 0:
+ 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))
+
+ return result
result[element.name] = unicode(element.value)
return result
+ def to_list(self):
+ """Convert the resource to unqualified dublin core, as a list of the form:
+ [(key, value), ...]"""
+ result = []
+ for element in self.elements:
+ result.append((element.name, unicode(element.value)))
+ return result
+
class Element(object):
"Represent a Dublin Core element"
super(MediaCollection, self).save(force_insert, force_update)
Revision(element_type='collection', element_id=self.id).touch()
+ def get_revision(self):
+ return Revision.objects.filter(element_type='collection', element_id=self.id).order_by('-time')[0]
+
class Meta:
app_label = 'telemeta'
ordering = ['title']
return duration
+ def get_revision(self):
+ return Revision.objects.filter(element_type='item', element_id=self.id).order_by('-time')[0]
+
def __unicode__(self):
return self.title
super(MediaPart, self).save(force_insert, force_update)
Revision(element_type='part', element_id=self.id).touch()
+ def get_revision(self):
+ return Revision.objects.filter(element_type='part', element_id=self.id).order_by('-time')[0]
+
class Meta:
app_label = 'telemeta'
ordering = ['title']
element_type = CharField(max_length=16, choices=(('collection', 'collection'),
('item', 'item'),
('part', 'part')))
- element_id = CharField(max_length=250)
- change_type = CharField(max_length=8, choices= (('create', 'create'),
+ element_id = CharField(max_length=250, db_index=True)
+ change_type = CharField(max_length=8, choices= (('import', 'import'),
+ ('create', 'create'),
('update', 'update'),
('delete', 'delete')))
time = DateTimeField(auto_now_add=True)
kwargs = {field + '__iregex': regex}
return self.filter(**kwargs)
+ def _by_change_time(self, type, from_time = None, until_time = None):
+ where = ["element_type = '%s'" % type]
+ if from_time:
+ where.append("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 telemeta_revision WHERE %s)" % " AND ".join(where)]);
+
class CoreManager(Manager):
"Base class for all models managers"
def by_ethnic_group(self, group):
return self.filter(items__ethnie_grsocial=group).distinct()
+ def by_change_time(self, from_time = None, until_time = None):
+ return self._by_change_time('collection', from_time, until_time)
+
class MediaCollectionManager(CoreManager):
"Manage collection queries"
def by_ethnic_group(self, *args, **kwargs):
return self.get_query_set().by_ethnic_group(*args, **kwargs)
+ def by_change_time(self, *args, **kwargs):
+ return self.get_query_set().by_change_time(*args, **kwargs)
+
def stat_continents(self, order_by='num'):
"Return the number of collections by continents and countries as a tree"
from django.db import connection
def by_publish_date(self, pattern):
return self.filter(collection__date_published__icontains=pattern)
+
+ def by_change_time(self, from_time = None, until_time = None):
+ return self._by_change_time('item', from_time, until_time)
class MediaItemManager(CoreManager):
"Manage media items queries"
def by_publish_date(self, *args, **kwargs):
return self.get_query_set().by_publish_date(*args, **kwargs)
+ def by_change_time(self, *args, **kwargs):
+ return self.get_query_set().by_change_time(*args, **kwargs)
+
def list_ethnic_groups(self):
"Return a list of all ethnic groups"
url(r'^timeside/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': htdocs+'/timeside'},
name="telemeta-timeside"),
+
+ # OAI-PMH Data Provider
+ url(r'^oai/.*$', web_view.handle_oai_request, name="telemeta-oai")
)
from telemeta.visualization import *
from telemeta.analysis import *
from telemeta.analysis.vamp import *
+import telemeta.interop.oai as oai
+from telemeta.interop.oaidatasource import TelemetaOAIDataSource
class WebView(Component):
"""Provide web UI methods"""
template_name='telemeta/geo_country_collections.html', paginate_by=20,
extra_context={'country': country, 'continent': continent})
+ def handle_oai_request(self, request):
+ url = request.META['HTTP_HOST'] + request.path
+ datasource = TelemetaOAIDataSource()
+ provider = oai.DataProvider(datasource, "Telemeta", url, "admin@telemeta.org")
+ args = request.GET.copy()
+ args.update(request.POST)
+ return HttpResponse(provider.handle(args), mimetype='text/xml')
+
+