Exemplo n.º 1
0
class LongSlugged(Slugged):
    long_slug = db.StringField(unique=True, required=True)
    mpath = db.StringField()

    def _create_mpath_long_slug(self):
        if hasattr(self, 'is_homepage'):  # is channel
            if self.parent and self.parent != self:
                self.long_slug = "/".join([self.parent.long_slug, self.slug])
                self.mpath = "".join([self.parent.mpath, self.slug, ','])
            else:
                self.long_slug = self.slug
                self.mpath = ",%s," % self.slug
        else:  # is Content
            self.long_slug = "/".join([self.channel.long_slug, self.slug])
            self.mpath = "".join([self.channel.mpath, self.slug, ','])

    def validate_long_slug(self):
        self._create_mpath_long_slug()

        filters = dict(long_slug=self.long_slug)
        if self.id:
            filters['id__ne'] = self.id

        exist = self.__class__.objects(**filters)
        if exist.count():
            if current_app.config.get('SMART_SLUG_ENABLED', False):
                self.slug = "{0}-{1}".format(self.slug, random.getrandbits(32))
                self._create_mpath_long_slug()
            else:
                raise db.ValidationError(
                    _l("%(slug)s slug already exists", slug=self.long_slug))
Exemplo n.º 2
0
class TemplateType(HasCustomValue):
    title = db.StringField(max_length=255, required=True)
    identifier = db.StringField(max_length=255, required=True, unique=True)
    template_suffix = db.StringField(max_length=255, required=True)
    theme_name = db.StringField(max_length=255, required=False)

    def __unicode__(self):
        return self.title
Exemplo n.º 3
0
class SubContentPurpose(db.Document):
    title = db.StringField(max_length=255, required=True)
    identifier = db.StringField(max_length=255, required=True, unique=True)
    module = db.StringField()

    def save(self, *args, **kwargs):
        self.identifier = slugify(self.identifier or self.title)
        super(SubContentPurpose, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.title
Exemplo n.º 4
0
class CustomValue(db.EmbeddedDocument):
    FORMATS = (
        ('json', "json"),
        ('text', "text"),
        ('int', "int"),
        ('float', "float"),
    )

    DEFAULT_FORMATTER = default_formatter

    FORMATTERS = {
        'json': json.loads,
        'text': DEFAULT_FORMATTER,
        'int': int,
        'float': float
    }

    REVERSE_FORMATTERS = {
        'json': lambda val: val if isinstance(val, str) else json.dumps(val),
        'text': DEFAULT_FORMATTER,
        'int': DEFAULT_FORMATTER,
        'float': DEFAULT_FORMATTER
    }

    name = db.StringField(max_length=50, required=True)
    rawvalue = db.StringField(verbose_name=_l("Value"), required=True)
    formatter = db.StringField(choices=FORMATS, default="text", required=True)

    @property
    def value(self):
        return self.FORMATTERS.get(self.formatter,
                                   self.DEFAULT_FORMATTER)(self.rawvalue)

    @value.setter
    def value(self, value):
        self.rawvalue = self.REVERSE_FORMATTERS.get(self.formatter,
                                                    self.STR_FORMATTER)(value)

    def clean(self):
        try:
            self.value
        except Exception as e:
            raise Exception(e.message)
        super(CustomValue, self).clean()

    def __unicode__(self):
        return u"{s.name} -> {s.value}".format(s=self)
Exemplo n.º 5
0
class Slugged(object):
    slug = db.StringField(max_length=255, required=True)

    def validate_slug(self, title=None):
        if self.slug:
            self.slug = slugify(self.slug)
        else:
            self.slug = slugify(title or self.title)
Exemplo n.º 6
0
class Link(Content):
    link = db.StringField(required=True)
    force_redirect = db.BooleanField(default=True)
    increment_visits = db.BooleanField(default=True)
    visits = db.IntField(default=0)
    show_on_channel = db.BooleanField(default=False)

    def pre_render(self, render_function, *args, **kwargs):
        if self.increment_visits:
            self.visits = self.visits + 1
            self.save()
        if self.force_redirect:
            return redirect(self.link)
        return super(Link, self).pre_render(render_function, *args, **kwargs)
Exemplo n.º 7
0
class SubContent(Publishable, Ordered, db.EmbeddedDocument):
    content = db.ReferenceField('Content', required=True)
    caption = db.StringField()
    purpose = db.ReferenceField(SubContentPurpose, required=True)
    identifier = db.StringField()

    @property
    def thumb(self):
        try:
            return url_for('flaskpress.core.media',
                           filename=self.content.thumb)
            # return self.content.thumb
        except Exception as e:
            logger.warning(str(e))
            return self.content.get_main_image_url(thumb=True)

    meta = {'ordering': ['order'], 'indexes': ['order']}

    def clean(self):
        self.identifier = self.purpose.identifier

    def __unicode__(self):
        return self.content and self.content.title or self.caption
Exemplo n.º 8
0
class ContentFormat(object):
    content_format = db.StringField(choices=TEXT_FORMATS,
                                    default=get_setting_value(
                                        'DEFAULT_TEXT_FORMAT', 'html'))
Exemplo n.º 9
0
class Tagged(object):
    tags = db.ListField(db.StringField(max_length=50))
Exemplo n.º 10
0
class Content(HasCustomValue, Publishable, LongSlugged, Channeling, Tagged,
              ContentFormat, db.DynamicDocument):
    title = db.StringField(max_length=255, required=True)
    summary = db.StringField(required=False)
    template_type = db.ReferenceField(ContentTemplateType,
                                      required=False,
                                      reverse_delete_rule=db.NULLIFY)
    contents = db.ListField(db.EmbeddedDocumentField(SubContent))
    model = db.StringField()
    comments_enabled = db.BooleanField(default=True)
    license = db.EmbeddedDocumentField(License)
    shortened_url = db.EmbeddedDocumentField(ShortenedURL)

    meta = {
        'allow_inheritance': True,
        'indexes': ['-created_at', 'slug'],
        'ordering': ['-created_at'],
    }

    @classmethod
    def available_objects(cls, **filters):
        now = datetime.datetime.now()
        default_filters = {
            "published": True,
            'available_at__lte': now,
        }
        default_filters.update(filters)
        return cls.objects(**default_filters)

    def get_main_image_url(self,
                           thumb=False,
                           default=None,
                           identifier='mainimage'):
        """method returns the path (url) of the main image
        """
        if not isinstance(identifier, (list, tuple)):
            identifier = [identifier]

        for item in identifier:
            try:
                if not thumb:
                    path = self.contents.get(identifier=item).content.path
                else:
                    path = self.contents.get(identifier=item).content.thumb
                return url_for('flaskpress.core.media', filename=path)
            except Exception as e:
                logger.warning('get_main_image_url:' + str(e))

        return default

    def get_main_image_http(self,
                            thumb=False,
                            default=None,
                            identifier='mainimage'):
        """method returns the path of the main image with http
        """
        site_url = get_site_url()
        image_url = self.get_main_image_url(thumb=thumb,
                                            default=default,
                                            identifier=identifier)
        return u"{}{}".format(site_url, image_url)

    def get_uid(self):
        return str(self.id)

    def get_themes(self):
        themes = self.channel.get_themes()
        theme = self.template_type and self.template_type.theme_name
        if theme:
            themes.insert(0, theme)
        return list(set(themes))

    def get_http_url(self):
        site_url = get_site_url()
        absolute_url = self.get_absolute_url()
        absolute_url = absolute_url[1:]
        return u"{0}{1}".format(site_url, absolute_url)

    def get_absolute_url(self, endpoint='flaskpress.core.detail'):
        if self.channel.is_homepage:
            long_slug = self.slug
        else:
            long_slug = self.long_slug

        try:
            return url_for(self.URL_NAMESPACE, long_slug=long_slug)
        except:
            return url_for(endpoint, long_slug=long_slug)

    def get_canonical_url(self, *args, **kwargs):
        return self.get_absolute_url()

    def get_recommendations(self, limit=3, ordering='-created_at', *a, **k):
        now = datetime.datetime.now()
        filters = {
            'published': True,
            'available_at__lte': now,
            "id__ne": self.id
        }
        contents = Content.objects(**filters).filter(tags__in=self.tags or [])

        return contents.order_by(ordering)[:limit]

    def get_summary(self):
        if self.summary:
            return self.summary
        return self.get_text()

    def get_text(self):
        if hasattr(self, 'body'):
            text = self.body
        elif hasattr(self, 'description'):
            text = self.description
        else:
            text = self.summary or ""

        if self.content_format == "markdown":
            return markdown(text)
        else:
            return text

    def __unicode__(self):
        return self.title

    @property
    def short_url(self):
        return self.shortened_url.short if self.shortened_url else ''

    @property
    def model_name(self):
        return self.__class__.__name__.lower()

    @property
    def module_name(self):
        module = self.__module__
        module_name = module.replace('flaskpress.modules.', '').split('.')[0]
        return module_name

    def heritage(self):
        self.model = "{0}.{1}".format(self.module_name, self.model_name)

    def save(self, *args, **kwargs):
        # all those functions should be in a dynamic pipeline
        self.validate_slug()
        self.validate_long_slug()
        self.heritage()
        self.populate_related_mpath()
        self.populate_channel_roles()
        self.populate_shorter_url()
        super(Content, self).save(*args, **kwargs)

    def pre_render(self, render_function, *args, **kwargs):
        return render_function(*args, **kwargs)

    def populate_shorter_url(self):
        if not self.published or not get_setting_value('SHORTENER_ENABLED'):
            return

        url = self.get_http_url()
        if not self.shortened_url or url != self.shortened_url.original:
            shortener = ShorterURL()
            self.shortened_url = ShortenedURL(original=url,
                                              short=shortener.short(url))
Exemplo n.º 11
0
class ShortenedURL(db.EmbeddedDocument):
    original = db.StringField(max_length=255)
    short = db.StringField(max_length=255)

    def __str__(self):
        return self.short
Exemplo n.º 12
0
class License(db.EmbeddedDocument):
    LICENSES = (('custom', 'custom'), ('creative_commons_by_nc_nd',
                                       'creative_commons_by_nc_nd'))
    title = db.StringField(max_length=255)
    link = db.StringField(max_length=255)
    identifier = db.StringField(max_length=255, choices=LICENSES)
Exemplo n.º 13
0
class Post(Content):
    # URL_NAMESPACE = 'flaskpress.modules.posts.detail'
    body = db.StringField(required=True)