Beispiel #1
0
class EntryAbstractClass(models.Model):
    """Base Model design for publishing entries"""
    STATUS_CHOICES = ((DRAFT, _('draft')), (HIDDEN, _('hidden')),
                      (PUBLISHED, _('published')))

    title = models.CharField(_('title'), max_length=255)

    image = models.ImageField(_('image'),
                              upload_to=UPLOAD_TO,
                              blank=True,
                              help_text=_('used for illustration'))
    content = models.TextField(_('content'))
    excerpt = models.TextField(_('excerpt'),
                               blank=True,
                               help_text=_('optional element'))

    tags = TagField(_('tags'))
    categories = models.ManyToManyField(Category,
                                        verbose_name=_('categories'),
                                        blank=True,
                                        null=True)
    related = models.ManyToManyField('self',
                                     verbose_name=_('related entries'),
                                     blank=True,
                                     null=True)

    slug = models.SlugField(help_text=_('used for publication'),
                            unique_for_date='creation_date',
                            max_length=255)

    authors = models.ManyToManyField(User,
                                     verbose_name=_('authors'),
                                     blank=True,
                                     null=False)
    status = models.IntegerField(choices=STATUS_CHOICES, default=DRAFT)
    featured = models.BooleanField(_('featured'), default=False)
    comment_enabled = models.BooleanField(_('comment enabled'), default=True)
    pingback_enabled = models.BooleanField(_('linkback enabled'), default=True)

    creation_date = models.DateTimeField(_('creation date'),
                                         default=datetime.now)
    last_update = models.DateTimeField(_('last update'), default=datetime.now)
    start_publication = models.DateTimeField(_('start publication'),
                                             help_text=_('date start publish'),
                                             default=datetime.now)
    end_publication = models.DateTimeField(_('end publication'),
                                           help_text=_('date end publish'),
                                           default=datetime(2042, 3, 15))

    sites = models.ManyToManyField(Site, verbose_name=_('sites publication'))

    login_required = models.BooleanField(
        _('login required'),
        default=False,
        help_text=_('only authenticated users can view the entry'))
    password = models.CharField(
        _('password'),
        max_length=50,
        blank=True,
        help_text=_('protect the entry with a password'))

    template = models.CharField(
        _('template'),
        max_length=250,
        default='zinnia/entry_detail.html',
        choices=[('zinnia/entry_detail.html', _('Default template'))] +
        ENTRY_TEMPLATES,
        help_text=_('template used to display the entry'))

    objects = models.Manager()
    published = EntryPublishedManager()

    @property
    def html_content(self):
        """Return the content correctly formatted"""
        if MARKUP_LANGUAGE == 'markdown':
            return markdown(self.content, MARKDOWN_EXTENSIONS)
        elif MARKUP_LANGUAGE == 'textile':
            return textile(self.content)
        elif MARKUP_LANGUAGE == 'restructuredtext':
            return restructuredtext(self.content)
        elif not '</p>' in self.content:
            return linebreaks(self.content)
        return self.content

    @property
    def previous_entry(self):
        """Return the previous entry"""
        entries = Entry.published.filter(
            creation_date__lt=self.creation_date)[:1]
        if entries:
            return entries[0]

    @property
    def next_entry(self):
        """Return the next entry"""
        entries = Entry.published.filter(
            creation_date__gt=self.creation_date).order_by('creation_date')[:1]
        if entries:
            return entries[0]

    @property
    def word_count(self):
        """Count the words of an entry"""
        return len(strip_tags(self.html_content).split())

    @property
    def is_actual(self):
        """Check if an entry is within publication period"""
        now = datetime.now()
        return now >= self.start_publication and now < self.end_publication

    @property
    def is_visible(self):
        """Check if an entry is visible on site"""
        return self.is_actual and self.status == PUBLISHED

    @property
    def related_published_set(self):
        """Return only related entries published"""
        return entries_published(self.related)

    @property
    def discussions(self):
        """Return published discussions"""
        return Comment.objects.for_model(self).filter(is_public=True)

    @property
    def comments(self):
        """Return published comments"""
        return self.discussions.filter(
            Q(flags=None) | Q(flags__flag=CommentFlag.MODERATOR_APPROVAL))

    @property
    def pingbacks(self):
        """Return published pingbacks"""
        return self.discussions.filter(flags__flag='pingback')

    @property
    def trackbacks(self):
        """Return published trackbacks"""
        return self.discussions.filter(flags__flag='trackback')

    @property
    def short_url(self):
        """Return the entry's short url"""
        if not USE_BITLY:
            return False

        from django_bitly.models import Bittle

        bittle = Bittle.objects.bitlify(self)
        url = bittle and bittle.shortUrl or self.get_absolute_url()
        return url

    def __unicode__(self):
        return '%s: %s' % (self.title, self.get_status_display())

    @models.permalink
    def get_absolute_url(self):
        """Return entry's URL"""
        return ('zinnia_entry_detail', (), {
            'year': self.creation_date.strftime('%Y'),
            'month': self.creation_date.strftime('%m'),
            'day': self.creation_date.strftime('%d'),
            'slug': self.slug
        })

    class Meta:
        abstract = True
Beispiel #2
0
class CoreEntry(models.Model):
    """
    Abstract core entry model class providing
    the fields and methods required for publishing
    content over time.
    """
    STATUS_CHOICES = ((DRAFT, _('draft')),
                      (HIDDEN, _('hidden')),
                      (PUBLISHED, _('published')))

    title = models.CharField(
        _('title'), max_length=255)

    slug = models.SlugField(
        _('slug'), max_length=255,
        unique_for_date='creation_date',
        help_text=_("Used to build the entry's URL."))

    status = models.IntegerField(
        _('status'), db_index=True,
        choices=STATUS_CHOICES, default=DRAFT)

    start_publication = models.DateTimeField(
        _('start publication'),
        db_index=True, blank=True, null=True,
        help_text=_('Start date of publication.'))

    end_publication = models.DateTimeField(
        _('end publication'),
        db_index=True, blank=True, null=True,
        help_text=_('End date of publication.'))

    sites = models.ManyToManyField(
        Site,
        related_name='entries',
        verbose_name=_('sites'),
        help_text=_('Sites where the entry will be published.'))

    creation_date = models.DateTimeField(
        _('creation date'),
        db_index=True, default=timezone.now,
        help_text=_("Used to build the entry's URL."))

    last_update = models.DateTimeField(
        _('last update'), default=timezone.now)

    objects = models.Manager()
    published = EntryPublishedManager()

    @property
    def is_actual(self):
        """
        Checks if an entry is within his publication period.
        """
        now = timezone.now()
        if self.start_publication and now < self.start_publication:
            return False

        if self.end_publication and now >= self.end_publication:
            return False
        return True

    @property
    def is_visible(self):
        """
        Checks if an entry is visible and published.
        """
        return self.is_actual and self.status == PUBLISHED

    @property
    def previous_entry(self):
        """
        Returns the previous published entry if exists.
        """
        return self.previous_next_entries[0]

    @property
    def next_entry(self):
        """
        Returns the next published entry if exists.
        """
        return self.previous_next_entries[1]

    @property
    def previous_next_entries(self):
        """
        Returns and caches a tuple containing the next
        and previous published entries.
        Only available if the entry instance is published.
        """
        previous_next = getattr(self, 'previous_next', None)

        if previous_next is None:
            if not self.is_visible:
                previous_next = (None, None)
                setattr(self, 'previous_next', previous_next)
                return previous_next

            entries = list(self.__class__.published.all())
            index = entries.index(self)
            try:
                previous = entries[index + 1]
            except IndexError:
                previous = None

            if index:
                next = entries[index - 1]
            else:
                next = None
            previous_next = (previous, next)
            setattr(self, 'previous_next', previous_next)
        return previous_next

    @property
    def short_url(self):
        """
        Returns the entry's short url.
        """
        return get_url_shortener()(self)

    @models.permalink
    def get_absolute_url(self):
        """
        Builds and returns the entry's URL based on
        the slug and the creation date.
        """
        creation_date = self.creation_date
        if timezone.is_aware(creation_date):
            creation_date = timezone.localtime(creation_date)
        return ('zinnia:entry_detail', (), {
            'year': creation_date.strftime('%Y'),
            'month': creation_date.strftime('%m'),
            'day': creation_date.strftime('%d'),
            'slug': self.slug})

    def __str__(self):
        return '%s: %s' % (self.title, self.get_status_display())

    class Meta:
        """
        CoreEntry's meta informations.
        """
        abstract = True
        ordering = ['-creation_date']
        get_latest_by = 'creation_date'
        verbose_name = _('entry')
        verbose_name_plural = _('entries')
        index_together = [['slug', 'creation_date'],
                          ['status', 'creation_date',
                           'start_publication', 'end_publication']]
        permissions = (('can_view_all', 'Can view all entries'),
                       ('can_change_status', 'Can change status'),
                       ('can_change_author', 'Can change author(s)'), )
Beispiel #3
0
class RegionEntry(ContentEntry, LeadEntry, ExcerptEntry, FeaturedEntry,
                  TagsEntry, Orderable):
    STATUS_CHOICES = ((DRAFT, _('draft')), (PUBLISHED, _('published')))
    title = models.CharField(_('title'), max_length=255)
    region = models.CharField(_('region'), max_length=100)
    region_title = models.CharField(_('region title'), max_length=150)
    region_subtitle = models.CharField(_('region sub-title'), max_length=150)
    region_subhead = models.CharField(_('region sub-head'), max_length=150)
    region_description = models.TextField()
    sub_regions = models.TextField()
    keywords = models.TextField()
    snippet = models.TextField()
    model_link_1 = models.URLField(_('model link 1'))
    model_link_2 = models.URLField(_('model link 2'))
    model_link_3 = models.URLField(_('model link 3'))
    model_subtitle_1 = models.CharField(_('model sub-title 1'), max_length=255)
    model_subtitle_2 = models.CharField(_('model sub-title 2'), max_length=255)
    model_subtitle_3 = models.CharField(_('model sub-title 3'), max_length=255)
    phone = models.CharField(max_length=30, blank=True)
    in_footer = models.BooleanField(default=False)

    slug = models.SlugField(_('slug'), max_length=255, unique=True)

    status = models.PositiveSmallIntegerField(_('status'),
                                              db_index=True,
                                              choices=STATUS_CHOICES,
                                              default=DRAFT)

    head_content = models.TextField(
        _('head content'),
        help_text=_('Add content to "head" when page is rendered'),
        blank=True,
        null=True)

    start_publication = models.DateTimeField(
        _('start publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('Start date of publication.'))

    end_publication = models.DateTimeField(
        _('end publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('End date of publication.'))

    sites = models.ManyToManyField(
        Site,
        related_name='region_entries',
        verbose_name=_('sites'),
        help_text=_('Sites where the entry will be published.'))

    creation_date = models.DateTimeField(
        _('creation date'),
        db_index=True,
        default=timezone.now,
        help_text=_("Used to build the entry's URL."))

    last_update = models.DateTimeField(_('last update'), auto_now=True)

    authors = models.ManyToManyField('zinnia.Author',
                                     blank=True,
                                     related_name='region_entries',
                                     verbose_name=_('authors'))

    image = FilerImageField(verbose_name=_('Image'),
                            blank=True,
                            null=True,
                            help_text=_('Featured image.'))

    og_tags = models.TextField(verbose_name=_('Custom OG:Tags'),
                               help_text=_('One file per line'),
                               blank=True)

    objects = models.Manager()
    published = EntryPublishedManager()

    class Meta:
        # From CoreEntry meta
        ordering = ('-featured', '-sort_order', '-creation_date')
        get_latest_by = 'creation_date'
        verbose_name = _('region entry')
        verbose_name_plural = _('region entries')
        index_together = ('status', 'creation_date', 'start_publication',
                          'end_publication')
        permissions = (('can_view_all_regions', 'Can view all entries'),
                       ('can_change_region_status', 'Can change status'),
                       ('can_change_region_author', 'Can change author(s)'))

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        """
        Always validate model link before saving. Set entry title and slug if
        they are blank.
        """
        self.full_clean()
        super(RegionEntry, self).save(*args, **kwargs)
        self.sites.add(Site.objects.get_current())

    def get_absolute_url(self):
        """
        Builds and returns the entry's URL based on
        the slug and the creation date.
        """
        return reverse('region_detail', args=(self.slug, ))

    @property
    def is_visible(self):
        """
        Checks if an entry is visible and published.
        """
        return self.is_actual and self.status == PUBLISHED

    @property
    def is_actual(self):
        """
        Checks if an entry is within his publication period.
        """
        now = timezone.now()
        if self.start_publication and now < self.start_publication:
            return False

        if self.end_publication and now >= self.end_publication:
            return False
        return True

    @property
    def publication_date(self):
        """
        Return the publication date of the entry.
        """
        return self.start_publication or self.creation_date

    @property
    def og_tags_list(self):
        if not self.og_tags:
            return []
        return [s for s in self.og_tags.split()]

    @cached_property
    def sub_regions_to_list(self):
        return [
            sub_region.strip()
            for sub_region in self.sub_regions.strip().split(',')
        ]

    @cached_property
    def sub_regions_to_json(self):
        return json.dumps([[sub_region, self.region]
                           for sub_region in self.sub_regions_to_list])

    @cached_property
    def sub_regions_to_seo_locations(self):
        return ' / '.join(self.sub_regions_to_list)
Beispiel #4
0
class EntryAbstractClass(models.Model):
    """Base Model design for publishing entries"""
    STATUS_CHOICES = ((DRAFT, _('draft')), (HIDDEN, _('hidden')),
                      (PUBLISHED, _('published')))

    title = models.CharField(_('title'), max_length=255)

    image = models.ImageField(_('image'),
                              upload_to=UPLOAD_TO,
                              blank=True,
                              help_text=_('used for illustration'))
    content = models.TextField(_('content'))
    excerpt = models.TextField(_('excerpt'),
                               blank=True,
                               help_text=_('optional element'))

    tags = TagField(_('tags'))
    categories = models.ManyToManyField(Category,
                                        verbose_name=_('categories'),
                                        related_name='entries',
                                        blank=True,
                                        null=True)
    related = models.ManyToManyField('self',
                                     verbose_name=_('related entries'),
                                     blank=True,
                                     null=True)

    slug = models.SlugField(help_text=_("used to build the entry's URL"),
                            unique_for_date='creation_date',
                            max_length=255)

    authors = models.ManyToManyField(Author,
                                     verbose_name=_('authors'),
                                     related_name='entries',
                                     blank=True,
                                     null=False)

    status = models.IntegerField(choices=STATUS_CHOICES, default=DRAFT)
    featured = models.BooleanField(_('featured'), default=False)
    comment_enabled = models.BooleanField(_('comment enabled'), default=True)
    pingback_enabled = models.BooleanField(_('linkback enabled'), default=True)

    creation_date = models.DateTimeField(
        _('creation date'),
        default=timezone.now,
        help_text=_("used to build the entry's URL"))
    last_update = models.DateTimeField(_('last update'), default=timezone.now)
    start_publication = models.DateTimeField(_('start publication'),
                                             blank=True,
                                             null=True,
                                             help_text=_('date start publish'))
    end_publication = models.DateTimeField(_('end publication'),
                                           blank=True,
                                           null=True,
                                           help_text=_('date end publish'))

    sites = models.ManyToManyField(Site,
                                   verbose_name=_('sites publication'),
                                   related_name='entries')

    login_required = models.BooleanField(
        _('login required'),
        default=False,
        help_text=_('only authenticated users can view the entry'))
    password = models.CharField(
        _('password'),
        max_length=50,
        blank=True,
        help_text=_('protect the entry with a password'))

    template = models.CharField(
        _('template'), max_length=250,
        default='entry_detail.html',
        choices=[('entry_detail.html', _('Default template'))] + \
        ENTRY_TEMPLATES,
        help_text=_('template used to display the entry'))

    objects = models.Manager()
    published = EntryPublishedManager()

    @property
    def html_content(self):
        """Return the Entry.content attribute formatted in HTML"""
        if MARKUP_LANGUAGE == 'markdown':
            return markdown(self.content, MARKDOWN_EXTENSIONS)
        elif MARKUP_LANGUAGE == 'textile':
            return textile(self.content)
        elif MARKUP_LANGUAGE == 'restructuredtext':
            return restructuredtext(self.content)
        elif not '</p>' in self.content:
            return linebreaks(self.content)
        return self.content

    @property
    def previous_entry(self):
        """Return the previous entry"""
        entries = Entry.published.filter(
            creation_date__lt=self.creation_date)[:1]
        if entries:
            return entries[0]

    @property
    def next_entry(self):
        """Return the next entry"""
        entries = Entry.published.filter(
            creation_date__gt=self.creation_date).order_by('creation_date')[:1]
        if entries:
            return entries[0]

    @property
    def word_count(self):
        """Count the words of an entry"""
        return len(strip_tags(self.html_content).split())

    @property
    def is_actual(self):
        """Check if an entry is within publication period"""
        now = timezone.now()
        if self.start_publication and now < self.start_publication:
            return False

        if self.end_publication and now >= self.end_publication:
            return False
        return True

    @property
    def is_visible(self):
        """Check if an entry is visible on site"""
        return self.is_actual and self.status == PUBLISHED

    @property
    def related_published(self):
        """Return only related entries published"""
        return entries_published(self.related)

    @property
    def discussions(self):
        """Return published discussions"""
        return comments.get_model().objects.for_model(self).filter(
            is_public=True)

    @property
    def comments(self):
        """Return published comments"""
        return self.discussions.filter(
            Q(flags=None) | Q(flags__flag=CommentFlag.MODERATOR_APPROVAL))

    @property
    def pingbacks(self):
        """Return published pingbacks"""
        return self.discussions.filter(flags__flag=PINGBACK)

    @property
    def trackbacks(self):
        """Return published trackbacks"""
        return self.discussions.filter(flags__flag=TRACKBACK)

    @property
    def comments_are_open(self):
        """Check if comments are open"""
        if AUTO_CLOSE_COMMENTS_AFTER and self.comment_enabled:
            return (timezone.now() - (self.start_publication or
                                      self.creation_date)).days < \
                                      AUTO_CLOSE_COMMENTS_AFTER
        return self.comment_enabled

    @property
    def short_url(self):
        """Return the entry's short url"""
        return get_url_shortener()(self)

    def __unicode__(self):
        return u'%s: %s' % (self.title, self.get_status_display())

    @models.permalink
    def get_absolute_url(self):
        """Return entry's URL"""
        creation_date = timezone.localtime(self.creation_date)
        return ('zinnia_entry_detail', (), {
            'year': creation_date.strftime('%Y'),
            'month': creation_date.strftime('%m'),
            'day': creation_date.strftime('%d'),
            'slug': self.slug
        })

    class Meta:
        """Entry's Meta"""
        abstract = True
        app_label = 'zinnia'
        ordering = ['-creation_date']
        get_latest_by = 'creation_date'
        verbose_name = _('entry')
        verbose_name_plural = _('entries')
        permissions = (
            ('can_view_all', 'Can view all entries'),
            ('can_change_status', 'Can change status'),
            ('can_change_author', 'Can change author(s)'),
        )
Beispiel #5
0
class NewsEntry(ContentEntry, LeadEntry, ExcerptEntry, FeaturedEntry,
                TagsEntry):

    STATUS_CHOICES = ((DRAFT, _('draft')), (HIDDEN, _('hidden')),
                      (PUBLISHED, _('published')))

    title = models.CharField(_('title'), blank=True, max_length=255)

    slug = models.SlugField(_('slug'),
                            blank=True,
                            max_length=255,
                            unique=True,
                            help_text=_("Used to build the entry's URL."))

    status = models.PositiveSmallIntegerField(_('status'),
                                              db_index=True,
                                              choices=STATUS_CHOICES,
                                              default=DRAFT)

    start_publication = models.DateTimeField(
        _('start publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('Start date of publication.'))

    end_publication = models.DateTimeField(
        _('end publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('End date of publication.'))

    sites = models.ManyToManyField(
        Site,
        related_name='news_entries',
        verbose_name=_('sites'),
        help_text=_('Sites where the entry will be published.'))

    creation_date = models.DateTimeField(
        _('creation date'),
        db_index=True,
        default=timezone.now,
        help_text=_("Used to build the entry's URL."))

    last_update = models.DateTimeField(_('last update'), auto_now=True)

    authors = models.ManyToManyField('zinnia.Author',
                                     blank=True,
                                     related_name='news_entries',
                                     verbose_name=_('authors'))

    categories = models.ManyToManyField(NewsCategory,
                                        blank=True,
                                        related_name='entries',
                                        verbose_name=_('categories'))

    image = FilerImageField(verbose_name=_('Image'),
                            blank=True,
                            null=True,
                            related_name='newsentry_image',
                            help_text=_('Featured image.'))

    image_caption = models.TextField(_('caption'),
                                     blank=True,
                                     help_text=_("Image's caption."))

    # News fields based on WP site
    video_link = models.URLField(
        _('embed video link'),
        blank=True,
        max_length=255,
        help_text=
        _('How to get embedded links: '
          '<a href="https://support.google.com/youtube/answer/171780?hl=en" target="_blank">YouTube</a>, '
          '<a href="https://vimeo.com/help/faq/sharing-videos/embedding-videos#how-do-i-embed-a-video-on-another-site" target="_blank">Vimeo</a>. '
          'If you need assistance embedding a video from another '
          'website contact your site administrator.<br>'
          'Vimeo link example: '
          'https://player.vimeo.com/video/157326630'))

    icon = FilerImageField(
        verbose_name=_('icon'),
        blank=True,
        null=True,
        related_name='newsentry_icon',
        help_text=_('Icon image at the top of the preview.'))

    icon_alt_text = models.CharField(
        _('icon alternate text'),
        blank=True,
        max_length=255,
        help_text=_('Alternate text if icon cannot be shown.'))

    external_link = models.URLField(_('external link'),
                                    blank=True,
                                    max_length=255)

    external_author = models.CharField(_('external author'),
                                       blank=True,
                                       max_length=255)

    external_author_url = models.URLField(_('external author URL'),
                                          blank=True,
                                          max_length=255)

    # Fields for comments, trackbacks and pingbacks
    comment_enabled = models.BooleanField(
        _('comments enabled'),
        default=True,
        help_text=_('Allows comments if checked.'))

    pingback_enabled = models.BooleanField(
        _('pingbacks enabled'),
        default=True,
        help_text=_('Allows pingbacks if checked.'))

    trackback_enabled = models.BooleanField(
        _('trackbacks enabled'),
        default=True,
        help_text=_('Allows trackbacks if checked.'))

    comment_count = models.IntegerField(_('comment count'), default=0)

    pingback_count = models.IntegerField(_('pingback count'), default=0)

    trackback_count = models.IntegerField(_('trackback count'), default=0)

    og_tags = models.TextField(verbose_name=_('Custom OG:Tags'),
                               help_text=_('One file per line'),
                               blank=True)

    objects = models.Manager()
    published = EntryPublishedManager()

    class Meta:
        """
        NewsEntry meta information.
        """
        # From CoreEntry meta
        ordering = ['-creation_date']
        get_latest_by = 'creation_date'
        verbose_name = _('news entry')
        verbose_name_plural = _('news entries')
        index_together = [['slug', 'creation_date'],
                          [
                              'status', 'creation_date', 'start_publication',
                              'end_publication'
                          ]]
        permissions = (
            ('can_view_all', 'Can view all entries'),
            ('can_change_status', 'Can change status'),
            ('can_change_author', 'Can change author(s)'),
        )

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        """
        Set the site to SITE_ID from settings/base.py
        """
        super(NewsEntry, self).save(*args, **kwargs)
        self.sites.add(Site.objects.get_current())

    def get_absolute_url(self):
        """
        Builds and returns the entry's URL based on
        the slug and the creation date.
        """
        return reverse('news_detail', args=(self.slug, ))

    @property
    def is_visible(self):
        """
        Checks if an entry is visible and published.
        """
        return self.is_actual and self.status == PUBLISHED

    @property
    def is_actual(self):
        """
        Checks if an entry is within his publication period.
        """
        now = timezone.now()
        if self.start_publication and now < self.start_publication:
            return False

        if self.end_publication and now >= self.end_publication:
            return False
        return True

    @property
    def publication_date(self):
        """
        Return the publication date of the entry.
        """
        return self.start_publication or self.creation_date

    @property
    def og_tags_list(self):
        if not self.og_tags:
            return []
        return [s for s in self.og_tags.split()]
Beispiel #6
0
class ModelEntry(ContentEntry, LeadEntry, ExcerptEntry, FeaturedEntry,
                 TagsEntry, Orderable):
    """
    Model Entry
    """

    STATUS_CHOICES = ((DRAFT, _('draft')), (PUBLISHED, _('published')))

    title = models.CharField(_('title'), blank=True, max_length=255)

    slug = models.SlugField(_('slug'),
                            blank=True,
                            max_length=255,
                            unique=True,
                            help_text=_("Used to build the entry's URL."))

    status = models.PositiveSmallIntegerField(_('status'),
                                              db_index=True,
                                              choices=STATUS_CHOICES,
                                              default=DRAFT)

    start_publication = models.DateTimeField(
        _('start publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('Start date of publication.'))

    end_publication = models.DateTimeField(
        _('end publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('End date of publication.'))

    sites = models.ManyToManyField(
        Site,
        related_name='model_entries',
        verbose_name=_('sites'),
        help_text=_('Sites where the entry will be published.'))

    creation_date = models.DateTimeField(
        _('creation date'),
        db_index=True,
        default=timezone.now,
        help_text=_("Used to build the entry's URL."))

    last_update = models.DateTimeField(_('last update'), auto_now=True)

    authors = models.ManyToManyField('zinnia.Author',
                                     blank=True,
                                     related_name='model_entries',
                                     verbose_name=_('authors'))

    categories = models.ManyToManyField(ModelCategory,
                                        blank=True,
                                        related_name='entries',
                                        verbose_name=_('categories'))

    image = FilerImageField(verbose_name=_('Image'),
                            blank=True,
                            null=True,
                            help_text=_('Featured image.'))

    image_caption = models.TextField(_('caption'),
                                     blank=True,
                                     help_text=_("Image's caption."))

    admin_note = models.TextField(
        _('Admin note'),
        blank=True,
        help_text=_('Add any administrative and NON-PUBLIC notes you might'
                    'want to associate with this model.'))

    model_link = models.URLField(
        _('Model Link'),
        help_text=_('Copy & Paste your Matterport "Model Link" from the'
                    'Sharing column of your dashboard. Make sure your model is'
                    'shared as PUBLIC!'))

    model_vr_link = models.URLField(
        _('VR Link'),
        blank=True,
        help_text=_('Add a model VR link to this page. Copy & Paste the full'
                    'VR URL here.'))

    model_subtitle = models.CharField(
        _('Subtitle'),
        blank=True,
        max_length=255,
        help_text=_('Include an optional text subtitle for your model. This is'
                    'seen both on the listing page(s) as well as the model'
                    'detail page.'))

    creator_link = models.URLField(
        _('Creator Link'),
        blank=True,
        help_text=_('Add creator link to this page. Copy & Paste the full URL '
                    'here.'))

    presenter_link = models.URLField(
        _('Presenter Link'),
        blank=True,
        help_text=_('Add presenter link to this page. Copy & Paste the full '
                    'URL here.'))

    model_embed_code = models.BooleanField(
        _('Embed Code'), default=True, help_text=_('Display Model Embed Code'))

    # TODO: Switch to JsonField when upgrading Django to 1.9.
    _model_info = models.TextField(_('Model Information'), blank=True)

    refresh_model_info = models.BooleanField(
        _('Refresh model info'),
        default=False,
        help_text=_('Reload model info from API'))

    og_tags = models.TextField(verbose_name=_('Custom OG:Tags'),
                               help_text=_('One file per line'),
                               blank=True)

    objects = models.Manager()
    published = EntryPublishedManager()

    class Meta:
        """
        ModelEntry meta information.
        """
        # From CoreEntry meta
        ordering = ['-featured', '-sort_order', '-creation_date']
        get_latest_by = 'creation_date'
        verbose_name = _('model entry')
        verbose_name_plural = _('model entries')
        index_together = [[
            'status', 'creation_date', 'start_publication', 'end_publication'
        ]]
        permissions = (
            ('can_view_all_models', 'Can view all entries'),
            ('can_change_model_status', 'Can change status'),
            ('can_change_model_author', 'Can change author(s)'),
        )

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        """
        Always validate model link before saving. Set entry title and slug if
        they are blank.
        """
        self.full_clean()
        if self.refresh_model_info:
            self._load_model_info()
            self.refresh_model_info = False
        if not self.title:
            self.title = self.model_info['name'][:255]
        if not self.slug:
            self.slug = slugify(self.title)[:255]
        if not self.content:
            self.content = self.model_info['summary']
        if not self.model_vr_link and self.model_info.get('is_vr'):
            self.model_vr_link = settings.MODEL_VR_URL_FORMAT.format(self.sid)
        if not self.image:
            self.capture_image()
        self.move_cover_image_to_folder()
        super(ModelEntry, self).save(*args, **kwargs)
        self.sites.add(Site.objects.get_current())

    def get_absolute_url(self):
        """
        Builds and returns the entry's URL based on
        the slug and the creation date.
        """
        return reverse('gallery_model_detail', args=(self.slug, ))

    @property
    def is_visible(self):
        """
        Checks if an entry is visible and published.
        """
        return self.is_actual and self.status == PUBLISHED

    @property
    def is_actual(self):
        """
        Checks if an entry is within his publication period.
        """
        now = timezone.now()
        if self.start_publication and now < self.start_publication:
            return False

        if self.end_publication and now >= self.end_publication:
            return False
        return True

    @property
    def publication_date(self):
        """
        Return the publication date of the entry.
        """
        return self.start_publication or self.creation_date

    @cached_property
    def sid(self):
        """
        This property is used as a validator of model link. So it doesn't
        catch any exceptions.
        """
        parsed_url = urlparse(self.model_link)
        qs = parse_qs(parsed_url.query)
        return qs['m'][0]

    @cached_property
    def model_info(self):
        """
        Get model information in json format through Portal API.
        """
        if not self._model_info:
            self._load_model_info()
        try:
            data = json.loads(self._model_info)
        except (TypeError, ValueError):
            data = {}
        return data

    @cached_property
    def time_created(self):
        return parse_datetime(self.model_info['created'])

    def _load_model_info(self, commit=False):
        url = settings.SCANMODEL_API_URL_FORMAT.format(self.sid)
        response = requests.get(url)
        self._model_info = response.content if response.status_code == 200 \
            else ''
        if commit:
            self.save()

    def capture_image(self):
        """
        Save model's image as ModelEntry's featured image.
        """
        image = upload_image_to_s3(self.model_info['image'])
        self.image = image

    def move_cover_image_to_folder(self, folder_name='3d-gallery-thumbnails'):
        if self.image:
            if not self.image.folder_id \
                    or self.image.folder.name != folder_name:
                folder, _created = Folder.objects.get_or_create(
                    name=folder_name)
                self.image.folder = folder
                self.image.save()

    def clean_fields(self, exclude=None):
        """
        Validate model url:
        1. Is model public?
        2. Get model information.
        """
        super(ModelEntry, self).clean_fields(exclude=exclude)
        # Make sure model link is SSL secured.
        # Since `model_link` is a URLField, it has been stripped and properly
        # prefixed with 'http://' or 'https://'.
        if self.model_link.lower().startswith('http://'):
            self.model_link = 'https://{}'.format(self.model_link[7:])
        try:
            self.model_info
        except (KeyError, IndexError):
            raise ValidationError(_('Please input an valid model link.'))

    @property
    def og_tags_list(self):
        if not self.og_tags:
            return []
        return [s for s in self.og_tags.split()]
class CoreEntry(models.Model):
    """
    Abstract core entry model class providing
    the fields and methods required for publishing
    content over time.
    """
    STATUS_CHOICES = ((DRAFT, _('draft')), (HIDDEN, _('hidden')),
                      (PUBLISHED, _('published')))

    title = models.CharField(_('title'), max_length=255)

    slug = models.SlugField(_('slug'),
                            max_length=255,
                            unique_for_date='creation_date',
                            help_text=_("Used to build the entry's URL."))

    status = models.IntegerField(_('status'),
                                 choices=STATUS_CHOICES,
                                 default=DRAFT)

    start_publication = models.DateTimeField(
        _('start publication'),
        blank=True,
        null=True,
        help_text=_('Start date of publication.'))

    end_publication = models.DateTimeField(
        _('end publication'),
        blank=True,
        null=True,
        help_text=_('End date of publication.'))

    sites = models.ManyToManyField(
        Site,
        related_name='entries',
        verbose_name=_('sites'),
        help_text=_('Sites where the entry will be published.'))

    creation_date = models.DateTimeField(
        _('creation date'),
        default=timezone.now,
        help_text=_("Used to build the entry's URL."))

    last_update = models.DateTimeField(_('last update'), default=timezone.now)

    objects = models.Manager()
    published = EntryPublishedManager()

    @property
    def is_actual(self):
        """
        Checks if an entry is within his publication period.
        """
        now = timezone.now()
        if self.start_publication and now < self.start_publication:
            return False

        if self.end_publication and now >= self.end_publication:
            return False
        return True

    @property
    def is_visible(self):
        """
        Checks if an entry is visible and published.
        """
        return self.is_actual and self.status == PUBLISHED

    @cached_property
    def previous_entry(self):
        """
        Returns the previous published entry if exists.
        """
        entries = self.__class__.published.filter(
            creation_date__lt=self.creation_date)[:1]
        if entries:
            return entries[0]

    @cached_property
    def next_entry(self):
        """
        Returns the next published entry if exists.
        """
        entries = self.__class__.published.filter(
            creation_date__gt=self.creation_date).order_by('creation_date')[:1]
        if entries:
            return entries[0]

    @property
    def short_url(self):
        """
        Returns the entry's short url.
        """
        return get_url_shortener()(self)

    @models.permalink
    def get_absolute_url(self):
        """
        Builds and returns the entry's URL based on
        the slug and the creation date.
        """
        creation_date = timezone.localtime(self.creation_date)
        return ('zinnia_entry_detail', (), {
            'year': creation_date.strftime('%Y'),
            'month': creation_date.strftime('%m'),
            'day': creation_date.strftime('%d'),
            'slug': self.slug
        })

    def __unicode__(self):
        return u'%s: %s' % (self.title, self.get_status_display())

    class Meta:
        """
        CoreEntry's meta informations.
        """
        abstract = True
        app_label = 'zinnia'
        ordering = ['-creation_date']
        get_latest_by = 'creation_date'
        verbose_name = _('entry')
        verbose_name_plural = _('entries')
        index_together = [['slug', 'creation_date']]
        permissions = (
            ('can_view_all', 'Can view all entries'),
            ('can_change_status', 'Can change status'),
            ('can_change_author', 'Can change author(s)'),
        )
Beispiel #8
0
class MatterAppsEntry(ContentEntry, LeadEntry, ExcerptEntry, FeaturedEntry,
                      TagsEntry, Orderable):
    """
    Gallery Page Entry
    """

    STATUS_CHOICES = ((DRAFT, _('draft')), (PUBLISHED, _('published')))

    CATEGORIES_CHOICES = ((1, _('Apps')), (2, _('Service')),
                          (3, _('Merchandise')))

    slug = models.SlugField(_('slug'),
                            blank=False,
                            max_length=255,
                            unique=True,
                            help_text=_("Used to build the entry's URL."))

    title = models.CharField(_('title'),
                             blank=False,
                             max_length=255,
                             unique=True)

    tagline = models.CharField(_('tagline'), blank=False, max_length=145)

    description = models.TextField(_('description'),
                                   blank=False,
                                   max_length=None)

    image = FilerImageField(verbose_name=_('Image'),
                            blank=True,
                            null=True,
                            help_text=_('Featured image.'))

    price = models.CharField(_('price'), blank=False, max_length=25)

    price_option = models.BooleanField(_('Starting at'), default=False)

    compatibility = models.CharField(_('compatibility'),
                                     blank=True,
                                     max_length=150,
                                     default='Nothing')

    status = models.PositiveSmallIntegerField(_('status'),
                                              db_index=True,
                                              choices=STATUS_CHOICES,
                                              default=DRAFT)

    category = models.PositiveSmallIntegerField(_('category'),
                                                db_index=False,
                                                choices=CATEGORIES_CHOICES,
                                                default=1)

    author = models.CharField(_('author name'), blank=False, max_length=60)

    author_image = FilerImageField(verbose_name=_('User Image'),
                                   blank=True,
                                   null=True,
                                   help_text=_('User Image Profile.'),
                                   related_name='author_image')

    company_name = models.CharField(_('company'),
                                    blank=True,
                                    null=True,
                                    max_length=150)

    company_url = models.URLField(_('company link'),
                                  blank=True,
                                  null=True,
                                  max_length=150,
                                  help_text=_('Link to company.'))

    company_description = models.TextField(_('company description'),
                                           blank=True,
                                           null=True,
                                           max_length=None)

    button_text = models.CharField(_('button text'),
                                   max_length='150',
                                   default='Download')

    button_link = models.URLField(_('button link'),
                                  max_length='150',
                                  help_text=_('Go to.'))

    creation_date = models.DateTimeField(
        _('creation date'),
        db_index=True,
        default=timezone.now,
        help_text=_("Used to build the entry's URL."))

    start_publication = models.DateTimeField(
        _('start publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('Start date of publication.'))

    end_publication = models.DateTimeField(
        _('end publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('End date of publication.'))

    sites = models.ManyToManyField(
        Site,
        related_name='matterapps_entry',
        verbose_name=_('sites'),
        help_text=_('Sites where the entry will be published.'))

    last_update = models.DateTimeField(_('last update'), auto_now=True)

    # TODO: Switch to JsonField when upgrading Django to 1.9.
    _model_info = models.TextField(_('Model Information'), blank=True)

    refresh_model_info = models.BooleanField(
        _('Refresh model info'),
        default=False,
        help_text=_('Reload model info from API'))

    og_tags = models.TextField(verbose_name=_('Custom OG:Tags'),
                               help_text=_('One file per line'),
                               blank=True)

    objects = models.Manager()
    published = EntryPublishedManager()

    class Meta:
        """
        MatterAppsEntry meta information.
        """
        # From CoreEntry meta
        ordering = ['-featured', '-sort_order', '-creation_date']
        get_latest_by = 'creation_date'
        verbose_name = _('App Entry')
        verbose_name_plural = _('App Entries')
        index_together = [['status', 'creation_date']]
        permissions = (
            ('can_view_all_models', 'Can view all entries'),
            ('can_change_model_status', 'Can change status'),
            ('can_change_model_author', 'Can change author(s)'),
        )

    def __unicode__(self):
        return self.title

    def get_absolute_url(self):
        """
        Builds and returns the entry's URL based on
        the slug and the creation date.
        """
        return reverse_lazy('matterapps_detail', kwargs={
            'slug': self.slug,
        })

    @property
    def og_tags_list(self):
        if not self.og_tags:
            return []
        return [s for s in self.og_tags.split()]

    @cached_property
    def model_info(self):
        """
        Get model information in json format through Portal API.
        """
        if not self._model_info:
            self._load_model_info()
        try:
            data = json.loads(self._model_info)
        except (TypeError, ValueError):
            data = {}
        return data

    @cached_property
    def time_created(self):
        return parse_datetime(self.model_info['created'])

    def move_cover_image_to_folder(self, folder_name='matterapps-thumbnails'):
        if self.image:
            if not self.image.folder_id \
                    or self.image.folder.name != folder_name:
                folder, _created = Folder.objects.get_or_create(
                    name=folder_name)
                self.image.folder = folder
                self.image.save()

        if self.author_image:
            if not self.author_image.folder_id \
                    or self.author_image.folder.name != folder_name:
                folder, _created = Folder.objects.get_or_create(
                    name=folder_name)
                self.author_image.folder = folder
                self.author_image.save()
Beispiel #9
0
class CoreEntry(models.Model):
    def get_imagen_video(instance, filename):
        now = datetime.datetime.now()
        return '/'.join([
            now.strftime('%Y'),
            now.strftime('%m'),
            now.strftime('%d'), instance.slug, 'video', filename
        ])

    video_uno = models.FileField(null=True,
                                 blank=True,
                                 upload_to=get_imagen_video,
                                 verbose_name="video_uno")
    video_dos = models.FileField(null=True,
                                 blank=True,
                                 upload_to=get_imagen_video,
                                 verbose_name="video_dos")
    video_tres = models.FileField(null=True,
                                  blank=True,
                                  upload_to=get_imagen_video,
                                  verbose_name="video_tres")
    video_cuatro = models.FileField(null=True,
                                    blank=True,
                                    upload_to=get_imagen_video,
                                    verbose_name="video_cuatro")
    video_cinco = models.FileField(null=True,
                                   blank=True,
                                   upload_to=get_imagen_video,
                                   verbose_name="video_cinco")
    video_seis = models.FileField(null=True,
                                  blank=True,
                                  upload_to=get_imagen_video,
                                  verbose_name="video_seis")
    """
    Abstract core entry model class providing
    the fields and methods required for publishing
    content over time.
    """

    RULETA_ESTADOS = (('mostrar', 'Mostrar'), ('ocultar', 'Ocultar'))

    ruleta_estado = models.CharField(_('ruleta_estado'),
                                     max_length=13,
                                     choices=RULETA_ESTADOS,
                                     default='ocultar',
                                     help_text='Estado')

    STATUS_CHOICES = ((DRAFT, _('draft')), (HIDDEN, _('hidden')),
                      (PUBLISHED, _('published')))

    title = models.CharField(_('Nombre'),
                             max_length=255,
                             help_text='Real o fantasía, usado en sitio')

    rut = models.CharField(_('Rut'),
                           max_length=13,
                           null=True,
                           blank=True,
                           help_text='Solo administración')

    nombreadmin = models.CharField(_('Nombre'),
                                   max_length=255,
                                   null=True,
                                   blank=True,
                                   help_text='Solo administración')

    apellidouno = models.CharField(_('Apellido Paterno'),
                                   max_length=255,
                                   null=True,
                                   blank=True,
                                   help_text='Solo administración')

    apellidodos = models.CharField(_('Apellido Materno'),
                                   max_length=255,
                                   null=True,
                                   blank=True,
                                   help_text='Solo administración')

    concelular = models.CharField(_('Teléfono Celular'),
                                  max_length=12,
                                  null=True,
                                  blank=True,
                                  help_text='ej: 988776655')

    conemail = models.EmailField(_('Email contacto'),
                                 max_length=255,
                                 null=True,
                                 blank=True,
                                 help_text='Solo administración')

    convalor = models.CharField(_('Valor'),
                                max_length=10,
                                help_text='ej: 100.000')

    conrecordatorio = models.TextField(_('Notas y Recordatorios'),
                                       null=True,
                                       blank=True,
                                       help_text='Solo administración')

    certificadomedico = models.ImageField(
        _('Certificado Médico'),
        null=True,
        blank=True,
        help_text='Subir archivo, solo administración')

    EXAMENMEDICO = (('aldia', 'Al día'), )
    examenaldia = models.CharField(_('Certificado Médico'),
                                   max_length=20,
                                   null=True,
                                   blank=True,
                                   choices=EXAMENMEDICO,
                                   default='',
                                   help_text='Usado en sitio')

    ATIENDEUNOS = (('departamentopropio', 'Depto propio'), )
    atiendeuno = models.CharField(_('Atiende en:'),
                                  max_length=20,
                                  null=True,
                                  blank=True,
                                  choices=ATIENDEUNOS,
                                  default='',
                                  help_text='Departamento propio')

    ATIENDEDOS = (('hoteles', 'Hoteles'), )
    atiendedos = models.CharField(_('Atiende en:'),
                                  max_length=20,
                                  null=True,
                                  blank=True,
                                  choices=ATIENDEDOS,
                                  default='',
                                  help_text='Hoteles')

    ATIENDETRES = (('moteles', 'Moteles'), )
    atiendetres = models.CharField(_('Atiende en:'),
                                   max_length=20,
                                   null=True,
                                   blank=True,
                                   choices=ATIENDETRES,
                                   default='',
                                   help_text='Moteles')

    ATIENDECUATRO = (('domicilios', 'Domicilios'), )
    atiendecuatro = models.CharField(_('Atiende en:'),
                                     max_length=20,
                                     null=True,
                                     blank=True,
                                     choices=ATIENDECUATRO,
                                     default='',
                                     help_text='Domicilios')

    DIALUNES = (('fulltime', 'Full Time'), )
    dialunes = models.CharField(_('Lunes'),
                                max_length=20,
                                null=True,
                                blank=True,
                                choices=DIALUNES,
                                default='fulltime',
                                help_text='')

    DIAMARTES = (('fulltime', 'Full Time'), )
    diamartes = models.CharField(_('Martes'),
                                 max_length=20,
                                 null=True,
                                 blank=True,
                                 choices=DIAMARTES,
                                 default='fulltime',
                                 help_text='')

    DIAMIERCOLES = (('fulltime', 'Full Time'), )
    diamiercoles = models.CharField(_('Miércoles'),
                                    max_length=20,
                                    null=True,
                                    blank=True,
                                    choices=DIAMIERCOLES,
                                    default='fulltime',
                                    help_text='')

    DIAJUEVES = (('fulltime', 'Full Time'), )
    diajueves = models.CharField(_('Jueves'),
                                 max_length=20,
                                 null=True,
                                 blank=True,
                                 choices=DIAJUEVES,
                                 default='fulltime',
                                 help_text='')

    DIAVIERNES = (('fulltime', 'Full Time'), )
    diaviernes = models.CharField(_('Viernes'),
                                  max_length=20,
                                  null=True,
                                  blank=True,
                                  choices=DIAVIERNES,
                                  default='fulltime',
                                  help_text='')

    DIASABADO = (('fulltime', 'Full Time'), )
    diasabado = models.CharField(_('Sábado'),
                                 max_length=20,
                                 null=True,
                                 blank=True,
                                 choices=DIASABADO,
                                 default='fulltime',
                                 help_text='')

    DIADOMINGO = (('fulltime', 'Full Time'), )
    diadomingo = models.CharField(_('Domingo'),
                                  max_length=20,
                                  null=True,
                                  blank=True,
                                  choices=DIADOMINGO,
                                  default='fulltime',
                                  help_text='')

    ATENCIONENPAREJA = (('atencionpareja', 'Atención en Pareja'), )
    atencion_pareja = models.CharField(_('Atención en Pareja'),
                                       max_length=24,
                                       null=True,
                                       blank=True,
                                       choices=ATENCIONENPAREJA,
                                       default='',
                                       help_text='')

    ATENCIONAMUEJRES = (('atencionmujeres', 'Atención a Mujeres'), )
    atencion_mujeres = models.CharField(_('Atención a Mujeres'),
                                        max_length=24,
                                        null=True,
                                        blank=True,
                                        choices=ATENCIONAMUEJRES,
                                        default='',
                                        help_text='')

    ATENCIONADISCACI = (('atenciondiscapaci', 'Atención a Discapacitados'), )
    atencion_discapaci = models.CharField(_('Atención a Discapacitados'),
                                          max_length=24,
                                          null=True,
                                          blank=True,
                                          choices=ATENCIONADISCACI,
                                          default='',
                                          help_text='')

    SERVICIOGRIEGO = (('griego', 'Griego'), )
    servicio_griego = models.CharField(_('Griego'),
                                       max_length=24,
                                       null=True,
                                       blank=True,
                                       choices=SERVICIOGRIEGO,
                                       default='',
                                       help_text='')

    FRANCESNATURAL = (('francesnatural', 'Francés Natural'), )
    frances_natural = models.CharField(_('Francés Natural'),
                                       max_length=24,
                                       null=True,
                                       blank=True,
                                       choices=FRANCESNATURAL,
                                       default='',
                                       help_text='')

    SEXOORAL = (('sexooral', 'Sexo Oral'), )
    sexo_oral = models.CharField(_('Francés Natural'),
                                 max_length=24,
                                 null=True,
                                 blank=True,
                                 choices=SEXOORAL,
                                 default='',
                                 help_text='')

    LESBICO = (('lesbico', 'Lésbico'), )
    lesbico = models.CharField(_('Lésbico'),
                               max_length=24,
                               null=True,
                               blank=True,
                               choices=LESBICO,
                               default='',
                               help_text='')

    GARGANTAPROF = (('gargantaproof', 'Garganta Profunda'), )
    garganta_profunda = models.CharField(_('Garganta Profunda'),
                                         max_length=24,
                                         null=True,
                                         blank=True,
                                         choices=GARGANTAPROF,
                                         default='',
                                         help_text='')

    DUALESTRIOS = (('dualestrios', 'Duales o Trios'), )
    duales_trios = models.CharField(_('Duales o Trios'),
                                    max_length=24,
                                    null=True,
                                    blank=True,
                                    choices=DUALESTRIOS,
                                    default='',
                                    help_text='')

    AMERICANAA = (('americana', 'Americana'), )
    americanaa = models.CharField(_('Americana'),
                                  max_length=24,
                                  null=True,
                                  blank=True,
                                  choices=AMERICANAA,
                                  default='',
                                  help_text='')

    AMERICANACORPORAL = (('americanacorporal', 'Americana Corporal'), )
    americana_corporal = models.CharField(_('Americana Corporal'),
                                          max_length=24,
                                          null=True,
                                          blank=True,
                                          choices=AMERICANACORPORAL,
                                          default='',
                                          help_text='')

    MASAJESS = (('masajes', 'Masajes'), )
    masajes = models.CharField(_('Masajes'),
                               max_length=24,
                               null=True,
                               blank=True,
                               choices=MASAJESS,
                               default='',
                               help_text='')

    BAILEEROTICO = (('baileerotico', 'Baile Erótico'), )
    baile_erotico = models.CharField(_('Baile Erótico'),
                                     max_length=24,
                                     null=True,
                                     blank=True,
                                     choices=BAILEEROTICO,
                                     default='',
                                     help_text='')

    BESOSDENOVIA = (('besosdenovia', 'Besos de Novia'), )
    besos_novia = models.CharField(_('Besos de Novia'),
                                   max_length=24,
                                   null=True,
                                   blank=True,
                                   choices=BESOSDENOVIA,
                                   default='',
                                   help_text='')

    JUGUETESEROTIC = (('jugueteserotic', 'Juguetes Eróticos'), )
    juguetes_eroticos = models.CharField(_('Juguetes Eróticos'),
                                         max_length=24,
                                         null=True,
                                         blank=True,
                                         choices=JUGUETESEROTIC,
                                         default='',
                                         help_text='')

    CUADROPLASTICOS = (('cuadroplastico', 'Cuadro Plástico'), )
    cuadro_plastico = models.CharField(_('Cuadro Plástico'),
                                       max_length=24,
                                       null=True,
                                       blank=True,
                                       choices=CUADROPLASTICOS,
                                       default='',
                                       help_text='')

    DESPEDIDASOLTEROS = (('despedidasolteros', 'Despedida de Solteros'), )
    despedida_soltero = models.CharField(_('Despedida de Solteros'),
                                         max_length=24,
                                         null=True,
                                         blank=True,
                                         choices=DESPEDIDASOLTEROS,
                                         default='',
                                         help_text='')

    VIAJESS = (('viajess', 'Viajes'), )
    viajess = models.CharField(_('Viajes'),
                               max_length=24,
                               null=True,
                               blank=True,
                               choices=VIAJESS,
                               default='',
                               help_text='')

    SADISMOSS = (('sadismo', 'Sadismo'), )
    sadismo = models.CharField(_('Sadismo'),
                               max_length=24,
                               null=True,
                               blank=True,
                               choices=SADISMOSS,
                               default='',
                               help_text='')

    servicio_adicional_uno = models.CharField(_('Servicio Adicional #1'),
                                              max_length=20,
                                              null=True,
                                              blank=True,
                                              help_text='')

    servicio_adicional_dos = models.CharField(_('Servicio Adicional #2'),
                                              max_length=20,
                                              null=True,
                                              blank=True,
                                              help_text='')

    servicio_adicional_tres = models.CharField(_('Servicio Adicional #3'),
                                               max_length=20,
                                               null=True,
                                               blank=True,
                                               help_text='')

    servicio_adicional_cuatro = models.CharField(_('Servicio Adicional #4'),
                                                 max_length=20,
                                                 null=True,
                                                 blank=True,
                                                 help_text='')

    servicio_adicional_cinco = models.CharField(_('Servicio Adicional #5'),
                                                max_length=20,
                                                null=True,
                                                blank=True,
                                                help_text='')

    servicio_adicional_seis = models.CharField(_('Servicio Adicional #6'),
                                               max_length=20,
                                               null=True,
                                               blank=True,
                                               help_text='')

    servicio_adicional_siete = models.CharField(_('Servicio Adicional #7'),
                                                max_length=20,
                                                null=True,
                                                blank=True,
                                                help_text='')
    servicio_adicional_ocho = models.CharField(_('Servicio Adicional #8'),
                                               max_length=20,
                                               null=True,
                                               blank=True,
                                               help_text='')

    MESESATRABS = (('mes_enero', 'Enero'), ('mes_febrero', 'Febrero'),
                   ('mes_marzo', 'Marzo'), ('mes_abril', 'Abril'),
                   ('mes_mayo', 'Mayo'), ('mes_junio', 'Junio'), ('mes_julio',
                                                                  'Julio'),
                   ('mes_agosto', 'Agosto'), ('mes_septiembre', 'Septiembre'),
                   ('mes_octubre', 'Octubre'), ('mes_noviembre', 'Noviembre'),
                   ('mes_diciembre', 'Diciembre'))
    mesesatra = MultiSelectField(_('Registro de meses'),
                                 null=True,
                                 blank=True,
                                 choices=MESESATRABS,
                                 help_text='Solo administración')
    edad = models.CharField(max_length=2,
                            default=16,
                            null=True,
                            blank=True,
                            choices=((str(x), x) for x in range(16, 61)),
                            help_text='Rango de edad')
    nacionalidad = models.CharField(_('Nacionalidad'),
                                    max_length=20,
                                    help_text='Pais de orígen')
    TIPOS_PIEL = (
        ('blanca', 'Blanca'),
        ('trigueña', 'Trigueña'),
        ('morena', 'Morena'),
    )
    tez = models.CharField(max_length=20,
                           null=True,
                           blank=True,
                           choices=TIPOS_PIEL,
                           default='blanca',
                           help_text='Tipo de piel')
    altura = models.CharField(max_length=3,
                              default=120,
                              null=True,
                              blank=True,
                              choices=((str(x), x) for x in range(120, 201)),
                              help_text='Altura en centímetros')
    peso = models.CharField(max_length=2,
                            default=40,
                            null=True,
                            blank=True,
                            choices=((str(x), x) for x in range(40, 91)),
                            help_text='Peso en kilogramos')
    busto = models.CharField(
        max_length=3,
        default=40,
        null=True,
        blank=True,
        choices=((str(x), x) for x in range(40, 181)),
        help_text='(X) Medida de busto en centímetros (X)')
    cintura = models.CharField(
        max_length=3,
        default=40,
        null=True,
        blank=True,
        choices=((str(x), x) for x in range(40, 181)),
        help_text='(Z) Medida de cintura en centímetros (Z)')
    cadera = models.CharField(
        max_length=3,
        default=40,
        null=True,
        blank=True,
        choices=((str(x), x) for x in range(40, 181)),
        help_text='(Y) Medida de cadera en centímetros (Y)')
    TIPOS_CONTEXTURA = (('flaca', 'Flaca'), ('delgada', 'Delgada'),
                        ('atletica', 'Atlética'), ('promedio', 'Promedio'),
                        ('gruesa', 'Gruesa'), ('vuluptuosa', 'Vuluptuosa'),
                        ('gorda', 'Gorda'))
    contextura = models.CharField(max_length=20,
                                  null=True,
                                  blank=True,
                                  choices=TIPOS_CONTEXTURA,
                                  default='flaca',
                                  help_text='Tipo de cuerpo')
    COLOR_CABELLO = (('negro', 'Negro'), ('castano', 'Castaño'), ('chocolate',
                                                                  'Chocolate'),
                     ('rubio', 'Rubio'), ('cobrizo', 'Cobrizo'))
    cabello = models.CharField(max_length=20,
                               null=True,
                               blank=True,
                               choices=COLOR_CABELLO,
                               default='negro',
                               help_text='Color de cabello')
    COLOR_OJOS = (('marrones', 'Marrones'), ('avellana', 'Avellana'),
                  ('miel', 'Miel'), ('verdes', 'Verdes'),
                  ('azulmar', 'Azul Mar'), ('azules', 'Azules'))
    ojos = models.CharField(max_length=20,
                            null=True,
                            blank=True,
                            choices=COLOR_OJOS,
                            default='marrones',
                            help_text='Color de ojos')
    MEDIDA_BUSTO = (('pequeño', 'Pequeño'), ('mediano', 'Mediano'),
                    ('grande', 'Grande'), ('muygrande', 'Muy grande'))
    busto2 = models.CharField(_('Tipo de busto'),
                              max_length=20,
                              null=True,
                              blank=True,
                              choices=MEDIDA_BUSTO,
                              default='pequeño',
                              help_text='Tipo de busto')
    MEDIDA_COLA = (('pequeña', 'Pequeña'), ('mediana', 'Mediana'),
                   ('grande', 'Grande'), ('muygrande', 'Muy grande'))
    cola = models.CharField(_('Tipo de cola'),
                            max_length=20,
                            null=True,
                            blank=True,
                            choices=MEDIDA_COLA,
                            default='pequeña',
                            help_text='Tipo de cola')
    TIPO_DEPILACION = (('sindepilar', 'Sin Depilar'), ('comun', 'Común'),
                       ('cavadofrances',
                        'Cavado francés'), ('cavadotanga', 'Cavado de tanga'),
                       ('cajatiffany', 'Caja tiffany'), ('brasileñototal',
                                                         'Brasileño total'),
                       ('completa', 'Depilada Completa'))
    depilacion = models.CharField(_('Depilación'),
                                  max_length=20,
                                  null=True,
                                  blank=True,
                                  choices=TIPO_DEPILACION,
                                  default='sindepilar',
                                  help_text='Tipo de depilación')
    CIUDADLISTA = (
        ('curico', 'Curicó'),
        ('talca', 'Talca'),
        ('concepción', 'Concepción'),
        ('chillan', 'Chillán'),
        ('losangeles', 'Los Angeles'),
        ('temuco', 'Temuco'),
        ('pucon', 'Pucón'),
        ('villarica', 'Villarrica'),
        ('futrono', 'Futrono'),
        ('valdivia', 'Valdivia'),
        ('riobueno', 'Rio Bueno'),
        ('launion', 'La Unión'),
        ('osorno', 'Osorno'),
        ('puertomontt', 'Puerto Montt'),
        ('puntaaernas', 'Punta Arenas'),
    )
    ciudadheader = models.CharField(
        _('Encabezado'),
        max_length=20,
        null=True,
        blank=True,
        choices=CIUDADLISTA,
        default='',
        help_text='Seleccione la ciudad para el encabezado de perfil ')
    IDIOMAUNO = (('espanol', 'Español'), ('ingles', 'Inglés'),
                 ('portugues', 'Portugués '), ('ruso', 'Ruso'),
                 ('aleman', 'Alemán'), ('frances', 'Frances'))
    idiomauno = models.CharField(_('Idioma Principal'),
                                 max_length=20,
                                 null=True,
                                 blank=True,
                                 choices=IDIOMAUNO,
                                 default='espanol',
                                 help_text='Idioma Principal')
    IDIOMADOS = (('espanol', 'Español'), ('ingles', 'Inglés'),
                 ('portugues', 'Portugués '), ('ruso', 'Ruso'),
                 ('aleman', 'Alemán'), ('frances', 'Francés'))
    idiomados = models.CharField(_('Idioma Secundario'),
                                 max_length=20,
                                 null=True,
                                 blank=True,
                                 choices=IDIOMADOS,
                                 default='',
                                 help_text='Idioma Secundario')

    modeloretoque = models.CharField(
        _('Comentario Retoque'),
        max_length=255,
        null=True,
        blank=True,
        help_text=
        'ej: ha sido entrevistada personalmente, sus fotografías están levemente retocadas'
    )

    def get_imagen_box(instance, filename):
        now = datetime.datetime.now()
        return '/'.join([
            now.strftime('%Y'),
            now.strftime('%m'),
            now.strftime('%d'), instance.slug, 'box', filename
        ])

    def get_imagen_perfil(instance, filename):
        now = datetime.datetime.now()
        return '/'.join([
            now.strftime('%Y'),
            now.strftime('%m'),
            now.strftime('%d'), instance.slug, 'perfil', filename
        ])

    def get_imagen_galeria(instance, filename):
        now = datetime.datetime.now()
        return '/'.join([
            now.strftime('%Y'),
            now.strftime('%m'),
            now.strftime('%d'), instance.slug, 'galeria', filename
        ])

    image = models.ImageField(_('Imagen de caja'),
                              upload_to=get_imagen_box,
                              help_text=_('Usada para portada'))
    image2 = models.ImageField(_('Imagen de Perfil'),
                               upload_to=get_imagen_perfil,
                               help_text='Usada para perfil')
    imagal1 = models.ImageField(_('Imagen de Galeria (1)'),
                                upload_to=get_imagen_galeria,
                                null=True,
                                blank=True,
                                help_text='Imagen 1')
    imagal2 = models.ImageField(_('Imagen de Galeria (2)'),
                                upload_to=get_imagen_galeria,
                                null=True,
                                blank=True,
                                help_text='Imagen 2')
    imagal3 = models.ImageField(_('Imagen de Galeria (3)'),
                                upload_to=get_imagen_galeria,
                                null=True,
                                blank=True,
                                help_text='Imagen 3')
    imagal4 = models.ImageField(_('Imagen de Galeria (4)'),
                                upload_to=get_imagen_galeria,
                                null=True,
                                blank=True,
                                help_text='Imagen 4')
    imagal5 = models.ImageField(_('Imagen de Galeria (5)'),
                                upload_to=get_imagen_galeria,
                                null=True,
                                blank=True,
                                help_text='Imagen 5')
    imagal6 = models.ImageField(_('Imagen de Galeria (6)'),
                                upload_to=get_imagen_galeria,
                                null=True,
                                blank=True,
                                help_text='Imagen 6')
    imagal7 = models.ImageField(_('Imagen de Galeria (7)'),
                                upload_to=get_imagen_galeria,
                                null=True,
                                blank=True,
                                help_text='Imagen 7')
    imagal8 = models.ImageField(_('Imagen de Galeria (8)'),
                                upload_to=get_imagen_galeria,
                                null=True,
                                blank=True,
                                help_text='Imagen 8')
    imagal9 = models.ImageField(_('Imagen de Galeria (9)'),
                                upload_to=get_imagen_galeria,
                                null=True,
                                blank=True,
                                help_text='Imagen 9')
    imagal10 = models.ImageField(_('Imagen de Galeria (10)'),
                                 upload_to=get_imagen_galeria,
                                 null=True,
                                 blank=True,
                                 help_text='Imagen 10')
    imagal11 = models.ImageField(_('Imagen de Galeria (11)'),
                                 upload_to=get_imagen_galeria,
                                 null=True,
                                 blank=True,
                                 help_text='Imagen 11')
    imagal12 = models.ImageField(_('Imagen de Galeria (12)'),
                                 upload_to=get_imagen_galeria,
                                 null=True,
                                 blank=True,
                                 help_text='Imagen 12')
    imagal13 = models.ImageField(_('Imagen de Galeria (13)'),
                                 upload_to=get_imagen_galeria,
                                 null=True,
                                 blank=True,
                                 help_text='Imagen 13')
    imagal14 = models.ImageField(_('Imagen de Galeria (14)'),
                                 upload_to=get_imagen_galeria,
                                 null=True,
                                 blank=True,
                                 help_text='Imagen 14')
    imagal15 = models.ImageField(_('Imagen de Galeria (15)'),
                                 upload_to=get_imagen_galeria,
                                 null=True,
                                 blank=True,
                                 help_text='Imagen 15')
    imagal16 = models.ImageField(_('Imagen de Galeria (16)'),
                                 upload_to=get_imagen_galeria,
                                 null=True,
                                 blank=True,
                                 help_text='Imagen 16')
    imagal17 = models.ImageField(_('Imagen de Galeria (17)'),
                                 upload_to=get_imagen_galeria,
                                 null=True,
                                 blank=True,
                                 help_text='Imagen 17')
    imagal18 = models.ImageField(_('Imagen de Galeria (18)'),
                                 upload_to=get_imagen_galeria,
                                 null=True,
                                 blank=True,
                                 help_text='Imagen 18')

    CATEGORIASS = (('vip', 'Vip'), ('premium', 'Premium'), ('gold', 'Gold '),
                   ('silver', 'Silver'))
    categoriass = models.CharField(_('Categoría'),
                                   max_length=20,
                                   null=True,
                                   blank=True,
                                   choices=CATEGORIASS,
                                   default='',
                                   help_text='Categoria')

    slug = models.SlugField(_('slug'),
                            unique=True,
                            max_length=255,
                            unique_for_date='publication_date',
                            help_text=_("Used to build the entry's URL."))

    status = models.IntegerField(
        _('status'),
        db_index=True,
        choices=STATUS_CHOICES,
        default=DRAFT,
        help_text=
        'Borrador: en edición / Oculto: almacenado / Publicado: en sitio')
    publication_date = models.DateTimeField(
        _('publication date'),
        db_index=True,
        default=timezone.now,
        help_text=_("Used to build the entry's URL."))

    start_publication = models.DateTimeField(
        _('start publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('Start date of publication.'))

    end_publication = models.DateTimeField(
        _('end publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('End date of publication.'))

    sites = models.ManyToManyField(
        Site,
        related_name='entries',
        verbose_name=_('sites'),
        help_text=_('Sites where the entry will be published.'))

    creation_date = models.DateTimeField(_('creation date'),
                                         default=timezone.now)

    last_update = models.DateTimeField(_('last update'), default=timezone.now)

    objects = models.Manager()

    published = EntryPublishedManager()

    @property
    def is_actual(self):
        """
        Checks if an entry is within his publication period.
        """
        now = timezone.now()
        if self.start_publication and now < self.start_publication:
            return False

        if self.end_publication and now >= self.end_publication:
            return False
        return True

    @property
    def is_visible(self):
        """
        Checks if an entry is visible and published.
        """
        return self.is_actual and self.status == PUBLISHED

    @property
    def previous_entry(self):
        """
        Returns the previous published entry if exists.
        """
        return self.previous_next_entries[0]

    @property
    def next_entry(self):
        """
        Returns the next published entry if exists.
        """
        return self.previous_next_entries[1]

    @property
    def previous_next_entries(self):
        """
        Returns and caches a tuple containing the next
        and previous published entries.
        Only available if the entry instance is published.
        """
        previous_next = getattr(self, 'previous_next', None)

        if previous_next is None:
            if not self.is_visible:
                previous_next = (None, None)
                setattr(self, 'previous_next', previous_next)
                return previous_next

            entries = list(self.__class__.published.all())
            index = entries.index(self)
            try:
                previous = entries[index + 1]
            except IndexError:
                previous = None

            if index:
                _next = entries[index - 1]
            else:
                _next = None
            previous_next = (previous, _next)
            setattr(self, 'previous_next', previous_next)
        return previous_next

    @property
    def short_url(self):
        """
        Returns the entry's short url.
        """
        return get_url_shortener()(self)

    def save(self, *args, **kwargs):
        """
        Overrides the save method to update the
        the last_update field.
        """
        self.last_update = timezone.now()
        super(CoreEntry, self).save(*args, **kwargs)

    def get_absolute_url(self):
        """
        Builds and returns the entry's URL based on
        the slug and the creation date.
        """
        publication_date = self.publication_date
        if timezone.is_aware(publication_date):
            publication_date = timezone.localtime(publication_date)
        return reverse('zinnia:entry_detail',
                       kwargs={
                           'year': publication_date.strftime('%Y'),
                           'month': publication_date.strftime('%m'),
                           'day': publication_date.strftime('%d'),
                           'slug': self.slug
                       })

    def __str__(self):
        return '%s: %s' % (self.title, self.get_status_display())

    class Meta:
        """
        CoreEntry's meta informations.
        """
        abstract = True
        ordering = ['-publication_date']
        get_latest_by = 'publication_date'
        verbose_name = _('entry')
        verbose_name_plural = _('entries')
        index_together = [['slug', 'publication_date'],
                          [
                              'status', 'publication_date',
                              'start_publication', 'end_publication'
                          ]]
        permissions = (
            ('can_view_all', 'Can view all entries'),
            ('can_change_status', 'Can change status'),
            ('can_change_author', 'Can change author(s)'),
        )
Beispiel #10
0
class CaseStudyEntry(ContentEntry, LeadEntry, ExcerptEntry, FeaturedEntry,
                     TagsEntry, Orderable):
    STATUS_CHOICES = (
        (DRAFT, _('draft')),
        (PUBLISHED, _('published')),
    )

    title = models.CharField(_('title'), blank=True, max_length=255)

    slug = models.SlugField(_('slug'),
                            blank=True,
                            max_length=255,
                            unique=True,
                            help_text=_("Used to build the entry's URL."))

    status = models.PositiveSmallIntegerField(_('status'),
                                              db_index=True,
                                              choices=STATUS_CHOICES,
                                              default=DRAFT)

    start_publication = models.DateTimeField(
        _('start publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('Start date of publication.'))

    end_publication = models.DateTimeField(
        _('end publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('End date of publication.'))

    sites = models.ManyToManyField(
        Site,
        related_name='case_study_entries',
        verbose_name=_('sites'),
        help_text=_('Sites where the entry will be published.'))

    creation_date = models.DateTimeField(
        _('creation date'),
        db_index=True,
        default=timezone.now,
        help_text=_("Used to build the entry's URL."))

    last_update = models.DateTimeField(_('last update'), auto_now=True)

    authors = models.ManyToManyField('zinnia.Author',
                                     blank=True,
                                     related_name='case_study_entries',
                                     verbose_name=_('authors'))

    image = FilerImageField(verbose_name=_('Image'),
                            help_text=_('Image (icon)'),
                            related_name='+')
    image_caption = models.TextField(_('caption'),
                                     help_text=_("Image's caption."),
                                     blank=True)
    background_image = FilerImageField(verbose_name=_('background image'),
                                       help_text=_('Background image'),
                                       related_name='+',
                                       blank=True,
                                       null=True)

    content_right = models.TextField(blank=True)

    og_tags = models.TextField(verbose_name=_('Custom OG:Tags'),
                               help_text=_('One file per line'),
                               blank=True)

    objects = models.Manager()
    published = EntryPublishedManager()

    class Meta:
        # from CoreEntry meta
        ordering = ['-featured', '-sort_order', '-creation_date']
        get_latest_by = 'creation_date'
        verbose_name = _('case study entry')
        verbose_name_plural = _('case study entries')
        index_together = (
            'status',
            'creation_date',
            'start_publication',
            'end_publication',
        )
        permissions = (
            ('can_view_all_case_studies', 'Can view all entries'),
            ('can_change_case_study_status', 'Can change status'),
        )

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        super(CaseStudyEntry, self).save(*args, **kwargs)
        self.sites.add(Site.objects.get_current())

    def get_absolute_url(self):
        return reverse('case_study_detail', args=(self.slug, ))

    @property
    def is_visible(self):
        return self.is_actual and self.status == PUBLISHED

    @property
    def is_actual(self):
        now = timezone.now()
        if self.start_publication and now < self.start_publication:
            return False

        if self.end_publication and now >= self.end_publication:
            return False
        return True

    @property
    def og_tags_list(self):
        if not self.og_tags:
            return []
        return [s for s in self.og_tags.split()]
Beispiel #11
0
class ResourceEntry(ContentEntry, LeadEntry, ExcerptEntry, FeaturedEntry,
                    TagsEntry, Orderable):
    STATUS_CHOICES = (
        (DRAFT, _('draft')),
        (PUBLISHED, _('published')),
    )

    title = models.CharField(_('title'), blank=True, max_length=255)

    slug = models.SlugField(_('slug'),
                            blank=True,
                            max_length=255,
                            unique=True,
                            help_text=_("Used to build the entry's URL."))

    status = models.PositiveSmallIntegerField(_('status'),
                                              db_index=True,
                                              choices=STATUS_CHOICES,
                                              default=DRAFT)

    start_publication = models.DateTimeField(
        _('start publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('Start date of publication.'))

    end_publication = models.DateTimeField(
        _('end publication'),
        db_index=True,
        blank=True,
        null=True,
        help_text=_('End date of publication.'))

    sites = models.ManyToManyField(
        Site,
        related_name='resource_entries',
        verbose_name=_('sites'),
        help_text=_('Sites where the entry will be published.'))

    creation_date = models.DateTimeField(
        _('creation date'),
        db_index=True,
        default=timezone.now,
        help_text=_("Used to build the entry's URL."))

    last_update = models.DateTimeField(_('last update'), auto_now=True)

    authors = models.ManyToManyField('zinnia.Author',
                                     blank=True,
                                     related_name='resource_entries',
                                     verbose_name=_('authors'))

    # categories
    topics = models.ManyToManyField(TopicCategory,
                                    blank=True,
                                    related_name='entries',
                                    verbose_name=_('topics'))
    types = models.ManyToManyField(TypeCategory,
                                   blank=True,
                                   related_name='entries',
                                   verbose_name=_('types'))
    industries = models.ManyToManyField(IndustryCategory,
                                        blank=True,
                                        related_name='entries',
                                        verbose_name=_('industries'))

    image = FilerImageField(verbose_name=_('Image'),
                            blank=True,
                            null=True,
                            help_text=_('Featured image.'))

    image_caption = models.TextField(_('caption'),
                                     blank=True,
                                     help_text=_("Image's caption."))

    form_link = models.URLField(_('form link'),
                                blank=True,
                                help_text=_('Form link for iframe.'))

    og_tags = models.TextField(verbose_name=_('Custom OG:Tags'),
                               help_text=_('One file per line'),
                               blank=True)

    objects = models.Manager()
    published = EntryPublishedManager()

    class Meta:
        # from CoreEntry meta
        ordering = ['-featured', '-sort_order', '-creation_date']
        get_latest_by = 'creation_date'
        verbose_name = _('resource entry')
        verbose_name_plural = _('resource entries')
        index_together = (
            'status',
            'creation_date',
            'start_publication',
            'end_publication',
        )
        permissions = (
            ('can_view_all_resources', 'Can view all entries'),
            ('can_change_resource_status', 'Can change status'),
        )

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        """
        Set the site to SITE_ID from settings/base.py
        """
        super(ResourceEntry, self).save(*args, **kwargs)
        self.sites.add(Site.objects.get_current())

    def get_absolute_url(self):
        """
        Builds and returns the entry's URL based on
        the slug and the creation date.
        """
        return reverse('resource_detail', args=(self.slug, ))

    @property
    def is_visible(self):
        """
        Checks if an entry is visible and published.
        """
        return self.is_actual and self.status == PUBLISHED

    @property
    def is_actual(self):
        """
        Checks if an entry is within his publication period.
        """
        now = timezone.now()
        if self.start_publication and now < self.start_publication:
            return False

        if self.end_publication and now >= self.end_publication:
            return False
        return True

    @property
    def og_tags_list(self):
        if not self.og_tags:
            return []
        return [s for s in self.og_tags.split()]