Exemple #1
0
class Series(models.Model):
    name = models.CharField(max_length=200)
    slug = AutoSlugField(populate_from='name',
                         editable=True,
                         blank=True,
                         overwrite=True)
    # uuid = UUIDField()
    uuid = models.UUIDField(default=uuid.uuid4, editable=False)
    description = extra.MarkdownTextField(blank=True, null=True)

    class Meta:
        app_label = 'alibrary'
        verbose_name = _('Series')
        verbose_name_plural = _('Series')
        ordering = ('-name', )

    def __unicode__(self):
        return '%s' % (self.name)
Exemple #2
0
class Shortcut(BaseModel):

    name = models.CharField(max_length=256, null=True, blank=True)
    #description = models.TextField(null=True, blank=True)
    description = extra.MarkdownTextField(blank=True, null=True)

    key = models.CharField(max_length=256, null=True, blank=True)

    position = models.PositiveIntegerField(default=0)

    url = models.URLField(_("link"), blank=True, null=True)
    page_link = models.ForeignKey(Page, verbose_name=_("page"), blank=True, null=True, help_text=_("A link to a page has priority over a text link."))
    
    collection = models.ForeignKey('ShortcutCollection', null=True, blank=True, on_delete=models.SET_NULL, related_name='shortcuts')


    
    # meta
    class Meta:
        app_label = 'shortcutter'
        verbose_name = _('Shortcut')
        verbose_name_plural = _('Shortcuts')
        ordering = ('position', 'name', )

    def __unicode__(self):
        return "%s" % self.name
    
    
    def get_link(self):
        if self.page_link:
            link = self.page_link.get_absolute_url()
        elif self.url:
            link = self.url
        else:
            link = None
            
        return link
    
    def save(self, *args, **kwargs):
        obj = self        
        super(Shortcut, self).save(*args, **kwargs)
class Station(BaseModel):

    name = models.CharField(max_length=256, null=True, blank=True)
    teaser = models.CharField(max_length=512, null=True, blank=True)
    slug = AutoSlugField(populate_from='name')
    
    TYPE_CHOICES = (
        ('stream', _('Stream')),
        ('djmon', _('DJ-Monitor')),
    )
    type = models.CharField(verbose_name=_('Type'), max_length=12, default='stream', choices=TYPE_CHOICES)
    
    main_image = FilerImageField(null=True, blank=True, related_name="station_main_image", rel='')
    description = extra.MarkdownTextField(blank=True, null=True)
    members = models.ManyToManyField(User, through='StationMembers', blank=True)
    website = models.URLField(max_length=256, null=True, blank=True)
    phone = PhoneNumberField(_('phone'), blank=True, null=True)
    fax = PhoneNumberField(_('fax'), blank=True, null=True)
    address1 = models.CharField(_('address'), null=True, blank=True, max_length=100)
    address2 = models.CharField(_('address (secondary)'), null=True, blank=True, max_length=100)
    city = models.CharField(_('city'), null=True, blank=True, max_length=100)
    zip = models.CharField(_('zip'), null=True, blank=True, max_length=10)
    country = models.ForeignKey(Country, blank=True, null=True)

    class Meta:
        app_label = 'abcast'
        verbose_name = _('Station')
        verbose_name_plural = _('Stations')
        ordering = ('name', )

    def __unicode__(self):
        return "%s" % self.name

    @models.permalink
    def get_absolute_url(self):
        return 'abcast-station-detail', [self.slug]

    def get_admin_url(self):
        return reverse("admin:abcast_station_change", args=(self.pk,))
Exemple #4
0
class Playlist(MigrationMixin, CachingMixin, models.Model):

    name = models.CharField(max_length=200)
    slug = AutoSlugField(populate_from='name',
                         editable=True,
                         blank=True,
                         overwrite=True)
    uuid = UUIDField()

    STATUS_CHOICES = (
        (0, _('Init')),
        (1, _('Ready')),
        (2, _('In progress')),
        (3, _('Scheduled')),
        (4, _('Descheduled')),
        (99, _('Error')),
        (11, _('Other')),
    )
    status = models.PositiveIntegerField(default=0, choices=STATUS_CHOICES)

    TYPE_CHOICES = (
        ('basket', _('Basket')),
        ('playlist', _('Playlist')),
        ('broadcast', _('Broadcast')),
        ('other', _('Other')),
    )
    type = models.CharField(max_length=12,
                            default='other',
                            null=True,
                            choices=TYPE_CHOICES)

    EDIT_MODE_CHOICES = (
        (0, _('Compact')),
        (1, _('Medium')),
        (2, _('Extended')),
    )
    edit_mode = models.PositiveIntegerField(default=2,
                                            choices=EDIT_MODE_CHOICES)

    rotation = models.BooleanField(default=False)

    main_image = models.ImageField(verbose_name=_('Image'),
                                   upload_to=filename_by_uuid,
                                   null=True,
                                   blank=True)

    # relations
    user = models.ForeignKey(User, null=True, blank=True, default=None)
    #media = models.ManyToManyField('Media', through='PlaylistMedia', blank=True, null=True)

    items = models.ManyToManyField('PlaylistItem',
                                   through='PlaylistItemPlaylist',
                                   blank=True,
                                   null=True)

    # tagging (d_tags = "display tags")
    d_tags = tagging.fields.TagField(max_length=1024,
                                     verbose_name="Tags",
                                     blank=True,
                                     null=True)

    # commenting
    enable_comments = models.BooleanField(_('Enable Comments'), default=True)

    # updated/calculated on save
    duration = models.IntegerField(max_length=12, null=True, default=0)

    target_duration = models.PositiveIntegerField(
        default=0, null=True, choices=TARGET_DURATION_CHOICES)

    dayparts = models.ManyToManyField(Daypart,
                                      null=True,
                                      blank=True,
                                      related_name='daypart_plalists')
    seasons = models.ManyToManyField('Season',
                                     null=True,
                                     blank=True,
                                     related_name='season_plalists')
    weather = models.ManyToManyField('Weather',
                                     null=True,
                                     blank=True,
                                     related_name='weather_plalists')

    #season = models.PositiveIntegerField(default=0, null=True, choices=TARGET_DURATION_CHOICES)

    # is currently selected as default?
    is_current = models.BooleanField(_('Currently selected?'), default=False)

    description = extra.MarkdownTextField(blank=True, null=True)

    # manager
    # objects = models.Manager()
    objects = CachingManager()

    # auto-update
    created = models.DateTimeField(auto_now_add=True, editable=False)
    updated = models.DateTimeField(auto_now=True, editable=False)

    # meta
    class Meta:
        app_label = 'alibrary'
        verbose_name = _('Playlist')
        verbose_name_plural = _('Playlists')
        ordering = ('-updated', )

        permissions = (
            ('view_playlist', 'View Playlist'),
            ('edit_playlist', 'Edit Playlist'),
            ('admin_playlist', 'Edit Playlist (extended)'),
        )

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return ('alibrary-playlist-detail', [self.slug])

    @models.permalink
    def get_edit_url(self):
        return ('alibrary-playlist-edit', [self.pk])

    def get_duration(self):
        duration = 0
        for item in self.items.all():
            duration += item.content_object.get_duration()

        # TODO: think about what to use as s reference
        duration = self.target_duration * 1000

        return duration

    #@models.permalink
    #def get_reorder_url(self):
    #    return ('alibrary-playlist-reorder', [self.pk])

    def get_api_url(self):
        return reverse('api_dispatch_detail',
                       kwargs={
                           'api_name': 'v1',
                           'resource_name': 'playlist',
                           'pk': self.pk
                       }) + ''

    def get_api_simple_url(self):
        return reverse('api_dispatch_detail',
                       kwargs={
                           'api_name': 'v1',
                           'resource_name': 'simpleplaylist',
                           'pk': self.pk
                       }) + ''

    def add_items_by_ids(self, ids, ct):

        from alibrary.models.mediamodels import Media

        log = logging.getLogger('alibrary.playlistmodels.add_items_by_ids')
        log.debug('Media ids: %s' % (ids))
        log.debug('Content Type: %s' % (ct))

        for id in ids:
            id = int(id)

            co = None

            if ct == 'media':
                co = Media.objects.get(pk=id)

            if ct == 'jingle':
                from abcast.models import Jingle
                co = Jingle.objects.get(pk=id)

            if co:

                i = PlaylistItem(content_object=co)
                i.save()
                """
                ctype = ContentType.objects.get_for_model(co)
                item, created = PlaylistItem.objects.get_or_create(object_id=co.pk, content_type=ctype)
                """

                pi, created = PlaylistItemPlaylist.objects.get_or_create(
                    item=i, playlist=self, position=self.items.count())
                # pi.save()

        self.save()

    def reorder_items_by_uuids(self, uuids):

        i = 0

        for uuid in uuids:
            print '%s - %s' % (i, uuid)

            pi = PlaylistItemPlaylist.objects.get(uuid=uuid)
            pi.position = i
            pi.save()

            i += 1

        self.save()

    """
    old method - for non-generic playlists
    """

    def add_media_by_ids(self, ids):

        from alibrary.models.mediamodels import Media

        log = logging.getLogger('alibrary.playlistmodels.add_media_by_id')
        log.debug('Media ids: %s' % (ids))

        for id in ids:
            id = int(id)

            m = Media.objects.get(pk=id)
            pm = PlaylistMedia(media=m,
                               playlist=self,
                               position=self.media.count())
            pm.save()

            print id
            print pm

            self.save()

    def convert_to(self, type):
        self.type = type
        self.save()

    def get_items(self):
        pis = PlaylistItemPlaylist.objects.filter(playlist=self)
        items = []
        for pi in pis:
            item = pi.item
            item.cue_in = pi.cue_in
            item.cue_out = pi.cue_out
            item.fade_in = pi.fade_in
            item.fade_out = pi.fade_out
            item.fade_cross = pi.fade_cross
            items.append(item)
        return items

    def save(self, *args, **kwargs):

        # status update
        if self.status == 0:
            self.status = 2
        """"""
        duration = 0
        try:
            for item in self.items.all():
                item.content_object.get_duration()
                if item.content_object.duration:
                    duration += item.content_object.duration
                    #duration -= item.cue_in
                    #duration -= item.cue_out
        except Exception, e:
            #print e
            pass

        self.duration = duration

        # update d_tags
        try:
            t_tags = ''
            for tag in self.tags:
                t_tags += '%s, ' % tag

            self.tags = t_tags
            self.d_tags = t_tags
        except Exception, e:
            #print e
            pass
Exemple #5
0
class Profile(MigrationMixin):
    """Profile model"""
    GENDER_CHOICES = (
        (0, _('Male')),
        (1, _('Female')),
        (2, _('Other')),
    )
    #user = models.ForeignKey(User, unique=True)
    user = models.OneToOneField(User, unique=True, on_delete=models.CASCADE)

    #
    uuid = UUIDField()

    # auto-update
    created = models.DateTimeField(auto_now_add=True, editable=False)
    updated = models.DateTimeField(auto_now=True, editable=False)

    #
    mentor = models.ForeignKey(User,
                               blank=True,
                               null=True,
                               related_name="godchildren")

    #Personal
    gender = models.PositiveSmallIntegerField(_('gender'),
                                              choices=GENDER_CHOICES,
                                              blank=True,
                                              null=True)
    birth_date = models.DateField(_('Date of birth'),
                                  blank=True,
                                  null=True,
                                  help_text=_('Format: YYYY-MM-DD'))

    # Profile
    pseudonym = models.CharField(
        blank=True,
        null=True,
        max_length=250,
        help_text=_('Will appear instead of your first- & last name'))
    description = models.CharField(_('Disambiguation'),
                                   blank=True,
                                   null=True,
                                   max_length=250)
    biography = extra.MarkdownTextField(blank=True, null=True)

    image = models.ImageField(verbose_name=_('Profile Image'),
                              upload_to=filename_by_uuid,
                              null=True,
                              blank=True)

    # Contact (personal)
    mobile = PhoneNumberField(_('mobile'), blank=True, null=True)
    phone = PhoneNumberField(_('phone'), blank=True, null=True)
    fax = PhoneNumberField(_('fax'), blank=True, null=True)

    address1 = models.CharField(_('address'),
                                null=True,
                                blank=True,
                                max_length=100)
    address2 = models.CharField(_('address (secondary)'),
                                null=True,
                                blank=True,
                                max_length=100)
    city = models.CharField(_('city'), null=True, blank=True, max_length=100)
    zip = models.CharField(_('zip'), null=True, blank=True, max_length=10)
    country = models.ForeignKey(Country, blank=True, null=True)

    iban = models.CharField(_('IBAN'), null=True, blank=True, max_length=120)
    paypal = models.EmailField(_('Paypal'),
                               null=True,
                               blank=True,
                               max_length=200)

    # relations
    expertise = models.ManyToManyField('Expertise',
                                       verbose_name=_('Fields of expertise'),
                                       blank=True)

    # tagging (d_tags = "display tags")
    d_tags = tagging.fields.TagField(max_length=1024,
                                     verbose_name="Tags",
                                     blank=True,
                                     null=True)

    # alpha features
    enable_alpha_features = models.BooleanField(default=False)

    class Meta:
        app_label = 'profiles'
        verbose_name = _('user profile')
        verbose_name_plural = _('user profiles')
        db_table = 'user_profiles'
        ordering = ('-user__last_login', )

        permissions = (
            ('mentor_profiles', _('Mentoring profiles')),
            ('view_profiles_private', _('View private profile-data.')),
        )

    def __unicode__(self):
        return u"%s" % self.get_display_name()

    def get_full_name(self):
        if self.user:
            return self.user.get_full_name()

    @property
    def name(self):
        return self.get_display_name()

    @property
    def main_image(self):
        return self.image

    def get_display_name(self):

        if self.pseudonym:
            return self.pseudonym

        if self.user.get_full_name():
            return self.user.get_full_name()

        return self.user.username

    @property
    def is_approved(self):
        if self.user in Group.objects.get(name='Mentor').user_set.all():
            return True

        return

    def approve(self, mentor, level):

        groups_to_add = []

        if level == 'music_pro':
            groups_to_add = (
                'Music PRO',
                'Mentor',
            )

        if level == 'radio_pro':
            groups_to_add = (
                'Radio PRO',
                'Mentor',
            )

        groups = Group.objects.filter(name__in=groups_to_add)

        for group in groups:
            self.user.groups.add(group)

        self.user.groups.remove(Group.objects.get(name=DEFAULT_GROUP))

    @property
    def age(self):
        TODAY = datetime.date.today()
        if self.birth_date:
            return u"%s" % relativedelta.relativedelta(TODAY,
                                                       self.birth_date).years
        else:
            return None

    def get_absolute_url(self):
        return reverse('profiles-profile-detail',
                       kwargs={'slug': self.user.username})

    @models.permalink
    def get_edit_url(self):
        return ('profiles-profile-edit', )

    def get_admin_url(self):
        return reverse("admin:profiles_profile_change", args=(self.pk, ))

    def get_api_url(self):
        return reverse('api_dispatch_detail',
                       kwargs={
                           'api_name': 'v1',
                           'resource_name': 'profile',
                           'pk': self.pk
                       })

    @property
    def sms_address(self):
        if (self.mobile and self.mobile_provider):
            return u"%s@%s" % (re.sub(
                '-', '', self.mobile), self.mobile_provider.domain)

    def get_groups(self):
        return self.user.groups

    def save(self, *args, **kwargs):
        super(Profile, self).save(*args, **kwargs)
Exemple #6
0
class Community(MigrationMixin):

    uuid = UUIDField(primary_key=False)
    name = models.CharField(max_length=200, db_index=True)
    slug = AutoSlugField(populate_from='name',
                         editable=True,
                         blank=True,
                         overwrite=True)

    group = models.OneToOneField(Group, unique=True, null=True, blank=True)
    members = models.ManyToManyField(User, blank=True)

    # auto-update
    created = models.DateTimeField(auto_now_add=True, editable=False)
    updated = models.DateTimeField(auto_now=True, editable=False)

    # Profile
    description = extra.MarkdownTextField(blank=True, null=True)
    image = models.ImageField(verbose_name=_('Profile Image'),
                              upload_to=filename_by_uuid,
                              null=True,
                              blank=True)

    # Contact
    mobile = PhoneNumberField(_('mobile'), blank=True, null=True)
    phone = PhoneNumberField(_('phone'), blank=True, null=True)
    fax = PhoneNumberField(_('fax'), blank=True, null=True)
    email = models.EmailField(blank=True, null=True)

    address1 = models.CharField(_('address'),
                                null=True,
                                blank=True,
                                max_length=100)
    address2 = models.CharField(_('address (secondary)'),
                                null=True,
                                blank=True,
                                max_length=100)
    city = models.CharField(_('city'), null=True, blank=True, max_length=100)
    zip = models.CharField(_('zip'), null=True, blank=True, max_length=10)
    #country = CountryField(blank=True, null=True)
    country = models.ForeignKey(Country, blank=True, null=True)
    # relations
    expertise = models.ManyToManyField('Expertise',
                                       verbose_name=_('Fields of expertise'),
                                       blank=True)

    # tagging (d_tags = "display tags")
    d_tags = tagging.fields.TagField(verbose_name="Tags",
                                     blank=True,
                                     null=True)

    class Meta:
        app_label = 'profiles'
        verbose_name = _('Community')
        verbose_name_plural = _('Communities')
        """
        permissions = (
            ('mentor_profiles', 'Mentoring profiles'),
        )
        """

    def __unicode__(self):
        return u"%s" % self.name

    """
    @permalink
    def get_absolute_url(self):
        return ('profiles-profile-detail', None, { 'slug': self.user.username })
    """

    def save(self, *args, **kwargs):
        t_tags = ''
        """"""
        for tag in self.tags:
            t_tags += '%s, ' % tag

        self.tags = t_tags
        self.d_tags = t_tags[:245]

        super(Community, self).save(*args, **kwargs)
Exemple #7
0
class Label(MigrationMixin):

    uuid = models.UUIDField(default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=400)
    slug = AutoSlugField(populate_from='name', editable=True, blank=True, overwrite=True)

    labelcode = models.CharField(max_length=250, blank=True, null=True)
    address = models.TextField(blank=True, null=True)
    country = models.ForeignKey(Country, blank=True, null=True)

    email = models.EmailField(blank=True, null=True)
    phone = PhoneNumberField(blank=True, null=True)
    fax = PhoneNumberField(blank=True, null=True)
    main_image = models.ImageField(verbose_name=_('Logo Image'), upload_to=upload_image_to, storage=OverwriteStorage(), null=True, blank=True)
    description = extra.MarkdownTextField(blank=True, null=True)

    created = models.DateTimeField(auto_now_add=True, editable=False)
    updated = models.DateTimeField(auto_now=True, editable=False)

    date_start = ApproximateDateField(verbose_name="Life-span begin", blank=True, null=True)
    date_end = ApproximateDateField(verbose_name="Life-span end", blank=True, null=True)

    owner = models.ForeignKey(User, blank=True, null=True, related_name="labels_owner", on_delete=models.SET_NULL)
    creator = models.ForeignKey(User, blank=True, null=True, related_name="labels_creator", on_delete=models.SET_NULL)
    last_editor = models.ForeignKey(User, blank=True, null=True, related_name="labels_last_editor", on_delete=models.SET_NULL)
    publisher = models.ForeignKey(User, blank=True, null=True, related_name="labels_publisher", on_delete=models.SET_NULL)

    listed = models.BooleanField(verbose_name='Include in listings', default=True, help_text=_('Should this Label be shown on the default Label-list?'))
    disable_link = models.BooleanField(verbose_name='Disable Link', default=False, help_text=_('Disable Linking. Useful e.g. for "Unknown Label"'))
    disable_editing = models.BooleanField(verbose_name='Disable Editing', default=False, help_text=_('Disable Editing. Useful e.g. for "Unknown Label"'))

    type = models.CharField(verbose_name="Label type", max_length=128, default='unknown', choices=alibrary_settings.LABELTYPE_CHOICES)

    relations = GenericRelation('Relation')
    d_tags = tagging.fields.TagField(max_length=1024,verbose_name="Tags", blank=True, null=True)

    # refactoring parent handling
    parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
    parent_temporary_id = models.PositiveIntegerField(null=True, blank=True)

    objects = LabelManager()

    class Meta:
        app_label = 'alibrary'
        verbose_name = _('Label')
        verbose_name_plural = _('Labels')
        ordering = ('name', )

        permissions = (
            ('merge_label', 'Merge Labels'),
        )


    def __unicode__(self):
        return self.name

    def get_folder(self, name):
        return

    def get_lookup_providers(self):

        providers = []
        for key, name in LOOKUP_PROVIDERS:
            relations = self.relations.filter(service=key)
            relation = None
            if relations.count() == 1:
                relation = relations[0]

            providers.append({'key': key, 'name': name, 'relation': relation})

        return providers


    def get_absolute_url(self):
        if self.disable_link:
            return None
        return reverse('alibrary-label-detail', kwargs={
            'pk': self.pk,
            'slug': self.slug,
        })

    def get_edit_url(self):
        return reverse("alibrary-label-edit", args=(self.pk,))

    def get_admin_url(self):
        return reverse("admin:alibrary_label_change", args=(self.pk,))


    def get_api_url(self):
        return reverse('api_dispatch_detail', kwargs={
            'api_name': 'v1',
            'resource_name': 'library/label',
            'pk': self.pk
        }) + ''


    def get_root(self):

        if not self.parent:
            return None

        if self.parent == self:
            return None

        parent = self.parent
        last_parent = None
        i = 0
        while parent and i < 10:
            i += 1
            parent = parent.parent
            if parent:
                last_parent = parent

        return last_parent



    def save(self, *args, **kwargs):
        unique_slugify(self, self.name)
        super(Label, self).save(*args, **kwargs)
Exemple #8
0
class Profile(MigrationMixin):
    """Profile model"""
    GENDER_CHOICES = (
        (0, _('Male')),
        (1, _('Female')),
        (2, _('Other')),
    )
    #user = models.ForeignKey(User, unique=True)
    user = models.OneToOneField(User, unique=True)

    #
    uuid = UUIDField()

    # auto-update
    created = models.DateTimeField(auto_now_add=True, editable=False)
    updated = models.DateTimeField(auto_now=True, editable=False)

    #
    mentor = models.ForeignKey(User,
                               blank=True,
                               null=True,
                               related_name="godchildren")

    #Personal
    gender = models.PositiveSmallIntegerField(_('gender'),
                                              choices=GENDER_CHOICES,
                                              blank=True,
                                              null=True)
    birth_date = models.DateField(_('Date of birth'), blank=True, null=True)

    # Profile
    description = extra.MarkdownTextField(blank=True, null=True)
    image = models.ImageField(verbose_name=_('Profile Image'),
                              upload_to=filename_by_uuid,
                              null=True,
                              blank=True)

    # hm...
    # mugshot = models.FileField(_('mugshot'), upload_to='mugshots', null=True, blank=True)

    # Contact
    mobile = PhoneNumberField(_('mobile'), blank=True, null=True)
    phone = PhoneNumberField(_('phone'), blank=True, null=True)
    fax = PhoneNumberField(_('fax'), blank=True, null=True)

    address1 = models.CharField(_('address'),
                                null=True,
                                blank=True,
                                max_length=100)
    address2 = models.CharField(_('address (secondary)'),
                                null=True,
                                blank=True,
                                max_length=100)
    # state = models.CharField(_('state'), null=True, blank=True, max_length=100)
    city = models.CharField(_('city'), null=True, blank=True, max_length=100)
    zip = models.CharField(_('zip'), null=True, blank=True, max_length=10)
    #country = models.CharField(_('country'), null=True, blank=True, max_length=100)
    #country = CountryField(blank=True, null=True)
    country = models.ForeignKey(Country, blank=True, null=True)

    iban = models.CharField(_('IBAN'), null=True, blank=True, max_length=120)
    paypal = models.EmailField(_('Paypal'),
                               null=True,
                               blank=True,
                               max_length=200)

    # relations
    expertise = models.ManyToManyField('Expertise',
                                       verbose_name=_('Fields of expertise'),
                                       null=True,
                                       blank=True)

    # tagging (d_tags = "display tags")
    d_tags = tagging.fields.TagField(max_length=1024,
                                     verbose_name="Tags",
                                     blank=True,
                                     null=True)

    class Meta:
        app_label = 'profiles'
        verbose_name = _('user profile')
        verbose_name_plural = _('user profiles')
        db_table = 'user_profiles'
        ordering = ('-user__last_login', )

        permissions = (('mentor_profiles', 'Mentoring profiles'), )

    def __unicode__(self):
        return u"%s" % self.user.get_full_name()

    @property
    def is_approved(self):

        if self.user in Group.objects.get(name='Member').user_set.all():
            return True

        return

    def approve(self, mentor):
        groups = Group.objects.filter(name__in=APPROVED_GROUPS)

        for group in groups:
            self.user.groups.add(group)

    @property
    def age(self):
        TODAY = datetime.date.today()
        if self.birth_date:
            return u"%s" % relativedelta.relativedelta(TODAY,
                                                       self.birth_date).years
        else:
            return None

    @permalink
    def get_absolute_url(self):
        return ('profiles-profile-detail', None, {'slug': self.user.username})

    @property
    def sms_address(self):
        if (self.mobile and self.mobile_provider):
            return u"%s@%s" % (re.sub(
                '-', '', self.mobile), self.mobile_provider.domain)

    def get_groups(self):
        return self.user.groups

    def save(self, *args, **kwargs):
        t_tags = ''
        """"""
        for tag in self.tags:
            t_tags += '%s, ' % tag

        self.tags = t_tags
        self.d_tags = t_tags[:1000]

        super(Profile, self).save(*args, **kwargs)
Exemple #9
0
class Release(MigrationMixin):

    # core fields
    uuid = UUIDField(primary_key=False)
    name = models.CharField(max_length=200, db_index=True)
    slug = AutoSlugField(populate_from='name',
                         editable=True,
                         blank=True,
                         overwrite=True)

    license = models.ForeignKey(License,
                                blank=True,
                                null=True,
                                related_name='release_license')

    release_country = CountryField(blank=True, null=True)

    uuid = UUIDField()

    main_image = FilerImageField(null=True,
                                 blank=True,
                                 related_name="release_main_image",
                                 rel='')
    cover_image = FilerImageField(
        null=True,
        blank=True,
        related_name="release_cover_image",
        rel='',
        help_text=_(
            'Cover close-up. Used e.g. for embedding in digital files.'))

    if FORCE_CATALOGNUMBER:
        catalognumber = models.CharField(max_length=50)
    else:
        catalognumber = models.CharField(max_length=50, blank=True, null=True)
    """
    releasedate stores the 'real' time, approx is for inputs
    lik 2012-12 etc.
    """
    releasedate = models.DateField(blank=True, null=True)
    releasedate_approx = ApproximateDateField(verbose_name="Releasedate",
                                              blank=True,
                                              null=True)

    pressings = models.PositiveIntegerField(max_length=12, default=0)

    totaltracks = models.IntegerField(null=True, blank=True)
    asin = models.CharField(max_length=150, blank=True)

    RELEASESTATUS_CHOICES = (
        (None, _('Not set')),
        ('official', _('Official')),
        ('promo', _('Promo')),
        ('bootleg', _('Bootleg')),
        ('other', _('Other')),
    )

    releasestatus = models.CharField(max_length=60,
                                     blank=True,
                                     choices=RELEASESTATUS_CHOICES)

    #publish_date = models.DateTimeField(default=datetime.now, blank=True, null=True, help_text=_('If set this Release will not be published on the site before the given date.'))
    publish_date = models.DateTimeField(
        blank=True,
        null=True,
        help_text=
        _('If set this Release will not be published on the site before the given date.'
          ))

    main_format = models.ForeignKey(Mediaformat,
                                    null=True,
                                    blank=True,
                                    on_delete=models.SET_NULL)

    #
    excerpt = models.TextField(blank=True, null=True)
    description = extra.MarkdownTextField(blank=True, null=True)

    # cms field
    placeholder_1 = PlaceholderField('placeholder_1')

    RELEASETYPE_CHOICES = (
        ('ep', _('EP')),
        ('album', _('Album')),
        ('compilation', _('Compilation')),
        ('remix', _('Remix')),
        ('live', _('Live')),
        ('single', _('Single')),
        ('other', _('Other')),
    )

    RELEASETYPE_CHOICES = (
        (_('General'), (
            ('ep', _('EP')),
            ('album', _('Album')),
            ('compilation', _('Compilation')),
            ('single', _('Single')),
        )),
        (_('Recording'), (
            ('remix', _('Remix')),
            ('live', _('Live')),
        )),
        ('other', _('Other')),
        ('unknown', _('Unknown')),
    )

    releasetype = models.CharField(verbose_name="Release type",
                                   max_length=24,
                                   default='other',
                                   choices=RELEASETYPE_CHOICES)

    # relations
    label = models.ForeignKey(Label,
                              blank=True,
                              null=True,
                              related_name='release_label',
                              on_delete=models.SET_NULL)
    folder = models.ForeignKey(Folder,
                               blank=True,
                               null=True,
                               related_name='release_folder',
                               on_delete=models.SET_NULL)

    # reworking media relationship
    media = models.ManyToManyField('Media',
                                   through='ReleaseMedia',
                                   blank=True,
                                   null=True,
                                   related_name="releases")
    #media = SortedManyToManyField('Media', blank=True, null=True, related_name="releases")

    # user relations
    owner = models.ForeignKey(User,
                              blank=True,
                              null=True,
                              related_name="releases_owner",
                              on_delete=models.SET_NULL)
    creator = models.ForeignKey(User,
                                blank=True,
                                null=True,
                                related_name="releases_creator",
                                on_delete=models.SET_NULL)
    publisher = models.ForeignKey(User,
                                  blank=True,
                                  null=True,
                                  related_name="releases_publisher",
                                  on_delete=models.SET_NULL)

    # extra-artists
    extra_artists = models.ManyToManyField('Artist',
                                           through='ReleaseExtraartists',
                                           blank=True,
                                           null=True)

    def get_extra_artists(self):
        ea = []
        for artist in self.extra_artists.all():
            ea.push(artist.name)
        return ea

    # special relation to provide 'multi-names' for artists.
    album_artists = models.ManyToManyField('Artist',
                                           through='ReleaseAlbumartists',
                                           related_name="release_albumartists",
                                           blank=True,
                                           null=True)

    # relations a.k.a. links
    relations = generic.GenericRelation(Relation)

    # tagging (d_tags = "display tags")
    d_tags = tagging.fields.TagField(max_length=1024,
                                     verbose_name="Tags",
                                     blank=True,
                                     null=True)

    enable_comments = models.BooleanField(_('Enable Comments'), default=True)

    # manager
    objects = ReleaseManager()

    # auto-update
    created = models.DateField(auto_now_add=True, editable=False)
    updated = models.DateField(auto_now=True, editable=False)

    # meta
    class Meta:
        app_label = 'alibrary'
        verbose_name = _('Release')
        verbose_name_plural = _('Releases')
        ordering = ('-created', )

        permissions = (
            ('view_release', 'View Release'),
            ('edit_release', 'Edit Release'),
            ('admin_release', 'Edit Release (extended)'),
        )

    def __unicode__(self):
        return self.name

    @property
    def classname(self):
        return self.__class__.__name__

    def get_versions(self):

        try:
            return reversion.get_for_object(self)
        except:
            return None

    def get_last_revision(self):
        try:
            return reversion.get_unique_for_object(self)[0].revision
        except:
            return None

    def get_last_editor(self):

        latest_revision = self.get_last_revision()

        if latest_revision:
            return latest_revision.user

        else:
            return None

    def is_active(self):

        now = date.today()
        try:
            if not self.releasedate:
                return True

            if self.releasedate <= now:
                return True

        except:
            pass

        return False

    def get_lookup_providers(self):

        providers = []
        for key, name in LOOKUP_PROVIDERS:
            relations = self.relations.filter(service=key)
            relation = None
            if relations.count() == 1:
                relation = relations[0]

            providers.append({'key': key, 'name': name, 'relation': relation})

        return providers

    @models.permalink
    def get_absolute_url(self):
        return ('alibrary-release-detail', [self.slug])

    @models.permalink
    def get_edit_url(self):
        return ('alibrary-release-edit', [self.pk])

    def get_admin_url(self):
        from lib.util.get_admin_url import change_url
        return change_url(self)

    def get_api_url(self):
        return reverse('api_dispatch_detail',
                       kwargs={
                           'api_name': 'v1',
                           'resource_name': 'release',
                           'pk': self.pk
                       }) + ''

    def get_media(self):
        return Media.objects.filter(release=self).select_related()

    def get_products(self):
        return self.releaseproduct.all()

    def get_media_indicator(self):

        media = self.get_media()

        indicator = []

        if self.totaltracks:
            for i in range(self.totaltracks):
                indicator.append(0)

            for m in media:
                try:
                    indicator[m.tracknumber - 1] = 3
                except Exception, e:
                    pass

        else:
Exemple #10
0
class Label(MPTTModel, MigrationMixin):

    # core fields
    uuid = UUIDField(primary_key=False)
    name = models.CharField(max_length=400)
    slug = AutoSlugField(populate_from='name',
                         editable=True,
                         blank=True,
                         overwrite=True)

    labelcode = models.CharField(max_length=250, blank=True, null=True)
    address = models.TextField(blank=True, null=True)

    #country = CountryField(blank=True, null=True)
    country = models.ForeignKey(Country, blank=True, null=True)

    email = models.EmailField(blank=True, null=True)
    phone = PhoneNumberField(blank=True, null=True)
    fax = PhoneNumberField(blank=True, null=True)

    main_image = FilerImageField(null=True,
                                 blank=True,
                                 related_name="label_main_image",
                                 rel='')

    description = extra.MarkdownTextField(blank=True, null=True)

    first_placeholder = PlaceholderField('first_placeholder')

    # auto-update
    created = models.DateField(auto_now_add=True, editable=False)
    updated = models.DateField(auto_now=True, editable=False)

    # relations
    parent = TreeForeignKey('self',
                            null=True,
                            blank=True,
                            related_name='label_children')
    folder = models.ForeignKey(Folder,
                               blank=True,
                               null=True,
                               related_name='label_folder')

    # user relations
    owner = models.ForeignKey(User,
                              blank=True,
                              null=True,
                              related_name="labels_owner",
                              on_delete=models.SET_NULL)
    creator = models.ForeignKey(User,
                                blank=True,
                                null=True,
                                related_name="labels_creator",
                                on_delete=models.SET_NULL)
    publisher = models.ForeignKey(User,
                                  blank=True,
                                  null=True,
                                  related_name="labels_publisher",
                                  on_delete=models.SET_NULL)

    # properties to create 'special' objects. (like 'Unknown')
    listed = models.BooleanField(
        verbose_name='Include in listings',
        default=True,
        help_text=_('Should this Label be shown on the default Label-list?'))
    disable_link = models.BooleanField(
        verbose_name='Disable Link',
        default=False,
        help_text=_('Disable Linking. Useful e.g. for "Unknown Label"'))
    disable_editing = models.BooleanField(
        verbose_name='Disable Editing',
        default=False,
        help_text=_('Disable Editing. Useful e.g. for "Unknown Label"'))

    TYPE_CHOICES = (
        ('unknown', _('Unknown')),
        ('major', _('Major Label')),
        ('indy', _('Independent Label')),
        ('net', _('Netlabel')),
        ('event', _('Event Label')),
    )

    type = models.CharField(verbose_name="Label type",
                            max_length=12,
                            default='unknown',
                            choices=TYPE_CHOICES)

    # relations a.k.a. links
    relations = generic.GenericRelation('Relation')

    # tagging (d_tags = "display tags")
    d_tags = tagging.fields.TagField(max_length=1024,
                                     verbose_name="Tags",
                                     blank=True,
                                     null=True)

    # manager
    objects = LabelManager()

    # meta
    class Meta:
        app_label = 'alibrary'
        verbose_name = _('Label')
        verbose_name_plural = _('Labels')
        ordering = ('name', )

    class MPTTMeta:
        order_insertion_by = ['name']

    def __unicode__(self):
        return self.name

    def get_folder(self, name):
        folder, created = Folder.objects.get_or_create(name=name,
                                                       parent=self.folder)
        return folder

    @models.permalink
    def get_absolute_url(self):
        if self.disable_link:
            return None

        return ('alibrary-label-detail', [self.slug])

    @models.permalink
    def get_edit_url(self):
        return ('alibrary-label-edit', [self.pk])

    def save(self, *args, **kwargs):
        unique_slugify(self, self.name)

        # update d_tags
        t_tags = ''
        for tag in self.tags:
            t_tags += '%s, ' % tag

        self.tags = t_tags
        self.d_tags = t_tags

        super(Label, self).save(*args, **kwargs)
class Channel(BaseModel):

    name = models.CharField(max_length=256, null=True, blank=True)
    teaser = models.CharField(max_length=512, null=True, blank=True)
    slug = AutoSlugField(populate_from='name')
    
    TYPE_CHOICES = (
        ('stream', _('Stream')),
        ('djmon', _('DJ-Monitor')),
    )
    type = models.CharField(verbose_name=_('Type'), max_length=12, default='stream', choices=TYPE_CHOICES)
    
    stream_url = models.CharField(max_length=256, null=True, blank=True, help_text=_('setting the stream-url overrides server settings'))
    description = extra.MarkdownTextField(blank=True, null=True)
    station = models.ForeignKey('Station', null=True, blank=True, on_delete=models.SET_NULL)
    rtmp_app = models.CharField(max_length=256, null=True, blank=True)
    rtmp_path = models.CharField(max_length=256, null=True, blank=True)
    has_scheduler = models.BooleanField(default=False)
    mount = models.CharField(max_length=64, null=True, blank=True)

    # credentials for tunein api
    tunein_station_id = models.CharField(max_length=16, null=True, blank=True)
    tunein_partner_id = models.CharField(max_length=16, null=True, blank=True)
    tunein_partner_key = models.CharField(max_length=16, null=True, blank=True)

    # credentials for icecast2 metadata
    icecast2_server = models.CharField(max_length=256, null=True, blank=True)
    icecast2_mountpoint = models.CharField(max_length=128, null=True, blank=True)
    icecast2_admin_user = models.CharField(max_length=128, null=True, blank=True)
    icecast2_admin_pass = models.CharField(max_length=128, null=True, blank=True)

    on_air_type = models.ForeignKey(ContentType, null=True, blank=True)
    on_air_id = models.PositiveIntegerField(null=True, blank=True)
    on_air = GenericForeignKey('on_air_type', 'on_air_id')

    class Meta:
        app_label = 'abcast'
        verbose_name = _('Channel')
        verbose_name_plural = _('Channels')
        ordering = ('name', )
        unique_together = ('on_air_type', 'on_air_id')

    def __unicode__(self):
        return "%s" % self.name


    def get_absolute_url(self):
        return reverse('abcast-station-detail', kwargs={
            'slug': self.station.slug
        })
    
    def get_api_url(self):
        return reverse('api_dispatch_detail', kwargs={  
            'api_name': 'v1',  
            'resource_name': 'abcast/channel',  
            'pk': self.pk  
        }) + ''

    def get_dayparts(self, day):
        dayparts = []
        daypart_sets = self.daypartsets.filter(time_start__lte=day, time_end__gte=day, channel=self)
        daypart_set = None
        if daypart_sets.count() > 0:
            daypart_set = daypart_sets[0]

        if daypart_set:
            for dp in daypart_set.daypart_set.all():
                dayparts.append(dp)
        
        return dayparts


    def get_on_air(self):
        """
        merge currently playing item (told by pypo) with estimated scheduler entry for the emission
        """
        now = datetime.datetime.now()
        emissions = self.scheduler_emissions.filter(channel__pk=self.pk, time_start__lte=now, time_end__gte=now)
        if emissions.count() > 0:

            emission = emissions[0]
            emission_url = emissions[0].get_api_url()

            emission_items = []
            """
            for e in emission.get_timestamped_media():
                item = e.content_object
                emission_items.append({
                    'pk': item.pk,
                    'time_start': e.timestamp,
                    'resource_uri': item.get_api_url()
                })
            """

        else:
            emission_url = None
            emission_items = []

        try:
            item_url = self.on_air.get_api_url()
        except:
            item_url = None

        on_air = {
            'item': item_url,
            'emission': emission_url,
            'emission_items': emission_items
        }

        return on_air
class Distributor(MigrationMixin):

    # core fields
    #uuid = UUIDField(primary_key=False)
    uuid = models.UUIDField(default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=400)
    slug = AutoSlugField(populate_from='name',
                         editable=True,
                         blank=True,
                         overwrite=True)

    code = models.CharField(max_length=50)
    country = models.ForeignKey(Country, blank=True, null=True)

    address = models.TextField(blank=True, null=True)

    email = models.EmailField(blank=True, null=True)
    phone = PhoneNumberField(blank=True, null=True)
    fax = PhoneNumberField(blank=True, null=True)

    description = extra.MarkdownTextField(blank=True, null=True)

    first_placeholder = PlaceholderField('first_placeholder')

    # auto-update
    created = models.DateTimeField(auto_now_add=True, editable=False)
    updated = models.DateTimeField(auto_now=True, editable=False)

    # relations
    parent = models.ForeignKey('self',
                               null=True,
                               blank=True,
                               related_name='children')

    labels = models.ManyToManyField('Label',
                                    through='DistributorLabel',
                                    blank=True,
                                    related_name="distributors")

    # user relations
    owner = models.ForeignKey(User,
                              blank=True,
                              null=True,
                              related_name="distributors_owner",
                              on_delete=models.SET_NULL)
    creator = models.ForeignKey(User,
                                blank=True,
                                null=True,
                                related_name="distributors_creator",
                                on_delete=models.SET_NULL)
    publisher = models.ForeignKey(User,
                                  blank=True,
                                  null=True,
                                  related_name="distributors_publisher",
                                  on_delete=models.SET_NULL)

    TYPE_CHOICES = (
        ('unknown', _('Unknown')),
        ('major', _('Major')),
        ('indy', _('Independent')),
        ('other', _('Other')),
    )

    type = models.CharField(verbose_name="Distributor type",
                            max_length=12,
                            default='unknown',
                            choices=TYPE_CHOICES)

    # relations a.k.a. links
    relations = GenericRelation('Relation')

    # tagging (d_tags = "display tags")
    d_tags = tagging.fields.TagField(max_length=1024,
                                     verbose_name="Tags",
                                     blank=True,
                                     null=True)

    # manager
    objects = models.Manager()

    # meta
    class Meta:
        app_label = 'alibrary'
        verbose_name = _('Distributor')
        verbose_name_plural = _('Distributors')
        ordering = ('name', )

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return ('alibrary-distributor-detail', [self.slug])

    @models.permalink
    def get_edit_url(self):
        return ('alibrary-distributor-edit', [self.pk])

    def save(self, *args, **kwargs):
        unique_slugify(self, self.name)

        # update d_tags
        t_tags = ''
        for tag in self.tags:
            t_tags += '%s, ' % tag

        self.tags = t_tags
        self.d_tags = t_tags

        super(Distributor, self).save(*args, **kwargs)
Exemple #13
0
class Playlist(MigrationMixin, models.Model):
    name = models.CharField(max_length=200)
    slug = AutoSlugField(populate_from='name',
                         editable=True,
                         blank=True,
                         overwrite=True)
    # uuid = UUIDField()
    uuid = models.UUIDField(default=uuid.uuid4, editable=False)

    status = models.PositiveIntegerField(
        default=0, choices=alibrary_settings.PLAYLIST_STATUS_CHOICES)
    type = models.CharField(max_length=12,
                            default='basket',
                            null=True,
                            choices=alibrary_settings.PLAYLIST_TYPE_CHOICES)
    broadcast_status = models.PositiveIntegerField(
        default=0, choices=alibrary_settings.PLAYLIST_BROADCAST_STATUS_CHOICES)
    broadcast_status_messages = JSONField(blank=True, null=True, default=None)

    EDIT_MODE_CHOICES = (
        (0, _('Compact')),
        (1, _('Medium')),
        (2, _('Extended')),
    )
    edit_mode = models.PositiveIntegerField(default=2,
                                            choices=EDIT_MODE_CHOICES)

    rotation = models.BooleanField(default=True)
    rotation_date_start = models.DateField(verbose_name=_('Rotate from'),
                                           blank=True,
                                           null=True)
    rotation_date_end = models.DateField(verbose_name=_('Rotate until'),
                                         blank=True,
                                         null=True)

    main_image = models.ImageField(verbose_name=_('Image'),
                                   upload_to=upload_image_to,
                                   storage=OverwriteStorage(),
                                   null=True,
                                   blank=True)

    # relations
    user = models.ForeignKey(User, null=True, blank=True, default=None)
    # media = models.ManyToManyField('Media', through='PlaylistMedia', blank=True, null=True)

    items = models.ManyToManyField('PlaylistItem',
                                   through='PlaylistItemPlaylist',
                                   blank=True)

    # tagging (d_tags = "display tags")
    d_tags = tagging.fields.TagField(max_length=1024,
                                     verbose_name="Tags",
                                     blank=True,
                                     null=True)

    # updated/calculated on save
    duration = models.IntegerField(null=True, default=0)

    target_duration = models.PositiveIntegerField(
        default=0,
        null=True,
        choices=alibrary_settings.PLAYLIST_TARGET_DURATION_CHOICES)

    dayparts = models.ManyToManyField(Daypart,
                                      blank=True,
                                      related_name='daypart_plalists')
    seasons = models.ManyToManyField('Season',
                                     blank=True,
                                     related_name='season_plalists')
    weather = models.ManyToManyField('Weather',
                                     blank=True,
                                     related_name='weather_plalists')

    # series
    series = models.ForeignKey(Series,
                               null=True,
                               blank=True,
                               on_delete=models.SET_NULL)
    series_number = models.PositiveIntegerField(null=True, blank=True)

    # is currently selected as default?
    is_current = models.BooleanField(_('Currently selected?'), default=False)

    description = extra.MarkdownTextField(blank=True, null=True)

    # auto-update
    created = models.DateTimeField(auto_now_add=True, editable=False)
    updated = models.DateTimeField(auto_now=True, editable=False)

    mixdown_file = models.FileField(null=True,
                                    blank=True,
                                    upload_to=upload_mixdown_to)

    # meta
    class Meta:
        app_label = 'alibrary'
        verbose_name = _('Playlist')
        verbose_name_plural = _('Playlists')
        ordering = ('-updated', )

        permissions = (
            ('view_playlist', 'View Playlist'),
            ('edit_playlist', 'Edit Playlist'),
            ('schedule_playlist', 'Schedule Playlist'),
            ('admin_playlist', 'Edit Playlist (extended)'),
        )

    def __unicode__(self):
        return self.name

    @property
    def sorted_items(self):
        return self.items.order_by('playlistitemplaylist__position')

    def get_absolute_url(self):
        return reverse('alibrary-playlist-detail',
                       kwargs={
                           'slug': self.slug,
                       })

    def get_edit_url(self):
        return reverse("alibrary-playlist-edit", args=(self.pk, ))

    def get_delete_url(self):
        return reverse("alibrary-playlist-delete", args=(self.pk, ))

    def get_admin_url(self):
        return reverse("admin:alibrary_playlist_change", args=(self.pk, ))

    def get_duration(self):
        duration = 0
        try:
            for item in self.items.all():
                duration += item.content_object.get_duration()
                pip = PlaylistItemPlaylist.objects.get(playlist=self,
                                                       item=item)
                duration -= pip.cue_in
                duration -= pip.cue_out
                duration -= pip.fade_cross
        except:
            pass

        return duration

    def get_emissions(self):
        from abcast.models import Emission
        ctype = ContentType.objects.get_for_model(self)
        emissions = Emission.objects.filter(
            content_type__pk=ctype.id,
            object_id=self.id).order_by('-time_start')
        return emissions

    def get_api_url(self):
        return reverse('api_dispatch_detail',
                       kwargs={
                           'api_name': 'v1',
                           'resource_name': 'library/playlist',
                           'pk': self.pk
                       }) + ''

    def get_api_simple_url(self):
        return reverse('api_dispatch_detail',
                       kwargs={
                           'api_name': 'v1',
                           'resource_name': 'library/simpleplaylist',
                           'pk': self.pk
                       }) + ''

    def can_be_deleted(self):

        can_delete = False
        reason = _('This playlist cannot be deleted.')

        if self.type == 'basket':
            can_delete = True
            reason = None

        if self.type == 'playlist':
            can_delete = False
            reason = _(
                'Playlist "%s" is public. It cannot be deleted anymore.' %
                self.name)

        if self.type == 'broadcast':
            can_delete = False
            reason = _(
                'Playlist "%s" published for broadcast. It cannot be deleted anymore.'
                % self.name)

        return can_delete, reason

    def get_transform_status(self, target_type):
        """
        check if transformation is possible /
        what needs to be done
        Not so nicely here - but...
        """

        status = False
        """
        criterias = [
            {
                'key': 'tags',
                'name': _('Tags'),
                'status': True,
                'warning': _('Please add some tags'),
            },
            {
                'key': 'description',
                'name': _('Description'),
                'status': False,
                'warning': _('Please add a description'),
            }
        ]
        """

        criterias = []

        # "basket" only used while dev...
        if target_type == 'basket':
            status = True

        if target_type == 'playlist':
            status = True
            # tags
            tag_count = self.tags.count()
            if tag_count < 1:
                status = False
            criteria = {
                'key': 'tags',
                'name': _('Tags'),
                'status': tag_count > 0,
                'warning': _('Please add some tags'),
            }
            criterias.append(criteria)
            # scheduled
            if self.type == 'broadcast':
                schedule_count = self.get_emissions().count()
                if schedule_count > 0:
                    status = False
                criteria = {
                    'key':
                    'scheduled',
                    'name':
                    _('Playlist already scheduled')
                    if schedule_count > 0 else _('Playlist not scheduled'),
                    'status':
                    schedule_count < 1,
                    'warning':
                    _('This playlist has already ben scheduled %s times. Remove all scheduler entries to "un-broadcast" this playlist.'
                      % schedule_count),
                }
                if schedule_count > 0:
                    criterias.append(criteria)

        if target_type == 'broadcast':
            status = True
            # tags
            tag_count = self.tags.count()
            if tag_count < 1:
                status = False
            criteria = {
                'key': 'tags',
                'name': _('Tags'),
                'status': tag_count > 0,
                'warning': _('Please add some tags'),
            }
            criterias.append(criteria)

            # dayparts
            dp_count = self.dayparts.count()
            if not dp_count:
                status = False
            criteria = {
                'key': 'dayparts',
                'name': _('Dayparts'),
                'status': dp_count > 0,
                'warning': _('Please specify the dayparts'),
            }
            criterias.append(criteria)

            # duration
            if not self.broadcast_status == 1:
                status = False
            criteria = {
                'key': 'duration',
                'name': _('Duration'),
                'status': True if self.broadcast_status == 1 else False,
                'warning': _('Durations do not match'),
                # 'warning': ', '.join(self.broadcast_status_messages),
            }
            criterias.append(criteria)

        transformation = {'criterias': criterias, 'status': status}

        return transformation

    def add_items_by_ids(self, ids, ct, timing=None):

        from alibrary.models.mediamodels import Media

        log = logging.getLogger('alibrary.playlistmodels.add_items_by_ids')
        log.debug('Media ids: %s' % (ids))
        log.debug('Content Type: %s' % (ct))

        for id in ids:
            id = int(id)

            co = None

            if ct == 'media':
                co = Media.objects.get(pk=id)

            if ct == 'jingle':
                from abcast.models import Jingle
                co = Jingle.objects.get(pk=id)

            if co:

                i = PlaylistItem(content_object=co)
                i.save()
                """
                ctype = ContentType.objects.get_for_model(co)
                item, created = PlaylistItem.objects.get_or_create(object_id=co.pk, content_type=ctype)
                """

                pi, created = PlaylistItemPlaylist.objects.get_or_create(
                    item=i, playlist=self, position=self.items.count())

                if timing:
                    try:
                        pi.fade_in = timing['fade_in']
                        pi.fade_out = timing['fade_out']
                        pi.cue_in = timing['cue_in']
                        pi.cue_out = timing['cue_out']
                        pi.save()
                    except:
                        pass

        self.save()

    def reorder_items_by_uuids(self, uuids):

        i = 0

        for uuid in uuids:
            pi = PlaylistItemPlaylist.objects.get(uuid=uuid)
            pi.position = i
            pi.save()

            i += 1

        self.save()

    """
    old method - for non-generic playlists
    """

    def add_media_by_ids(self, ids):

        from alibrary.models.mediamodels import Media

        log = logging.getLogger('alibrary.playlistmodels.add_media_by_id')
        log.debug('Media ids: %s' % (ids))

        for id in ids:
            id = int(id)

            m = Media.objects.get(pk=id)
            pm = PlaylistMedia(media=m,
                               playlist=self,
                               position=self.media.count())
            pm.save()

            self.save()

    def convert_to(self, type):

        log.debug('requested to convert "%s" from %s to %s' %
                  (self.name, self.type, type))

        if type == 'broadcast':
            self.broadcast_status, self.broadcast_status_messages = self.self_check(
            )

        transformation = self.get_transform_status(type)
        status = transformation['status']

        if type == 'broadcast' and status:
            _status, messages = self.self_check()
            if _status == 1:
                status = True

        if status:
            self.type = type
            self.save()

        return self, status

    def get_items(self):
        pis = PlaylistItemPlaylist.objects.filter(
            playlist=self).order_by('position')
        items = []
        for pi in pis:
            item = pi.item
            item.cue_in = pi.cue_in
            item.cue_out = pi.cue_out
            item.fade_in = pi.fade_in
            item.fade_out = pi.fade_out
            item.fade_cross = pi.fade_cross
            # get the actual playout duration
            try:
                # print '// getting duration for:'
                # print '%s - %s' % (item.content_object.pk, item.content_object.name)
                # print 'obj duration: %s' % item.content_object.duration_s
                item.playout_duration = item.content_object.duration_ms - item.cue_in - item.cue_out - item.fade_cross
            except Exception as e:
                print 'unable to get duration: %s' % e
                item.playout_duration = 0

            items.append(item)
        return items

    def self_check(self):
        """
        check if everything is fine to be 'schedulable'
        """

        log.info('Self check requested for: %s' % self.name)

        status = 1  # set to 'OK'
        messages = []

        try:

            # check ready-status of related media

            for item in self.items.all():
                # log.debug('Self check content object: %s' % item.content_object)
                # log.debug('Self check master: %s' % item.content_object.master)
                # log.debug('Self check path: %s' % item.content_object.master.path)

                # check if file available
                try:
                    with open(item.content_object.master.path):
                        pass
                except IOError as e:
                    log.warning(
                        _('File does not exists: %s | %s') %
                        (e, item.content_object.master.path))
                    status = 99
                    messages.append(
                        _('File does not exists: %s | %s') %
                        (e, item.content_object.master.path))
                """
                pip = PlaylistItemPlaylist.objects.get(playlist=self, item=item)
                duration -= pip.cue_in
                duration -= pip.cue_out
                duration -= pip.fade_cross
                """

            # check duration & matching target_duration
            """
            compare durations. target: in seconds | calculated duration in milliseconds
            """
            diff = self.get_duration() - self.target_duration * 1000
            if abs(diff) > DURATION_MAX_DIFF:
                messages.append(
                    _('durations do not match. difference is: %s seconds' %
                      int(diff / 1000)))
                log.warning(
                    'durations do not match. difference is: %s seconds' %
                    int(diff / 1000))
                status = 2

        except Exception as e:
            messages.append(_('Validation error: %s ' % e))
            log.warning('validation error: %s ' % e)
            status = 99

        if status == 1:
            log.info('Playlist "%s" checked - all fine!' % (self.name))

        return status, messages

    ###################################################################
    # playlist mixdown
    ###################################################################
    def get_mixdown(self):
        """
        get mixdown from api 
        """
        return MixdownAPIClient().get_for_playlist(self)

    def request_mixdown(self):
        """
        request (re-)creation of mixdown
        """
        return MixdownAPIClient().request_for_playlist(self)

    def download_mixdown(self):
        """
        download generated mixdown from api & store locally (in `mixdown_file` field)
        """
        if not self.mixdown:
            log.info('mixdown not available on api')
            return

        if not self.mixdown['status'] == 3:
            log.info('mixdown not ready on api')
            return

        url = self.mixdown['mixdown_file']

        log.debug('download mixdown from api: {} > {}'.format(url, self.name))

        f_temp = NamedTemporaryFile(delete=True)
        f_temp.write(urlopen(url).read())
        f_temp.flush()

        # wipe existing file
        try:
            self.mixdown_file.delete(False)
        except IOError:
            pass

        self.mixdown_file.save(url.split('/')[-1], File(f_temp))

        return MixdownAPIClient().request_for_playlist(self)

    @cached_property
    def mixdown(self):
        return self.get_mixdown()

    def save(self, *args, **kwargs):

        # status update
        if self.status == 0:
            self.status = 2

        duration = 0
        try:
            duration = self.get_duration()

        except Exception as e:
            pass

        self.duration = duration
        """
        TODO: maybe move
        """
        self.broadcast_status, self.broadcast_status_messages = self.self_check(
        )
        # print '%s - %s (id: %s)' % (self.broadcast_status, self.name, self.pk)
        # print ', '.join(self.broadcast_status_messages)
        # map to object status (not extremly dry - we know...)
        if self.broadcast_status == 1:
            self.status = 1  # 'ready'
        else:
            self.status = 99  # 'error'

        # self.user = request.user
        super(Playlist, self).save(*args, **kwargs)
class Release(MigrationMixin):

    # core fields
    name = models.CharField(max_length=200, db_index=True)
    slug = AutoSlugField(populate_from='name',
                         editable=True,
                         blank=True,
                         overwrite=True)
    license = models.ForeignKey(License,
                                blank=True,
                                null=True,
                                related_name='release_license')
    release_country = models.ForeignKey(Country, blank=True, null=True)

    #uuid = UUIDField(primary_key=False)
    #uuid = UUIDField()
    uuid = models.UUIDField(default=uuid.uuid4, editable=False)

    main_image = models.ImageField(verbose_name=_('Cover'),
                                   upload_to=upload_cover_to,
                                   storage=OverwriteStorage(),
                                   null=True,
                                   blank=True)

    if FORCE_CATALOGNUMBER:
        catalognumber = models.CharField(max_length=50)
    else:
        catalognumber = models.CharField(max_length=50, blank=True, null=True)
    """
    releasedate stores the 'real' time, approx is for inputs
    lik 2012-12 etc.
    """
    releasedate = models.DateField(blank=True, null=True)
    releasedate_approx = ApproximateDateField(verbose_name="Releasedate",
                                              blank=True,
                                              null=True)
    pressings = models.PositiveIntegerField(default=0)
    TOTALTRACKS_CHOICES = ((x, x) for x in range(1, 301))
    totaltracks = models.IntegerField(verbose_name=_('Total Tracks'),
                                      blank=True,
                                      null=True,
                                      choices=TOTALTRACKS_CHOICES)
    asin = models.CharField(max_length=150, blank=True)
    RELEASESTATUS_CHOICES = (
        (None, _('Not set')),
        ('official', _('Official')),
        ('promo', _('Promo')),
        ('bootleg', _('Bootleg')),
        ('other', _('Other')),
    )

    releasestatus = models.CharField(max_length=60,
                                     blank=True,
                                     choices=RELEASESTATUS_CHOICES)
    excerpt = models.TextField(blank=True, null=True)
    description = extra.MarkdownTextField(blank=True, null=True)
    releasetype = models.CharField(
        verbose_name="Release type",
        max_length=24,
        blank=True,
        null=True,
        choices=alibrary_settings.RELEASETYPE_CHOICES)
    label = models.ForeignKey('alibrary.Label',
                              blank=True,
                              null=True,
                              related_name='release_label',
                              on_delete=models.SET_NULL)
    media = models.ManyToManyField('alibrary.Media',
                                   through='ReleaseMedia',
                                   blank=True,
                                   related_name="releases")

    owner = models.ForeignKey(User,
                              blank=True,
                              null=True,
                              related_name="releases_owner",
                              on_delete=models.SET_NULL)
    creator = models.ForeignKey(User,
                                blank=True,
                                null=True,
                                related_name="releases_creator",
                                on_delete=models.SET_NULL)
    last_editor = models.ForeignKey(User,
                                    blank=True,
                                    null=True,
                                    related_name="releases_last_editor",
                                    on_delete=models.SET_NULL)
    publisher = models.ForeignKey(User,
                                  blank=True,
                                  null=True,
                                  related_name="releases_publisher",
                                  on_delete=models.SET_NULL)

    barcode = models.CharField(max_length=32, blank=True, null=True)

    extra_artists = models.ManyToManyField('alibrary.Artist',
                                           through='ReleaseExtraartists',
                                           blank=True)
    album_artists = models.ManyToManyField('alibrary.Artist',
                                           through='ReleaseAlbumartists',
                                           related_name="release_albumartists",
                                           blank=True)

    relations = GenericRelation(Relation)
    d_tags = tagging.fields.TagField(max_length=1024,
                                     verbose_name="Tags",
                                     blank=True,
                                     null=True)

    created = models.DateTimeField(auto_now_add=True, editable=False)
    updated = models.DateTimeField(auto_now=True, editable=False)
    objects = ReleaseManager()

    # meta
    class Meta:
        app_label = 'alibrary'
        verbose_name = _('Release')
        verbose_name_plural = _('Releases')
        ordering = ('-created', )

        permissions = (
            ('view_release', 'View Release'),
            ('edit_release', 'Edit Release'),
            ('merge_release', 'Merge Releases'),
            ('admin_release', 'Edit Release (extended)'),
        )

    def __unicode__(self):
        return self.name

    @property
    def classname(self):
        return self.__class__.__name__

    @property
    def publish_date(self):
        # compatibility hack TODO: refactor all dependencies
        return datetime.utcnow()

    def get_extra_artists(self):
        ea = []
        for artist in self.extra_artists.all():
            ea.append(artist.name)
        return ea

    def is_active(self):
        now = date.today()
        try:
            if not self.releasedate:
                return True

            if self.releasedate <= now:
                return True

        except:
            pass

        return False

    @property
    def is_promotional(self):
        # TODO: refactor to license query
        if self.releasedate:
            if self.releasedate > datetime.now().date():
                return True

        if License.objects.filter(media_license__in=self.get_media(),
                                  is_promotional=True).distinct().exists():
            return True

        return False

    @property
    def is_new(self):
        if self.is_promotional:
            return False
        if self.releasedate and self.releasedate >= (
                datetime.now() - timedelta(days=14)).date():
            return True

        return False

    def get_lookup_providers(self):

        providers = []
        for key, name in LOOKUP_PROVIDERS:
            relations = self.relations.filter(service=key)
            relation = None
            if relations.count() == 1:
                relation = relations[0]

            providers.append({'key': key, 'name': name, 'relation': relation})

        return providers

    def get_absolute_url(self):
        return reverse('alibrary-release-detail',
                       kwargs={
                           'pk': self.pk,
                           'slug': self.slug,
                       })

    def get_edit_url(self):
        return reverse("alibrary-release-edit", args=(self.pk, ))

    def get_admin_url(self):
        return reverse("admin:alibrary_release_change", args=(self.pk, ))

    def get_api_url(self):
        return reverse('api_dispatch_detail',
                       kwargs={
                           'api_name': 'v1',
                           'resource_name': 'library/release',
                           'pk': self.pk
                       }) + ''

    def get_api_simple_url(self):
        return reverse('api_dispatch_detail',
                       kwargs={
                           'api_name': 'v1',
                           'resource_name': 'library/simplerelease',
                           'pk': self.pk
                       }) + ''

    def get_media(self):
        from alibrary.models import Media
        return Media.objects.filter(release=self)

    def get_products(self):
        return self.releaseproduct.all()

    def get_media_indicator(self):

        media = self.get_media()
        indicator = []

        if self.totaltracks:
            for i in range(self.totaltracks):
                indicator.append(0)

            for m in media:
                try:
                    indicator[m.tracknumber - 1] = 3
                except Exception as e:
                    pass

        else:
            for m in media:
                indicator.append(2)

        return indicator

    def get_license(self):

        licenses = License.objects.filter(
            media_license__in=self.get_media()).distinct()
        if not licenses.exists():
            return {'name': _(u'Not Defined')}

        if licenses.count() > 1:
            license, created = License.objects.get_or_create(name="Multiple")
            return license

        if licenses.count() == 1:
            return licenses[0]

    """
    compose artist display as string
    """

    def get_artist_display(self):

        artist_str = ''
        artists = self.get_artists()
        if len(artists) > 1:
            try:
                for artist in artists:
                    if artist['join_phrase']:
                        artist_str += ' %s ' % artist['join_phrase']
                    artist_str += artist['artist'].name
            except:
                artist_str = artists[0]['artist'].name
        else:
            try:
                artist_str = artists[0]['artist'].name
            except:
                try:
                    artist_str = artists[0].name
                except:
                    artist_str = _('Unknown Artist')

        return artist_str

    def get_artists(self):

        artists = []
        if self.album_artists.count() > 0:
            for albumartist in self.release_albumartist_release.all():
                artists.append({
                    'artist': albumartist.artist,
                    'join_phrase': albumartist.join_phrase
                })
            return artists

        medias = self.get_media()
        for media in medias:
            artists.append(media.artist)

        artists = list(set(artists))
        if len(artists) > 1:
            from alibrary.models import Artist
            a, c = Artist.objects.get_or_create(name="Various Artists")
            artists = [a]

        return artists

    def get_extra_artists(self):

        artists = []

        roles = ReleaseExtraartists.objects.filter(release=self.pk)

        for role in roles:
            try:
                role.artist.profession = role.profession.name
                artists.append(role.artist)
            except:
                pass

        return artists

    def get_downloads(self):
        return None

    def get_download_url(self, format, version):

        return '%sdownload/%s/%s/' % (self.get_absolute_url(), format, version)

    def get_cache_file_path(self, format, version):

        tmp_directory = TEMP_DIR
        file_name = '%s_%s_%s.%s' % (format, version, str(self.uuid), 'zip')
        tmp_path = '%s/%s' % (tmp_directory, file_name)

        return tmp_path

    def clear_cache_file(self):

        tmp_directory = TEMP_DIR
        pattern = '*%s.zip' % (str(self.uuid))
        versions = glob.glob('%s/%s' % (tmp_directory, pattern))

        try:
            for version in versions:
                os.remove(version)

        except Exception as e:
            pass

    def get_cache_file(self, format, version):

        cache_file_path = self.get_cache_file_path(format, version)

        if os.path.isfile(cache_file_path):
            logger.info('serving from cache: %s' % (cache_file_path))
            return cache_file_path

        else:
            return self.build_cache_file(format, version)

    def build_cache_file(self, format, version):

        cache_file_path = self.get_cache_file_path(format, version)

        logger.info('building cache for: %s' % (cache_file_path))

        try:
            os.remove(cache_file_path)

        except Exception as e:
            pass

        archive_file = ZipFile(cache_file_path, "w")
        """
        adding corresponding media files
        """
        for media in self.get_media():
            media_cache_file = media.inject_metadata(format, version)

            # filename for the file archive
            file_name = '%02d - %s - %s' % (media.tracknumber,
                                            media.artist.name, media.name)
            file_name = '%s.%s' % (file_name.encode('ascii', 'ignore'), format)

            archive_file.write(media_cache_file.path, file_name)

        return cache_file_path

    def get_extraimages(self):
        return None

    # OBSOLETE
    def complete_by_mb_id(self, mb_id):

        obj = self

        log = logging.getLogger('alibrary.release.complete_by_mb_id')
        log.info('complete release, r: %s | mb_id: %s' % (obj.name, mb_id))

        inc = ('artists', 'url-rels', 'aliases', 'tags', 'recording-rels',
               'work-rels', 'work-level-rels', 'artist-credits')
        url = 'http://%s/ws/2/release/%s/?fmt=json&inc=%s' % (
            MUSICBRAINZ_HOST, mb_id, "+".join(inc))

        r = requests.get(url)
        result = r.json()

        return obj

    def save(self, *args, **kwargs):

        self.clear_cache_file()
        unique_slugify(self, self.name)

        # convert approx date to real one
        ad = self.releasedate_approx
        try:
            ad_y = ad.year
            ad_m = ad.month
            ad_d = ad.day
            if ad_m == 0:
                ad_m = 1
            if ad_d == 0:
                ad_d = 1

            rd = datetime.strptime('%s/%s/%s' % (ad_y, ad_m, ad_d), '%Y/%m/%d')
            self.releasedate = rd
        except:
            self.releasedate = None

        super(Release, self).save(*args, **kwargs)