from django.db import models from django.utils.text import slugify from django.utils import timezone from django.conf import settings from django.shortcuts import resolve_url import random import boto3 from datetime import datetime import os.path s3client = boto3.client('s3') BUCKET = settings.AWS_BUCKET MEDIA_TYPES = [ ('audio', "Audio"), ('video', "Video"), ('general', "General"), ] def generate_code(length=9): return "".join([ random.choice('0123456789') for _ in range(length) ]) class Ensemble(models.Model): name = models.CharField(max_length=100) code = models.CharField(max_length=9, default=generate_code) passphrase = models.CharField(max_length=100) admins = models.ManyToManyField('auth.User', related_name='ensembles') def active_projects(self): return self.projects.filter(active=True) def ensemble_code(self): code = str(self.code) return "{}-{}-{}".format(code[:3], code[3:6], code[6:]) def __str__(self): return self.name class Project(models.Model): name = models.CharField(max_length=100) ensemble = models.ForeignKey(Ensemble, related_name='projects', on_delete=models.CASCADE, null=True) active = models.BooleanField(default=True) deadline =models.DateField(null=True, blank=True) owner = models.CharField(max_length=255, blank=True) @property def submissions(self): return self.all_submissions.filter(complete=True).order_by('-pk') def presigned_post(self, object_name, fields=None, conditions=None, expires=3600): key = os.path.join(slugify(self.name), object_name) return s3client.generate_presigned_post(BUCKET, key, Fields=fields or {}, Conditions=conditions or [], ExpiresIn=expires) def __str__(self): return self.name class Resource(models.Model): project = models.ForeignKey(Project, related_name='resources', on_delete=models.CASCADE) name = models.CharField(max_length=100) description = models.TextField(blank=True) key = models.CharField(max_length=255, blank=True) media_type = models.CharField(max_length=10, choices=MEDIA_TYPES, default='*') visible = models.BooleanField(default=True) def key_template(self): return "{}/${{filename}}".format(slugify(self.name)) def accept(self): if self.media_type == 'general': return ".*" return f"{self.media_type}/*" def presigned_url(self): if not self.key: return "" params = {'Bucket': BUCKET, 'Key': self.key} return s3client.generate_presigned_url('get_object', Params=params, ExpiresIn=3600*24) def __str__(self): return self.name class WikiPage(models.Model): project = models.ForeignKey(Project, related_name='wiki_pages', on_delete=models.CASCADE) title = models.CharField(max_length=255) markdown = models.TextField() def get_absolute_url(self): return resolve_url('wiki', project=self.project_id, pk=self.pk) def __str__(self): return self.title class Submission(models.Model): project = models.ForeignKey(Project, related_name='all_submissions', on_delete=models.CASCADE) date = models.DateTimeField(auto_now_add=True, ) name = models.CharField(max_length=255) instrument = models.CharField(max_length=100, verbose_name="Instrument / Voice") notes = models.TextField(blank=True) complete = models.BooleanField(default=False) key = models.CharField(max_length=512, blank=True) def presigned_url(self): params = {'Bucket': BUCKET, 'Key': self.key} return s3client.generate_presigned_url('get_object', Params=params, ExpiresIn=3600) def key_template(self): return "{}_{}_{}_${{filename}}".format( timezone.localtime(self.date).isoformat(timespec='seconds').replace(':', ''), slugify(self.name), slugify(self.instrument) ) def __str__(self): return f"{self.name}: {self.date}"