예제 #1
0
파일: models.py 프로젝트: rockyburt/Rezine
class Category(object):
    """Represents a category."""

    query = db.query_property(CategoryQuery)

    def __init__(self, name, description='', slug=None):
        self.name = name
        if slug is None:
            self.set_auto_slug()
        else:
            self.slug = slug
        self.description = description

    def set_auto_slug(self):
        """Generate a slug for this category."""
        full_slug = gen_slug(self.name)
        if not full_slug:
            # if slug generation failed we select the highest category
            # id as base for slug generation.
            category = Category.query.autoflush(False) \
                               .order_by(Category.id.desc()).first()
            full_slug = unicode(category and category.id or u'1')
        if full_slug != self.slug:
            while Category.query.autoflush(False) \
                          .filter_by(slug=full_slug).limit(1).count():
                full_slug = increment_string(full_slug)
            self.slug = full_slug

    def get_url_values(self):
        return 'blog/show_category', {'slug': self.slug}

    def __repr__(self):
        return '<%s %r>' % (self.__class__.__name__, self.name)
예제 #2
0
파일: models.py 프로젝트: rockyburt/Rezine
class SummarizedPost(_PostBase):
    """Like a regular post but without text and parser data."""

    query = db.query_property(SummarizedPostQuery)

    def __init__(self):
        raise TypeError('You cannot create %r instance' % type(self).__name__)
예제 #3
0
파일: models.py 프로젝트: rockyburt/Rezine
class Post(_PostBase, _ZEMLDualContainer):
    """A full blown post."""

    query = db.query_property(PostQuery)
    parser_reason = 'post'

    def __init__(self,
                 title,
                 author,
                 text,
                 slug=None,
                 pub_date=None,
                 last_update=None,
                 comments_enabled=True,
                 pings_enabled=True,
                 status=STATUS_PUBLISHED,
                 parser=None,
                 uid=None,
                 content_type='entry',
                 extra=None):
        app = get_application()
        self.content_type = content_type
        self.title = title
        self.author = author
        if parser is None:
            parser = app.cfg['default_parser']

        self.parser = parser
        self.text = text or u''
        if extra:
            self.extra = dict(extra)
        else:
            self.extra = {}

        self.comments_enabled = comments_enabled
        self.pings_enabled = pings_enabled
        self.status = status

        # set times now, they depend on status being set
        self.touch_times(pub_date)
        if last_update is not None:
            self.last_update = last_update

        # now bind the slug for which we need the times set.
        self.bind_slug(slug)

        # generate a UID if none is given
        if uid is None:
            uid = build_tag_uri(app, self.pub_date, content_type, self.slug)
        self.uid = uid

    @property
    def comments_closed(self):
        """True if commenting is no longer possible."""
        app = get_application()
        open_for = app.cfg['comments_open_for']
        if open_for == 0:
            return False
        return self.pub_date + timedelta(days=open_for) < datetime.utcnow()
예제 #4
0
파일: models.py 프로젝트: rockyburt/Rezine
class SchemaVersion(object):
    """Represents a database schema version."""

    query = db.query_property(db.Query)

    def __init__(self, repos, version=0):
        self.repository_id = repos.config.get('repository_id')
        self.repository_path = repos.path
        self.version = version
예제 #5
0
파일: models.py 프로젝트: rockyburt/Rezine
class Tag(object):
    """A single tag."""
    query = db.query_property(TagQuery)

    def __init__(self, name, slug=None):
        self.name = name
        if slug is None:
            self.set_auto_slug()
        else:
            self.slug = slug

    @staticmethod
    def get_or_create(name):
        tag = Tag.query.filter_by(name=name).first()
        if tag is not None:
            return tag
        return Tag(name)

    def set_auto_slug(self):
        full_slug = gen_slug(self.name)
        if not full_slug:
            # if slug generation failed we select the highest category
            # id as base for slug generation.
            tag = Tag.query.autoflush(False).order_by(Tag.id.desc()).first()
            full_slug = unicode(tag and tag.id or u'1')
        if full_slug != self.slug:
            while Tag.query.autoflush(False) \
                          .filter_by(slug=full_slug).limit(1).count():
                full_slug = increment_string(full_slug)
            self.slug = full_slug

    def get_url_values(self):
        return 'blog/show_tag', {'slug': self.slug}

    def __repr__(self):
        return u'<%s %r>' % (self.__class__.__name__, self.name)
예제 #6
0
파일: models.py 프로젝트: rockyburt/Rezine
class Comment(_ZEMLContainer):
    """Represent one comment."""

    query = db.query_property(CommentQuery)
    parser_reason = 'comment'

    def __init__(self,
                 post,
                 author,
                 text,
                 email=None,
                 www=None,
                 parent=None,
                 pub_date=None,
                 submitter_ip='0.0.0.0',
                 parser=None,
                 is_pingback=False,
                 status=COMMENT_MODERATED):
        self.post = post
        if isinstance(author, basestring):
            self.user = None
            self._author = author
            self._email = email
            self._www = www
        else:
            assert email is www is None, \
                'email and www can only be provided if the author is ' \
                'an anonymous user'
            self.user = author

        if parser is None:
            parser = get_application().cfg['comment_parser']
        self.parser = parser
        self.text = text or ''
        self.parent = parent
        if pub_date is None:
            pub_date = datetime.utcnow()
        self.pub_date = pub_date
        self.blocked_msg = None
        self.submitter_ip = submitter_ip
        self.is_pingback = is_pingback
        self.status = status

    def _union_property(attribute, user_attribute=None):
        """An attribute that can exist on a user and the comment."""
        user_attribute = user_attribute or attribute
        attribute = '_' + attribute

        def get(self):
            if self.user:
                return getattr(self.user, user_attribute)
            return getattr(self, attribute)

        def set(self, value):
            if self.user:
                raise TypeError('can\'t set this attribute if the comment '
                                'does not belong to an anonymous user')
            setattr(self, attribute, value)

        return property(get, set)

    email = _union_property('email')
    www = _union_property('www')
    author = _union_property('author', 'display_name')
    del _union_property

    def unbind_user(self):
        """If a user is deleted, the cascading rules would also delete all
        the comments created by this user, or cause a transaction error
        because the relation is set to restrict, depending on the current
        phase of the moon (this changed a lot in the past, i expect it to
        continue to change).

        This method unsets the user and updates the comment builtin columns
        to the values from the user object.
        """
        assert self.user is not None
        self._email = self.user.email
        self._www = self.user.www
        self._author = self.user.display_name
        self.user = None

    def _get_status(self):
        return self._status

    def _set_status(self, value):
        was_blocked = self.blocked
        self._status = value
        now_blocked = self.blocked

        # update the comment count on the post if the moderation flag
        # changed from blocked to unblocked or vice versa
        if was_blocked != now_blocked:
            self.post._comment_count = (self.post._comment_count or 0) + \
                                       (now_blocked and -1 or +1)

    status = property(_get_status, _set_status)
    del _get_status, _set_status

    @property
    def anonymous(self):
        """True if this comment is an anonymous comment."""
        return self.user is None

    @property
    def requires_moderation(self):
        """This is `True` if the comment requires moderation with the
        current moderation settings.  This does not check if the comment
        is already moderated.
        """
        if not self.anonymous:
            return False
        moderate = get_application().cfg['moderate_comments']
        if moderate == MODERATE_ALL:
            return True
        elif moderate == MODERATE_NONE:
            return False
        return db.execute(
            comments.select(
                (comments.c.author == self._author)
                & (comments.c.email == self._email)
                & (comments.c.status == COMMENT_MODERATED))).fetchone() is None

    def make_visible_for_request(self, request=None):
        """Make the comment visible for the current request."""
        if request is None:
            request = get_request()
        comments = set(request.session.get('visible_comments', ()))
        comments.add(self.id)
        request.session['visible_comments'] = tuple(comments)

    def visible_for_user(self, user=None):
        """Check if the current user or the user given can see this comment"""
        request = get_request()
        if user is None:
            user = request.user
        if self.post.author is user and \
           user.has_privilege(MODERATE_OWN_ENTRIES | MODERATE_OWN_PAGES):
            return True
        elif user.has_privilege(MODERATE_COMMENTS):
            # User is able to manage comments. It's visible.
            return True
        elif self.id in request.session.get('visible_comments', ()):
            # Comment was made visible for current request. It's visible
            return True
        # Finally, comment is visible if not blocked
        return not self.blocked

    @property
    def visible(self):
        """Check the current session it can see the comment or check against the
        current user.  To display a comment for a request you can use the
        `make_visible_for_request` function.  This is useful to show a comment
        to a user that submitted a comment which is not yet moderated.
        """
        request = get_request()
        if request is None:
            return True
        return self.visible_for_user(request.user)

    @property
    def visible_children(self):
        """Only the children that are visible for the current user."""
        return [x for x in self.children if x.visible]

    @property
    def blocked(self):
        """This is true if the status is anything but moderated."""
        return self.status != COMMENT_MODERATED

    @property
    def is_spam(self):
        """This is true if the comment is currently flagged as spam."""
        return self.status == COMMENT_BLOCKED_SPAM

    @property
    def is_unmoderated(self):
        """True if the comment is not yet approved."""
        return self.status == COMMENT_UNMODERATED

    @property
    def is_deleted(self):
        """True if the comment has been deleted."""
        return self.status == COMMENT_DELETED

    def get_url_values(self):
        return url_for(self.post) + '#comment-%d' % self.id

    def summarize(self, chars=140, ellipsis=u'…'):
        """Summarizes the comment to the given number of characters."""
        words = self.body.to_text(simple=True).split()
        words.reverse()
        length = 0
        result = []
        while words:
            word = words.pop()
            length += len(word) + 1
            if length >= chars:
                break
            result.append(word)
        if words:
            result.append(ellipsis)
        return u' '.join(result)

    def __repr__(self):
        return '<%s %r>' % (self.__class__.__name__, self.author)
예제 #7
0
파일: models.py 프로젝트: rockyburt/Rezine
class User(object):
    """Represents an user.

    If you change something on this model, even default values, keep in mind
    that the websetup does not use this model to create the admin account
    because at that time the Rezine system is not yet ready. Also update
    the code in `rezine.websetup.WebSetup.start_setup`.
    """

    query = db.query_property(UserQuery)
    is_somebody = True

    def __init__(self,
                 username,
                 password,
                 email,
                 real_name=u'',
                 description=u'',
                 www=u'',
                 is_author=False):
        self.username = username
        if password is not None:
            self.set_password(password)
        else:
            self.disable()
        self.email = email
        self.www = www
        self.real_name = real_name
        self.description = description
        self.extra = {}
        self.display_name = u'$username'
        self.is_author = is_author

    @property
    def is_manager(self):
        return self.has_privilege(ENTER_ADMIN_PANEL)

    @property
    def is_admin(self):
        return self.has_privilege(BLOG_ADMIN)

    def _set_display_name(self, value):
        self._display_name = value

    def _get_display_name(self):
        from string import Template
        return Template(self._display_name).safe_substitute(
            username=self.username, real_name=self.real_name)

    display_name = property(_get_display_name, _set_display_name)
    own_privileges = privilege_attribute('_own_privileges')

    @property
    def privileges(self):
        """A read-only set with all privileges."""
        result = set(self.own_privileges)
        for group in self.groups:
            result.update(group.privileges)
        return frozenset(result)

    def has_privilege(self, privilege):
        """Check if the user has a given privilege.  If the user has the
        BLOG_ADMIN privilege he automatically has all the other privileges
        as well.
        """
        return add_admin_privilege(privilege)(self.privileges)

    def set_password(self, password):
        self.pw_hash = gen_pwhash(password)

    def check_password(self, password):
        if self.pw_hash == '!':
            return False
        return check_pwhash(self.pw_hash, password)

    def disable(self):
        self.pw_hash = '!'

    @property
    def disabled(self):
        return self.pw_hash == '!'

    def get_url_values(self):
        if self.is_author:
            return 'blog/show_author', {'username': self.username}
        return self.www or '#'

    def __repr__(self):
        return '<%s %r>' % (self.__class__.__name__, self.username)