forked from spitkov/sxbin
fix v2
This commit is contained in:
parent
5751297239
commit
5c0d0413ef
130
app.py
130
app.py
@ -1,4 +1,4 @@
|
|||||||
from flask import Flask, request, jsonify, send_from_directory, render_template, url_for, redirect, send_file, session, make_response, flash
|
from flask import Flask, request, jsonify, send_from_directory, render_template, url_for, redirect, send_file, session, make_response, flash, g
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
import shortuuid
|
import shortuuid
|
||||||
import os
|
import os
|
||||||
@ -29,9 +29,9 @@ if not os.path.exists(UPLOAD_FOLDER):
|
|||||||
|
|
||||||
# Database setup and helper functions
|
# Database setup and helper functions
|
||||||
def get_db():
|
def get_db():
|
||||||
db = getattr(threading.current_thread(), '_database', None)
|
db = getattr(g, '_database', None)
|
||||||
if db is None:
|
if db is None:
|
||||||
db = threading.current_thread()._database = sqlite3.connect(DATABASE)
|
db = g._database = sqlite3.connect(DATABASE)
|
||||||
return db
|
return db
|
||||||
|
|
||||||
def init_db():
|
def init_db():
|
||||||
@ -39,16 +39,30 @@ def init_db():
|
|||||||
db = get_db()
|
db = get_db()
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
|
|
||||||
# Check if users table exists
|
# Create users table
|
||||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='users'")
|
cursor.execute('''
|
||||||
if not cursor.fetchone():
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
# If it doesn't exist, create it
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
with app.open_resource('schema.sql', mode='r') as f:
|
username TEXT UNIQUE NOT NULL,
|
||||||
db.cursor().executescript(f.read())
|
password_hash TEXT NOT NULL,
|
||||||
db.commit()
|
api_key TEXT
|
||||||
print("Database initialized with users table.")
|
)
|
||||||
else:
|
''')
|
||||||
print("Users table already exists.")
|
|
||||||
|
# Create content table
|
||||||
|
cursor.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS content (
|
||||||
|
vanity TEXT PRIMARY KEY,
|
||||||
|
type TEXT NOT NULL,
|
||||||
|
data TEXT NOT NULL,
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
user_id INTEGER,
|
||||||
|
FOREIGN KEY (user_id) REFERENCES users (id)
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
|
||||||
|
db.commit()
|
||||||
|
print("Database initialized with users and content tables.")
|
||||||
|
|
||||||
# Call init_db() when the application starts
|
# Call init_db() when the application starts
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
@ -69,7 +83,7 @@ def migrate_db():
|
|||||||
|
|
||||||
@app.teardown_appcontext
|
@app.teardown_appcontext
|
||||||
def close_connection(exception):
|
def close_connection(exception):
|
||||||
db = getattr(threading.current_thread(), '_database', None)
|
db = getattr(g, '_database', None)
|
||||||
if db is not None:
|
if db is not None:
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
@ -85,29 +99,30 @@ def get_username(user_id):
|
|||||||
|
|
||||||
# Add this function to delete old files
|
# Add this function to delete old files
|
||||||
def delete_old_files():
|
def delete_old_files():
|
||||||
while True:
|
with app.app_context():
|
||||||
db = get_db()
|
while True:
|
||||||
cursor = db.cursor()
|
db = get_db()
|
||||||
|
cursor = db.cursor()
|
||||||
|
|
||||||
# Delete files older than 30 days
|
# Delete files older than 30 days
|
||||||
thirty_days_ago = datetime.now() - timedelta(days=30)
|
thirty_days_ago = datetime.now() - timedelta(days=30)
|
||||||
cursor.execute("SELECT vanity, type, data FROM content WHERE created_at < ?", (thirty_days_ago,))
|
cursor.execute("SELECT vanity, type, data FROM content WHERE created_at < ?", (thirty_days_ago,))
|
||||||
old_files = cursor.fetchall()
|
old_files = cursor.fetchall()
|
||||||
|
|
||||||
for vanity, content_type, data in old_files:
|
for vanity, content_type, data in old_files:
|
||||||
if content_type == 'file':
|
if content_type == 'file':
|
||||||
file_path = os.path.join(app.config['UPLOAD_FOLDER'], f'{vanity}_{data}')
|
file_path = os.path.join(app.config['UPLOAD_FOLDER'], f'{vanity}_{data}')
|
||||||
if os.path.exists(file_path):
|
if os.path.exists(file_path):
|
||||||
os.remove(file_path)
|
os.remove(file_path)
|
||||||
elif content_type == 'folder':
|
elif content_type == 'folder':
|
||||||
folder_path = os.path.join(app.config['UPLOAD_FOLDER'], vanity)
|
folder_path = os.path.join(app.config['UPLOAD_FOLDER'], vanity)
|
||||||
if os.path.exists(folder_path):
|
if os.path.exists(folder_path):
|
||||||
shutil.rmtree(folder_path)
|
shutil.rmtree(folder_path)
|
||||||
|
|
||||||
cursor.execute("DELETE FROM content WHERE created_at < ?", (thirty_days_ago,))
|
cursor.execute("DELETE FROM content WHERE created_at < ?", (thirty_days_ago,))
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
time.sleep(86400) # Sleep for 24 hours
|
time.sleep(86400) # Sleep for 24 hours
|
||||||
|
|
||||||
# Start the cleanup thread
|
# Start the cleanup thread
|
||||||
cleanup_thread = threading.Thread(target=delete_old_files)
|
cleanup_thread = threading.Thread(target=delete_old_files)
|
||||||
@ -236,6 +251,7 @@ def serve_user_page(username, filename=None):
|
|||||||
current_folder=current_folder)
|
current_folder=current_folder)
|
||||||
|
|
||||||
@app.route('/<vanity>')
|
@app.route('/<vanity>')
|
||||||
|
@app.route('/<vanity>/download')
|
||||||
def redirect_vanity(vanity):
|
def redirect_vanity(vanity):
|
||||||
db = get_db()
|
db = get_db()
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
@ -248,7 +264,20 @@ def redirect_vanity(vanity):
|
|||||||
if content_type == 'file':
|
if content_type == 'file':
|
||||||
file_path = os.path.join(app.config['UPLOAD_FOLDER'], content_data)
|
file_path = os.path.join(app.config['UPLOAD_FOLDER'], content_data)
|
||||||
if os.path.exists(file_path):
|
if os.path.exists(file_path):
|
||||||
return send_file(file_path)
|
if '/download' in request.path:
|
||||||
|
return send_file(file_path, as_attachment=True)
|
||||||
|
else:
|
||||||
|
# Embed the file if it's an image, video, or audio
|
||||||
|
file_extension = os.path.splitext(content_data)[1].lower()
|
||||||
|
if file_extension in ['.jpg', '.jpeg', '.png', '.gif', '.svg']:
|
||||||
|
return send_file(file_path, mimetype=f'image/{file_extension[1:]}')
|
||||||
|
elif file_extension in ['.mp3', '.wav']:
|
||||||
|
return send_file(file_path, mimetype=f'audio/{file_extension[1:]}')
|
||||||
|
elif file_extension in ['.mp4', '.webm']:
|
||||||
|
return send_file(file_path, mimetype=f'video/{file_extension[1:]}')
|
||||||
|
else:
|
||||||
|
# For other file types, send as attachment
|
||||||
|
return send_file(file_path, as_attachment=True)
|
||||||
else:
|
else:
|
||||||
return "File not found", 404
|
return "File not found", 404
|
||||||
elif content_type == 'url':
|
elif content_type == 'url':
|
||||||
@ -791,11 +820,6 @@ def api_upload():
|
|||||||
|
|
||||||
url = url_for('redirect_vanity', vanity=vanity, _external=True)
|
url = url_for('redirect_vanity', vanity=vanity, _external=True)
|
||||||
delete_url = url_for('delete_content', vanity=vanity, _external=True)
|
delete_url = url_for('delete_content', vanity=vanity, _external=True)
|
||||||
return jsonify({
|
|
||||||
'status': 'success',
|
|
||||||
'url': url,
|
|
||||||
'deletion_url': delete_url,
|
|
||||||
})
|
|
||||||
else:
|
else:
|
||||||
# Handle other file types
|
# Handle other file types
|
||||||
vanity = shortuuid.uuid()[:8]
|
vanity = shortuuid.uuid()[:8]
|
||||||
@ -809,11 +833,12 @@ def api_upload():
|
|||||||
|
|
||||||
url = url_for('redirect_vanity', vanity=new_filename, _external=True)
|
url = url_for('redirect_vanity', vanity=new_filename, _external=True)
|
||||||
delete_url = url_for('delete_content', vanity=new_filename, _external=True)
|
delete_url = url_for('delete_content', vanity=new_filename, _external=True)
|
||||||
return jsonify({
|
|
||||||
'status': 'success',
|
return json.dumps({
|
||||||
'url': url,
|
'status': 'success',
|
||||||
'deletion_url': delete_url,
|
'url': url.replace('/download', ''),
|
||||||
})
|
'deletion_url': delete_url,
|
||||||
|
})
|
||||||
elif 'text' in request.form:
|
elif 'text' in request.form:
|
||||||
content = request.form['text']
|
content = request.form['text']
|
||||||
vanity = shortuuid.uuid()[:8]
|
vanity = shortuuid.uuid()[:8]
|
||||||
@ -824,9 +849,10 @@ def api_upload():
|
|||||||
|
|
||||||
url = url_for('redirect_vanity', vanity=vanity, _external=True)
|
url = url_for('redirect_vanity', vanity=vanity, _external=True)
|
||||||
delete_url = url_for('delete_content', vanity=vanity, _external=True)
|
delete_url = url_for('delete_content', vanity=vanity, _external=True)
|
||||||
return jsonify({
|
|
||||||
|
return json.dumps({
|
||||||
'status': 'success',
|
'status': 'success',
|
||||||
'url': url,
|
'url': url.replace('/download', ''),
|
||||||
'deletion_url': delete_url,
|
'deletion_url': delete_url,
|
||||||
})
|
})
|
||||||
elif 'url' in request.form:
|
elif 'url' in request.form:
|
||||||
@ -839,9 +865,10 @@ def api_upload():
|
|||||||
|
|
||||||
short_url = url_for('redirect_vanity', vanity=vanity, _external=True)
|
short_url = url_for('redirect_vanity', vanity=vanity, _external=True)
|
||||||
delete_url = url_for('delete_content', vanity=vanity, _external=True)
|
delete_url = url_for('delete_content', vanity=vanity, _external=True)
|
||||||
return jsonify({
|
|
||||||
|
return json.dumps({
|
||||||
'status': 'success',
|
'status': 'success',
|
||||||
'url': short_url,
|
'url': short_url.replace('/download', ''),
|
||||||
'deletion_url': delete_url,
|
'deletion_url': delete_url,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -877,4 +904,9 @@ def create_new_file(username):
|
|||||||
return redirect(url_for('user_files', username=username, subpath=subpath))
|
return redirect(url_for('user_files', username=username, subpath=subpath))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(debug=True,host='0.0.0.0',port=7123)
|
# Start the cleanup thread
|
||||||
|
cleanup_thread = threading.Thread(target=delete_old_files)
|
||||||
|
cleanup_thread.daemon = True
|
||||||
|
cleanup_thread.start()
|
||||||
|
|
||||||
|
app.run(debug=True, host='0.0.0.0', port=7123)
|
@ -49,12 +49,14 @@
|
|||||||
{% if info.file_size %}
|
{% if info.file_size %}
|
||||||
<div class="info-item"><strong>File Size:</strong> {{ info.file_size }} bytes</div>
|
<div class="info-item"><strong>File Size:</strong> {{ info.file_size }} bytes</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<a href="{{ url_for('redirect_vanity', vanity=info.vanity)|replace('/download', '') }}" class="btn">View/Embed</a>
|
||||||
|
<a href="{{ url_for('redirect_vanity', vanity=info.vanity) ~ ('/download' if '/download' not in url_for('redirect_vanity', vanity=info.vanity) else '') }}" class="btn">Download</a>
|
||||||
{% elif info.type == 'url' %}
|
{% elif info.type == 'url' %}
|
||||||
<div class="info-item"><strong>Target URL:</strong> {{ info.data }}</div>
|
<div class="info-item"><strong>Target URL:</strong> {{ info.data }}</div>
|
||||||
{% endif %}
|
<a href="{{ url_for('redirect_vanity', vanity=info.vanity) }}" class="btn">Visit URL</a>
|
||||||
<a href="{{ url_for('redirect_vanity', vanity=info.vanity) }}" class="btn">View Content</a>
|
{% elif info.type == 'pastebin' %}
|
||||||
{% if info.type == 'file' %}
|
<a href="{{ url_for('redirect_vanity', vanity=info.vanity) }}" class="btn">View Pastebin</a>
|
||||||
<a href="{{ url_for('redirect_vanity', vanity=info.vanity) }}/download" class="btn">Download</a>
|
<a href="{{ url_for('raw_vanity', vanity=info.vanity) }}" class="btn">View Raw</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if current_user.is_authenticated and current_user.username == info.username %}
|
{% if current_user.is_authenticated and current_user.username == info.username %}
|
||||||
{% if info.type != 'file' or not info.is_media %}
|
{% if info.type != 'file' or not info.is_media %}
|
||||||
|
Loading…
Reference in New Issue
Block a user