示例#1
0
    def change_comment(self, request, id, action):
        comment = Comment.query.get(id)
        if action in ('hide', 'restore'):
            message = {
                'hide': _(u'Do you really want to hide the comment?'),
                'restore': _(u'Do you really want to restore the comment?')
            }
            if confirm_action(request,
                              message[action],
                              'news/edit_comment',
                              id=id,
                              action=action):
                comment.deleted = action == 'hide'
                db.session.commit()
                request.flash(_(u'The comment has been hidden') if \
                    action == 'hide' else _(u'The comment has been restored'))
                return redirect_to(comment)
            return redirect_to(comment.article)

        # action == 'edit'
        form = EditCommentForm(request.form)
        if form.validate_on_submit():
            if form.validate():
                comment.text = form.text.data
                db.session.commit()
                request.flash(_(u'The comment was saved'), True)
                return redirect_to(comment)
        else:
            form.text.data = comment.text
        return {
            'comment': comment,
            'form': form,
        }
示例#2
0
    def detail(self, request, slug):
        article = Article.query.filter_by(slug=slug).one()
        if article.hidden:
            #TODO: ACL Check
            request.flash(_(u'This article is hidden'), False)

        if article.comments_enabled:
            form = EditCommentForm(request.form)
            if form.validate_on_submit():
                if form.data.get('comment_id', None):
                    comment = Comment.query.get(form.comment_id.data)
                    comment.text = form.text.data
                    request.flash(_(u'The comment was successfully edited'),
                                  True)
                else:
                    comment = Comment(text=form.text.data, author=request.user)
                    article.comments.append(comment)
                    Subscription.new(comment, 'news.comment.new')
                    request.flash(_(u'Your comment was successfully created'),
                                  True)
                db.session.commit()
                return redirect_to(comment)
        else:
            form = EditCommentForm()

        # increase counters
        article.touch()

        comments = list(article.comments.options(db.joinedload('author')))
        Subscription.accessed(request.user, object=article, subject=article)

        return {'article': article, 'comments': comments, 'form': form}
示例#3
0
    def detail(self, request, slug):
        article = Article.query.filter_by(slug=slug).one()
        if article.hidden:
            # TODO: ACL Check
            request.flash(_(u"This article is hidden"), False)

        if article.comments_enabled:
            form = EditCommentForm(request.form)
            if form.validate_on_submit():
                if form.data.get("comment_id", None):
                    comment = Comment.query.get(form.comment_id.data)
                    comment.text = form.text.data
                    request.flash(_(u"The comment was successfully edited"), True)
                else:
                    comment = Comment(text=form.text.data, author=request.user)
                    article.comments.append(comment)
                    Subscription.new(comment, "news.comment.new")
                    request.flash(_(u"Your comment was successfully created"), True)
                db.session.commit()
                return redirect_to(comment)
        else:
            form = EditCommentForm()

        # increase counters
        article.touch()

        comments = list(article.comments.options(db.joinedload("author")))
        Subscription.accessed(request.user, object=article, subject=article)

        return {"article": article, "comments": comments, "form": form}
示例#4
0
    def change_comment(self, request, id, action):
        comment = Comment.query.get(id)
        if action in ("hide", "restore"):
            message = {
                "hide": _(u"Do you really want to hide the comment?"),
                "restore": _(u"Do you really want to restore the comment?"),
            }
            if confirm_action(request, message[action], "news/edit_comment", id=id, action=action):
                comment.deleted = action == "hide"
                db.session.commit()
                request.flash(
                    _(u"The comment has been hidden") if action == "hide" else _(u"The comment has been restored")
                )
                return redirect_to(comment)
            return redirect_to(comment.article)

        # action == 'edit'
        form = EditCommentForm(request.form)
        if form.validate_on_submit():
            if form.validate():
                comment.text = form.text.data
                db.session.commit()
                request.flash(_(u"The comment was saved"), True)
                return redirect_to(comment)
        else:
            form.text.data = comment.text
        return {"comment": comment, "form": form}
示例#5
0
 def tags_delete(self, request, slug):
     message = _(u'Do you really want to delete this tag?')
     tag = Tag.query.filter_by(slug=slug).one()
     if confirm_action(request, message, 'portal/tag_delete', slug=slug):
         db.session.delete(tag)
         db.session.commit()
         request.flash(_(u'The tag “%s” was deleted successfully.' %
                         tag.name))
         return redirect_to('portal/tags')
     return redirect_to(tag)
示例#6
0
def parse(markup, catch_stack_errors=True, transformers=None):
    """Parse markup into a node."""
    try:
        return Parser(markup, transformers).parse()
    except StackExhaused:
        if not catch_stack_errors:
            raise
        return nodes.Paragraph([
            nodes.Strong([nodes.Text(_(u'Internal parser error: '))]),
            nodes.Text(_(u'The parser could not process the text because '
                         u'it exceeded the maximum allowed depth for nested '
                         u'elements'))
        ])
示例#7
0
def parse(markup, catch_stack_errors=True, transformers=None):
    """Parse markup into a node."""
    try:
        return Parser(markup, transformers).parse()
    except StackExhaused:
        if not catch_stack_errors:
            raise
        return nodes.Paragraph([
            nodes.Strong([nodes.Text(_(u'Internal parser error: '))]),
            nodes.Text(
                _(u'The parser could not process the text because '
                  u'it exceeded the maximum allowed depth for nested '
                  u'elements'))
        ])
示例#8
0
 def articles_delete(self, request, slug):
     article = Article.query.filter_by(slug=slug).one()
     if 'cancel' in request.form:
         request.flash(_(u'Action canceled'))
     elif request.method in ('POST', 'PUT') and 'confirm' in request.form:
         db.session.delete(article)
         db.session.commit()
         request.flash(_(u'The article “%s” was deleted successfully.'
                       % article.title))
         return redirect_to('news/articles')
     else:
         request.flash(render_template('news/admin/article_delete.html', {
             'article': article
         }), html=True)
     return redirect_to(article, action='edit')
示例#9
0
def get_serializer(request_or_format):
    """Returns the serializer for the given API request."""
    def _search_for_accepted(req):
        best_match = (None, 0)
        for mimetype, serializer in _serializer_for_mimetypes.iteritems():
            quality = req.accept_mimetypes[mimetype]
            if quality > best_match[1]:
                best_match = (serializer, quality)

        if best_match[0] is None:
            raise BadRequest(_(u'Could not detect format.  You have to specify '
                               u'the format as query argument or in the accept '
                               u'HTTP header.'))

        # special case.  If the best match is not html and the quality of
        # text/html is the same as the best match, we prefer HTML.
        if best_match[0] != 'text/html' and \
           best_match[1] == req.accept_mimetypes['text/html']:
            return _serializer_map['debug']
        return _serializer_map[best_match[0]]

    if not isinstance(request_or_format, basestring):
        # we got no string so we assume that we got a proper
        # request object and search for the format.
        format = request_or_format.args.get('format')
        if format is not None:
            rv = _serializer_map.get(format)
            if rv is None:
                raise BadRequest(_(u'Unknown format "%s"') % escape(format))
            return rv
        return _search_for_accepted(request_or_format)

    # we got a string so we assume we got a proper format applied.
    return _serializer_map[request_or_format]
示例#10
0
def get_serializer(request_or_format):
    """Returns the serializer for the given API request."""
    def _search_for_accepted(req):
        best_match = (None, 0)
        for mimetype, serializer in _serializer_for_mimetypes.iteritems():
            quality = req.accept_mimetypes[mimetype]
            if quality > best_match[1]:
                best_match = (serializer, quality)

        if best_match[0] is None:
            raise BadRequest(
                _(u'Could not detect format.  You have to specify '
                  u'the format as query argument or in the accept '
                  u'HTTP header.'))

        # special case.  If the best match is not html and the quality of
        # text/html is the same as the best match, we prefer HTML.
        if best_match[0] != 'text/html' and \
           best_match[1] == req.accept_mimetypes['text/html']:
            return _serializer_map['debug']
        return _serializer_map[best_match[0]]

    if not isinstance(request_or_format, basestring):
        # we got no string so we assume that we got a proper
        # request object and search for the format.
        format = request_or_format.args.get('format')
        if format is not None:
            rv = _serializer_map.get(format)
            if rv is None:
                raise BadRequest(_(u'Unknown format "%s"') % escape(format))
            return rv
        return _search_for_accepted(request_or_format)

    # we got a string so we assume we got a proper format applied.
    return _serializer_map[request_or_format]
示例#11
0
    def subscribe_comments(self, request, action, slug):
        do = {"subscribe": Subscription.subscribe, "unsubscribe": Subscription.unsubscribe}[action]
        article = Article.query.filter_by(slug=slug).one()
        existed = do(request.user, CommentSubscriptionType, article)

        msg = {
            "subscribe": [
                _(u"You had already been subscribed before."),
                _(u"You have successfully been subscribed to " u"new comments on this article."),
            ],
            "unsubscribe": [
                _(u"You had not been subscribed before."),
                _(u"You have successfully been unsubscribed from " u"new comments on this article."),
            ],
        }
        request.flash(msg[action][existed], True if not existed else None)
        return redirect_to(article)
示例#12
0
    def subscribe_articles(self, request, action):
        do = {"subscribe": Subscription.subscribe, "unsubscribe": Subscription.unsubscribe}[action]
        existed = do(request.user, ArticleSubscriptionType)

        msg = {
            "subscribe": [
                _(u"You had already been subscribed before."),
                _(u"You have successfully been subscribed to " u"new News articles."),
            ],
            "unsubscribe": [
                _(u"You had not been subscribed before."),
                _(u"You have successfully been unsubscribed from " u"new News articles."),
            ],
        }
        request.flash(msg[action][existed], True if not existed else None)

        return redirect_to("news/index")
示例#13
0
def _get_pygments_lexers(add_empty=True):
    r = []
    if add_empty:
        r.append((u'', u''), )
    for lexer in get_all_lexers():
        r.append((lexer[1][0], _(lexer[0])), )
    r.sort(key=itemgetter(1))
    return r
示例#14
0
def _get_pygments_lexers(add_empty=True):
    r = []
    if add_empty:
        r.append((u'', u''),)
    for lexer in get_all_lexers():
        r.append((lexer[1][0], _(lexer[0])),)
    r.sort(key=itemgetter(1))
    return r
示例#15
0
def send_activation_mail(user_id, activation_url):
    user = User.query.get(user_id)
    website_title = ctx.cfg['website_title']
    send_email(_(u'Registration at %s') % website_title, render_template('mails/registration', {
        'user':             user,
        'activation_url':   activation_url,
        'website_title':    website_title,
    }), ctx.cfg['mail_address'], user.email)
示例#16
0
def send_activation_mail(user_id, activation_url):
    user = User.query.get(user_id)
    website_title = ctx.cfg['website_title']
    send_email(
        _(u'Registration at %s') % website_title,
        render_template(
            'mails/registration', {
                'user': user,
                'activation_url': activation_url,
                'website_title': website_title,
            }), ctx.cfg['mail_address'], user.email)
示例#17
0
    def subscribe_comments(self, request, action, slug):
        do = {
            'subscribe': Subscription.subscribe,
            'unsubscribe': Subscription.unsubscribe,
        }[action]
        article = Article.query.filter_by(slug=slug).one()
        existed = do(request.user, CommentSubscriptionType, article)

        msg = {
            'subscribe': [
                _(u'You had already been subscribed before.'),
                _(u'You have successfully been subscribed to '
                  u'new comments on this article.')
            ],
            'unsubscribe': [
                _(u'You had not been subscribed before.'),
                _(u'You have successfully been unsubscribed from '
                  u'new comments on this article.')
            ],
        }
        request.flash(msg[action][existed], True if not existed else None)
        return redirect_to(article)
示例#18
0
    def subscribe_articles(self, request, action):
        do = {
            'subscribe': Subscription.subscribe,
            'unsubscribe': Subscription.unsubscribe,
        }[action]
        existed = do(request.user, ArticleSubscriptionType)

        msg = {
            'subscribe': [
                _(u'You had already been subscribed before.'),
                _(u'You have successfully been subscribed to '
                  u'new News articles.')
            ],
            'unsubscribe': [
                _(u'You had not been subscribed before.'),
                _(u'You have successfully been unsubscribed from '
                  u'new News articles.')
            ],
        }
        request.flash(msg[action][existed], True if not existed else None)

        return redirect_to('news/index')
示例#19
0
    def article_feed(self, request, slug=None):
        """
        Shows all news entries that match the given criteria in an atom feed.
        """
        query = Article.query
        title = u"News"

        if slug:
            # filter the articles matching a defined tag
            tag = Tag.query.public().filter_by(slug=slug).one()
            query = tag.articles
            title = _(u"News for %s" % slug)

        query = query.options(db.eagerload("author")).order_by(Article.updated.desc()).limit(20)

        feed = AtomFeed(
            _(u"%s – %s" % (title, ctx.cfg["website_title"])),
            feed_url=request.url,
            url=request.url_root,
            icon=href("static", file="img/favicon.ico"),
        )

        for article in query.all():
            value = u"%s\n%s" % (
                article.get_rendered_text(article.intro, request, "html"),
                article.get_rendered_text(article.text, request, "html"),
            )
            feed.add(
                article.title,
                value,
                content_type="html",
                url=href(article, _external=True),
                author={"name": article.author.display_name, "uri": href(article.author.profile)},
                id=article.guid,
                updated=article.updated,
                published=article.pub_date,
            )

        return feed
示例#20
0
    def article_feed(self, request, slug=None):
        """
        Shows all news entries that match the given criteria in an atom feed.
        """
        query = Article.query
        title = u'News'

        if slug:
            # filter the articles matching a defined tag
            tag = Tag.query.public().filter_by(slug=slug).one()
            query = tag.articles
            title = _(u'News for %s' % slug)

        query = query.options(db.eagerload('author')) \
                     .order_by(Article.updated.desc()).limit(20)

        feed = AtomFeed(_(u'%s – %s' % (title, ctx.cfg['website_title'])),
                        feed_url=request.url,
                        url=request.url_root,
                        icon=href('static', file='img/favicon.ico'))

        for article in query.all():
            value = u'%s\n%s' % (
                article.get_rendered_text(article.intro, request, 'html'),
                article.get_rendered_text(article.text, request, 'html'))
            feed.add(article.title,
                     value,
                     content_type='html',
                     url=href(article, _external=True),
                     author={
                         'name': article.author.display_name,
                         'uri': href(article.author.profile)
                     },
                     id=article.guid,
                     updated=article.updated,
                     published=article.pub_date)

        return feed
示例#21
0
class AddEventForm(Form):
    title = TextField(_(u'Title'),
                      [validators.length(max=100),
                       validators.required()])
    text = TextField(_(u'Text'), [validators.required()],
                     widget=widgets.TextArea())
    start = DateTimeField(_(u'Start'), [validators.required()])
    end = DateTimeField(_(u'End'), [validators.required()])
    tags = AutocompleteField(_(u'Tags'),
                             get_label='name',
                             query_factory=lambda: Tag.query.autoflush(False))
    discussion_question = BooleanField(_(u'Create topic for discussion'))
    info_question = BooleanField(_(u'Create topic for further information'))
示例#22
0
    def get_sorted(self):
        """Return a query object with the proper ordering applied."""
        ocol = escape(self.order_by.lstrip('-'))
        if ocol not in self.columns.keys():
            # safes us from some bad usage that raises an exception
            ctx.current_request.flash(
                _(u'The selected criterium “%s” is not available, '
                  u'falling back to default ordering') % ocol, html=True)
            self.order_by = self.default_col
            ocol = self.order_by.lstrip('-')

        if self.order_by is None:
            return self.query
        order = (db.asc, db.desc)[self.order_by.startswith('-')]
        return self.query.order_by(order(self.columns[ocol]))
示例#23
0
    def tags_edit(self, request, slug=None):
        new = slug is None
        if new:
            tag, data = Tag(), {}
        else:
            tag = Tag.query.filter_by(slug=slug).one()
            data = model_to_dict(tag, exclude=('slug'))

        form = EditTagForm(request.form, **data)

        if 'delete' in request.form:
            return redirect_to('portal/tag_delete', slug=tag.slug)
        elif form.validate_on_submit():
            tag = update_model(tag, form, ('name'))
            db.session.commit()
            if new:
                request.flash(_(u'Created tag “%s”' % tag.name), True)
            else:
                request.flash(_(u'Updated tag “%s”' % tag.name), True)

        return {
            'form': form,
            'tag': tag,
        }
示例#24
0
    def articles_edit(self, request, slug=None):
        new = slug is None
        if new:
            article, data = Article(), {'tags': []}
        else:
            article = Article.query.filter_by(slug=slug).one()
            data = model_to_dict(article, exclude=('slug'))

        form = EditArticleForm(request.form, **data)
        if 'delete' in request.form:
            return redirect_to('news/article_delete', slug=article.slug)
        elif form.validate_on_submit():
            article = update_model(article, form, ('pub_date', 'updated',
                'title', 'intro', 'text', 'public', 'tags',
                'author'))
            db.session.commit()
            msg = slug and _(u'Updated article “%s”') \
                       or _(u'Created article “%s”')
            request.flash(msg % article.title, True)
            return redirect_to(article)
        return {
            'form': form,
            'article': article,
        }
示例#25
0
class EditArticleForm(Form):
    title = TextField(_(u'Title'), [validators.required(), validators.length(max=200)])
    intro = TextField(_(u'Intro'), [validators.required()], widget=widgets.TextArea())
    text = TextField(_(u'Text'), [validators.required()], widget=widgets.TextArea())
    public = BooleanField(_(u'Published'))
    tags = AutocompleteField(_(u'Tags'), get_label='name',
                             query_factory=lambda: Tag.query.autoflush(False))
    author = QuerySelectField(_(u'Author'), [validators.required()],
                             query_factory=lambda: User.query.autoflush(False),
                             widget=widgets.Select())
示例#26
0
    def get_sorted(self):
        """Return a query object with the proper ordering applied."""
        ocol = escape(self.order_by.lstrip('-'))
        if ocol not in self.columns.keys():
            # safes us from some bad usage that raises an exception
            ctx.current_request.flash(
                _(u'The selected criterium “%s” is not available, '
                  u'falling back to default ordering') % ocol,
                html=True)
            self.order_by = self.default_col
            ocol = self.order_by.lstrip('-')

        if self.order_by is None:
            return self.query
        order = (db.asc, db.desc)[self.order_by.startswith('-')]
        return self.query.order_by(order(self.columns[ocol]))
示例#27
0
def timedeltaformat(datetime_or_timedelta, threshold=.85, granularity='second'):
    """Special locale aware timedelta format function

    Usage Example::

        >>> timedeltaformat(timedelta(weeks=12))
        u'three mths ago'
        >>> timedeltaformat(timedelta(seconds=30))
        u'30 secs ago'
        >>> timedeltaformat(timedelta(seconds=0))
        u'just now'

        The granularity parameter can be provided to alter the lowest unit
        presented, which defaults to a second.

        >>> timedeltaformat(timedelta(hours=3), granularity='day')
        u'one day ago'

        The threshold parameter can be used to determine at which value the
        presentation switches to the next higher unit. A higher threshold factor
        means the presentation will switch later. For example:

        >>> timedeltaformat(timedelta(hours=23), threshold=0.9)
        u'one day ago'
        >>> timedeltaformat(timedelta(hours=23), threshold=1.1)
        u'23 hrs ago'

    :param datetime_or_timedelta: Either a datetime or timedelta object.
                                  If it's a datetime object we caclculate the
                                  timedelta from this object to now (using UTC)
    :param threshold: factor that determines at which point the presentation
                      switches to the next higher unit
    :param granularity: determines the smallest unit that should be displayed,
                        the value can be one of "year", "month", "week", "day",
                        "hour", "minute" or "second"

    """
    if isinstance(datetime_or_timedelta, datetime):
        datetime_or_timedelta = datetime.utcnow() - datetime_or_timedelta

    if datetime_or_timedelta <= timedelta(seconds=3):
        return _(u'just now')

    timedelta_ = _format_timedelta(datetime_or_timedelta, granularity,
                                  threshold=threshold)
    return lazy_gettext(u'%(timedelta)s ago') % {'timedelta': timedelta_}
示例#28
0
def timedeltaformat(datetime_or_timedelta, threshold=0.85, granularity="second"):
    """Special locale aware timedelta format function

    Usage Example::

        >>> timedeltaformat(timedelta(weeks=12))
        u'three mths ago'
        >>> timedeltaformat(timedelta(seconds=30))
        u'30 secs ago'
        >>> timedeltaformat(timedelta(seconds=0))
        u'just now'

        The granularity parameter can be provided to alter the lowest unit
        presented, which defaults to a second.

        >>> timedeltaformat(timedelta(hours=3), granularity='day')
        u'one day ago'

        The threshold parameter can be used to determine at which value the
        presentation switches to the next higher unit. A higher threshold factor
        means the presentation will switch later. For example:

        >>> timedeltaformat(timedelta(hours=23), threshold=0.9)
        u'one day ago'
        >>> timedeltaformat(timedelta(hours=23), threshold=1.1)
        u'23 hrs ago'

    :param datetime_or_timedelta: Either a datetime or timedelta object.
                                  If it's a datetime object we caclculate the
                                  timedelta from this object to now (using UTC)
    :param threshold: factor that determines at which point the presentation
                      switches to the next higher unit
    :param granularity: determines the smallest unit that should be displayed,
                        the value can be one of "year", "month", "week", "day",
                        "hour", "minute" or "second"

    """
    if isinstance(datetime_or_timedelta, datetime):
        datetime_or_timedelta = datetime.utcnow() - datetime_or_timedelta

    if datetime_or_timedelta <= timedelta(seconds=3):
        return _(u"just now")

    timedelta_ = _format_timedelta(datetime_or_timedelta, granularity, threshold=threshold)
    return lazy_gettext(u"%(timedelta)s ago") % {"timedelta": timedelta_}
示例#29
0
    def _search_for_accepted(req):
        best_match = (None, 0)
        for mimetype, serializer in _serializer_for_mimetypes.iteritems():
            quality = req.accept_mimetypes[mimetype]
            if quality > best_match[1]:
                best_match = (serializer, quality)

        if best_match[0] is None:
            raise BadRequest(_(u'Could not detect format.  You have to specify '
                               u'the format as query argument or in the accept '
                               u'HTTP header.'))

        # special case.  If the best match is not html and the quality of
        # text/html is the same as the best match, we prefer HTML.
        if best_match[0] != 'text/html' and \
           best_match[1] == req.accept_mimetypes['text/html']:
            return _serializer_map['debug']
        return _serializer_map[best_match[0]]
示例#30
0
    def as_message(self):
        """Return the email as MIMEText object."""
        if not self.subject or not self.text or not self.to_addrs:
            raise RuntimeError(_(u'Not all mailing parameters filled in'))

        msg = MIMEText(self.text.encode('utf-8'))

        #: MIMEText sucks, it does not override the values on
        #: setitem, it appends them.  We get rid of some that
        #: are predefined under some versions of python
        del msg['Content-Transfer-Encoding']
        del msg['Content-Type']

        msg['From'] = self.from_addr.encode('utf-8')
        msg['To'] = ', '.join(x.encode('utf-8') for x in self.to_addrs)
        msg['Subject'] = self.subject.encode('utf-8')
        msg['Content-Transfer-Encoding'] = '8bit'
        msg['Content-Type'] = 'text/plain; charset=utf-8'
        return msg
示例#31
0
    def _search_for_accepted(req):
        best_match = (None, 0)
        for mimetype, serializer in _serializer_for_mimetypes.iteritems():
            quality = req.accept_mimetypes[mimetype]
            if quality > best_match[1]:
                best_match = (serializer, quality)

        if best_match[0] is None:
            raise BadRequest(
                _(u'Could not detect format.  You have to specify '
                  u'the format as query argument or in the accept '
                  u'HTTP header.'))

        # special case.  If the best match is not html and the quality of
        # text/html is the same as the best match, we prefer HTML.
        if best_match[0] != 'text/html' and \
           best_match[1] == req.accept_mimetypes['text/html']:
            return _serializer_map['debug']
        return _serializer_map[best_match[0]]
示例#32
0
    def as_message(self):
        """Return the email as MIMEText object."""
        if not self.subject or not self.text or not self.to_addrs:
            raise RuntimeError(_(u'Not all mailing parameters filled in'))

        msg = MIMEText(self.text.encode('utf-8'))

        #: MIMEText sucks, it does not override the values on
        #: setitem, it appends them.  We get rid of some that
        #: are predefined under some versions of python
        del msg['Content-Transfer-Encoding']
        del msg['Content-Type']

        msg['From'] = self.from_addr.encode('utf-8')
        msg['To'] = ', '.join(x.encode('utf-8') for x in self.to_addrs)
        msg['Subject'] = self.subject.encode('utf-8')
        msg['Content-Transfer-Encoding'] = '8bit'
        msg['Content-Type'] = 'text/plain; charset=utf-8'
        return msg
示例#33
0
 def add_addr(self, addr):
     """Add an mail address to the list of recipients"""
     lines = addr.splitlines()
     if len(lines) != 1:
         raise ValueError(_(u'invalid value for email address'))
     self.to_addrs.append(lines[0])
示例#34
0
 def decorated(*args, **kwargs):
     if ctx.current_request.user.is_anonymous:
         ctx.current_request.flash(_(u'You must login to view this!'))
         return redirect_to('portal/login', _next=ctx.current_request.url)
     return func(*args, **kwargs)
示例#35
0
"""
import random
from datetime import datetime
from werkzeug import cached_property

from inyoka.i18n import _
from inyoka.core.cache import cache
from inyoka.context import ctx
from inyoka.core.database import db
from inyoka.core.serializer import SerializableObject
from inyoka.core.subscriptions import subscribed
from inyoka.utils.datastructures import BidiMap
from inyoka.utils.crypt import get_hexdigest

USER_STATUS_MAP = BidiMap({
    0: _(u'inactive'),  #not yet activated
    1: _(u'normal'),
    2: _(u'banned'),
    3: _(u'deleted'),  #deleted itself
})

group_group = db.Table(
    'core_group_group',
    db.metadata,
    db.Column('group_id', db.Integer, db.ForeignKey('core_group.id')),
    db.Column('parent_id', db.Integer, db.ForeignKey('core_group.id')),
)

user_group = db.Table(
    'core_group_user', db.metadata,
    db.Column('user_id', db.Integer, db.ForeignKey('core_user.id')),
示例#36
0
class EditPasteForm(AddPasteForm):
    hidden = BooleanField(_(u'Hide Paste'))
示例#37
0
class AddPasteForm(Form):
    title = TextField(_(u'Title (optional)'), [validators.length(max=50)])
    text = TextField(_(u'Text'), [validators.required()],
                     widget=widgets.TextArea())
    language = SelectField(_(u'Language'), choices=_get_pygments_lexers())
    parent = HiddenIntegerField(validators=[validators.optional()])
示例#38
0
 def decorated(*args, **kwargs):
     if ctx.current_request.user.is_anonymous:
         ctx.current_request.flash(_(u'You must login to view this!'))
         return redirect_to('portal/login', _next=ctx.current_request.url)
     return func(*args, **kwargs)
示例#39
0
 def add_addr(self, addr):
     """Add an mail address to the list of recipients"""
     lines = addr.splitlines()
     if len(lines) != 1:
         raise ValueError(_(u'invalid value for email address'))
     self.to_addrs.append(lines[0])
示例#40
0
def humanize_number(number):
    """Format numbers from 0 to 12 to strings.
    unfortunately, this cannot be done with Babel.

    Usage Example::

        >>> humanize_number(6)
        u'six'
        >>> humanize_number(13)
        u'13'
        >>> humanize_number(u'some_string')
        u'some_string'

    """
    strings = [
        _(u"zero"),
        _(u"one"),
        _(u"two"),
        _(u"three"),
        _(u"four"),
        _(u"five"),
        _(u"six"),
        _(u"seven"),
        _(u"eight"),
        _(u"nine"),
        _(u"ten"),
        _(u"eleven"),
        _(u"twelve"),
    ]
    return strings[number] if number in xrange(13) else unicode(number)
示例#41
0
class Pagination(object):
    """
    :param query: A SQLAlchemy query object.
    :param page: The page number.
    :param link: The base link for the pagination. If it is not supplied,
                 relative links are used instead.
    :param args: URL parameters, that, if given, are included in the generated
                 urls.
    :param per_page: Number of entries displayed on one page.

    After initialisation, ``pagination.query`` is a list of the matching
    objects.  Call the pagination object for html code of links to the other
    pages.
    """

    # translatable strings for the pagination buttons
    _comma = u'<span class="comma">%s</span>' % escape(_(u', '))
    _next = escape(_(u'next »'))
    _prev = escape(_(u'« previous'))
    _ellipsis = escape(_(u'…'))

    # defaults
    left_threshold = 2
    inner_threshold = 1
    right_threshold = 1
    per_page = 15

    def __init__(self, query, page=None, link=None, args=None, per_page=None):
        self.base_query = query
        self.page = 1 if page is None else page
        if link is not None and not isinstance(link, basestring):
            link = link()
        self.link = link
        self.args = {} if args is None else args
        if per_page is not None:
            self.per_page = per_page

        #TODO: implement position_col
        self.total = self.base_query.count()

        self.pages = (max(0, self.total - 1) // self.per_page) + 1

        if self.page > self.pages or self.page < 1:
            raise NotFound()

        offset = (self.page - 1) * self.per_page
        #TODO: implement position_col
        self.query = query[offset:offset + self.per_page]

    @abstract
    def make_link(self, page):
        """
        Create a link to the given page. Usually used internally only.

        Subclasses must implement this.
        """

    def make_template(self):
        """
        Return a template for creating links. Usually used internally only.

        The template must contain a ``!`` at the place where the page number is
        to be inserted. This is used by JavaScript.

        Subclasses may implement this to enable a JavaScript page selector.
        """
        return None

    def _get_buttons(self, left_threshold=None, inner_threshold=None,
                    right_threshold=None, prev=True, next=True):
        """
        Return the buttons as tuples.
        First item is page number or one of prev, next, ellipsis.
        Second item is link or None if it's the current page or
               (for prev/next) if it's the first or last page
        This is split into a separate method to ease unittesting.
        """
        if left_threshold is None:
            left_threshold = self.left_threshold
        if inner_threshold is None:
            inner_threshold = self.inner_threshold
        if right_threshold is None:
            right_threshold = self.right_threshold

        def include(num, avoidsingle=True):
            if num < 1 or num > self.pages:
                return False

            if num < (left_threshold + 1):
                return True
            if num < self.page and num >= (self.page - inner_threshold):
                return True
            if num == self.page:
                return True
            if num > self.page and num <= (self.page + inner_threshold):
                return True
            if num > (self.pages - right_threshold):
                return True

            # avoid 4 ... 6
            if avoidsingle:
                if include(num + 1, False) and include(num - 1, False):
                    return True

            return False

        if prev:
            if self.page == 1:
                yield 'prev', None
            else:
                yield 'prev', self.make_link(self.page - 1)

        was_ellipsis = False
        for num in xrange(1, self.pages + 1):
            if include(num):
                if num == self.page:
                    yield num, None
                else:
                    yield num, self.make_link(num)
                was_ellipsis = False
            else:
                if not was_ellipsis:
                    yield 'ellipsis', self.make_template()
                was_ellipsis = True

        if next:
            if self.page == self.pages:
                yield 'next', None
            else:
                yield 'next', self.make_link(self.page + 1)

    def buttons(self, left_threshold=None, inner_threshold=None,
                right_threshold=None, prev=True, next=True,
                class_=u'pagination', force=False):
        """
        Return HTML code for the page selector if there is more than one page.

        For convenience, the ``__call__`` method is an alias for this.

        :param left_threshold: The number of pages to be shown after the
                               `prev` button.
        :param inner_threshold: The number of pages to be shown before and
                                after the current page.
        :param right_threshold: The number of pages to be shown before the
                                `next` button.
        :param prev: If False, do not show an extra link to the previous page.
        :param next: If False, do not show an extra link to the next page.
        :param class_: The class attribute for the enclosing `div` element.
                       Defaults to `pagination`.
        :param force: If True, return buttons even if there is only one page.
        """

        if self.pages == 1 and not force:
            return Markup(u'')

        ret = []
        add = ret.append
        add(u'<div class="%s">' % class_)

        # no comma at beginning
        was_ellipsis = True
        for type, link in self._get_buttons(left_threshold=left_threshold,
                                            inner_threshold=inner_threshold,
                                            right_threshold=right_threshold,
                                            prev=prev, next=next):
            if type == 'ellipsis':
                add(u' <span class="ellipsis">%s</span> ' % self._ellipsis)
                if link:
                    add(u'<input type="hidden" class="url-template" value="%s">'
                        % escape(link))
                was_ellipsis = True
                continue

            if not was_ellipsis:
                add(self._comma)
            was_ellipsis = False

            if type == 'prev':
                if link:
                    add(u'<a href="%s" class="prev">%s</a>'
                        % (escape(link), self._prev))
                else:
                    add(u'<span class="prev disabled">%s</span>' % self._prev)
            elif type == 'next':
                if link:
                    add(u'<a href="%s" class="next">%s</a>'
                        % (escape(link), self._next))
                else:
                    add(u'<span class="next disabled">%s</span>' % self._next)
            else:
                _pageclass = ' page1' if type == 1 else '' # required for JS
                if link:
                    add(u'<a href="%s" class="page%s">%d</a>'
                        % (escape(link), _pageclass, type))
                else:
                    add(u'<strong class="page%s">%d</strong>'
                        % (_pageclass, type))

        add(u'</div>')
        return Markup(u''.join(ret))

    def __call__(self, *args, **kwargs):
        """Alias for :meth:`buttons()`."""
        return self.buttons(*args, **kwargs)
示例#42
0
def humanize_number(number):
    """Format numbers from 0 to 12 to strings.
    unfortunately, this cannot be done with Babel.

    Usage Example::

        >>> humanize_number(6)
        u'six'
        >>> humanize_number(13)
        u'13'
        >>> humanize_number(u'some_string')
        u'some_string'

    """
    strings = [_(u'zero'), _(u'one'), _(u'two'), _(u'three'), _(u'four'),
               _(u'five'), _(u'six'), _(u'seven'), _(u'eight'),
               _(u'nine'), _(u'ten'), _(u'eleven'), _(u'twelve')]
    return strings[number] if number in xrange(13) else unicode(number)
示例#43
0
import random
from datetime import datetime
from werkzeug import cached_property

from inyoka.i18n import _
from inyoka.core.cache import cache
from inyoka.context import ctx
from inyoka.core.database import db
from inyoka.core.serializer import SerializableObject
from inyoka.core.subscriptions import subscribed
from inyoka.utils.datastructures import BidiMap
from inyoka.utils.crypt import get_hexdigest


USER_STATUS_MAP = BidiMap({
    0: _(u'inactive'), #not yet activated
    1: _(u'normal'),
    2: _(u'banned'),
    3: _(u'deleted'), #deleted itself
})


group_group = db.Table('core_group_group', db.metadata,
    db.Column('group_id', db.Integer, db.ForeignKey('core_group.id')),
    db.Column('parent_id', db.Integer, db.ForeignKey('core_group.id')),
)

user_group = db.Table('core_group_user', db.metadata,
    db.Column('user_id', db.Integer, db.ForeignKey('core_user.id')),
    db.Column('group_id', db.Integer, db.ForeignKey('core_group.id'))
)
示例#44
0
class EditCommentForm(Form):
    text = TextField(_(u'Text'), widget=widgets.TextArea(),
        description=Markup(_(u'To quote another comment use '
                             u'<em>@comment_number</em>. This is '
                             u'automatically used if you click “answer”.')))
示例#45
0
class EMail(object):
    """Represents one E-Mail message that can be sent."""
    def __init__(self, subject=None, text='', to_addrs=None):
        self.subject = u' '.join(subject.splitlines())
        self.text = text
        from_addr = ctx.cfg['email.system_email']
        self.from_addr = u'%s <%s>' % (ctx.cfg['website_title'], from_addr)
        self.to_addrs = []
        if isinstance(to_addrs, basestring):
            self.add_addr(to_addrs)
        else:
            for addr in to_addrs:
                self.add_addr(addr)

    def add_addr(self, addr):
        """Add an mail address to the list of recipients"""
        lines = addr.splitlines()
        if len(lines) != 1:
            raise ValueError(_(u'invalid value for email address'))
        self.to_addrs.append(lines[0])

    def as_message(self):
        """Return the email as MIMEText object."""
        if not self.subject or not self.text or not self.to_addrs:
            raise RuntimeError(_(u'Not all mailing parameters filled in'))

        msg = MIMEText(self.text.encode('utf-8'))

        #: MIMEText sucks, it does not override the values on
        #: setitem, it appends them.  We get rid of some that
        #: are predefined under some versions of python
        del msg['Content-Transfer-Encoding']
        del msg['Content-Type']

        msg['From'] = self.from_addr.encode('utf-8')
        msg['To'] = ', '.join(x.encode('utf-8') for x in self.to_addrs)
        msg['Subject'] = self.subject.encode('utf-8')
        msg['Content-Transfer-Encoding'] = '8bit'
        msg['Content-Type'] = 'text/plain; charset=utf-8'
        return msg

    def format(self, sep='\r\n'):
        """Format the message into a string."""
        return sep.join(self.as_message().as_string().splitlines())

    def log(self):
        """Logs the email"""
        logger.debug('%s\n%s\n\n' % ('-' * 79, self.format('\n').rstrip()))
        if ctx.cfg['testing']:
            outbox.append(self.as_message().as_string())

    def send(self):
        """Send the message."""
        try:
            smtp = SMTP(ctx.cfg['email.smtp_host'], ctx.cfg['email.smtp_port'])
        except SMTPException, e:
            raise RuntimeError(str(e))

        if ctx.cfg['email.smtp_use_tls']:
            smtp.ehlo()
            if not smtp.esmtp_features.has_key('starttls'):
                raise RuntimeError(
                    _(u'TLS enabled but server does not '
                      u'support TLS'))
            smtp.starttls()
            smtp.ehlo()

        if ctx.cfg['email.smtp_user']:
            try:
                smtp.login(ctx.cfg['email.smtp_user'],
                           ctx.cfg['email.smtp_password'])
            except SMTPException, e:
                raise RuntimeError(str(e))