diff --git a/landing.html b/landing.html new file mode 100644 index 0000000..2a0256f --- /dev/null +++ b/landing.html @@ -0,0 +1,49 @@ + + +
+ + +
+{name} File Upload and URL Shortener
+
+Welcome to the {name} file upload and URL shortening service.
+This service allows you to easily upload files or shorten URLs for quick access.
+Files are stored for {expiration_days} days, and URLs are shortened for convenient sharing.
+
+Usage:
+
+Upload a file:
+curl -F file=@yourfile.ext {base_url}/
+
+Shorten a URL:
+curl -d "url=https://example.com" {base_url}/shorten
+
+Details:
+
+Files uploaded to this service are stored for {expiration_days} days or until they are automatically cleaned up.
+The maximum file size is {max_file_size}MB.
+URLs shortened with this service will redirect to the original URL for the same period.
+
+Examples:
+
+File upload:
+curl -F file=@document.pdf {base_url}/
+Response:
+{base_url}/abcdef
+
+URL shortening:
+curl -d "url=https://example.com" {base_url}/shorten
+Response:
+{base_url}/ghijkl
+
+Disclaimer:
+
+This service is provided as-is with no guarantees.
+Uploaded files and shortened URLs are not private and can be accessed by anyone with the link.
+Use at your own risk.
+
+
+
diff --git a/main.py b/main.py
index 271ecc6..fd4a48f 100755
--- a/main.py
+++ b/main.py
@@ -1,67 +1,73 @@
-import os
-import uuid
-import time
-import json
-import threading
-from flask import Flask, request, redirect, send_from_directory, abort
+import os, uuid, time, json, sqlite3, threading
+from flask import Flask, request, redirect, send_from_directory, abort, render_template_string
app = Flask(__name__)
-# config
-UPLOAD_FOLDER = './uploads'
-MAX_FILE_SIZE = 1024 * 1024 * 100 # last number = megabytes
-EXPIRATION_TIME = 60 * 60 * 24 * 7 # last number = days
-DATA_FILE = 'data.json'
-URL_PREFIX = 'http://localhost:5000/'
+with open('config.json') as f:
+ config = json.load(f)
-if not os.path.exists(UPLOAD_FOLDER):
- os.makedirs(UPLOAD_FOLDER)
+UPLOAD_FOLDER = config['upload_folder']
+MAX_FILE_SIZE = config['max_file_size']
+EXPIRATION_TIME = config['expiration_time']
+DATA_FILE = config['data_file']
+URL_PREFIX = config['base_url']
+NAME = config['name']
+
+os.makedirs(UPLOAD_FOLDER, exist_ok=True)
+
+def init_db():
+ with sqlite3.connect(DATA_FILE) as conn:
+ conn.execute('CREATE TABLE IF NOT EXISTS files (key TEXT PRIMARY KEY, type TEXT NOT NULL, path TEXT, url TEXT, expiry REAL)')
+
+init_db()
def load_data():
- if os.path.exists(DATA_FILE):
- with open(DATA_FILE, 'r') as f:
- return json.load(f)
- return {}
+ with sqlite3.connect(DATA_FILE) as conn:
+ return {row[0]: {'type': row[1], 'path': row[2], 'url': row[3], 'expiry': row[4]} for row in conn.execute('SELECT * FROM files')}
+
+def save_data():
+ with sqlite3.connect(DATA_FILE) as conn:
+ conn.execute('DELETE FROM files')
+ conn.executemany('INSERT INTO files VALUES (?, ?, ?, ?, ?)',
+ [(k, v['type'], v.get('path'), v.get('url'), v['expiry']) for k, v in data.items()])
data = load_data()
-def save_data():
- with open(DATA_FILE, 'w') as f:
- json.dump(data, f)
-
def cleanup_files():
while True:
- time.sleep(60 * 60)
+ time.sleep(3600)
now = time.time()
- for key, item in list(data.items()):
- if 'expiry' in item and now > item['expiry']:
- try:
- os.remove(item['path'])
- except Exception as e:
- print(f"Error removing file {item['path']}: {e}")
- del data[key]
+ expired_keys = [k for k, v in data.items() if v['expiry'] < now]
+ for k in expired_keys:
+ if data[k]['type'] == 'file':
+ os.remove(data[k]['path'])
+ data.pop(k)
save_data()
threading.Thread(target=cleanup_files, daemon=True).start()
+@app.route('/', methods=['GET'])
+def landing_page():
+ with open('landing.html') as f:
+ html = f.read().format(
+ name=NAME,
+ base_url=URL_PREFIX.rstrip('/'),
+ expiration_days=EXPIRATION_TIME // 86400,
+ max_file_size=MAX_FILE_SIZE // 1048576
+ )
+ return render_template_string(html)
+
@app.route('/', methods=['POST'])
def upload_file():
file = request.files.get('file')
- if not file:
- return "No file uploaded\n", 400
- if file.content_length > MAX_FILE_SIZE:
- return "File too large\n", 400
+ if not file or file.content_length > MAX_FILE_SIZE:
+ return "No file uploaded or file too large\n", 400
- filename = file.filename
key = uuid.uuid4().hex[:6]
- filepath = os.path.join(UPLOAD_FOLDER, f"{key}_{filename}")
+ filepath = os.path.join(UPLOAD_FOLDER, f"{key}_{file.filename}")
file.save(filepath)
- data[key] = {
- 'type': 'file',
- 'path': filepath,
- 'expiry': time.time() + EXPIRATION_TIME
- }
+ data[key] = {'type': 'file', 'path': filepath, 'expiry': time.time() + EXPIRATION_TIME}
save_data()
return f"{URL_PREFIX}{key}\n"
@@ -72,11 +78,7 @@ def shorten_url():
return "No URL provided\n", 400
key = uuid.uuid4().hex[:6]
- data[key] = {
- 'type': 'url',
- 'url': url,
- 'expiry': time.time() + EXPIRATION_TIME
- }
+ data[key] = {'type': 'url', 'url': url, 'expiry': time.time() + EXPIRATION_TIME}
save_data()
return f"{URL_PREFIX}{key}\n"
@@ -88,10 +90,9 @@ def get_content(key):
if item['type'] == 'file':
return send_from_directory(UPLOAD_FOLDER, os.path.basename(item['path']))
- elif item['type'] == 'url':
+ if item['type'] == 'url':
return redirect(item['url'])
- else:
- abort(404)
+ abort(404)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)