summaryrefslogtreecommitdiffstats
path: root/app/views.py
blob: f81cfd492d963871f78040df4d81601f23464e43 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from io import BytesIO
from .request_routine import db_route
from sanic.response import text, redirect, json
from jinja2_sanic import render_template
from app import log, blure
from requests import get as fetch_url
from .imutil import NGXImage
from .util import URLDecodeError
from sanic.exceptions import NotFound, InvalidUsage as BadRequest


async def is_image_exists(pg, id: int):
    rec = await pg.fetchval('SELECT 1 FROM pics WHERE id=$1', id)
    return rec is not None


@blure.exception(NotFound)
async def not_found(req, exc):
    return render_template('404.html.j2', req, dict())


@db_route('/')
async def index(ctx):
    records = await ctx.pg.fetch('SELECT id FROM pics')
    picurls = [ctx.app.url.to_url(rec['id']) for rec in records]
    return render_template('index.html.j2', ctx.r, dict(picurls=picurls))


@db_route('/i/<url>')
async def raw_image(ctx, url):
    try:
        id = ctx.app.url.to_id(url)
    except URLDecodeError as err:
        log.warn(f'URL not decoded: {err}')
        return NGXImage.not_found()

    if not await is_image_exists(ctx.pg, id):
        log.error('Image not in db')
        return NGXImage.not_found()

    return NGXImage(id).orig()


@db_route('/t/<url>')
async def thumb_image(ctx, url):
    try:
        id = ctx.app.url.to_id(url)
    except URLDecodeError:
        return NGXImage.not_found()

    if not await is_image_exists(ctx.pg, id):
        log.error('Image not in db')
        return NGXImage.not_found()

    return NGXImage(id).thumb()


@db_route('/p/<url>')
async def pic_profile(ctx, url):
    log.warn(url)
    try:
        id = ctx.app.url.to_id(url)
        if await is_image_exists(ctx.pg, id):
            return render_template('profile.html.j2',
                                   ctx.r,
                                   dict(url=url, tags=[]))
        else:
            raise NotFound('Url not found')
    except URLDecodeError:
        raise NotFound('Invalid url')


@db_route('/c/push', methods=['POST'])
async def pic_push(ctx):
    try:
        file = ctx.r.files['im'][0]
        image_stream = BytesIO(file.body)
        ext = file.name.split('.')[-1]

        if len(ctx.r.form['content-type']) != 1:
            raise BadRequest('Need only one content-type')

        content_type = ctx.r.form['content-type'][0]

        id = await ctx.pg.fetchval(
            '''
            INSERT INTO pics(src_url, content_type)
            VALUES ($1, $2)
            RETURNING id
            ''',
            '',
            ext
        )

        im = NGXImage(id)
        im.save(image_stream, content_type)

        return text('new url is ' + ctx.app.url.to_url(id))
    except KeyError:
        return text('you did not post anything')


@db_route('/c/push_url', methods=['POST'])
async def push_url(ctx):
    return redirect(ctx.app.url_for('index'))
    return json({'err': 'not_implemented'})
    response = fetch_url(ctx.r.json['url'])
    if response is None:
        return json({'err': 'fetch'})


@db_route('/c/delete/<url>', methods=['POST'])
async def delete_pic(ctx, url):
    id = ctx.app.url.to_id(url)
    await ctx.pg.execute('DELETE FROM pics WHERE id=$1', id)
    im = NGXImage(id)
    im.delete_from_disk()
    return redirect(ctx.app.url_for('index'))