Пример #1
0
def newscomments(page):
    objects = NewsComment.select()
    filter_deleted = current_user.is_staff and request.args.get(
        'deleted') == '1'
    if filter_deleted:
        objects = objects.filter(lambda x: x.deleted).order_by(
            NewsComment.last_deleted_at.desc())
    else:
        objects = objects.filter(lambda x: not x.deleted).order_by(
            NewsComment.id.desc())

    page_obj = Paginator(
        page,
        objects.count(),
        per_page=current_app.config['COMMENTS_COUNT']['stream'])
    objects = [('news', x) for x in page_obj.slice_or_404(objects)]

    comment_votes_cache = {
    }  # FIXME: здесь пересечение айдишников с айдшниками комментов к рассказам

    return render_template(
        'stream/comments.html',
        page_title='Лента комментариев',
        tab='news',
        comments=objects,
        filter_deleted=filter_deleted,
        with_target_link=True,
        comment_votes_cache=comment_votes_cache,
        page_obj=page_obj,
        robots_noindex=True,
    )
Пример #2
0
def ajax_author_overview(user_id, page):
    author = Author.get(id=user_id)
    if not author:
        abort(404)

    comments_list = StoryComment.select(lambda x: x.author == author and not x.deleted and x.story_published)
    comments_list = comments_list.order_by(StoryComment.id.desc())
    comments_count = comments_list.count()

    paged = Paginator(
        number=page,
        total=comments_count,
        per_page=current_app.config['COMMENTS_COUNT']['author_page'],
    )  # TODO: restore orphans?
    comments = paged.slice(comments_list)
    if not comments and page != 1:
        abort(404)

    data = {
        'author': author,
        'comments': comments,
        'page_obj': paged,
        'comments_short': True,
    }
    data.update(cached_lists([x.story.id for x in comments]))

    return jsonify({
        'success': True,
        'link': url_for('author.info', user_id=author.id, comments_page=page),
        'comments_count': comments_count,
        'comments_list': render_template('includes/story_comments_list.html', **data),
        'pagination': render_template('includes/comments_pagination_author_overview.html', **data),
    })
Пример #3
0
def storylocalcomments(page):
    if not current_user.is_staff:
        abort(403)

    objects = StoryLocalComment.select()
    filter_deleted = current_user.is_staff and request.args.get('deleted') == '1'
    if filter_deleted:
        objects = objects.filter(lambda x: x.deleted).order_by(StoryLocalComment.last_deleted_at.desc())
    else:
        objects = objects.filter(lambda x: not x.deleted).order_by(StoryLocalComment.id.desc())

    page_obj = Paginator(page, objects.count(), per_page=current_app.config['COMMENTS_COUNT']['stream'])
    objects = [('local', x) for x in page_obj.slice_or_404(objects)]

    comment_votes_cache = {}  # FIXME: здесь пересечение айдишников с айдшниками комментов к рассказам

    return render_template(
        'stream/comments.html',
        page_title='Лента комментариев',
        tab='local',
        comments=objects,
        filter_deleted=filter_deleted,
        with_target_link=True,
        comment_votes_cache=comment_votes_cache,
        page_obj=page_obj,
        robots_noindex=True,
    )
Пример #4
0
def tag_index(tag_name, page):
    iname = normalize_tag(tag_name)
    if not iname:
        abort(404)
    tag = Tag.get(iname=iname)
    if tag and tag.is_alias_for is not None:
        if tag.is_alias_for.is_alias_for:
            raise RuntimeError('Tag alias {} refers to another alias {}!'.format(tag.id, tag.is_alias_for.id))
        tag = tag.is_alias_for
    if not tag or tag.is_blacklisted:
        abort(404)
    if tag.iname != tag_name:
        return redirect(url_for('tags.tag_index', tag_name=tag.iname, page=page))

    objects = Story.bl.select_by_tag(tag, user=current_user._get_current_object())
    objects = objects.prefetch(Story.characters, Story.contributors, StoryContributor.user, Story.tags, StoryTag.tag, Tag.category)
    objects = objects.order_by(Story.first_published_at.desc(), Story.id.desc())

    page_obj = Paginator(page, objects.count(), per_page=current_app.config['STORIES_COUNT']['stream'])
    objects = page_obj.slice_or_404(objects)

    return render_template(
        'tags/tag_index.html',
        page_title=tag.name,
        tag=tag,
        aliases=[x.name for x in Tag.bl.get_aliases_for([tag])[tag.id]],
        category=tag.category,
        stories=objects,
        page_obj=page_obj,
        **cached_lists([x.id for x in objects])
    )
Пример #5
0
def comments(page):
    objects = StoryComment.select(lambda x: x.story_published)
    filter_deleted = current_user.is_staff and request.args.get(
        'deleted') == '1'
    if filter_deleted:
        objects = objects.filter(lambda x: x.deleted).order_by(
            StoryComment.last_deleted_at.desc())
    else:
        objects = objects.filter(lambda x: not x.deleted).order_by(
            StoryComment.id.desc())

    page_obj = Paginator(
        page,
        objects.count(),
        per_page=current_app.config['COMMENTS_COUNT']['stream'])
    objects = [('story', x) for x in page_obj.slice_or_404(objects)]

    comment_votes_cache = Story.bl.select_comment_votes(
        current_user._get_current_object(),
        [x[1].id for x in objects]) if current_user.is_authenticated else {}

    return render_template('stream/comments.html',
                           page_title='Лента комментариев',
                           tab='story',
                           comments=objects,
                           filter_deleted=filter_deleted,
                           with_target_link=True,
                           comment_votes_cache=comment_votes_cache,
                           page_obj=page_obj,
                           robots_noindex=True,
                           **cached_lists([x[1].story.id for x in objects]))
Пример #6
0
def favorites(user_id, page):
    user = Author.get(id=user_id)
    if not user:
        abort(404)

    objects = select(x.story for x in Favorites if x.author == user)
    if not current_user.is_authenticated or (not current_user.is_staff and current_user.id != user.id):
        objects = objects.filter(lambda story: not story.draft and story.approved)
    objects = objects.without_distinct().order_by('-x.id')

    if current_user.is_authenticated and user.id == current_user.id:
        page_title = 'Мое избранное'
    else:
        page_title = 'Избранное автора %s' % user.username

    page_obj = Paginator(page, objects.count(), per_page=10)
    stories = page_obj.slice_or_404(objects)

    data = dict(
        stories=stories,
        page_obj=page_obj,
        page_title=page_title,
        author=user,
    )
    data.update(cached_lists([x.id for x in stories]))

    return render_template('favorites.html', **data)
Пример #7
0
def comments(page):
    objects = StoryComment.select(lambda x: x.story_published)
    filter_deleted = current_user.is_staff and request.args.get('deleted') == '1'
    if filter_deleted:
        objects = objects.filter(lambda x: x.deleted).order_by(StoryComment.last_deleted_at.desc())
    else:
        objects = objects.filter(lambda x: not x.deleted).order_by(StoryComment.id.desc())

    page_obj = Paginator(page, objects.count(), per_page=current_app.config['COMMENTS_COUNT']['stream'])
    objects = [('story', x) for x in page_obj.slice_or_404(objects)]

    comment_votes_cache = Story.bl.select_comment_votes(
        current_user._get_current_object(),
        [x[1].id for x in objects]
    ) if current_user.is_authenticated else {}

    return render_template(
        'stream/comments.html',
        page_title='Лента комментариев',
        tab='story',
        comments=objects,
        filter_deleted=filter_deleted,
        with_target_link=True,
        comment_votes_cache=comment_votes_cache,
        page_obj=page_obj,
        robots_noindex=True,
        **cached_lists([x[1].story.id for x in objects])
    )
Пример #8
0
def ajax_author_dashboard(page):
    if not current_user.is_authenticated:
        abort(403)

    comments_list = StoryComment.bl.select_by_story_author(current_user)
    comments_list = comments_list.order_by(StoryComment.id.desc())
    comments_count = comments_list.count()

    paged = Paginator(
        number=page,
        total=comments_count,
        per_page=current_app.config['COMMENTS_COUNT']['author_page'],
    )  # TODO: restore orphans?
    comments = paged.slice(comments_list)
    if not comments and page != 1:
        abort(404)

    data = {
        'comments': comments,
        'page_obj': paged,
        'comments_short': True,
    }
    data.update(cached_lists([x.story.id for x in comments]))

    return jsonify({
        'success': True,
        'link': url_for('author.info', comments_page=page),
        'comments_count': comments_count,
        'comments_list': render_template('includes/story_comments_list.html', **data),
        'pagination': render_template('includes/comments_pagination_author_dashboard.html', **data),
    })
Пример #9
0
def paginate_view(template, objlist, page=None, objlistname='objects', endpoint=None, view_args=None, per_page=50, extra_context=None, **kwargs):
    # legacy
    data = dict(kwargs)
    if 'count' in data:
        count = data.pop('count')
    else:
        count = len(objlist)

    if view_args is None:
        view_args = dict(request.view_args or {})

    if page is None:
        page = view_args.pop('page')

    page_obj = Paginator(page, count, per_page=per_page)
    page_objlist = page_obj.slice(objlist)
    # page_objlist = objlist[0:2]
    if not page_objlist and page != 1:
        abort(404)

    data.update({
        'endpoint': endpoint or request.endpoint,
        'view_args': view_args,
        'page_obj': page_obj,
    })
    if extra_context:
        data.update(extra_context(page_objlist, page_obj) or {})
    data[objlistname] = page_objlist

    return render_template(template, **data)
Пример #10
0
    def paginate_comments(self, comments_page=1, per_page=25, maxdepth=None, last_viewed_comment=None):
        target = self.model  # pylint: disable=e1101

        comments_count = target.comments.select().count()
        if comments_count > 0:
            root_comments_total = self.select_comments().filter(lambda x: x.tree_depth == 0).count()
        else:
            root_comments_total = comments_count

        paged = Paginator(
            number=comments_page,
            total=root_comments_total,
            per_page=per_page,
        )  # TODO: restore orphans?

        # paginate_comments вызывается откуда попало, и endpoint запроса
        # неприменим или вообще не существует
        paged.endpoint = None
        paged.view_args = None

        comments_tree_list = target.bl.get_comments_tree_list(
            maxdepth=maxdepth,
            root_offset=per_page * (paged.number - 1),
            root_count=per_page,
            last_viewed_comment=last_viewed_comment,
        )

        return comments_count, paged, comments_tree_list
Пример #11
0
    def paginate_comments(self,
                          comments_page=1,
                          per_page=25,
                          maxdepth=None,
                          last_viewed_comment=None):
        target = self.model  # pylint: disable=e1101

        comments_count = target.comments.select().count()
        if comments_count > 0:
            root_comments_total = self.select_comments().filter(
                lambda x: x.tree_depth == 0).count()
        else:
            root_comments_total = comments_count

        paged = Paginator(
            number=comments_page,
            total=root_comments_total,
            per_page=per_page,
        )  # TODO: restore orphans?

        # paginate_comments вызывается откуда попало, и endpoint запроса
        # неприменим или вообще не существует
        paged.endpoint = None
        paged.view_args = None

        comments_tree_list = target.bl.get_comments_tree_list(
            maxdepth=maxdepth,
            root_offset=per_page * (paged.number - 1),
            root_count=per_page,
            last_viewed_comment=last_viewed_comment,
        )

        return comments_count, paged, comments_tree_list
Пример #12
0
def index(page):
    if not current_user.is_superuser:
        abort(403)

    objects = Author.select().order_by(Author.username)

    args = {
        'page': page,
        'sorting': request.args.get('sorting') or 'id',
    }

    if request.args.get('username'):
        args['username'] = request.args['username']
        objects = objects.filter(lambda x: args['username'].lower() in x.username.lower())

    if request.args.get('email'):
        args['email'] = request.args['email']
        objects = objects.filter(lambda x: args['email'].lower() in x.email.lower())

    if request.args.get('is_active') in ('0', '1'):
        args['is_active'] = request.args['is_active']
        is_active = args['is_active'] == '1'
        objects = objects.filter(lambda x: x.is_active == is_active)

    if request.args.get('is_staff') in ('0', '1'):
        args['is_staff'] = request.args['is_staff']
        is_staff = args['is_staff'] == '1'
        objects = objects.filter(lambda x: x.is_staff == is_staff)

    if request.args.get('is_superuser') in ('0', '1'):
        args['is_superuser'] = request.args['is_superuser']
        is_superuser = args['is_superuser'] == '1'
        objects = objects.filter(lambda x: x.is_superuser == is_superuser)

    if request.args.get('premoderation_mode') in ('none', 'on', 'off'):
        args['premoderation_mode'] = request.args['premoderation_mode']
        premoderation_mode = '' if args['premoderation_mode'] == 'none' else args['premoderation_mode']
        objects = objects.filter(lambda x: x.premoderation_mode == premoderation_mode)

    objects = admin_sort(args['sorting'], objects, {
        'username': Author.username,
        'date_joined': (Author.date_joined, Author.id),
        'last_visit': (Author.last_visit, Author.id),
        'is_active': (Author.is_active, Author.id),
        'id': Author.id,
    })

    page_obj = Paginator(page, objects.count(), per_page=100, endpoint=request.endpoint, view_args=args)

    return render_template(
        'admin/authors/index.html',
        authors=page_obj.slice_or_404(objects),
        page_obj=page_obj,
        page_title=gettext('Authors'),
        endpoint=request.endpoint,
        args=args,
    )
Пример #13
0
def index(page):
    objects = Logopic.select().order_by(Logopic.id)

    page_obj = Paginator(page, objects.count(), per_page=100)
    objects = page_obj.slice_or_404(objects)

    return render_template(
        'admin/logopics/index.html',
        page_title=gettext('Header pictures'),
        logopics=objects,
        page_obj=page_obj,
    )
Пример #14
0
def index(page):
    if not current_user.is_staff:
        abort(403)

    objects = Vote.select().order_by(Vote.id.desc())

    args = {
        'page': page,
    }

    if request.args.get('story_id'):
        try:
            story_id = int(request.args['story_id'])
        except ValueError:
            pass
        else:
            args['story_id'] = story_id
            objects = objects.filter(lambda x: x.story.id == story_id)

    if request.args.get('username'):
        args['username'] = request.args['username']
        user_ids = list(
            select(x.id for x in Author
                   if args['username'].lower() in x.username.lower()))
        objects = objects.filter(lambda x: x.author.id in user_ids)

    if request.args.get('ip'):
        args['ip'] = request.args['ip']
        objects = objects.filter(lambda x: x.ip == args['ip'])

    if request.args.get('revoked') == 'no':
        args['revoked'] = 'no'
        objects = objects.filter(lambda x: x.revoked_at is None)
    elif request.args.get('revoked') == 'yes':
        args['revoked'] = 'yes'
        objects = objects.filter(lambda x: x.revoked_at is not None)

    objects = objects.prefetch(Vote.story, Vote.author)

    page_obj = Paginator(page,
                         objects.count(),
                         per_page=100,
                         endpoint=request.endpoint,
                         view_args=args)

    return render_template(
        'admin/votes/index.html',
        votes=page_obj.slice_or_404(objects),
        page_obj=page_obj,
        page_title='Оценки',
        endpoint=request.endpoint,
        args=args,
    )
Пример #15
0
def index(page):
    objects = TagCategory.select().order_by(TagCategory.id)

    page_obj = Paginator(page, objects.count(), per_page=100)
    objects = page_obj.slice_or_404(objects)

    return render_template(
        'admin/tag_categories/index.html',
        page_title=gettext('Tag categories'),
        tag_categories=objects,
        page_obj=page_obj,
    )
Пример #16
0
def index(page):
    objects = Logopic.select().order_by(Logopic.id)

    page_obj = Paginator(page, objects.count(), per_page=100)
    objects = page_obj.slice_or_404(objects)

    return render_template(
        'admin/logopics/index.html',
        page_title=gettext('Header pictures'),
        logopics=objects,
        page_obj=page_obj,
    )
Пример #17
0
def index(page):
    objects = TagCategory.select().order_by(TagCategory.id)

    page_obj = Paginator(page, objects.count(), per_page=100)
    objects = page_obj.slice_or_404(objects)

    return render_template(
        'admin/tag_categories/index.html',
        page_title=gettext('Tag categories'),
        tag_categories=objects,
        page_obj=page_obj,
    )
Пример #18
0
def index(page):
    if not current_user.is_superuser:
        abort(403)

    objects = RegistrationProfile.select().order_by(RegistrationProfile.id.desc())
    page_obj = Paginator(page, objects.count(), per_page=100)

    return render_template(
        'admin/registrations/index.html',
        registrations=page_obj.slice_or_404(objects),
        page_obj=page_obj,
        page_title=gettext('Registrations'),
    )
Пример #19
0
def bookmarks(page):
    objects = select(x.story for x in Bookmark if x.author.id == current_user.id).without_distinct().order_by('-x.id')
    page_obj = Paginator(page, objects.count(), per_page=10)
    stories = page_obj.slice_or_404(objects)

    data = dict(
        stories=stories,
        page_obj=page_obj,
        page_title='Прочитать позже',
    )
    data.update(cached_lists([x.id for x in stories]))

    return render_template('bookmarks.html', **data)
Пример #20
0
def index(page):
    user = current_user._get_current_object()

    view_args = {'page': page}

    if request.args.get('all') == '1':
        if not user.is_staff:
            abort(403)
        view_args['all'] = '1'
        queryset = StoryLog.select()
    else:
        queryset = StoryLog.select(lambda l: l.story in select(
            c.story for c in StoryContributor if c.user == user))

    if request.args.get('staff') == '1':
        view_args['staff'] = '1'
        queryset = queryset.filter(lambda l: l.by_staff)

    # TODO: это довольно медленно, стоит оптимизировать
    if request.args.get('published') == '1':
        view_args['published'] = '1'
        queryset = queryset.filter(
            lambda l: l.story.approved and not l.story.draft)
    elif request.args.get('published') == '0':
        view_args['published'] = '0'
        queryset = queryset.filter(
            lambda l: not l.story.approved or l.story.draft)

    queryset = queryset.order_by(StoryLog.created_at.desc()).prefetch(
        StoryLog.story, StoryLog.user)

    page_obj = Paginator(
        page,
        queryset.count(),
        per_page=current_app.config.get('EDIT_LOGS_PER_PAGE', 100),
        view_args=view_args,
    )

    edit_log = page_obj.slice_or_404(queryset)

    return render_template(
        'story_edit_log.html',
        edit_log=edit_log,
        edit_log_users=load_users_for_editlog(edit_log),
        page_obj=page_obj,
        page_title=_('Edit log'),
        view_args=view_args,
        filter_all=view_args.get('all') == '1',
        filter_staff=view_args.get('staff') == '1',
        filter_published=view_args.get('published'),
    )
Пример #21
0
def stories(page):
    objects = Story.select_published().order_by(Story.first_published_at.desc(), Story.id.desc())
    objects = objects.prefetch(Story.characters, Story.contributors, StoryContributor.user, Story.tags, StoryTag.tag, Tag.category)

    page_obj = Paginator(page, objects.count(), per_page=current_app.config['STORIES_COUNT']['stream'])
    objects = page_obj.slice_or_404(objects)

    return render_template(
        'stream/stories.html',
        page_title='Лента добавлений',
        stories=objects,
        page_obj=page_obj,
        robots_noindex=True,
        **cached_lists([x.id for x in objects])
    )
Пример #22
0
def submitted(page):
    if not current_user.is_staff:
        abort(403)
    objects = Story.select_submitted()
    page_obj = Paginator(page, objects.count(), per_page=10)
    stories = page_obj.slice_or_404(objects)

    data = dict(
        stories=stories,
        page_obj=page_obj,
        page_title='Новые поступления',
    )
    data.update(cached_lists([x.id for x in stories]))

    return render_template('submitted.html', **data)
Пример #23
0
def index(page):
    user = current_user._get_current_object()

    view_args = {'page': page}

    if request.args.get('all') == '1':
        if not user.is_staff:
            abort(403)
        view_args['all'] = '1'
        queryset = StoryLog.select()
    else:
        queryset = StoryLog.select(
            lambda l: l.story in select(c.story for c in StoryContributor if c.user == user)
        )

    if request.args.get('staff') == '1':
        view_args['staff'] = '1'
        queryset = queryset.filter(lambda l: l.by_staff)

    # TODO: это довольно медленно, стоит оптимизировать
    if request.args.get('published') == '1':
        view_args['published'] = '1'
        queryset = queryset.filter(lambda l: l.story.approved and not l.story.draft)
    elif request.args.get('published') == '0':
        view_args['published'] = '0'
        queryset = queryset.filter(lambda l: not l.story.approved or l.story.draft)

    queryset = queryset.order_by(StoryLog.created_at.desc()).prefetch(StoryLog.story, StoryLog.user)

    page_obj = Paginator(
        page, queryset.count(),
        per_page=current_app.config.get('EDIT_LOGS_PER_PAGE', 100),
        view_args=view_args,
    )

    edit_log = page_obj.slice_or_404(queryset)

    return render_template(
        'story_edit_log.html',
        edit_log=edit_log,
        edit_log_users=load_users_for_editlog(edit_log),
        page_obj=page_obj,
        page_title=_('Edit log'),
        view_args=view_args,
        filter_all=view_args.get('all') == '1',
        filter_staff=view_args.get('staff') == '1',
        filter_published=view_args.get('published'),
    )
Пример #24
0
def chapters(page):
    objects = orm.select(c for c in Chapter if not c.draft and c.story_published and c.order != 1)
    objects = objects.prefetch(Chapter.text, Chapter.story, Story.contributors, StoryContributor.user)
    objects = objects.order_by(Chapter.first_published_at.desc(), Chapter.order.desc())

    page_obj = Paginator(page, objects.count(), per_page=current_app.config['CHAPTERS_COUNT']['stream'])
    objects = page_obj.slice_or_404(objects)

    return render_template(
        'stream/chapters.html',
        page_title='Лента обновлений',
        chapters=objects,
        page_obj=page_obj,
        robots_noindex=True,
        **cached_lists([x.story.id for x in objects])
    )
Пример #25
0
def index(page):
    if not current_user.is_staff:
        abort(403)

    objects = Vote.select().order_by(Vote.id.desc())

    args = {
        'page': page,
    }

    if request.args.get('story_id'):
        try:
            story_id = int(request.args['story_id'])
        except ValueError:
            pass
        else:
            args['story_id'] = story_id
            objects = objects.filter(lambda x: x.story.id == story_id)

    if request.args.get('username'):
        args['username'] = request.args['username']
        user_ids = list(select(x.id for x in Author if args['username'].lower() in x.username.lower()))
        objects = objects.filter(lambda x: x.author.id in user_ids)

    if request.args.get('ip'):
        args['ip'] = request.args['ip']
        objects = objects.filter(lambda x: x.ip == args['ip'])

    if request.args.get('revoked') == 'no':
        args['revoked'] = 'no'
        objects = objects.filter(lambda x: x.revoked_at is None)
    elif request.args.get('revoked') == 'yes':
        args['revoked'] = 'yes'
        objects = objects.filter(lambda x: x.revoked_at is not None)

    objects = objects.prefetch(Vote.story, Vote.author)

    page_obj = Paginator(page, objects.count(), per_page=100, endpoint=request.endpoint, view_args=args)

    return render_template(
        'admin/votes/index.html',
        votes=page_obj.slice_or_404(objects),
        page_obj=page_obj,
        page_title='Оценки',
        endpoint=request.endpoint,
        args=args,
    )
Пример #26
0
def viewed(page):
    views = select(
        (x.story, min(x.id)) for x in StoryView if x.author.id == current_user.id and x.story
    )
    views = views.prefetch(StoryView.story, Story.characters, Story.contributors, StoryContributor.user, Story.tags, StoryTag.tag, Tag.category)
    views = views.order_by(-2)

    page_obj = Paginator(page, views.count(), per_page=10)

    stories = [x[0] for x in page_obj.slice_or_404(views)]

    return render_template(
        'viewed.html',
        stories=stories,
        page_obj=page_obj,
        page_title='Просмотренные рассказы',
        stories_detail_view=True,
        **cached_lists([x.id for x in stories])
    )
Пример #27
0
def chapters(page):
    objects = orm.select(c for c in Chapter
                         if not c.draft and c.story_published and c.order != 1)
    objects = objects.prefetch(Chapter.text, Chapter.story, Story.contributors,
                               StoryContributor.user)
    objects = objects.order_by(Chapter.first_published_at.desc(),
                               Chapter.order.desc())

    page_obj = Paginator(
        page,
        objects.count(),
        per_page=current_app.config['CHAPTERS_COUNT']['stream'])
    objects = page_obj.slice_or_404(objects)

    return render_template('stream/chapters.html',
                           page_title='Лента обновлений',
                           chapters=objects,
                           page_obj=page_obj,
                           robots_noindex=True,
                           **cached_lists([x.story.id for x in objects]))
Пример #28
0
def tag_index(tag_name, page):
    iname = normalize_tag(tag_name)
    if not iname:
        abort(404)
    tag = Tag.get(iname=iname)
    if tag and tag.is_alias_for is not None:
        if tag.is_alias_for.is_alias_for:
            raise RuntimeError(
                'Tag alias {} refers to another alias {}!'.format(
                    tag.id, tag.is_alias_for.id))
        tag = tag.is_alias_for
    if not tag or tag.is_blacklisted:
        abort(404)
    if tag.iname != tag_name:
        return redirect(
            url_for('tags.tag_index', tag_name=tag.iname, page=page))

    objects = Story.bl.select_by_tag(tag,
                                     user=current_user._get_current_object())
    objects = objects.prefetch(Story.characters, Story.contributors,
                               StoryContributor.user, Story.tags, StoryTag.tag,
                               Tag.category)
    objects = objects.order_by(Story.first_published_at.desc(),
                               Story.id.desc())

    page_obj = Paginator(
        page,
        objects.count(),
        per_page=current_app.config['STORIES_COUNT']['stream'])
    objects = page_obj.slice_or_404(objects)

    return render_template(
        'tags/tag_index.html',
        page_title=tag.name,
        tag=tag,
        aliases=[x.name for x in Tag.bl.get_aliases_for([tag])[tag.id]],
        category=tag.category,
        stories=objects,
        page_obj=page_obj,
        **cached_lists([x.id for x in objects]))
Пример #29
0
def top(page):
    period = request.args.get('period')
    if period and period.isdigit():
        period = int(period)
    else:
        period = 0

    objects = Story.bl.select_top(period)
    objects = objects.prefetch(Story.characters, Story.contributors, StoryContributor.user, Story.tags, StoryTag.tag, Tag.category)

    page_obj = Paginator(
        page,
        objects.count(),
        per_page=current_app.config['STORIES_COUNT']['stream'],
        view_args={'period': period} if period > 0 else None,
    )

    stories = page_obj.slice_or_404(objects)

    if period == 7:
        page_title = gettext('Top stories for the week')
    elif period == 30:
        page_title = gettext('Top stories for the month')
    elif period == 365:
        page_title = gettext('Top stories for the year')
    elif period == 0:
        page_title = gettext('Top stories for all time')
    else:
        page_title = ngettext('Top stories in %(num)d day', 'Top stories in %(num)d days', period)

    data = dict(
        stories=stories,
        page_obj=page_obj,
        count=objects.count(),
        page_title=page_title,
        period=period,
    )
    data.update(cached_lists([x.id for x in stories]))

    return render_template('stream/stories_top.html', **data)
Пример #30
0
def paginate_view(template,
                  objlist,
                  page=None,
                  objlistname='objects',
                  endpoint=None,
                  view_args=None,
                  per_page=50,
                  extra_context=None,
                  **kwargs):
    # legacy
    data = dict(kwargs)
    if 'count' in data:
        count = data.pop('count')
    else:
        count = len(objlist)

    if view_args is None:
        view_args = dict(request.view_args or {})

    if page is None:
        page = view_args.pop('page')

    page_obj = Paginator(page, count, per_page=per_page)
    page_objlist = page_obj.slice(objlist)
    # page_objlist = objlist[0:2]
    if not page_objlist and page != 1:
        abort(404)

    data.update({
        'endpoint': endpoint or request.endpoint,
        'view_args': view_args,
        'page_obj': page_obj,
    })
    if extra_context:
        data.update(extra_context(page_objlist, page_obj) or {})
    data[objlistname] = page_objlist

    return render_template(template, **data)
Пример #31
0
def search_action(postform):
    from mini_fiction.apis.amsphinxql import SphinxError

    if not postform.validate():
        data = {
            'form': postform,
            'page_title': gettext('Search of stories'),
            'robots_noindex': True
        }
        return render_template('search.html', **data)

    try:
        page_current = int(request.args.get('page') or 1)
    except Exception:
        page_current = 1

    query = postform.data['q']
    limit = ((page_current - 1) * current_app.config['SPHINX_CONFIG']['limit'],
             current_app.config['SPHINX_CONFIG']['limit'])
    search_type = postform.data['type']
    sort_type = postform.data['sort']

    data = {
        'page_title': query.strip() or gettext('Search results'),
        'search_type': search_type,
        'robots_noindex': True
    }

    if search_type == 0:
        # if current_user.is_authenticated:
        #     excluded_categories = [x for x in current_user.excluded_categories_list if x not in postform.data['genre']]
        # else:
        excluded_categories = []
        try:
            raw_result, result = Story.bl.search(
                query,
                limit,
                int(sort_type),
                only_published=not current_user.is_authenticated
                or not current_user.is_staff,
                extended_syntax=postform.data.get('extsyntax'),
                character=postform.data['char'],
                # classifier=postform.data['cls'],
                tags=smart_split(postform.data.get('tags', '')),
                exclude_tags=smart_split(postform.data.get('exclude_tags',
                                                           '')),
                # category=postform.data['genre'],
                rating_id=postform.data['rating'],
                original=postform.data['original'],
                finished=postform.data['finished'],
                freezed=postform.data['freezed'],
                min_words=postform.data['min_words'],
                max_words=postform.data['max_words'],
                min_vote_total=current_app.config['MINIMUM_VOTES_FOR_VIEW']
                if int(sort_type) == 3 else None,
                excluded_categories=excluded_categories,
            )
        except SphinxError as exc:
            data = {
                'form': postform,
                'page_title': gettext('Search of stories'),
                'error': 'Кажется, есть синтаксическая ошибка в запросе',
                'error_type': 'syntax'
            }
            if current_app.config['DEBUG'] or current_user.is_superuser:
                data['error'] += ': ' + str(exc)
            return render_template('search.html', **data)

    else:
        try:
            raw_result, result = Chapter.bl.search(
                query,
                limit,
                int(sort_type),
                # TODO: сортировка и для глав тоже
                only_published=not current_user.is_authenticated
                or not current_user.is_staff,
                extended_syntax=postform.data.get('extsyntax'),
                character=postform.data['char'],
                # lassifier=postform.data['cls'],
                tags=smart_split(postform.data.get('tags', '')),
                exclude_tags=smart_split(postform.data.get('exclude_tags',
                                                           '')),
                # category=postform.data['genre'],
                rating_id=postform.data['rating'],
                original=postform.data['original'],
                finished=postform.data['finished'],
                freezed=postform.data['freezed'],
                min_words=postform.data['min_words'],
                max_words=postform.data['max_words'],
                min_vote_total=current_app.config['MINIMUM_VOTES_FOR_VIEW']
                if int(sort_type) == 3 else None,
            )
        except SphinxError as exc:
            data = {
                'form': postform,
                'page_title': gettext('Search of stories'),
                'error': 'Кажется, есть синтаксическая ошибка в запросе',
                'error_type': 'syntax'
            }
            if current_app.config['DEBUG'] or current_user.is_superuser:
                data['error'] += ': ' + str(exc)
            return render_template('search.html', **data)

    pagination = Paginator(
        number=page_current,
        total=int(raw_result['total'] or 0),
        per_page=current_app.config['SPHINX_CONFIG']['limit'])

    data['form'] = postform
    data['pagination'] = pagination
    data['total'] = int(raw_result['total_found'])
    data['result'] = result
    data['weights'] = [(x['id'], x['weight']) for x in raw_result['matches']]

    if search_type == 0:
        data.update(cached_lists([x.id for x in result]))
    else:
        data.update(cached_lists([x[0].story.id for x in result]))

    return render_template('search.html', **data)
Пример #32
0
def info(user_id=None, comments_page=1):
    if user_id is not None:
        try:
            user_id = int(user_id)
        except ValueError:
            abort(404)

    data = {}

    if user_id is None:
        if not current_user.is_authenticated:
            abort(403)
        author = current_user._get_current_object()
        comments_list = StoryComment.bl.select_by_story_author(author)
        comments_list = comments_list.order_by(StoryComment.id.desc())
        stories = list(author.stories)
        stories.sort(key=lambda x: x.first_published_at or x.date,
                     reverse=True)
        contributing_stories = list(author.contributing_stories)
        contributing_stories.sort(key=lambda x: x.first_published_at or x.date,
                                  reverse=True)

        data['all_views'] = Story.bl.get_all_views_for_author(author)

        data['page_title'] = gettext('My cabinet')
        template = 'author_dashboard.html'
    else:
        author = Author.get(id=user_id)
        if not author:
            abort(404)
        author_id = author.id  # обход утечки памяти
        comments_list = StoryComment.select(
            lambda x: x.author.id == author_id and not x.deleted and x.
            story_published)
        comments_list = comments_list.order_by(StoryComment.id.desc())
        data['page_title'] = gettext('Author: {author}').format(
            author=author.username)
        stories = list(Story.bl.select_by_author(author,
                                                 for_user=current_user))
        stories.sort(key=lambda x: x.first_published_at or x.date,
                     reverse=True)
        contributing_stories = None
        template = 'author_overview.html'

    comments_count = comments_list.count()
    series = list(author.series)
    paged = Paginator(
        number=comments_page,
        total=comments_count,
        per_page=current_app.config['COMMENTS_COUNT']['author_page'],
        page_arg_name='comments_page',
    )  # TODO: restore orphans?
    comments = paged.slice(comments_list)
    if not comments and comments_page != 1:
        abort(404)

    data.update({
        'author':
        author,
        'is_system_user':
        author.id == current_app.config['SYSTEM_USER_ID'],
        'sub':
        author.bl.get_stories_subscription(current_user._get_current_object()),
        'stories':
        stories,
        'contributing_stories':
        contributing_stories,
        'series':
        series,
        'comments':
        comments,
        'comments_count':
        comments_count,
        'comments_short':
        True,
        'page_obj':
        paged,
    })

    story_ids = set(x.id for x in stories)
    if contributing_stories:
        story_ids |= set(x.id for x in contributing_stories)
    story_ids |= set(x.story.id for x in comments)

    data.update(cached_lists(story_ids))

    return render_template(template, **data)
Пример #33
0
def index(page):
    objects = models.AbuseReport.select().order_by(models.AbuseReport.id.desc())

    args = {
        'page': page,
    }

    target_type = request.args.get('target_type')
    if target_type:
        args['target_type'] = target_type
        objects = objects.filter(lambda x: x.target_type == target_type)
        if request.args.get('target_id'):
            try:
                target_id = int(request.args['target_id'])
            except ValueError:
                pass
            else:
                args['target_id'] = target_id
                objects = objects.filter(lambda x: x.target_id == target_id)

    if request.args.get('username'):
        args['username'] = request.args['username']
        user_ids = list(select(x.id for x in models.Author if args['username'].lower() in x.username.lower()))
        objects = objects.filter(lambda x: x.user.id in user_ids)

    if request.args.get('status') == 'none':
        args['status'] = 'none'
        objects = objects.filter(lambda x: not x.ignored and x.resolved_at is None)
    elif request.args.get('status') == 'accepted':
        args['status'] = 'accepted'
        objects = objects.filter(lambda x: not x.ignored and x.resolved_at is not None and x.accepted)
    elif request.args.get('status') == 'rejected':
        args['status'] = 'rejected'
        objects = objects.filter(lambda x: not x.ignored and x.resolved_at is not None and not x.accepted)
    elif request.args.get('status') == 'ignored':
        args['status'] = 'ignored'
        objects = objects.filter(lambda x: x.ignored)

    objects = objects.prefetch(models.AbuseReport.user)

    page_obj = Paginator(page, objects.count(), per_page=100, endpoint=request.endpoint, view_args=args)
    abuse_reports = page_obj.slice_or_404(objects)

    # Предзагружаем таргеты (prefetch для них не вызвать, к сожалению)
    stories = {}
    story_ids = [x.target_id for x in abuse_reports if x.target_type == 'story']
    if story_ids:
        stories = {x.id: x for x in models.Story.select(lambda s: s.id in story_ids)}

    storycomments = {}
    storycomment_ids = [x.target_id for x in abuse_reports if x.target_type == 'storycomment']
    if storycomment_ids:
        storycomments = {x.id: x for x in models.StoryComment.select(lambda s: s.id in storycomment_ids).prefetch(models.StoryComment.story, models.StoryComment.author)}

    newscomments = {}
    newscomment_ids = [x.target_id for x in abuse_reports if x.target_type == 'newscomment']
    if storycomment_ids:
        newscomments = {x.id: x for x in models.NewsComment.select(lambda s: s.id in newscomment_ids).prefetch(models.NewsComment.newsitem, models.NewsComment.author)}

    return render_template(
        'admin/abuse_reports/index.html',
        page_title='Жалобы',
        abuse_reports=abuse_reports,
        stories=stories,
        storycomments=storycomments,
        newscomments=newscomments,
        page_obj=page_obj,
        endpoint=request.endpoint,
        args=args,
    )
Пример #34
0
def index(page):
    objects = models.AbuseReport.select().order_by(
        models.AbuseReport.id.desc())

    args = {
        'page': page,
    }

    target_type = request.args.get('target_type')
    if target_type:
        args['target_type'] = target_type
        objects = objects.filter(lambda x: x.target_type == target_type)
        if request.args.get('target_id'):
            try:
                target_id = int(request.args['target_id'])
            except ValueError:
                pass
            else:
                args['target_id'] = target_id
                objects = objects.filter(lambda x: x.target_id == target_id)

    if request.args.get('username'):
        args['username'] = request.args['username']
        user_ids = list(
            select(x.id for x in models.Author
                   if args['username'].lower() in x.username.lower()))
        objects = objects.filter(lambda x: x.user.id in user_ids)

    if request.args.get('status') == 'none':
        args['status'] = 'none'
        objects = objects.filter(
            lambda x: not x.ignored and x.resolved_at is None)
    elif request.args.get('status') == 'accepted':
        args['status'] = 'accepted'
        objects = objects.filter(lambda x: not x.ignored and x.resolved_at is
                                 not None and x.accepted)
    elif request.args.get('status') == 'rejected':
        args['status'] = 'rejected'
        objects = objects.filter(lambda x: not x.ignored and x.resolved_at is
                                 not None and not x.accepted)
    elif request.args.get('status') == 'ignored':
        args['status'] = 'ignored'
        objects = objects.filter(lambda x: x.ignored)

    objects = objects.prefetch(models.AbuseReport.user)

    page_obj = Paginator(page,
                         objects.count(),
                         per_page=100,
                         endpoint=request.endpoint,
                         view_args=args)
    abuse_reports = page_obj.slice_or_404(objects)

    # Предзагружаем таргеты (prefetch для них не вызвать, к сожалению)
    stories = {}
    story_ids = [
        x.target_id for x in abuse_reports if x.target_type == 'story'
    ]
    if story_ids:
        stories = {
            x.id: x
            for x in models.Story.select(lambda s: s.id in story_ids)
        }

    storycomments = {}
    storycomment_ids = [
        x.target_id for x in abuse_reports if x.target_type == 'storycomment'
    ]
    if storycomment_ids:
        storycomments = {
            x.id: x
            for x in models.StoryComment.select(
                lambda s: s.id in storycomment_ids).prefetch(
                    models.StoryComment.story, models.StoryComment.author)
        }

    newscomments = {}
    newscomment_ids = [
        x.target_id for x in abuse_reports if x.target_type == 'newscomment'
    ]
    if storycomment_ids:
        newscomments = {
            x.id: x
            for x in models.NewsComment.select(
                lambda s: s.id in newscomment_ids).prefetch(
                    models.NewsComment.newsitem, models.NewsComment.author)
        }

    return render_template(
        'admin/abuse_reports/index.html',
        page_title='Жалобы',
        abuse_reports=abuse_reports,
        stories=stories,
        storycomments=storycomments,
        newscomments=newscomments,
        page_obj=page_obj,
        endpoint=request.endpoint,
        args=args,
    )
Пример #35
0
def index(page):
    objects = Tag.select().order_by(Tag.iname)

    args = {
        'page': page,
        'sorting': request.args.get('sorting') or 'iname',
    }

    if request.args.get('name'):
        iname = normalize_tag(request.args['name'])
        args['name'] = iname
        objects = objects.filter(lambda x: iname in x.iname)

    if request.args.get('category'):
        if request.args['category'] == '0':
            args['category'] = '0'
            objects = objects.filter(lambda x: x.category is None)
        elif request.args['category'].isdigit():
            args['category'] = request.args['category']
            cat_id = int(request.args['category'])
            objects = objects.filter(lambda x: x.category.id == cat_id)

    if request.args.get('is_blacklisted') == '0':
        args['is_blacklisted'] = '0'
        objects = objects.filter(lambda x: not x.is_blacklisted)
    elif request.args.get('is_blacklisted') == '1':
        args['is_blacklisted'] = '1'
        objects = objects.filter(lambda x: x.is_blacklisted)

    if request.args.get('is_alias') == '0':
        args['is_alias'] = '0'
        objects = objects.filter(lambda x: not x.is_alias)
    elif request.args.get('is_alias') == '1':
        args['is_alias'] = '1'
        objects = objects.filter(lambda x: x.is_alias)

    if request.args.get('is_main_tag') == '0':
        args['is_main_tag'] = '0'
        objects = objects.filter(lambda x: not x.is_main_tag)
    elif request.args.get('is_main_tag') == '1':
        args['is_main_tag'] = '1'
        objects = objects.filter(lambda x: x.is_main_tag)

    objects = objects.prefetch(Tag.is_alias_for, Tag.created_by, Tag.category)

    objects = admin_sort(args['sorting'], objects, {
        'iname': Tag.iname,
        'created_at': (Tag.created_at, Tag.id),
        'stories_count': (Tag.stories_count, Tag.id),
    }, default='iname')

    page_obj = Paginator(page, objects.count(), per_page=100, endpoint=request.endpoint, view_args=args)

    return render_template(
        'admin/tags/index.html',
        tags=page_obj.slice_or_404(objects),
        page_obj=page_obj,
        page_title=gettext('Tags'),
        endpoint=request.endpoint,
        args=args,
        tag_categories=list(TagCategory.select().order_by(TagCategory.id)),
    )
Пример #36
0
def index(page):
    objects = Tag.select().order_by(Tag.iname)

    args = {
        'page': page,
        'sorting': request.args.get('sorting') or 'iname',
    }

    if request.args.get('name'):
        iname = normalize_tag(request.args['name'])
        args['name'] = iname
        objects = objects.filter(lambda x: iname in x.iname)

    if request.args.get('category'):
        if request.args['category'] == '0':
            args['category'] = '0'
            objects = objects.filter(lambda x: x.category is None)
        elif request.args['category'].isdigit():
            args['category'] = request.args['category']
            cat_id = int(request.args['category'])
            objects = objects.filter(lambda x: x.category.id == cat_id)

    if request.args.get('is_blacklisted') == '0':
        args['is_blacklisted'] = '0'
        objects = objects.filter(lambda x: not x.is_blacklisted)
    elif request.args.get('is_blacklisted') == '1':
        args['is_blacklisted'] = '1'
        objects = objects.filter(lambda x: x.is_blacklisted)

    if request.args.get('is_alias') == '0':
        args['is_alias'] = '0'
        objects = objects.filter(lambda x: not x.is_alias)
    elif request.args.get('is_alias') == '1':
        args['is_alias'] = '1'
        objects = objects.filter(lambda x: x.is_alias)

    if request.args.get('is_main_tag') == '0':
        args['is_main_tag'] = '0'
        objects = objects.filter(lambda x: not x.is_main_tag)
    elif request.args.get('is_main_tag') == '1':
        args['is_main_tag'] = '1'
        objects = objects.filter(lambda x: x.is_main_tag)

    objects = objects.prefetch(Tag.is_alias_for, Tag.created_by, Tag.category)

    objects = admin_sort(args['sorting'],
                         objects, {
                             'iname': Tag.iname,
                             'created_at': (Tag.created_at, Tag.id),
                             'stories_count': (Tag.stories_count, Tag.id),
                         },
                         default='iname')

    page_obj = Paginator(page,
                         objects.count(),
                         per_page=100,
                         endpoint=request.endpoint,
                         view_args=args)

    return render_template(
        'admin/tags/index.html',
        tags=page_obj.slice_or_404(objects),
        page_obj=page_obj,
        page_title=gettext('Tags'),
        endpoint=request.endpoint,
        args=args,
        tag_categories=list(TagCategory.select().order_by(TagCategory.id)),
    )
Пример #37
0
def info(user_id=None, comments_page=1):
    if user_id is not None:
        try:
            user_id = int(user_id)
        except ValueError:
            abort(404)

    data = {}

    if user_id is None:
        if not current_user.is_authenticated:
            abort(403)
        author = current_user._get_current_object()
        comments_list = StoryComment.bl.select_by_story_author(author)
        comments_list = comments_list.order_by(StoryComment.id.desc())
        stories = list(author.stories)
        stories.sort(key=lambda x: x.first_published_at or x.date, reverse=True)
        contributing_stories = list(author.contributing_stories)
        contributing_stories.sort(key=lambda x: x.first_published_at or x.date, reverse=True)

        data['all_views'] = Story.bl.get_all_views_for_author(author)

        data['page_title'] = gettext('My cabinet')
        template = 'author_dashboard.html'
    else:
        author = Author.get(id=user_id)
        if not author:
            abort(404)
        author_id = author.id  # обход утечки памяти
        comments_list = StoryComment.select(lambda x: x.author.id == author_id and not x.deleted and x.story_published)
        comments_list = comments_list.order_by(StoryComment.id.desc())
        data['page_title'] = gettext('Author: {author}').format(author=author.username)
        stories = list(Story.bl.select_by_author(author, for_user=current_user))
        stories.sort(key=lambda x: x.first_published_at or x.date, reverse=True)
        contributing_stories = None
        template = 'author_overview.html'

    comments_count = comments_list.count()
    series = list(author.series)
    paged = Paginator(
        number=comments_page,
        total=comments_count,
        per_page=current_app.config['COMMENTS_COUNT']['author_page'],
        page_arg_name='comments_page',
    )  # TODO: restore orphans?
    comments = paged.slice(comments_list)
    if not comments and comments_page != 1:
        abort(404)

    data.update({
        'author': author,
        'is_system_user': author.id == current_app.config['SYSTEM_USER_ID'],
        'sub': author.bl.get_stories_subscription(current_user._get_current_object()),
        'stories': stories,
        'contributing_stories': contributing_stories,
        'series': series,
        'comments': comments,
        'comments_count': comments_count,
        'comments_short': True,
        'page_obj': paged,
    })

    story_ids = set(x.id for x in stories)
    if contributing_stories:
        story_ids |= set(x.id for x in contributing_stories)
    story_ids |= set(x.story.id for x in comments)

    data.update(cached_lists(story_ids))

    return render_template(template, **data)