import os import re from django.db import models from django.db.models.fields.related import ForeignKey from django.utils.translation import ugettext as _ from django.contrib.auth.models import User from django.utils.safestring import mark_safe ############################# Helper Functions ####################################################### def space_to_camelcase(value): def camelcase(): yield type(value).lower while True: yield type(value).capitalize c = camelcase() return "".join(c.next()(x) if x else '_' for x in value.split()) def score_filename(score, original_name): fileExtension = os.path.splitext(original_name)[1] filename = "scores/" filename += space_to_camelcase(score.piece.title) + "/" filename += space_to_camelcase(score.score_type) filename += fileExtension return filename def recordingFileName(recording, originalName): fileExtension = os.path.splitext(originalName)[1] filename = "recordings/" filename += space_to_camelcase(recording.piece.title) + "/" filename += space_to_camelcase(recording.artist) filename += fileExtension return filename ####################################################################################################### class Piece(models.Model): title = models.CharField(max_length=255, verbose_name=_("title"), unique=True) composer = models.CharField(max_length=255, blank=True, verbose_name=_("composer")) repertoire_nr = models.IntegerField(null=True, blank=True, unique=True, default=None) def __unicode__(self): res = self.title return res def isInRepertoire(self): return self.repertoire_nr is not None def get_score_for_user(self, user): try: return ScoreUserMapping.objects.get(user=user, score__in=self.scores.all()).score except Piece.DoesNotExist: if len(self.scores.all()) > 0: return self.scores.all()[0] else: return None @staticmethod def getRepertoire(): return Piece.objects.filter(repertoire_nr__isnull=False).order_by('repertoire_nr') class Meta: permissions = ( ("manage_scores", "Administrate and manage scores"), ) class BookLocation(models.Model): piece = models.ForeignKey('Piece', on_delete=models.PROTECT) book = models.CharField(max_length=100, blank=False, verbose_name=_("Buch")) page = models.IntegerField(verbose_name=_("page")) def __unicode__(self): return "%s, %d" % (self.book, self.page) class Score(models.Model): piece = ForeignKey('Piece', related_name="scores", on_delete=models.PROTECT) score_type = models.CharField(max_length=100, verbose_name="score type") # for example partitur, unterstimmen ... file = models.FileField(upload_to=score_filename, verbose_name=_("file")) uploaded_by = ForeignKey(User, verbose_name=_("uploaded_by"), on_delete=models.PROTECT) @property def image_file_name(self): return os.path.splitext("image_cache/" + str(self.file))[0] + ".jpg" @staticmethod def pdf2jpg(source_file, target_file, resolution=100, crop=15): from wand.image import Image ret = True try: with Image(filename=source_file, resolution=(resolution, resolution)) as img: img.crop(crop, crop, width=img.width - 2 * crop, height=int(0.5 * img.height) - 2 * crop) img.format = 'jpeg' img.save(filename=target_file) except Exception as e: print(e) ret = False return ret def get_image_file(self): from django.conf import settings inputFile = settings.MEDIA_ROOT + "/" + str(self.file) cacheFile = settings.MEDIA_ROOT + "/" + str(self.image_file_name) # Create a jpg for this score, if it does not exist yet if not os.path.exists(cacheFile): if not os.path.exists(os.path.dirname(cacheFile)): os.makedirs(os.path.dirname(cacheFile)) Score.pdf2jpg(inputFile, cacheFile) return self.image_file_name def is_active_score(self, user): return len(ScoreUserMapping.objects.filter(score=self, user=user)) > 0 class Meta: unique_together = (("piece", "score_type"),) ordering = ['score_type'] class Recording(models.Model): piece = ForeignKey('Piece', related_name='recordings', on_delete=models.PROTECT) artist = models.CharField(max_length=100, verbose_name=_("Artist")) file = models.FileField(upload_to=recordingFileName, verbose_name=_("file")) uploaded_by = ForeignKey(User, verbose_name=_("uploaded_by"), on_delete=models.PROTECT) class Meta: unique_together = (("piece", "artist"),) ordering = ['artist'] class YoutubeRecording(models.Model): piece = models.ForeignKey('Piece', related_name="youtubeLinks", on_delete=models.PROTECT) link = models.CharField(max_length=300, blank=False) uploaded_by = ForeignKey(User, verbose_name=_("uploaded_by"), on_delete=models.PROTECT) youtubeRegex = re.compile(u'(?:https://)?(?:http://)?www.youtube.(?:com|de)/watch\?v=(?P[-\w]*)') @property def embed_html(self): replacement = """
""" return mark_safe(YoutubeRecording.youtubeRegex.sub(replacement, self.link)) class Meta: unique_together = ("link", "piece") class ScoreUserMapping(models.Model): score = ForeignKey('Score', on_delete=models.PROTECT) user = models.OneToOneField(User, on_delete=models.PROTECT) piece = ForeignKey('Piece', on_delete=models.PROTECT) @staticmethod def add_user_score_mapping(score, user): piece = score.piece ScoreUserMapping.objects.filter(user=user, piece=piece).delete() ScoreUserMapping.objects.create(score=score, user=user, piece=piece) class Meta: unique_together = ("piece", "user")