from django.db import models
import cremquery as query
from xml.dom.minidom import getDOMImplementation
+from telemeta.util.unaccent import unaccent_icmp
class ModelCore(models.Model):
return False
is_well_formed_id = classmethod(is_well_formed_id)
+ def save(self, force_insert=False, force_update=False, using=None):
+ raise MissingUserError("save() method disabled, use save_by_user()")
+
+ def save_by_user(self, user, force_insert=False, force_update=False, using=None):
+ "Save a media object and add a revision"
+ super(MediaCore, self).save(force_insert, force_update, using)
+ Revision(element_type=self.element_type, element_id=self.id, user=user).touch()
+
+ def get_revision(self):
+ return Revision.objects.filter(element_type=self.element_type, element_id=self.id).order_by('-time')[0]
+
class Meta:
abstract = True
class MediaCollection(MediaCore):
"Describe a collection of items"
+ element_type = 'collection'
PUBLIC_ACCESS_CHOICES = (('none', 'none'), ('metadata', 'metadata'), ('metadata', 'full'))
reference = models.CharField(unique=True, max_length=250,
def __unicode__(self):
return self.code
- def save(self, force_insert=False, force_update=False, using=None):
- raise MissingUserError("save() method disabled, use save_by_user()")
-
- def save_by_user(self, user, force_insert=False, force_update=False, using=None):
- "Save a collection and add a revision"
- super(MediaCollection, self).save(force_insert, force_update, using)
- Revision(element_type='collection', element_id=self.id, user=user).touch()
-
def has_mediafile(self):
"Tell wether this collection has any media files attached to its items"
items = self.items.all()
return True
return False
+ def __name_cmp(self, obj1, obj2):
+ return unaccent_icmp(obj1.name, obj2.name)
+
+ def get_countries(self):
+ "Return the countries of the items"
+ countries = []
+ items = self.items.all()
+ for item in items:
+ if item.location:
+ country = item.location.country()
+ if country and not country in countries:
+ countries.append(country)
+
+ countries.sort(self.__name_cmp)
+
+ return countries
+
+ def get_ethnic_groups(self):
+ "Return the ethnic groups of the items"
+ groups = []
+ items = self.items.all()
+ for item in items:
+ if item.ethnic_group and not item.ethnic_group in groups:
+ groups.append(item.ethnic_group)
+
+ groups.sort(self.__name_cmp)
+
+ return groups
+
class Meta(MetaCore):
db_table = 'media_collections'
class MediaItem(MediaCore):
"Describe an item"
+ element_type = 'item'
PUBLIC_ACCESS_CHOICES = (('none', 'none'), ('metadata', 'metadata'), ('full', 'full'))
collection = models.ForeignKey('MediaCollection', related_name="items")
return self.code
return self.old_code
- def save(self, force_insert=False, force_update=False):
- raise MissingUserError("save() method disabled, use save_by_user()")
-
- def save_by_user(self, user, force_insert=False, force_update=False):
- "Save an item and add a revision"
- super(MediaItem, self).save(force_insert, force_update)
- Revision(element_type='item', element_id=self.id, user=user).touch()
-
class MediaPart(MediaCore):
"Describe an item part"
+ element_type = 'part'
item = models.ForeignKey('MediaItem', related_name="parts")
title = models.CharField(max_length=250)
start = models.FloatField()
self.assertEquals(self.items.without_collection().count(), 0)
def testCodeRequired(self):
+ "Test that a proper failure occur when a collection code isn't provided"
c = MediaCollection()
try:
c.save_by_user(self.olivier)
self.fail("No exception raised")
def testDomForeignKey(self):
+ "Test DOM foreign key embedding"
doc = self.item_4.to_dom()
self.assertEquals(doc.getElementsByTagName('collection')[0].getAttribute('key'), str(self.persepolis.id))
def testLocationRelation(self):
+ "Test location country and continent resolving"
self.assertEquals(self.france, self.item_1.location.country())
self.assertEquals(self.europe, self.item_1.location.continent())
self.assertEquals(self.france, self.item_2.location.country())
self.assertEquals(self.europe, self.item_2.location.continent())
+
+ def testCollectionCountries(self):
+ "Test the MediaCollection.get_countries() method"
+ self.assertEquals(self.volonte.get_countries(), [self.belgique, self.france])
+
--- /dev/null
+# This file by Fredrik Lundh from:
+# http://effbot.org/zone/unicode-convert.htm
+# http://effbot.python-hosting.com/file/stuff/sandbox/text/unaccent.py
+
+# use a dynamically populated translation dictionary to remove accents
+# from a string
+
+import unicodedata, sys
+
+CHAR_REPLACEMENT = {
+ # latin-1 characters that don't have a unicode decomposition
+ 0xc6: u"AE", # LATIN CAPITAL LETTER AE
+ 0xd0: u"D", # LATIN CAPITAL LETTER ETH
+ 0xd8: u"OE", # LATIN CAPITAL LETTER O WITH STROKE
+ 0xde: u"Th", # LATIN CAPITAL LETTER THORN
+ 0xdf: u"ss", # LATIN SMALL LETTER SHARP S
+ 0xe6: u"ae", # LATIN SMALL LETTER AE
+ 0xf0: u"d", # LATIN SMALL LETTER ETH
+ 0xf8: u"oe", # LATIN SMALL LETTER O WITH STROKE
+ 0xfe: u"th", # LATIN SMALL LETTER THORN
+ }
+
+##
+# Translation dictionary. Translation entries are added to this
+# dictionary as needed.
+
+class UnaccentedMap(dict):
+
+ ##
+ # Maps a unicode character code (the key) to a replacement code
+ # (either a character code or a unicode string).
+
+ def mapchar(self, key):
+ ch = self.get(key)
+ if ch is not None:
+ return ch
+ de = unicodedata.decomposition(unichr(key))
+ if de:
+ try:
+ ch = int(de.split(None, 1)[0], 16)
+ except (IndexError, ValueError):
+ ch = key
+ else:
+ ch = CHAR_REPLACEMENT.get(key, key)
+ self[key] = ch
+ return ch
+
+ if sys.version >= "2.5":
+ # use __missing__ where available
+ __missing__ = mapchar
+ else:
+ # otherwise, use standard __getitem__ hook (this is slower,
+ # since it's called for each character)
+ __getitem__ = mapchar
+
+
+_map = UnaccentedMap()
+
+def unaccent(str):
+ return str.translate(_map)
+
+def unaccent_icmp(str1, str2):
+ str1 = unaccent(str1).lower()
+ str2 = unaccent(str2).lower()
+ if str1 > str2:
+ return 1
+
+ if str1 < str2:
+ return -1
+
+ return 0