Skip to content
Snippets Groups Projects
models.py 5.02 KiB
Newer Older
  • Learn to ignore specific revisions
  • import uuid
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    from django.conf import settings
    
    from django.contrib.postgres.fields import JSONField
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    from django.db import models
    from django.utils import timezone
    
    TYPE_CHOICES = [
        ('Person', 'Person'),
        ('Application', 'Application'),
        ('Group', 'Group'),
        ('Organization', 'Organization'),
        ('Service', 'Service'),
    ]
    
    
    class Actor(models.Model):
    
        ap_type = 'Actor'
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        url = models.URLField(unique=True, max_length=500, db_index=True)
        outbox_url = models.URLField(max_length=500)
        inbox_url = models.URLField(max_length=500)
        following_url = models.URLField(max_length=500, null=True, blank=True)
        followers_url = models.URLField(max_length=500, null=True, blank=True)
        shared_inbox_url = models.URLField(max_length=500, null=True, blank=True)
        type = models.CharField(
            choices=TYPE_CHOICES, default='Person', max_length=25)
        name = models.CharField(max_length=200, null=True, blank=True)
        domain = models.CharField(max_length=1000)
        summary = models.CharField(max_length=500, null=True, blank=True)
        preferred_username = models.CharField(
            max_length=200, null=True, blank=True)
        public_key = models.CharField(max_length=5000, null=True, blank=True)
        private_key = models.CharField(max_length=5000, null=True, blank=True)
        creation_date = models.DateTimeField(default=timezone.now)
        last_fetch_date = models.DateTimeField(
            default=timezone.now)
        manually_approves_followers = models.NullBooleanField(default=None)
    
        followers = models.ManyToManyField(
            to='self',
            symmetrical=False,
            through='Follow',
            through_fields=('target', 'actor'),
            related_name='following',
        )
    
        class Meta:
            unique_together = ['domain', 'preferred_username']
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        @property
        def webfinger_subject(self):
            return '{}@{}'.format(
                self.preferred_username,
                settings.FEDERATION_HOSTNAME,
            )
    
    
        @property
        def private_key_id(self):
            return '{}#main-key'.format(self.url)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    
        @property
        def mention_username(self):
            return '@{}@{}'.format(self.preferred_username, self.domain)
    
        def save(self, **kwargs):
            lowercase_fields = [
                'domain',
            ]
            for field in lowercase_fields:
                v = getattr(self, field, None)
                if v:
                    setattr(self, field, v.lower())
    
            super().save(**kwargs)
    
        @property
        def is_local(self):
            return self.domain == settings.FEDERATION_HOSTNAME
    
    
        @property
        def is_system(self):
            from . import actors
            return all([
                settings.FEDERATION_HOSTNAME == self.domain,
                self.preferred_username in actors.SYSTEM_ACTORS
            ])
    
    
        @property
        def system_conf(self):
            from . import actors
            if self.is_system:
                return actors.SYSTEM_ACTORS[self.preferred_username]
    
    
    
    class Follow(models.Model):
    
        ap_type = 'Follow'
    
    
        uuid = models.UUIDField(default=uuid.uuid4, unique=True)
        actor = models.ForeignKey(
            Actor,
            related_name='emitted_follows',
            on_delete=models.CASCADE,
        )
        target = models.ForeignKey(
            Actor,
            related_name='received_follows',
            on_delete=models.CASCADE,
        )
        creation_date = models.DateTimeField(default=timezone.now)
    
        modification_date = models.DateTimeField(
            auto_now=True)
    
        approved = models.NullBooleanField(default=None)
    
    
        class Meta:
            unique_together = ['actor', 'target']
    
    
        def get_federation_url(self):
            return '{}#follows/{}'.format(self.actor.url, self.uuid)
    
    class Library(models.Model):
        creation_date = models.DateTimeField(default=timezone.now)
        modification_date = models.DateTimeField(
            auto_now=True)
        fetched_date = models.DateTimeField(null=True, blank=True)
        actor = models.OneToOneField(
            Actor,
            on_delete=models.CASCADE,
            related_name='library')
        uuid = models.UUIDField(default=uuid.uuid4)
        url = models.URLField()
    
        # use this flag to disable federation with a library
        federation_enabled = models.BooleanField()
        # should we mirror files locally or hotlink them?
        download_files = models.BooleanField()
    
        # should we automatically import new files from this library?
        autoimport = models.BooleanField()
        tracks_count = models.PositiveIntegerField(null=True, blank=True)
    
    
    class LibraryTrack(models.Model):
        url = models.URLField(unique=True)
        audio_url = models.URLField()
        audio_mimetype = models.CharField(max_length=200)
        creation_date = models.DateTimeField(default=timezone.now)
        modification_date = models.DateTimeField(
            auto_now=True)
        fetched_date = models.DateTimeField(null=True, blank=True)
        published_date = models.DateTimeField(null=True, blank=True)
        library = models.ForeignKey(
            Library, related_name='tracks', on_delete=models.CASCADE)
        artist_name = models.CharField(max_length=500)
        album_title = models.CharField(max_length=500)
        title = models.CharField(max_length=500)
        metadata = JSONField(default={}, max_length=10000)