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
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)'), )
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)
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)'), )
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()]
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)'), )
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()
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)'), )
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()]
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()]