Ejemplo n.º 1
0
async def list_posts(request):
    limit = int(request.args.get('limit')) or PER_PAGE
    page = int(request.args.get('page')) or 1
    special_id = int(request.args.get('special_id') or 0)
    offset = (page - 1) * limit
    _posts = await Post.filter().order_by('-id').offset(offset).limit(limit)
    total = await Post.filter().count()
    posts = []
    exclude_ids = []
    if special_id:
        topic = await SpecialTopic.cache(special_id)
        if topic:
            items = await topic.get_items()
            exclude_ids = [s.post_id for s in items]
        total -= len(exclude_ids)
    for post in _posts:
        dct = post.to_dict()
        if post.id in exclude_ids:
            continue
        if limit < 100:
            author = await post.author
            dct['author_name'] = author.name
            tags = await post.tags
            dct['tags'] = [t.name for t in tags]
        posts.append(dct)
    return json({'items': posts, 'total': total})
Ejemplo n.º 2
0
async def topic(request, topic_id):
    if request.method == 'PUT':
        return await _topic(request, topic_id=topic_id)
    topic = await SpecialTopic.get_or_404(topic_id)
    topic = await topic.to_sync_dict()
    topic['status'] = str(topic['status'])
    return json(topic)
Ejemplo n.º 3
0
Archivo: admin.py Proyecto: ihyf/blog
async def upload(request):
    try:
        file = request.files['avatar'][0]
        is_avatar = True
    except KeyError:
        file = request.files['file'][0]
        is_avatar = False
    suffix = file.name.split(".")[-1]
    fid = generate_id()
    filename = f'{fid}.{suffix}'
    uploaded_file = Path(UPLOAD_FOLDER) / filename
    with open(uploaded_file, 'wb') as f:
        f.write(file.body)

    mime, _ = mimetypes.guess_type(str(uploaded_file))
    encoded = b''.join(base64.encodestring(file.body).splitlines()).decode()

    dct: Dict[str, Union[Dict, int, str]]

    if is_avatar:
        dct = {
            'files': {
                'avatar': f'data:{mime};base64,{encoded}', 'avatar_path': filename
            }
        }
    else:
        if USE_FFMPEG and suffix == 'mp4':
            subprocess.call(
                f'ffmpeg -loglevel error -y -i {uploaded_file} -qscale:v 1 -qmin 1 -qmax 1 -frames:v 1 {Path(UPLOAD_FOLDER) / fid}.png', shell=True)  # noqa

        dct = {'r': 0, 'filename': filename}

    return json(dct)
Ejemplo n.º 4
0
async def _post(request, post_id=None):
    form = PostForm(request)
    form.status.data = int(form.status.data)

    post = None
    if post_id is not None:
        post = await Post.get_or_404(post_id)

    if request.method in ('POST', 'PUT') and form.validate():
        title = form.title.data
        assert str(form.author_id.data).isdigit()
        if post_id is None:
            post = await Post.filter(title=title).first()
        if not post:
            post = Post()
        tags = form.tags.data
        content = form.content.data
        is_page = form.is_page.data
        del form.tags
        del form.content
        del form.is_page
        form.populate_obj(post)
        post.type = Post.TYPE_PAGE if is_page else Post.TYPE_ARTICLE
        await post.save()
        await post.update_tags(tags)
        await post.set_content(content)
        ok = True
    else:
        ok = False
    post = await post.to_sync_dict()
    post['tags'] = [t.name for t in post['tags']]
    return json({'post': post if post else None, 'ok': ok})
Ejemplo n.º 5
0
Archivo: j.py Proyecto: r4b3rt/lyanna
async def target_react(request, user, target):
    reaction_type = int(request.form.get('reaction_type', ReactItem.K_LOVE))
    if reaction_type not in (ReactItem.K_LOVE, ReactItem.K_UPVOTE):
        return json({'r': 1, 'msg': 'Not supported reaction_type'})

    if request.method == 'POST':
        rv = await target.add_reaction(user['gid'], reaction_type)
    elif request.method == 'DELETE':
        rv = await target.cancel_reaction(user['gid'], reaction_type)

    n_reacted = 0
    if reaction_type == ReactItem.K_LOVE:
        n_reacted = await target.n_likes
    elif reaction_type == ReactItem.K_UPVOTE:
        n_reacted = await target.n_upvotes

    return json({'r': int(not rv), 'n_reacted': n_reacted})
Ejemplo n.º 6
0
Archivo: j.py Proyecto: r4b3rt/lyanna
def login_required(f: Callable) -> Callable:
    async def wrapped(request, **kwargs):
        if not (user := request.ctx.session.get('user')):
            return json({'r': 403, 'msg': 'Login required.'})
            user = {'gid': 841395}  # My Github id
        if (target_id := kwargs.pop('target_id', None)) is not None:
            target_kind = kwargs.pop('target_kind', 'post')
            if target_kind == 'post':
                kls = Post
            elif target_kind == 'activity':
                kls = Activity
            elif target_kind == 'comment':
                kls = Comment
            else:
                return json({'r': 403, 'msg': 'Not support'})
            if not (target := await kls.cache(target_id)):
                return json({'r': 1, 'msg': f'{kls.__class__.__name__} not exist'})
Ejemplo n.º 7
0
async def user(request, user_id):
    if request.method == 'PUT':
        return await _user(request, user_id=user_id)
    user = await User.get_or_404(user_id)
    user = await user.to_sync_dict()
    avatar = user.avatar
    user['avatar_url'] = (
        request.app.url_for('static', filename=f'upload/{avatar}')  # noqa
        if avatar else '')
    return json(user)
Ejemplo n.º 8
0
async def post(request, post_id):
    if request.method == 'PUT':
        return await _post(request, post_id=post_id)
    post = await Post.get_or_404(post_id)
    rv = await post.to_sync_dict()
    rv['tags'] = [t.name for t in rv['tags']]
    author = rv['author']
    rv['status'] = str(rv['status'])
    rv['author'] = {'id': author.id, 'name': author.name}
    return json(rv)
Ejemplo n.º 9
0
Archivo: j.py Proyecto: r4b3rt/lyanna
async def react(request, user, post):
    if request.method == 'POST':
        reaction_type = request.form.get('reaction_type', None)
        if reaction_type is None:
            return json({'r': 1, 'msg': 'Reaction type error.'})
        rv = await post.add_reaction(user['gid'], reaction_type)
    elif request.method == 'DELETE':
        rv = await post.cancel_reaction(user['gid'])

    stats = await post.stats
    reaction_type = None

    if user:
        reaction_type = await post.get_reaction_type(user['gid'])
    return json({'r': int(not rv),
                 'html': await render_template_def(
        'utils.html', 'render_react_container', request,
                      {'stats': stats, 'reaction_type': reaction_type})
                 })
Ejemplo n.º 10
0
async def list_posts(request):
    limit = int(request.args.get('limit')) or PER_PAGE
    page = int(request.args.get('page')) or 1
    offset = (page - 1) * limit
    _posts = await Post.sync_filter(limit=limit, offset=offset,
                                    orderings='-id')
    total = await Post.filter().count()
    posts = []
    for post in _posts:
        post['author_name'] = post['author'].name
        post['tags'] = [t.name for t in post['tags']]
        posts.append(post)
    return json({'items': posts, 'total': total})
Ejemplo n.º 11
0
async def post(request, post_id):
    if request.method == 'PUT':
        return await _post(request, post_id=post_id)

    post = await Post.get_or_404(id=post_id)
    if not post:
        return response.json({'r': 0, 'msg': 'Post not exist'})

    if request.method == 'DELETE':
        await post.delete()
        await PostTag.filter(Q(post_id=post_id)).delete()
        return response.json({'r': 1})

    rv = await post.to_sync_dict()
    rv['tags'] = [t.name for t in rv['tags']]
    author = rv['author']
    rv['status'] = str(rv['status'])
    rv['author'] = {'id': author.id, 'name': author.name}
    return json(rv)
Ejemplo n.º 12
0
async def _topic(request, topic_id=None):
    form = TopicForm(request)
    form.status.data = int(form.status.data)

    topic = None
    if topic_id is not None:
        topic = await SpecialTopic.get_or_404(topic_id)

    if request.method in ('POST', 'PUT') and form.validate():
        dct = defaultdict(dict)
        for k in copy.copy(request.form):
            if k.startswith('posts'):
                match = FORM_REGEX.search(k)
                if match:
                    key = match['key']
                    val = request.form[k][0]
                    dct[match['index']][key] = int(val) if key == 'id' else val
                    del request.form[k]

        title = form.title.data
        if topic_id is None:
            topic = await SpecialTopic.filter(title=title).first()
        if not topic:
            topic = SpecialTopic()

        form.populate_obj(topic)
        if dct:
            indexes = [
                (i['id'], int(index))
                for index, i in sorted(dct.items(), key=lambda i: i[0])
            ]
        else:
            indexes = []
        if topic_id is not None:
            await topic.set_indexes(indexes)
        await topic.save()
        if topic_id is None:
            await topic.set_indexes(indexes)
        ok = True
    else:
        ok = False
    topic = await topic.to_sync_dict()
    return json({'topic': topic if topic else None, 'ok': ok})
Ejemplo n.º 13
0
Archivo: j.py Proyecto: r4b3rt/lyanna
    ref_id = int(request.form.get('ref_id', 0))
    comment = await target.add_comment(user['gid'], content, ref_id, target.kind)
    comment = await comment.to_sync_dict()

    rv = {'r': 0 if comment else 1}
    if target.kind == K_POST:
        reacted_comments = await target.comments_reacted_by(user['gid'])
        rv.update({
            'html': await render_template_def(
                'utils.html', 'render_single_comment', request,
                {'comment': comment, 'github_user': user,
                 'reacted_comments': reacted_comments})
        })
    else:
        rv.update({'comment': comment})
    return json(rv)


@bp.route('/post/<post_id>/comments')
async def comments(request, post_id):
    if not (post := await Post.cache(post_id)):
        return json({'r': 1, 'msg': 'Post not exist'})

    page = int(request.args.get('page', 1))
    per_page = int(request.args.get('per_page', 20))

    start = (page - 1) * per_page
    comments = (await post.comments)[start: start + per_page]

    reacted_comments: List[List[int]] = []
    if (user := request.ctx.session.get('user')):
Ejemplo n.º 14
0
    if (special_id := int(request.args.get('special_id') or 0)):
        if (topic := await SpecialTopic.cache(special_id)):
            items = await topic.get_items()  # type: ignore
            exclude_ids = [s.post_id for s in items]
        total -= len(exclude_ids)
    for post in _posts:
        dct = post.to_dict()
        if post.id in exclude_ids:
            continue
        if with_tag:
            author = await post.author
            dct['author_name'] = author.name
            tags = await post.tags
            dct['tags'] = [t.name for t in tags]
        posts.append(dct)
    return json({'items': posts, 'total': total})


@bp.route('/api/post/new', methods=['POST'])
@protected(bp)
async def new_post(request: Request):
    return await _post(request)


async def _post(request: Request, post_id: Optional[Any] = None):
    form = PostForm(request)
    form.status.data = int(form.status.data)

    post = None
    if post_id is not None:
        post = await Post.get_or_404(post_id)
Ejemplo n.º 15
0
Archivo: j.py Proyecto: r4b3rt/lyanna
async def render_markdown(request, user):
    if not (text := request.form.get('text')):
        return json({'r': 1, 'msg': 'Text required.'})
Ejemplo n.º 16
0
Archivo: j.py Proyecto: r4b3rt/lyanna
async def comments(request, post_id):
    if not (post := await Post.cache(post_id)):
        return json({'r': 1, 'msg': 'Post not exist'})
Ejemplo n.º 17
0
Archivo: j.py Proyecto: r4b3rt/lyanna
async def create_comment(request, user, target):
    if not (content := request.form.get('content')):
        return json({'r': 1, 'msg': 'Content required.'})
Ejemplo n.º 18
0
Archivo: j.py Proyecto: r4b3rt/lyanna
async def activity_comments(request, activity_id):
    if not (activity := await Activity.cache(activity_id)):
        return json({'r': 1, 'msg': 'Activity not exist'})
Ejemplo n.º 19
0
Archivo: j.py Proyecto: r4b3rt/lyanna
 async def wrapped(request, **kwargs):
     if not (user := request.ctx.session.get('user')):
         return json({'r': 403, 'msg': 'Login required.'})
         user = {'gid': 841395}  # My Github id
Ejemplo n.º 20
0
async def list_users(request: Request) -> HTTPResponse:
    users = await User.sync_all()
    total = await User.filter().count()
    return json({'items': users, 'total': total})
Ejemplo n.º 21
0
async def list_topics(request: Request) -> HTTPResponse:
    topics = await SpecialTopic.sync_all()
    total = len(topics)
    return json({'items': topics, 'total': total})
Ejemplo n.º 22
0
Archivo: admin.py Proyecto: ihyf/blog
async def api_status(request):
    user_id = request.user.id
    obj, msg = await create_status(user_id, request.json)
    activity = None if not obj else await obj.to_full_dict()  # type: ignore
    return json({'r': not bool(obj), 'msg': msg, 'activity': activity})
Ejemplo n.º 23
0
Archivo: admin.py Proyecto: ihyf/blog
async def get_url_info(request):
    if not (url := request.json.get('url')):
        return json({'r': 403, 'msg': 'URL required'})
Ejemplo n.º 24
0
Archivo: admin.py Proyecto: ihyf/blog
    if (special_id := int(request.args.get('special_id') or 0)):
        if (topic := await SpecialTopic.cache(special_id)):
            items = await topic.get_items()  # type: ignore
            exclude_ids = [s.post_id for s in items]
        total -= len(exclude_ids)
    for post in _posts:
        dct = post.to_dict()
        if post.id in exclude_ids:
            continue
        if with_tag:
            author = await post.author
            dct['author_name'] = author.name
            tags = await post.tags
            dct['tags'] = [t.name for t in tags]
        posts.append(dct)
    return json({'items': posts, 'total': total})


@bp.route('/api/post/new', methods=['POST'])
@protected(bp)
async def new_post(request: Request):
    return await _post(request)


async def _post(request: Request, post_id: Optional[Any] = None):
    form = PostForm(request)
    form.status.data = int(form.status.data)

    post = None
    if post_id is not None:
        post = await Post.get_or_404(post_id)