Esempio n. 1
0
class Publishable(Dated, Owned):
    published = db.BooleanField(default=False)

    @property
    def is_available(self):
        now = datetime.datetime.now()
        return (self.published and self.available_at <= now and
                (self.available_until is None or self.available_until >= now))

    def save(self, *args, **kwargs):
        self.updated_at = datetime.datetime.now()

        user = get_current_user_for_models()

        if not self.id and not self.created_by:
            self.created_by = user
        self.last_updated_by = user

        super(Publishable, self).save(*args, **kwargs)
Esempio n. 2
0
class Publishable(object):
    published = db.BooleanField(default=False)
    available_at = db.DateTimeField(default=datetime.datetime.now)
    created_at = db.DateTimeField(default=datetime.datetime.now)
    updated_at = db.DateTimeField(default=datetime.datetime.now)
    created_by = db.ReferenceField(User, reverse_delete_rule=db.DENY)
    last_updated_by = db.ReferenceField(User, reverse_delete_rule=db.DENY)

    def save(self, *args, **kwargs):
        self.updated_at = datetime.datetime.now()

        try:
            user = User.objects.get(id=current_user.id)
            if not self.id:
                self.created_by = user
            self.last_updated_by = user
        except Exception as e:
            logger.warning("No user to save the model: %s" % e.message)

        super(Publishable, self).save(*args, **kwargs)
Esempio n. 3
0
class User(db.DynamicDocument, UserMixin):
    name = db.StringField(max_length=255)
    email = db.EmailField(max_length=255, unique=True)
    password = db.StringField(max_length=255)
    active = db.BooleanField(default=True)
    confirmed_at = db.DateTimeField()
    roles = db.ListField(db.ReferenceField(Role, reverse_delete_rule=db.DENY),
                         default=[])

    last_login_at = db.DateTimeField()
    current_login_at = db.DateTimeField()
    last_login_ip = db.StringField(max_length=255)
    current_login_ip = db.StringField(max_length=255)
    login_count = db.IntField()

    username = db.StringField(max_length=50, requied=False, unique=True)

    @classmethod
    def generate_username(cls, name, user=None):
        name = name or ''
        username = slugify(name)
        filters = dict(username=username)
        if user:
            filters['id__ne'] = user.id
        if cls.objects.filter(**filters).count():
            username = '******'.format(username, random.randint(1, 1000))
        return username

    def set_password(self, password, save=False):
        self.password = encrypt_password(password)
        if save:
            self.save()

    @classmethod
    def create_user(cls,
                    name,
                    email,
                    password,
                    active=True,
                    roles=None,
                    username=None,
                    *args,
                    **kwargs):

        username = username or cls.generate_username(name)

        if 'links' in kwargs:
            kwargs['links'] = [UserLink(**link) for link in kwargs['links']]

        return cls.objects.create(name=name,
                                  email=email,
                                  password=encrypt_password(password),
                                  active=active,
                                  roles=roles,
                                  username=username,
                                  *args,
                                  **kwargs)

    @property
    def connections(self):
        return Connection.objects(user_id=str(self.id))

    def __unicode__(self):
        return '{0} <{1}>'.format(self.name or '', self.email)
Esempio n. 4
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)

    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'):
        """
        """
        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('media', filename=path)
            except Exception as e:
                logger.warning(str(e))

        return default

    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_absolute_url(self, endpoint='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

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

    def __unicode__(self):
        return self.title

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

    @property
    def module_name(self):
        module = self.__module__
        module_name = module.replace('quokka.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):
        self.validate_slug()
        self.validate_long_slug()
        self.heritage()
        super(Content, self).save(*args, **kwargs)
Esempio n. 5
0
class Channel(Tagged, HasCustomValue, Publishable, LongSlugged,
              ChannelConfigs, ContentFormat, db.DynamicDocument):
    title = db.StringField(max_length=255, required=True)
    description = db.StringField()
    show_in_menu = db.BooleanField(default=False)
    is_homepage = db.BooleanField(default=False)
    include_in_rss = db.BooleanField(default=True)
    indexable = db.BooleanField(default=True)
    canonical_url = db.StringField()
    order = db.IntField(default=0)

    parent = db.ReferenceField('self', required=False, default=None,
                               reverse_delete_rule=db.DENY)

    per_page = db.IntField(default=0)
    aliases = db.ListField(db.StringField(), default=[])
    channel_type = db.ReferenceField(ChannelType, required=False,
                                     reverse_delete_rule=db.NULLIFY)

    redirect_url = db.StringField(max_length=255)
    render_content = db.ReferenceField(ContentProxy,
                                       required=False,
                                       reverse_delete_rule=db.NULLIFY)
    sort_by = db.ListField(db.StringField(), default=[])

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

    def get_text(self):
        if self.content_format == "markdown":
            return markdown(self.description)
        else:
            return self.description

    def get_content_filters(self):
        filters = {}
        if self.channel_type and self.channel_type.content_filters:
            filters.update(self.channel_type.content_filters)
        if self.content_filters:
            filters.update(self.content_filters)
        return filters

    def get_ancestors_slugs(self):
        """return ancestors slugs including self as 1st item
        >>> channel = Channel(long_slug='articles/technology/programming')
        >>> channel.get_ancestors_slugs()
        ['articles/technology/programming',
         'articles/technology',
         'articles']
        """

        channel_list = []
        channel_slugs = self.long_slug.split('/')
        while channel_slugs:
            channel_list.append("/".join(channel_slugs))
            channel_slugs.pop()
        return channel_list

    def get_ancestors(self, **kwargs):
        """return all ancestors includind self as 1st item"""
        channel_list = self.get_ancestors_slugs()
        ancestors = self.__class__.objects(
            long_slug__in=channel_list,
            **kwargs
        ).order_by('-long_slug')
        return ancestors

    def get_children(self, **kwargs):
        """return direct children 1 level depth"""
        return self.__class__.objects(
            parent=self, **kwargs
        ).order_by('long_slug')

    def get_descendants(self, **kwargs):
        """return all descendants including self as 1st item"""
        return self.__class__.objects(
            __raw__={'mpath': {'$regex': '^{0}'.format(self.mpath)}}
        ).order_by('long_slug')

    def get_themes(self):
        return list({
            c.channel_type.theme_name
            for c in self.get_ancestors(channel_type__ne=None)
            if c.channel_type and c.channel_type.theme_name
        })

    @classmethod
    def get_homepage(cls, attr=None):
        try:
            homepage = cls.objects.get(is_homepage=True)
        except Exception as e:
            logger.info("There is no homepage: %s" % e.message)
            return None
        else:
            if not attr:
                return homepage
            else:
                return getattr(homepage, attr, homepage)

    def __unicode__(self):
        return self.long_slug

    def get_absolute_url(self, *args, **kwargs):
        return "/{0}/".format(self.long_slug)

    def get_canonical_url(self, *args, **kwargs):
        if self.is_homepage:
            return "/"
        return self.get_absolute_url()

    def clean(self):
        homepage = Channel.objects(is_homepage=True)
        if self.is_homepage and homepage and not self in homepage:
            raise db.ValidationError(_l("Home page already exists"))
        super(Channel, self).clean()

    def validate_render_content(self):
        if self.render_content and \
                not isinstance(self.render_content, ContentProxy):
            self.render_content, created = ContentProxy.objects.get_or_create(
                content=self.render_content)
        else:
            self.render_content = None

    def heritage(self):
        """populate inheritance from parent channels"""
        parent = self.parent
        if not parent or not self.inherit_parent:
            return

        self.content_filters = self.content_filters or parent.content_filters
        self.include_in_rss = self.include_in_rss or parent.include_in_rss
        self.show_in_menu = self.show_in_menu or parent.show_in_menu
        self.indexable = self.indexable or parent.indexable
        self.channel_type = self.channel_type or parent.channel_type

    def update_descendants_and_contents(self):
        """TODO:
        Detect if self.long_slug and self.mpath has changed.
        if so, update every descendant using get_descendatns method
        to query.
        Also update long_slug and mpath for every Content in this channel
        This needs to be done by default in araw immediate way, but if
        current_app.config.get('ASYNC_SAVE_MODE') is True it will delegate
        all those tasks to celery."""

    def save(self, *args, **kwargs):
        self.validate_render_content()
        self.validate_slug()
        self.validate_long_slug()
        self.heritage()
        self.update_descendants_and_contents()
        super(Channel, self).save(*args, **kwargs)
Esempio n. 6
0
class ChannelConfigs(object):
    content_filters = db.DictField(required=False, default=lambda: {})
    inherit_parent = db.BooleanField(default=True)
Esempio n. 7
0
class User(db.DynamicDocument, ThemeChanger, HasCustomValue, UserMixin,
           HasImages):
    name = db.StringField(max_length=255)
    email = db.EmailField(max_length=255, unique=True)
    password = db.StringField(max_length=255)
    active = db.BooleanField(default=True)
    confirmed_at = db.DateTimeField()
    roles = db.ListField(db.ReferenceField(Role, reverse_delete_rule=db.DENY),
                         default=[])

    last_login_at = db.DateTimeField()
    current_login_at = db.DateTimeField()
    last_login_ip = db.StringField(max_length=255)
    current_login_ip = db.StringField(max_length=255)
    login_count = db.IntField()

    username = db.StringField(max_length=50, required=False, unique=True)

    remember_token = db.StringField(max_length=255)
    authentication_token = db.StringField(max_length=255)

    tagline = db.StringField(max_length=255)
    bio = db.StringField()
    links = db.ListField(db.EmbeddedDocumentField(UserLink))

    use_avatar_from = db.StringField(choices=(("gravatar", "gravatar"),
                                              ("url", "url"), ("upload",
                                                               "upload"),
                                              ("facebook", "facebook")),
                                     default='gravatar')
    gravatar_email = db.EmailField(max_length=255)
    avatar_file_path = db.StringField()
    avatar_url = db.StringField(max_length=255)

    @property
    def display_name(self):
        rtn = None
        if self.name:
            rtn = self.name
        elif self.username:
            rtn = self.username
        elif self.email:
            rtn = self.email
        else:
            rtn = str(self)
        return rtn

    def get_avatar_url(self, *args, **kwargs):
        if self.use_avatar_from == 'url':
            return self.avatar_url
        elif self.use_avatar_from == 'upload':
            return url_for('quokka.core.media', filename=self.avatar_file_path)
        elif self.use_avatar_from == 'facebook':
            try:
                return Connection.objects(
                    provider_id='facebook',
                    user_id=self.id,
                ).first().image_url
            except Exception as e:
                logger.warning(
                    '%s use_avatar_from is set to facebook but: Error: %s' %
                    (self.display_name, str(e)))
        return Gravatar()(self.get_gravatar_email(), *args, **kwargs)

    @property
    def summary(self):
        return (self.bio or self.tagline or '')[:255]

    def get_gravatar_email(self):
        return self.gravatar_email or self.email

    def clean(self, *args, **kwargs):
        if not self.username:
            self.username = User.generate_username(self.name)
        super(User, self).clean(*args, **kwargs)

    @classmethod
    def generate_username(cls, name, user=None):
        name = name or ''
        username = slugify(name)
        filters = {"username": username}
        if user:
            filters["id__ne"] = user.id
        if cls.objects.filter(**filters).count():
            username = "******".format(username, randint(1, 1000))
        return username

    def set_password(self, password, save=False):
        self.password = encrypt_password(password)
        if save:
            self.save()

    @classmethod
    def createuser(cls,
                   name,
                   email,
                   password,
                   active=True,
                   roles=None,
                   username=None,
                   *args,
                   **kwargs):

        username = username or cls.generate_username(name)
        if 'links' in kwargs:
            kwargs['links'] = [UserLink(**link) for link in kwargs['links']]

        return cls.objects.create(name=name,
                                  email=email,
                                  password=encrypt_password(password),
                                  active=active,
                                  roles=roles,
                                  username=username,
                                  *args,
                                  **kwargs)

    @property
    def display_name(self):
        return abbreviate(self.name) or self.email

    def __unicode__(self):
        return u"{0} <{1}>".format(self.name or '', self.email)

    @property
    def connections(self):
        return Connection.objects(user_id=str(self.id))
Esempio n. 8
0
class User(db.DynamicDocument, UserMixin):
    name = db.StringField(max_length=255)
    email = db.EmailField(max_length=255, unique=True)
    password = db.StringField(max_length=255)
    active = db.BooleanField(default=True)
    confirmed_at = db.DateTimeField()
    roles = db.ListField(db.ReferenceField(Role, reverse_delete_rule=db.DENY),
                         default=[])

    last_login_at = db.DateTimeField()
    current_login_at = db.DateTimeField()
    last_login_ip = db.StringField(max_length=255)
    current_login_ip = db.StringField(max_length=255)
    login_count = db.IntField()

    username = db.StringField(max_length=50, required=False, unique=True)

    remember_token = db.StringField(max_length=255)
    authentication_token = db.StringField(max_length=255)

    tagline = db.StringField(max_length=255)
    bio = db.StringField()
    links = db.ListField(db.EmbeddedDocumentField(UserLink))
    gravatar_email = db.EmailField(max_length=255)

    def get_gravatar_email(self):
        return self.gravatar_email or self.email

    def clean(self, *args, **kwargs):
        if not self.username:
            self.username = User.generate_username(self.name)

        try:
            super(User, self).clean(*args, **kwargs)
        except:
            pass

    @classmethod
    def generate_username(cls, name):
        # username = email.lower()
        # for item in ['@', '.', '-', '+']:
        #     username = username.replace(item, '_')
        # return username
        username = slugify(name)
        if cls.objects.filter(username=username).count():
            username = "******".format(username, randint(1, 1000))
        return username

    def set_password(self, password, save=False):
        self.password = encrypt_password(password)
        if save:
            self.save()

    @classmethod
    def createuser(cls,
                   name,
                   email,
                   password,
                   active=True,
                   roles=None,
                   username=None,
                   *args,
                   **kwargs):

        username = username or cls.generate_username(name)
        if "links" in kwargs:
            kwargs["links"] = [UserLink(**link) for link in kwargs['links']]

        return cls.objects.create(name=name,
                                  email=email,
                                  password=encrypt_password(password),
                                  active=active,
                                  roles=roles,
                                  username=username,
                                  *args,
                                  **kwargs)

    @property
    def display_name(self):
        return abbreviate(self.name) or self.email

    def __unicode__(self):
        return u"{0} <{1}>".format(self.name or '', self.email)

    @property
    def connections(self):
        return Connection.objects(user_id=str(self.id))
Esempio n. 9
0
class Cart(Publishable, db.DynamicDocument):
    STATUS = (
        ("pending", _l("Pending")),  # not checked out
        ("checked_out", _l("Checked out")),  # not confirmed (payment)
        ("analysing", _l("Analysing")),  # Analysing payment
        ("confirmed", _l("Confirmed")),  # Payment confirmed
        ("completed", _l("Completed")),  # Payment completed (money released)
        ("refunding", _l("Refunding")),  # Buyer asks refund
        ("refunded", _l("Refunded")),  # Money refunded to buyer
        ("cancelled", _l("Cancelled")),  # Cancelled without processing
        ("abandoned", _l("Abandoned")),  # Long time no update
    )
    reference = db.GenericReferenceField()
    """reference must implement set_status(**kwargs) method
    arguments: status(str), value(float), date, uid(str), msg(str)
    and extra(dict).
    Also reference must implement get_uid() which will return
    the unique identifier for this transaction"""

    belongs_to = db.ReferenceField(
        'User',
        # default=get_current_user,
        reverse_delete_rule=db.NULLIFY)
    items = db.ListField(db.EmbeddedDocumentField(Item))
    payment = db.ListField(db.EmbeddedDocumentField(Payment))
    status = db.StringField(choices=STATUS, default='pending')
    total = db.FloatField(default=0)
    extra_costs = db.DictField(default=lambda: {})
    sender_data = db.DictField(default=lambda: {})
    shipping_data = db.DictField(default=lambda: {})
    shipping_cost = db.FloatField(default=0)
    tax = db.FloatField(default=0)
    processor = db.ReferenceField(Processor,
                                  default=Processor.get_default_processor,
                                  reverse_delete_rule=db.NULLIFY)
    reference_code = db.StringField()  # Reference code for filtering
    checkout_code = db.StringField()  # The UID for transaction checkout
    transaction_code = db.StringField()  # The UID for transaction
    requires_login = db.BooleanField(default=True)
    continue_shopping_url = db.StringField(
        default=lambda: current_app.config.get('CART_CONTINUE_SHOPPING_URL',
                                               '/'))
    pipeline = db.ListField(db.StringField(), default=[])
    log = db.ListField(db.StringField(), default=[])
    config = db.DictField(default=lambda: {})

    search_helper = db.StringField()

    meta = {'ordering': ['-created_at']}

    def send_response(self, response, identifier):
        if self.reference and hasattr(self.reference, 'get_response'):
            self.reference.get_response(response, identifier)

        for item in self.items:
            if hasattr(item, 'get_response'):
                item.get_response(response, identifier)

    def set_tax(self, tax, save=False):
        """
        set tax and send to references
        """
        try:
            tax = float(tax)
            self.tax = tax
            self.set_reference_tax(tax)
        except Exception as e:
            self.addlog("impossible to set tax: %s" % str(e))

    def set_status(self, status, save=False):
        """
        THis method will be called by the processor
        which will pass a valid status as in STATUS
        so, this method will dispatch the STATUS to
        all the items and also the 'reference' if set
        """
        if self.status != status:
            self.status = status

        self.set_reference_statuses(status)

        if save:
            self.save()

    def set_reference_statuses(self, status):
        if self.reference and hasattr(self.reference, 'set_status'):
            self.reference.set_status(status, cart=self)

        for item in self.items:
            item.set_status(status, cart=self)

    def set_reference_tax(self, tax):
        if self.reference and hasattr(self.reference, 'set_tax'):
            self.reference.set_tax(tax)

        for item in self.items:
            if hasattr(item, 'set_tax'):
                item.set_tax(tax)

    def addlog(self, msg, save=True):
        try:
            self.log.append(u"{0},{1}".format(datetime.datetime.now(), msg))
            logger.debug(msg)
            save and self.save()
        except UnicodeDecodeError as e:
            logger.info(msg)
            logger.error(str(e))

    @property
    def uid(self):
        return self.get_uid()

    def get_uid(self):
        try:
            return self.reference.get_uid() or str(self.id)
        except Exception:
            self.addlog("Using self.id as reference", save=False)
            return str(self.id)

    def __unicode__(self):
        return u"{o.uid} - {o.processor.identifier}".format(o=self)

    def get_extra_costs(self):
        if self.extra_costs:
            return sum(self.extra_costs.values())

    @classmethod
    def get_cart(cls, no_dereference=False, save=True):
        """
        get or create a new cart related to the session
        if there is a current logged in user it will be set
        else it will be set during the checkout.
        """
        session.permanent = current_app.config.get("CART_PERMANENT_SESSION",
                                                   True)
        try:
            cart = cls.objects(id=session.get('cart_id'), status='pending')

            if not cart:
                raise cls.DoesNotExist('A pending cart not found')

            if no_dereference:
                cart = cart.no_dereference()

            cart = cart.first()

            save and cart.save()

        except (cls.DoesNotExist, db.ValidationError):
            cart = cls(status="pending")
            cart.save()
            session['cart_id'] = str(cart.id)
            session.pop('cart_pipeline_index', None)
            session.pop('cart_pipeline_args', None)

        return cart

    def assign(self):
        self.belongs_to = self.belongs_to or get_current_user()

    def save(self, *args, **kwargs):
        self.total = sum([item.total for item in self.items])
        self.assign()
        self.reference_code = self.get_uid()
        self.search_helper = self.get_search_helper()
        if not self.id:
            self.published = True
        super(Cart, self).save(*args, **kwargs)
        self.set_reference_statuses(self.status)

    def get_search_helper(self):
        if not self.belongs_to:
            return ""
        user = self.belongs_to
        return " ".join([user.name or "", user.email or ""])

    def get_item(self, uid):
        # MongoEngine/mongoengine#503
        return self.items.get(uid=uid)

    def set_item(self, **kwargs):
        if 'product' in kwargs:
            if not isinstance(kwargs['product'], Content):
                try:
                    kwargs['product'] = Content.objects.get(
                        id=kwargs['product'])
                except Content.DoesNotExist:
                    kwargs['product'] = None

        uid = kwargs.get(
            'uid',
            kwargs['product'].get_uid() if kwargs.get('product') else None)

        if not uid:
            self.addlog("Cannot add item without an uid %s" % kwargs)
            return

        item = self.get_item(uid)

        kwargs = Item.normalize(kwargs)

        if not item:
            # items should only be added if there is a product (for safety)
            if not kwargs.get('product'):
                self.addlog("there is no product to add item")
                return
            allowed = ['product', 'quantity']
            item = self.items.create(
                **{k: v
                   for k, v in kwargs.items() if k in allowed})
            self.addlog("New item created %s" % item, save=False)
        else:
            # update only allowed attributes
            item = self.items.update(
                {k: v
                 for k, v in kwargs.items() if k in item.allowed_to_set},
                uid=item.uid)
            self.addlog("Item updated %s" % item, save=False)

            if int(kwargs.get('quantity', "1")) == 0:
                self.addlog("quantity is 0, removed %s" % kwargs, save=False)
                self.remove_item(**kwargs)

        self.save()
        self.reload()
        return item

    def remove_item(self, **kwargs):
        deleted = self.items.delete(**kwargs)
        if self.reference and hasattr(self.reference, 'remove_item'):
            self.reference.remove_item(**kwargs)
        return deleted

    def checkout(self, processor=None, *args, **kwargs):
        self.set_processor(processor)
        processor_instance = self.processor.get_instance(self, *args, **kwargs)
        if processor_instance.validate():
            response = processor_instance.process()
            self.status = 'checked_out'
            self.save()
            session.pop('cart_id', None)
            return response
        else:
            self.addlog("Cart did not validate")
            raise Exception("Cart did not validate")  # todo: specialize this

    def get_items_pipeline(self):
        if not self.items:
            return []

        return reduce(lambda x, y: x + y,
                      [item.pipeline for item in self.items])

    def build_pipeline(self):
        items = ['quokka.modules.cart.pipelines:StartPipeline']
        items.extend(current_app.config.get('CART_PIPELINE', []))
        items.extend(self.get_items_pipeline())
        items.extend(self.pipeline)
        items.extend(self.processor and self.processor.pipeline or [])
        return items

    def process_pipeline(self):
        if not self.items:
            return render_template('cart/empty_cart.html',
                                   url=self.continue_shopping_url)

        pipelines = self.build_pipeline()
        index = session.get('cart_pipeline_index', 0)
        pipeline = import_string(pipelines[index])
        return pipeline(self, pipelines, index)._preprocess()

    def set_processor(self, processor=None):
        if not self.processor:
            self.processor = Processor.get_default_processor()
            self.save()

        if not processor:
            return

        if isinstance(processor, Processor):
            self.processor = processor
            self.save()
            return

        try:
            self.processor = Processor.objects.get(id=processor)
        except:
            self.processor = Processor.objects.get(identifier=processor)

        self.save()

    def get_available_processors(self):
        return Processor.objects(published=True)
Esempio n. 10
0
class User(db.DynamicDocument, UserMixin):
    name = db.StringField(max_length=255, verbose_name=_l('Name'))
    email = db.EmailField(max_length=255,
                          unique=True,
                          verbose_name=_l('Email'))
    password = db.StringField(max_length=255, verbose_name=_l('Password'))
    active = db.BooleanField(default=True, verbose_name=_l('Active'))
    confirmed_at = db.DateTimeField(verbose_name=_l('Confirmed At'))
    roles = db.ListField(db.ReferenceField(Role, reverse_delete_rule=db.DENY),
                         default=[],
                         verbose_name=_l('Roles'))

    last_login_at = db.DateTimeField(verbose_name=_l('Last Login At'))
    current_login_at = db.DateTimeField(verbose_name=_l('Current Login At'))
    last_login_ip = db.StringField(max_length=255,
                                   verbose_name=_l('Last Login IP'))
    current_login_ip = db.StringField(max_length=255,
                                      verbose_name=_l('Current Login IP'))
    login_count = db.IntField(verbose_name=_l('Login Count'))

    username = db.StringField(max_length=50,
                              required=False,
                              unique=True,
                              verbose_name=_l('Username'))

    remember_token = db.StringField(max_length=255,
                                    verbose_name=_l('Remember Token'))
    authentication_token = db.StringField(
        max_length=255, verbose_name=_l('Authentication Tokern'))

    def clean(self, *args, **kwargs):
        if not self.username:
            self.username = User.generate_username(self.email)

        try:
            super(User, self).clean(*args, **kwargs)
        except:
            pass

    @classmethod
    def generate_username(cls, email):
        username = email.lower()
        for item in ['@', '.', '-', '+']:
            username = username.replace(item, '_')
        return username

    def set_password(self, password, save=False):
        self.password = encrypt_password(password)
        if save:
            self.save()

    @classmethod
    def createuser(cls,
                   name,
                   email,
                   password,
                   active=True,
                   roles=None,
                   username=None):

        username = username or cls.generate_username(email)
        return cls.objects.create(name=name,
                                  email=email,
                                  password=encrypt_password(password),
                                  active=active,
                                  roles=roles,
                                  username=username)

    @property
    def display_name(self):
        return self.name or self.email

    def __unicode__(self):
        return u"{0} <{1}>".format(self.name or '', self.email)

    @property
    def connections(self):
        return Connection.objects(user_id=str(self.id))
Esempio n. 11
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)

    image_file = db.ImageField()

    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 identifier in ['mainimage', 'dbimage', 'postimage'
                          ] and self.image_file is not None:
            image_file = self.image_file if not hasattr(
                self.image_file, 'image') else getattr(self.image_file,
                                                       'image')
            #args = helpers.make_thumb_args(image_fil
            return getattr(
                self.image_file, 'main_image_path',
                '')  #get_url('{}.api_file_view'.format(identifier), **args)
        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('quokka.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='quokka.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('quokka.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))