Saddle/saddle.py

119 lines
3.1 KiB
Python
Raw Normal View History

2019-10-01 23:06:51 -04:00
#!/usr/bin/env python3
"""
A file hosting service similar to Pomf and Uguu but without the public nature.
"""
2019-10-02 18:44:06 -04:00
import os
import string
import random
2019-10-02 19:47:27 -04:00
import datetime
2019-10-02 18:44:06 -04:00
2019-10-01 23:06:51 -04:00
from aiohttp import web
import jinja2
import aiohttp_jinja2
from aiohttp_jinja2 import render_template
import asyncpg
import uvloop
import config
import buckler_aiohttp
uvloop.install()
routes = web.RouteTableDef()
@routes.get('/', name='index')
2019-10-02 18:44:06 -04:00
@routes.post('/', name='index')
2019-10-01 23:06:51 -04:00
async def index(request):
"""The index page."""
2019-10-02 18:44:06 -04:00
if request.method == 'GET':
return render_template("index.html", request, locals())
data = await request.post()
2019-10-02 19:47:27 -04:00
rand_name = bool(data.get('rand_name'))
2019-10-02 18:44:06 -04:00
files = []
for filefield in data.getall('files'):
2019-10-02 19:47:27 -04:00
files.append(handle_filefield(filefield, rand_name=rand_name))
if data.get('delete_this'):
delete_num = data.get('delete_num', '')
delete_type = data.get('delete_type', '')
try:
delete_num = int(delete_num)
assert delete_num >= 1 and delete_num <= 59
assert delete_type in ['minutes', 'hours', 'days', 'weeks']
except (ValueError, AssertionError):
return 'ur ghey' # TODO: return error
delta = datetime.timedelta(**{delete_type: delete_num})
expiration_date = datetime.datetime.now() + delta
else:
expiration_date = None
2019-10-02 18:44:06 -04:00
files_insert = []
for file in files:
2019-10-02 19:47:27 -04:00
t = (int(request.cookies.get('userid')), file[0], file[1], expiration_date)
files_insert.append(t)
2019-10-02 18:44:06 -04:00
async with request.app['pool'] as conn:
await conn.executemany(
"INSERT INTO upload (user_id, id, filename, expiration_date) "
"VALUES ($1, $2, $3, $4)",
files_insert)
urls = [config.upload_url + f[1] for f in files]
return render_template("result.html", request, locals())
def handle_filefield(filefield, rand_name=True):
"""Handles a posted file."""
filename = safe_filename(filefield.filename)
if not filename:
rand_name = True
prefix = get_rand_chars()
if rand_name:
filename = prefix + os.path.splitext(filename)[1]
else:
filename = prefix + '_' + filename
with open(os.path.join(config.upload_dir, filename), 'wb') as file:
file.write(filefield.file.read())
t = (prefix, filename)
return t
def safe_filename(filename=''):
"""Sanitizes the given filename."""
safe_char = string.ascii_letters + string.digits + '._ '
filename = ''.join([c for c in filename if c in safe_char])
filename = filename.strip('._ ')
return filename
def get_rand_chars(n=8):
"""Returns `n` number of random ASCII characters."""
chars = []
for _ in range(n):
char = random.choice(string.ascii_letters + string.digits)
chars.append(char)
return "".join(chars)
2019-10-01 23:06:51 -04:00
async def init_app():
"""Initializes the application."""
#app = web.Application(middlewares=[buckler_aiohttp.buckler_session])
app = web.Application()
aiohttp_jinja2.setup(app, loader=jinja2.FileSystemLoader('templates'))
app['pool'] = await asyncpg.create_pool(**config.db)
async with app['pool'].acquire() as conn:
with open('saddle.sql', 'r') as file:
await conn.execute(file.read())
app.router.add_routes(routes)
app_wrap = web.Application()
app_wrap.add_subapp(config.url_prefix, app)
return app_wrap
if __name__ == "__main__":
app = init_app()
web.run_app(app, host='0.0.0.0', port=5000)