from telemeta.models.enum import *
from django.db.models.fields import URLField
-
+
collection_published_code_regex = '[A-Za-z0-9._-]*'
collection_unpublished_code_regex = '[A-Za-z0-9._-]*'
-collection_code_regex = '(?:%s|%s)' % (collection_published_code_regex,
+collection_code_regex = '(?:%s|%s)' % (collection_published_code_regex,
collection_unpublished_code_regex)
item_published_code_regex = '[A-Za-z0-9._-]*'
def set_revision(self, user):
"Save a media object and add a revision"
- Revision.touch(self, user)
+ Revision.touch(self, user)
def get_revision(self):
return Revision.objects.filter(element_type=self.element_type, element_id=self.id).order_by('-time')[0]
class MediaRelated(MediaResource):
"Related media"
-
+
element_type = 'media'
-
+
title = CharField(_('title'))
date = DateTimeField(_('date'), auto_now=True)
description = TextField(_('description'))
url = CharField(_('url'), max_length=500)
credits = CharField(_('credits'))
file = FileField(_('file'), upload_to='items/%Y/%m/%d', db_column="filename")
-
+
def is_image(self):
is_url_image = False
if self.url:
if type in self.url:
is_url_image = True
return 'image' in self.mime_type or is_url_image
-
+
def save(self, force_insert=False, force_update=False):
super(MediaRelated, self).save(force_insert, force_update)
-
+
def set_mime_type(self):
if self.file:
self.mime_type = mimetypes.guess_type(self.file.path)[0]
-
+
def __unicode__(self):
if self.title and not re.match('^ *N *$', self.title):
title = self.title
else:
title = unicode(self.item)
return title
-
+
class Meta:
abstract = True
class MediaCorpus(MediaResource):
"Describe a corpus of collections"
-
+
element_type = 'corpus'
# General informations
title = CharField(_('title'), required=True)
description = CharField(_('description'))
code = CharField(_('code'), unique=True, required=True)
- public_access = CharField(_('public access'), choices=PUBLIC_ACCESS_CHOICES,
+ public_access = CharField(_('public access'), choices=PUBLIC_ACCESS_CHOICES,
max_length=16, default="metadata")
-
+
def __unicode__(self):
return self.code
def save(self, force_insert=False, force_update=False, user=None, code=None):
super(MediaCorpus, self).save(force_insert, force_update)
-
+
class Meta(MetaCore):
db_table = 'media_corpus'
ordering = ['code']
class MediaCorpusCollectionRelation(ModelCore):
"Relations between Corpus and Collections"
-
- collection = ForeignKey('MediaCollection', related_name="parent_relation",
+
+ collection = ForeignKey('MediaCollection', related_name="parent_relation",
verbose_name=_('collection'))
- corpus = ForeignKey('MediaCorpus', related_name="child_relation",
+ corpus = ForeignKey('MediaCorpus', related_name="child_relation",
verbose_name=_('corpus'))
class Meta(MetaCore):
db_table = 'media_corpus_collection_relations'
unique_together = (('collection', 'corpus'),)
-
+
def __unicode__(self):
sep = ' > '
return self.corpus.code + sep + self.collection.code
-
+
class MediaCollection(MediaResource):
"Describe a collection of items"
-
+
element_type = 'collection'
def is_valid_collection_code(value):
regex = '^' + collection_code_regex + '$'
if not re.match(regex, value):
raise ValidationError(u'%s is not a valid collection code' % value)
-
+
# General informations
reference = CharField(_('reference'), unique=True, null=True)
title = CharField(_('title'), required=True)
alt_title = CharField(_('original title / translation'))
creator = CharField(_('depositor / contributor'))
- recording_context = WeakForeignKey('RecordingContext', related_name="collections",
+ recording_context = WeakForeignKey('RecordingContext', related_name="collections",
verbose_name=_('recording context'))
recorded_from_year = IntegerField(_('recording year (from)'))
recorded_to_year = IntegerField(_('recording year (until)'))
year_published = IntegerField(_('year published'))
-
+
# Geographic and cultural informations
## See "countries" and "ethnic_groups" methods below
# Legal notices
collector = CharField(_('recordist'))
- publisher = WeakForeignKey('Publisher', related_name="collections",
- verbose_name=_('publisher / status'))
- publisher_collection = WeakForeignKey('PublisherCollection', related_name="collections",
+ publisher = WeakForeignKey('Publisher', related_name="collections",
+ verbose_name=_('publisher / status'))
+ publisher_collection = WeakForeignKey('PublisherCollection', related_name="collections",
verbose_name=_('publisher collection'))
publisher_serial = CharField(_('publisher serial number'))
booklet_author = CharField(_('author of published notice'))
external_references = TextField(_('bibliographic references'))
doctype_code = IntegerField(_('document type'))
- public_access = CharField(_('public access'), choices=PUBLIC_ACCESS_CHOICES,
+ public_access = CharField(_('public access'), choices=PUBLIC_ACCESS_CHOICES,
max_length=16, default="metadata")
- legal_rights = WeakForeignKey('LegalRight', related_name="collections",
+ legal_rights = WeakForeignKey('LegalRight', related_name="collections",
verbose_name=_('legal rights'))
-
+
# Archiving data
- acquisition_mode = WeakForeignKey('AcquisitionMode', related_name="collections",
+ acquisition_mode = WeakForeignKey('AcquisitionMode', related_name="collections",
verbose_name=_('mode of acquisition'))
cnrs_contributor = CharField(_('CNRS depositor'))
- metadata_author = WeakForeignKey('MetadataAuthor', related_name="collections",
+ metadata_author = WeakForeignKey('MetadataAuthor', related_name="collections",
verbose_name=_('record author'))
booklet_description = TextField(_('related documentation'))
- publishing_status = WeakForeignKey('PublishingStatus', related_name="collections",
+ publishing_status = WeakForeignKey('PublishingStatus', related_name="collections",
verbose_name=_('secondary edition'))
alt_ids = CharField(_('copies'))
comment = TextField(_('comment'))
- metadata_writer = WeakForeignKey('MetadataWriter', related_name="collections",
+ metadata_writer = WeakForeignKey('MetadataWriter', related_name="collections",
verbose_name=_('record writer'))
travail = CharField(_('archiver notes'))
items_done = CharField(_('items finished'))
collector_is_creator = BooleanField(_('recordist identical to depositor'))
is_published = BooleanField(_('published'))
conservation_site = CharField(_('conservation site'))
-
+
# Technical data
code = CharField(_('code'), unique=True, required=True, validators=[is_valid_collection_code])
old_code = CharField(_('old code'), unique=False, null=True, blank=True)
approx_duration = DurationField(_('approximative duration'))
physical_items_num = IntegerField(_('number of components (medium / piece)'))
- physical_format = WeakForeignKey('PhysicalFormat', related_name="collections",
+ physical_format = WeakForeignKey('PhysicalFormat', related_name="collections",
verbose_name=_('archive format'))
- ad_conversion = WeakForeignKey('AdConversion', related_name='collections',
+ ad_conversion = WeakForeignKey('AdConversion', related_name='collections',
verbose_name=_('digitization'))
state = TextField(_('status'))
a_informer_07_03 = CharField(_('a_informer_07_03'))
-
+
# All
objects = MediaCollectionManager()
-
+
def __unicode__(self):
return self.code
@property
def public_id(self):
return self.code
-
+
@property
def has_mediafile(self):
"Tell wether this collection has any media files attached to its items"
if item.file:
return True
return False
-
+
def __name_cmp(self, obj1, obj2):
return unaccent_icmp(obj1.name, obj2.name)
for country in item.location.countries():
if not country in countries:
countries.append(country)
-
- countries.sort(self.__name_cmp)
+
+ countries.sort(self.__name_cmp)
return countries
countries.verbose_name = _("states / nations")
groups.append(item.ethnic_group)
cmp = lambda a, b: unaccent_icmp(a.value, b.value)
- groups.sort(cmp)
+ groups.sort(cmp)
return groups
ethnic_groups.verbose_name = _('populations / social groups')
for item in self.items.all():
duration += item.computed_duration()
return duration
-
- computed_duration.verbose_name = _('computed duration')
-
+
+ computed_duration.verbose_name = _('computed duration')
+
def save(self, force_insert=False, force_update=False, user=None, code=None):
super(MediaCollection, self).save(force_insert, force_update)
-
+
class Meta(MetaCore):
db_table = 'media_collections'
ordering = ['code']
class MediaCollectionRelated(MediaRelated):
"Collection related media"
-
+
collection = ForeignKey('MediaCollection', related_name="related", verbose_name=_('collection'))
-
+
class Meta(MetaCore):
db_table = 'media_collection_related'
-
+
class MediaItem(MediaResource):
"Describe an item"
-
+
element_type = 'item'
-
+
# Main Informations
title = CharField(_('title'))
alt_title = CharField(_('original title / translation'))
collector = CharField(_('recordist'))
- collection = ForeignKey('MediaCollection', related_name="items",
- verbose_name=_('collection'))
+ collection = ForeignKey('MediaCollection', related_name="items",
+ verbose_name=_('collection'))
recorded_from_date = DateField(_('recording date (from)'))
recorded_to_date = DateField(_('recording date (until)'))
-
+
# Geographic and cultural informations
location = WeakForeignKey('Location', verbose_name=_('location'))
location_comment = CharField(_('location details'))
cultural_area = CharField(_('cultural area'))
- ethnic_group = WeakForeignKey('EthnicGroup', related_name="items",
+ ethnic_group = WeakForeignKey('EthnicGroup', related_name="items",
verbose_name=_('population / social group'))
language = CharField(_('language'))
context_comment = TextField(_('comments / ethnographic context'))
moda_execut = CharField(_('moda_execut'))
-
+
# Musical informations
- vernacular_style = WeakForeignKey('VernacularStyle', related_name="items",
+ vernacular_style = WeakForeignKey('VernacularStyle', related_name="items",
verbose_name=_('vernacular style'))
- generic_style = WeakForeignKey('GenericStyle', related_name="items",
+ generic_style = WeakForeignKey('GenericStyle', related_name="items",
verbose_name=_('generic style'))
author = CharField(_('author / compositor'))
-
+
# General informations
comment = TextField(_('remarks'))
collector_selection = CharField(_('recordist selection'))
collector_from_collection = BooleanField(_('recordist as in collection'))
-
+
# Archiving data
code = CharField(_('code'), unique=True, blank=True)
old_code = CharField(_('old code'), unique=False, blank=True)
copied_from_item = WeakForeignKey('self', related_name="copies", verbose_name=_('copy of'))
public_access = CharField(_('public access'), choices=PUBLIC_ACCESS_CHOICES, max_length=16, default="metadata")
file = FileField(_('file'), upload_to='items/%Y/%m/%d', db_column="filename")
-
+
# Technical data
approx_duration = DurationField(_('approximative duration'))
-
+
# All
objects = MediaItemManager()
class Meta(MetaCore):
db_table = 'media_items'
- permissions = (("can_play_all_items", "Can play all media items"),
+ permissions = (("can_play_all_items", "Can play all media items"),
("can_download_all_items", "Can download all media items"), )
def is_valid_code(self, code):
def clean(self):
if self.code and not self.is_valid_code(self.code):
- raise ValidationError("%s is not a valid item code for collection %s"
+ raise ValidationError("%s is not a valid item code for collection %s"
% (self.code, self.collection.code))
-
+
def save(self, force_insert=False, force_update=False):
super(MediaItem, self).save(force_insert, force_update)
"Tell the length in seconds of this item media data"
return self.approx_duration
- computed_duration.verbose_name = _('computed duration')
+ computed_duration.verbose_name = _('computed duration')
def __unicode__(self):
if self.title and not re.match('^ *N *$', self.title):
class MediaItemRelated(MediaRelated):
"Item related media"
-
+
item = ForeignKey('MediaItem', related_name="related", verbose_name=_('item'))
-
+
class Meta(MetaCore):
db_table = 'media_item_related'
class MediaItemPerformance(ModelCore):
"Item performance"
- media_item = ForeignKey('MediaItem', related_name="performances",
+ media_item = ForeignKey('MediaItem', related_name="performances",
verbose_name=_('item'))
- instrument = WeakForeignKey('Instrument', related_name="performances",
+ instrument = WeakForeignKey('Instrument', related_name="performances",
verbose_name=_('composition'))
- alias = WeakForeignKey('InstrumentAlias', related_name="performances",
+ alias = WeakForeignKey('InstrumentAlias', related_name="performances",
verbose_name=_('vernacular name'))
instruments_num = CharField(_('number'))
musicians = CharField(_('interprets'))
class MediaItemAnalysis(ModelCore):
"Item analysis result computed by TimeSide"
- element_type = 'analysis'
+ element_type = 'analysis'
item = ForeignKey('MediaItem', related_name="analysis", verbose_name=_('item'))
analyzer_id = CharField(_('id'), required=True)
name = CharField(_('name'))
value = CharField(_('value'))
unit = CharField(_('unit'))
-
+
class Meta(MetaCore):
db_table = 'media_analysis'
ordering = ['name']
-
+
def to_dict(self):
if self.analyzer_id == 'duration':
if '.' in self.value:
value = self.value.split('.')
self.value = '.'.join([value[0], value[1][:2]])
return {'id': self.analyzer_id, 'name': self.name, 'value': self.value, 'unit': self.unit}
-
-
+
+
class MediaPart(MediaResource):
"Describe an item part"
element_type = 'part'
title = CharField(_('title'), required=True)
start = FloatField(_('start'), required=True)
end = FloatField(_('end'), required=True)
-
+
class Meta(MetaCore):
db_table = 'media_parts'
def __unicode__(self):
return self.title
-
+
class PlaylistResource(ModelCore):
"Playlist components"
class Meta(MetaCore):
db_table = 'playlist_resources'
-
-
+
+
class MediaItemMarker(MediaResource):
"2D marker object : text value vs. time"
-
+
element_type = 'marker'
-
+
item = ForeignKey('MediaItem', related_name="markers", verbose_name=_('item'))
public_id = CharField(_('public_id'), required=True)
time = FloatField(_('time'))
date = DateTimeField(_('date'), auto_now=True)
description = TextField(_('description'))
author = ForeignKey(User, related_name="markers", verbose_name=_('author'))
-
+
class Meta(MetaCore):
db_table = 'media_markers'
class MediaItemTranscodingFlag(ModelCore):
"Item flag to know if the MediaItem has been transcoded to a given format"
-
+
item = ForeignKey('MediaItem', related_name="transcoding", verbose_name=_('item'))
mime_type = CharField(_('mime_type'), required=True)
date = DateTimeField(_('date'), auto_now=True)
value = BooleanField(_('transcoded'))
-
+
class Meta(MetaCore):
db_table = 'media_transcoding'
-
-
+
+
class Search(ModelCore):
"Keywork search"
-
+
element_type = 'search'
-
+
username = ForeignKey(User, related_name="searches", db_column="username")
keywords = CharField(_('keywords'), required=True)
date = DateField(_('date'), auto_now_add=True)
class DublinCoreToFormatMetadata(object):
- """ a mapping class to get item DublinCore metadata dictionaries
+ """ a mapping class to get item DublinCore metadata dictionaries
in various audio metadata format (MP3, OGG, etc...)"""
-
+
#FIXME: should be given by timeside
- unavailable_extensions = ['wav', 'aiff', 'aif']
-
- metadata_mapping = {
+ unavailable_extensions = ['wav', 'aiff', 'aif', 'flac']
+
+ metadata_mapping = {
'mp3' : {
'title': 'TIT2', #title2
'creator': 'TCOM', #composer
'publisher': 'TPUB', #publisher
'date': 'TDRC', #year
# 'coverage': 'COMM', #comment
- },
+ },
'ogg': {
'creator': 'artist',
- 'relation': 'album',
- 'all': 'all',
- },
+ 'relation': 'album',
+ 'all': 'all',
+ },
'flac': {
'creator': 'artist',
- 'relation': 'album',
- 'all': 'all',
- },
+ 'relation': 'album',
+ 'all': 'all',
+ },
'wav': {
'creator': 'artist',
- 'relation': 'album',
- 'all': 'all',
- },
+ 'relation': 'album',
+ 'all': 'all',
+ },
}
-
+
def __init__(self, format):
self.format = format
-
+
def get_metadata(self, dc_metadata):
mapp = self.metadata_mapping[self.format]
metadata = {}