upload from url

This commit is contained in:
iou1name 2019-10-06 17:01:46 -04:00
parent 793c3c8646
commit 3c088027c0
3 changed files with 66 additions and 4 deletions

View File

@ -4,7 +4,7 @@ A file hosting service similar to Pomf and Uguu but without the public nature.
## Requirements ## Requirements
Python 3.7+ Python 3.7+
PostgreSQL 11.5+ PostgreSQL 11.5+
Python packages: `wheel gunicorn aiohttp aiohttp_jinja2 asyncpg uvloop` Python packages: `wheel gunicorn aiohttp aiohttp_jinja2 asyncpg uvloop requests`
## Install ## Install
``` ```

View File

@ -3,6 +3,7 @@
A file hosting service similar to Pomf and Uguu but without the public nature. A file hosting service similar to Pomf and Uguu but without the public nature.
""" """
import os import os
import time
import string import string
import random import random
import datetime import datetime
@ -13,6 +14,7 @@ import aiohttp_jinja2
from aiohttp_jinja2 import render_template from aiohttp_jinja2 import render_template
import asyncpg import asyncpg
import uvloop import uvloop
import requests
import config import config
import buckler_aiohttp import buckler_aiohttp
@ -29,9 +31,15 @@ async def index(request):
return render_template("index.html", request, locals()) return render_template("index.html", request, locals())
data = await request.post() data = await request.post()
rand_name = bool(data.get('rand_name')) rand_name = bool(data.get('rand_name'))
files = [] files = []
for filefield in data.getall('files'): for filefield in data.getall('files'):
if not filefield:
continue
files.append(handle_filefield(filefield, rand_name=rand_name)) files.append(handle_filefield(filefield, rand_name=rand_name))
if data.get('url'):
files.append(handle_url(data.get('url'), rand_name=rand_name))
if data.get('delete_this'): if data.get('delete_this'):
delete_num = data.get('delete_num', '') delete_num = data.get('delete_num', '')
delete_type = data.get('delete_type', '') delete_type = data.get('delete_type', '')
@ -74,8 +82,31 @@ def handle_filefield(filefield, rand_name=True):
with open(os.path.join(config.upload_dir, filename), 'wb') as file: with open(os.path.join(config.upload_dir, filename), 'wb') as file:
file.write(filefield.file.read()) file.write(filefield.file.read())
t = (prefix, filename) tup = (prefix, filename)
return t return tup
def handle_url(url, rand_name=True):
"""Handles a posted URL."""
try:
filename, data = download_file(url)
except ValueError:
return None
filename = safe_filename(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(data)
tup = (prefix, filename)
return tup
def safe_filename(filename=''): def safe_filename(filename=''):
@ -95,6 +126,36 @@ def get_rand_chars(n=8):
return "".join(chars) return "".join(chars)
def download_file(url, timeout=10, max_file_size=config.client_max_size):
"""
Downloads the file at the given url while observing file size and
timeout limitations.
"""
requests_kwargs = {
'stream': True,
'headers': {'User-Agent': "Steelbea.me LTD needs YOUR files."},
'timeout': timeout,
'verify': True
}
temp = b''
with requests.get(url, **requests_kwargs) as r:
size = 0
start_time = time.time()
for chunk in r.iter_content(102400):
if time.time() - start_time > timeout:
raise ValueError('timeout reached')
if len(temp) > max_file_size:
raise ValueError('response too large')
temp += chunk
if r.headers.get('Content-Disposition'):
fname = re.search(r'filename="(.+)"',
r.headers['content-disposition'])
else:
fname = os.path.basename(url)
return (fname, temp)
async def init_app(): async def init_app():
"""Initializes the application.""" """Initializes the application."""
#app = web.Application(middlewares=[buckler_aiohttp.buckler_session]) #app = web.Application(middlewares=[buckler_aiohttp.buckler_session])
@ -108,7 +169,7 @@ async def init_app():
app.router.add_routes(routes) app.router.add_routes(routes)
app_wrap = web.Application() app_wrap = web.Application(client_max_size=config.client_max_size)
app_wrap.add_subapp(config.url_prefix, app) app_wrap.add_subapp(config.url_prefix, app)
return app_wrap return app_wrap

View File

@ -14,6 +14,7 @@
<section> <section>
<form method="POST" enctype="multipart/form-data"> <form method="POST" enctype="multipart/form-data">
<input type="file" name="files" multiple><br> <input type="file" name="files" multiple><br>
<input type="url" name="url" placeholder="URL"><br>
<input type="checkbox" name="rand_name" id="rand_name" checked> <input type="checkbox" name="rand_name" id="rand_name" checked>
<label for="rand_name">Generate random filename.</label><br> <label for="rand_name">Generate random filename.</label><br>
<input type="hidden" name="reponse_type" value="html"> <input type="hidden" name="reponse_type" value="html">