def token_create(): if request.mimetype == '': return ({'code': 400, 'msg': 'missing content type'}, 400, {'Accept': 'application/json,application/x-www-form-urlencoded,text/plain'}) if request.is_json: name = str(request.json.get('name', '')) elif request.mimetype == 'application/x-www-form-urlencoded': name = request.form.get('name', default='', type=str) elif request.mimetype == 'text/plain': name = request.data.decode().strip() else: return ({'code': 415, 'msg': 'unsupported content type'}, 415, {'Accept': 'application/json,application/x-www-form-urlencoded,text/plain'}) charset = request.mimetype_params.get('charset', 'utf-8') if charset != 'utf-8': name = name.encode(charset).decode() if len(name) == 0: return ({'code': 400, 'msg': 'missing token name'}, 400) else: token = generate_token() user_id = request.authorization['user_id'] user_ip = request.remote_addr db = get_db() result = db.execute('SELECT id FROM user WHERE name = ?', (name,)).fetchone() if result: return ({'code': 409, 'msg': 'token name already in use'}, 409) else: db.execute('INSERT INTO user (name,token,ip,created_by) VALUES (?, ?, ?, ?)', (name, token, user_ip, user_id,)) db.commit() return {'token': token}
def tipp_update(id): if request.mimetype == '': return ({'code': 400, 'msg': 'missing content type'}, 400, {'Accept': 'application/json,application/x-www-form-urlencoded,text/plain'}) if request.is_json: content = str(request.json.get('content', '')) template = str(request.json.get('template', 'default')) elif request.mimetype == 'application/x-www-form-urlencoded': content = request.form.get('content', default='', type=str) template = request.form.get('template', default='default', type=str) elif request.mimetype == 'text/plain': content = request.data.decode().strip() template = 'default' else: return ({'code': 415, 'msg': 'unsupported content type'}, 415, {'Accept': 'application/json,application/x-www-form-urlencoded,text/plain'}) charset = request.mimetype_params.get('charset', 'utf-8') if charset != 'utf-8': content = content.encode(charset).decode() template = template.encode(charset).decode() if len(content.strip()) == 0: return ({'code': 400, 'msg': 'content may not be empty'}, 400) timestamp = update_tipp(id, content, template=template) db = get_db() db.execute('UPDATE tipp SET compiled = ?, template = ? WHERE id = ?', (timestamp, template, id,)) db.commit() return ({ 'id': id, 'compiled': timestamp, 'template': template }, 200)
def recompile_command(): click.echo('Recompiling all known tipps. This might take a while!') db = get_db() result = db.execute('SELECT id,template FROM tipp').fetchall() for tipp in result: compile_tipp(tipp['id'], template=tipp['template']) click.echo(f'Compiled tipp {tipp["id"]}.') click.echo('Done compiling.')
def tipp_delete(id): db = get_db() result = db.execute('SELECT user_id FROM tipp WHERE id = ?', (id,)).fetchone() if not result: return({'code': 404, 'msg': f'unknown id'}, 404) if result['user_id'] != request.authorization['user_id']: return({'code': 403, 'msg': f'tipp owned by other token'}, 403) db.execute('DELETE FROM tipp WHERE id = ? AND user_id = ?', (id, request.authorization['user_id'],)) db.commit() return ('', 204)
def authenticate(*args, **kwargs): if 'Authorization' in request.headers and request.headers['Authorization'].startswith('Bearer'): token = request.headers['Authorization'][7:].strip() db = get_db() user_id = db.execute('SELECT id FROM user WHERE token = ?', (token,)).fetchone() if user_id: request.authorization = {'type': 'bearer', 'user_id': user_id['id'], 'token': token} return func(*args, **kwargs) return ({'code': 401, 'msg': 'authentication failed'}, 401)
def delete_command(id): db = get_db() db.execute('DELETE FROM tipp WHERE id = ?', (id, )) db.commit() raw_path = Path(current_app.config['RAWPATH']) / f'{id}.md' if raw_path.is_file(): raw_path.unlink() page_path = Path(current_app.config['PAGEPATH']) / f'{id}.html' if page_path.is_file(): page_path.unlink() click.echo(f'Tipp {id} deleted.')
def create(): if request.method == 'POST': content = request.form.get('content', default='', type=str) token = request.form.get('token', default='', type=str) template = request.form.get('template', default='default', type=str) if len(content.strip()) == 0 or len(token.strip()) == 0: return render_template( 'input.html', form={ 'type': 'create', 'token': token, 'templates': get_templates(), 'error': 'Inhalt und Token dürfen nicht leer sein.' }, tipp={ 'content': content, 'template': template }) db = get_db() user_id = db.execute('SELECT id FROM user WHERE token = ?', (token, )).fetchone() if not user_id: return render_template('input.html', form={ 'type': 'create', 'token': token, 'templates': get_templates(), 'error': 'Kein gültiges Token.' }, tipp={ 'content': content, 'template': template }) id = create_tipp(content, template=template) db.execute('INSERT INTO tipp (id,user_id,template) VALUES (?, ?, ?)', ( id, user_id['id'], template, )) db.commit() return redirect(url_for('web.show_tipp', id=id), 303) else: return render_template('input.html', form={ 'type': 'create', 'templates': get_templates() }, tipp={})
def list_tipps(token=None): details = request.args.get('details', default=False, type=bool) sort = request.args.get('sort', default='created_desc', type=str).lower().split('_') if sort[0] == 'rand': sort[0] = 'RANDOM()' elif sort[0] not in ['created','compiled','id']: sort[0] = 'tipp.created' else: sort[0] = f'tipp.{sort[0]}' if len(sort) < 2: sort.append('asc') elif sort[1] not in ['asc', 'desc']: sort[1] = 'asc' sort = f'{sort[0]} {sort[1].upper()}' limit = request.args.get('limit', default=20, type=int) offset = request.args.get('offset', default=0, type=int) # filters filters = {} template = request.args.get('template', default=None) if template: filters['tipp.template'] = template if token: filters['user.token'] = token if len(filters) > 0: where = 'WHERE ' + ', '.join([f'{k} = ?' for k in filters.keys()]) else: where = '' db = get_db() result = db.execute(f'SELECT tipp.id,tipp.created,tipp.template FROM tipp INNER JOIN user ON user.id = tipp.user_id {where} ORDER BY {sort} LIMIT {limit} OFFSET {offset}', tuple(filters.values())).fetchall() tipps = [] if not details: for row in result: tipps.append(row['id']) else: for row in result: tipps.append({ 'id': row['id'], 'url': get_tipp_url(row["id"]), 'qrurl': get_qr_url(row["id"]), 'created': row['created'], 'template': row['template'] }) return {'tipps': tipps}
def tipp_compile(id): db = get_db() result = db.execute('SELECT template FROM tipp WHERE id = ?', (id,)).fetchone() if result: # TODO: allow form-date / plaintext here? template = str(request.json.get('template', result['template'])) timestamp = compile_tipp(id, template=template) db.execute('UPDATE tipp SET compiled = ?, template = ? WHERE id = ?', (timestamp, template, id,)) db.commit() return { 'id': id, 'compiled': timestamp, 'template': template } else: return ({'code': 400, 'msg': 'unknown id'}, 400)
def maintenance_command(): db = get_db() raw_path = Path(current_app.config['RAWPATH']) for raw in raw_path.glob('*.md'): result = db.execute('SELECT template FROM tipp WHERE id = ?', (raw.stem, )).fetchone() if not result: db.execute('INSERT INTO tipp (id,user_id) VALUES (?, 1)', (raw.stem, )) result = {'template': 'default'} click.echo(f'Added tipp {raw.stem} to database.') page_path = Path(current_app.config['PAGEPATH']) / f'{id}.html' if not page_path.is_file(): compile_tipp(id, template=result['template']) click.echo(f'Compiled tipp {raw.stem}.') db.commit() click.echo('Done!')
def list(): token = 'webfij23h87revb03fbre' db = get_db() result = db.execute( f'SELECT tipp.id,tipp.created,tipp.template FROM tipp INNER JOIN user ON user.id = tipp.user_id WHERE user.token = "{token}" ORDER BY tipp.created DESC' ).fetchall() tipps = [] for row in result: tipps.append({ 'id': row['id'], 'url': get_tipp_url(row["id"]), 'qrurl': get_qr_url(row["id"]), 'created': row['created'], 'template': row['template'] }) return render_template('list.html', tipps=tipps)
def tipp_details(id): db = get_db() result = db.execute('SELECT * FROM tipp WHERE id = ?', (id,)).fetchone() if result: tipp = { 'id': id, 'created': result['created'], 'compiled': result['compiled'], 'template': result['template'], 'url': get_tipp_url(id), 'qrurl': get_qr_url(id), 'content': '' } raw_path = Path(current_app.config['RAWPATH']) / f'{id}.md' if raw_path.is_file(): tipp['content'] = raw_path.read_text() return tipp else: return ({'error': 404, 'msg': f'unknown id'}, 404)
def tipp_create(): if request.mimetype == '': return ({'code': 400, 'msg': 'missing content type'}, 400, {'Accept': 'application/json,application/x-www-form-urlencoded,text/plain'}) if request.is_json: content = str(request.json.get('content', '')) template = str(request.json.get('template', 'default')) elif request.mimetype == 'application/x-www-form-urlencoded': content = request.form.get('content', default='', type=str) template = request.form.get('template', default='default', type=str) elif request.mimetype == 'text/plain': content = request.data.decode().strip() template = 'default' else: return ({'code': 415, 'msg': 'unsupported content type'}, 415, {'Accept': 'application/json,application/x-www-form-urlencoded,text/plain'}) charset = request.mimetype_params.get('charset', 'utf-8') if charset != 'utf-8': content = content.encode(charset).decode() template = template.encode(charset).decode() if len(content.strip()) == 0: return ({'code': 400, 'msg': 'content may not be empty'}, 400) id = create_tipp(content, template=template) db = get_db() db.execute('INSERT INTO tipp (id,user_id,template) VALUES (?, ?, ?)', (id, request.authorization['user_id'], template,)) db.commit() return ({ 'id': id, 'created': datetime.now(), 'compiled': datetime.now(), 'template': template, 'url': get_tipp_url(id), 'qrurl': get_qr_url(id), 'content': content }, 201)
def edit(id): if request.method == 'POST': content = request.form.get('content', default='', type=str) token = request.form.get('token', default='', type=str) template = request.form.get('template', default='default', type=str) if len(content.strip()) == 0 or len(token.strip()) == 0: return render_template( 'input.html', form={ 'type': 'create', 'token': token, 'templates': get_templates(), 'error': 'Inhalt und Token dürfen nicht leer sein.' }, tipp={ 'content': content, 'template': template }) db = get_db() user_id = db.execute('SELECT id FROM user WHERE token = ?', (token, )).fetchone() if not user_id: return render_template('input.html', form={ 'type': 'create', 'token': token, 'templates': get_templates(), 'error': 'Kein gültiges Token.' }, tipp={ 'content': content, 'template': template }) timestamp = update_tipp(id, content, template=template) db.execute('UPDATE tipp SET compiled = ?, template = ? WHERE id = ?', ( timestamp, template, id, )) db.commit() return redirect(url_for('web.show_tipp', id=id), 303) else: token = 'webfij23h87revb03fbre' db = get_db() result = db.execute( 'SELECT tipp.* FROM tipp INNER JOIN user ON user.id = tipp.user_id WHERE tipp.id = ? AND user.token = ?', ( id, token, )).fetchone() form = {'type': 'edit', 'token': token, 'templates': get_templates()} tipp = dict(result) if result: tipp['content'] = get_tipp_content(id) else: tipp['content'] = '' tipp['template'] = 'default' form['error'] = 'Kein Tipp mit der angegebenen ID gefunden.' return render_template('input.html', form=form, tipp=tipp)