too many changes for me to list but basically user suppport file lsiting uploading deleting renaming moving copying etc and toggle if index.html presnet shw it to acces ur page /username and then ASKDJAKLSDl this is a development why do i have to document everything

This commit is contained in:
spitkov 2024-09-10 16:00:43 +02:00
parent 7c641df41e
commit 0f444b7606
10 changed files with 710 additions and 302 deletions

428
app.py
View File

@ -1,20 +1,19 @@
from flask import Flask, request, jsonify, send_from_directory, render_template, url_for, redirect, send_file from flask import Flask, request, jsonify, send_from_directory, render_template, url_for, redirect, send_file, session
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
import shortuuid import shortuuid
import os import os
from datetime import datetime from datetime import datetime, timedelta
import zipfile import zipfile
import sqlite3 import sqlite3
import threading import threading
import time import time
import shutil import shutil
from datetime import timedelta
from pygments import highlight from pygments import highlight
from pygments.lexers import get_lexer_by_name, guess_lexer from pygments.lexers import get_lexer_by_name, guess_lexer
from pygments.formatters import HtmlFormatter from pygments.formatters import HtmlFormatter
from pygments.util import ClassNotFound from pygments.util import ClassNotFound
import json import json
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user, login_remembered
import hashlib import hashlib
app = Flask(__name__) app = Flask(__name__)
@ -22,6 +21,7 @@ app.secret_key = 'your_secret_key_here' # Add this line
UPLOAD_FOLDER = './uploads' UPLOAD_FOLDER = './uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
DATABASE = 'data.db' DATABASE = 'data.db'
app.config['REMEMBER_COOKIE_DURATION'] = timedelta(days=30) # Set cookie to expire after 30 days
if not os.path.exists(UPLOAD_FOLDER): if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER) os.makedirs(UPLOAD_FOLDER)
@ -115,146 +115,82 @@ def load_user(user_id):
@app.route('/') @app.route('/')
def index(): def index():
return render_template('index.html') if current_user.is_authenticated:
return render_template('index.html', user=current_user)
return render_template('index.html', user=None)
@app.route('/content/<vanity>') @app.route('/u/<username>')
def content(vanity): @app.route('/u/<username>/')
@app.route('/u/<username>/<path:filename>')
def serve_user_page(username, filename=None):
print(f"Accessing user page: {username}, filename: {filename}") # Debug print
# Check if the username exists in the database
db = get_db() db = get_db()
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT * FROM content WHERE vanity = ?", (vanity,)) cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
target = cursor.fetchone() user = cursor.fetchone()
if not user:
print(f"User {username} not found") # Debug print
return "User not found", 404
if target: user_folder = os.path.join(app.config['UPLOAD_FOLDER'], username)
content_type, content_data = target[1], target[2] print(f"User folder path: {user_folder}") # Debug print
if content_type == 'pastebin':
try:
lexer = guess_lexer(content_data)
language = lexer.aliases[0]
except ClassNotFound:
language = 'text'
lexer = get_lexer_by_name(language)
formatter = HtmlFormatter(style='monokai', linenos=True, cssclass="source") if not os.path.exists(user_folder):
highlighted_code = highlight(content_data, lexer, formatter) print(f"User folder does not exist for {username}") # Debug print
css = formatter.get_style_defs('.source') os.makedirs(user_folder) # Create the folder if it doesn't exist
return render_template('content.html',
highlighted_content=highlighted_code,
css=css,
raw_content=content_data,
created_at=target[3],
vanity=vanity,
language=language)
elif content_type == 'file':
file_path = os.path.join(app.config['UPLOAD_FOLDER'], f'{vanity}_{content_data}')
file_info = {
'name': content_data,
'size': os.path.getsize(file_path),
'modified_at': datetime.fromtimestamp(os.path.getmtime(file_path)).strftime('%Y-%m-%d %H:%M:%S'),
'url': url_for('download_file', vanity=vanity)
}
return render_template('file.html', **file_info)
elif content_type == 'url':
return render_template('content.html', url=content_data)
return 'Not Found', 404
@app.route('/download/<vanity>', methods=['GET']) current_path = os.path.join(user_folder, filename.rstrip('/') if filename else '')
def download_file(vanity): if not os.path.exists(current_path):
db = get_db() return "Folder or file not found", 404
cursor = db.cursor()
cursor.execute("SELECT * FROM content WHERE vanity = ? AND type = 'file'", (vanity,))
target = cursor.fetchone()
if target:
filename = f'{vanity}_{target[2]}'
return send_from_directory(app.config['UPLOAD_FOLDER'], filename, as_attachment=True)
return 'Not Found', 404
@app.route('/upload/pastebin', methods=['POST']) if os.path.isfile(current_path):
def upload_pastebin(): return send_file(current_path)
content = request.form['content']
vanity = shortuuid.uuid()[:6]
created_at = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
db = get_db() # Check if we should ignore index.html
cursor = db.cursor() ignore_index = session.get(f'ignore_index_{username}', False)
cursor.execute("INSERT INTO content (vanity, type, data, created_at) VALUES (?, ?, ?, ?)",
(vanity, 'pastebin', content, created_at))
db.commit()
return jsonify({'vanity': vanity}) # Check for index.html
index_path = os.path.join(current_path, 'index.html')
if os.path.exists(index_path) and not ignore_index:
return send_file(index_path)
@app.route('/upload/file', methods=['POST']) # Directory listing
def upload_file(): files = []
if 'file' not in request.files: folders = []
return 'No file part', 400 for item in os.listdir(current_path):
file = request.files['file'] item_path = os.path.join(current_path, item)
if file.filename == '': relative_path = os.path.relpath(item_path, user_folder)
return 'No selected file', 400 if os.path.isfile(item_path):
if file: files.append({'name': item, 'path': relative_path})
vanity = shortuuid.uuid()[:6]
filename = secure_filename(file.filename)
filepath = os.path.join(app.config['UPLOAD_FOLDER'], f'{vanity}_{filename}')
file.save(filepath)
db = get_db()
cursor = db.cursor()
cursor.execute("INSERT INTO content (vanity, type, data) VALUES (?, ?, ?)",
(vanity, 'file', filename))
db.commit()
return jsonify({'vanity': vanity})
def save_file(file, folder_path):
filename = secure_filename(file.filename)
file_path = os.path.join(folder_path, filename)
file.save(file_path)
def handle_uploaded_folder(files, base_path):
for file in files:
if file.filename.endswith('/'):
subfolder_path = os.path.join(base_path, secure_filename(file.filename))
os.makedirs(subfolder_path, exist_ok=True)
handle_uploaded_folder(request.files.getlist(file.filename), subfolder_path)
else: else:
save_file(file, base_path) folders.append({'name': item, 'path': relative_path})
@app.route('/upload/folder', methods=['POST']) parent_folder = os.path.dirname(filename.rstrip('/')) if filename else None
def upload_folder(): current_folder = os.path.basename(current_path)
if 'file' not in request.files:
return 'No files uploaded', 400
files = request.files.getlist('file') # Generate the correct parent folder URL
if not files: parent_url = None
return 'No files selected', 400 if parent_folder:
parent_url = url_for('serve_user_page', username=username, filename=parent_folder)
elif filename: # If we're in a subfolder, parent is the root
parent_url = url_for('serve_user_page', username=username)
vanity = shortuuid.uuid()[:6] return render_template('user_files_public.html',
folder_path = os.path.join(app.config['UPLOAD_FOLDER'], vanity) username=username,
os.makedirs(folder_path) files=files,
folders=folders,
current_path=filename.rstrip('/') if filename else '',
parent_url=parent_url,
current_folder=current_folder)
handle_uploaded_folder(files, folder_path) @app.route('/<path:path>')
def redirect_vanity(path):
parts = path.rstrip('/').split('/')
vanity = parts[0]
subpath = '/'.join(parts[1:]) if len(parts) > 1 else ''
db = get_db()
cursor = db.cursor()
cursor.execute("INSERT INTO content (vanity, type, data) VALUES (?, ?, ?)",
(vanity, 'folder', ','.join([file.filename for file in files])))
db.commit()
return jsonify({'vanity': vanity})
@app.route('/shorten', methods=['POST'])
def shorten_url():
original_url = request.form['url']
vanity = shortuuid.uuid()[:6]
db = get_db()
cursor = db.cursor()
cursor.execute("INSERT INTO content (vanity, type, data) VALUES (?, ?, ?)",
(vanity, 'url', original_url))
db.commit()
return jsonify({'vanity': vanity})
@app.route('/<vanity>', methods=['GET'])
def redirect_vanity(vanity):
db = get_db() db = get_db()
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT * FROM content WHERE vanity = ?", (vanity,)) cursor.execute("SELECT * FROM content WHERE vanity = ?", (vanity,))
@ -388,6 +324,12 @@ def register():
cursor.execute("INSERT INTO users (username, password_hash) VALUES (?, ?)", cursor.execute("INSERT INTO users (username, password_hash) VALUES (?, ?)",
(username, hashed_password)) (username, hashed_password))
db.commit() db.commit()
# Create user directory
user_folder = os.path.join(app.config['UPLOAD_FOLDER'], username)
if not os.path.exists(user_folder):
os.makedirs(user_folder)
return redirect(url_for('login')) return redirect(url_for('login'))
return render_template('register.html') return render_template('register.html')
@ -396,12 +338,14 @@ def login():
if request.method == 'POST': if request.method == 'POST':
username = request.form['username'] username = request.form['username']
password = request.form['password'] password = request.form['password']
remember = 'remember' in request.form
db = get_db() db = get_db()
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT * FROM users WHERE username = ?", (username,)) cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
user = cursor.fetchone() user = cursor.fetchone()
if user and User.verify_password(user[2], password): if user and User.verify_password(user[2], password):
login_user(User(user[0], user[1], user[2])) user_obj = User(user[0], user[1], user[2])
login_user(user_obj, remember=remember)
return redirect(url_for('user_files', username=username)) return redirect(url_for('user_files', username=username))
return "Invalid username or password" return "Invalid username or password"
return render_template('login.html') return render_template('login.html')
@ -412,21 +356,74 @@ def logout():
logout_user() logout_user()
return redirect(url_for('index')) return redirect(url_for('index'))
@app.route('/user/<username>') @app.route('/dash/<username>')
def user_files(username): @app.route('/dash/<username>/')
if current_user.is_authenticated and current_user.username == username: @app.route('/dash/<username>/<path:subpath>')
user_folder = os.path.join(app.config['UPLOAD_FOLDER'], username) @login_required
if not os.path.exists(user_folder): def user_files(username, subpath=''):
os.makedirs(user_folder) if current_user.username != username:
files = os.listdir(user_folder)
return render_template('user_files.html', username=username, files=files)
return "Unauthorized", 401 return "Unauthorized", 401
@app.route('/user/<username>/upload', methods=['POST']) user_folder = os.path.join(app.config['UPLOAD_FOLDER'], username)
current_path = os.path.join(user_folder, subpath.rstrip('/'))
# Create user folder if it doesn't exist
if not os.path.exists(user_folder):
os.makedirs(user_folder)
if not os.path.exists(current_path):
return "Folder not found", 404
if not os.path.isdir(current_path):
return "Not a directory", 400
items = []
folders = []
for item in os.listdir(current_path):
item_path = os.path.join(current_path, item)
relative_path = os.path.relpath(item_path, user_folder)
if os.path.isfile(item_path):
items.append({'name': item, 'type': 'file', 'path': relative_path})
else:
items.append({'name': item, 'type': 'folder', 'path': relative_path})
folders.append(relative_path)
parent_folder = os.path.dirname(subpath.rstrip('/')) if subpath else None
current_folder = os.path.basename(current_path)
# Check if index.html exists in the current folder
index_exists = 'index.html' in [item['name'] for item in items if item['type'] == 'file']
# Get the current setting for ignoring index.html
ignore_index = session.get(f'ignore_index_{username}', False)
return render_template('user_files.html',
username=username,
items=items,
folders=folders,
current_path=subpath.rstrip('/'),
parent_folder=parent_folder,
current_folder=current_folder,
index_exists=index_exists,
ignore_index=ignore_index)
@app.route('/dash/<username>/toggle_index')
@login_required
def toggle_index(username):
if current_user.username != username:
return "Unauthorized", 401
current_setting = session.get(f'ignore_index_{username}', False)
session[f'ignore_index_{username}'] = not current_setting
return redirect(url_for('user_files', username=username))
@app.route('/dash/<username>/upload', methods=['POST'])
@login_required @login_required
def upload_user_file(username): def upload_user_file(username):
if current_user.username != username: if current_user.username != username:
return "Unauthorized", 401 return "Unauthorized", 401
subpath = request.form.get('subpath', '').rstrip('/')
if 'file' not in request.files: if 'file' not in request.files:
return 'No file part', 400 return 'No file part', 400
file = request.files['file'] file = request.files['file']
@ -434,11 +431,12 @@ def upload_user_file(username):
return 'No selected file', 400 return 'No selected file', 400
if file: if file:
filename = secure_filename(file.filename) filename = secure_filename(file.filename)
file_path = os.path.join(app.config['UPLOAD_FOLDER'], username, filename) file_path = os.path.join(app.config['UPLOAD_FOLDER'], username, subpath, filename)
os.makedirs(os.path.dirname(file_path), exist_ok=True)
file.save(file_path) file.save(file_path)
return redirect(url_for('user_files', username=username)) return redirect(url_for('user_files', username=username, subpath=subpath))
@app.route('/user/<username>/delete/<filename>', methods=['POST']) @app.route('/dash/<username>/delete/<filename>', methods=['POST'])
@login_required @login_required
def delete_user_file(username, filename): def delete_user_file(username, filename):
if current_user.username != username: if current_user.username != username:
@ -448,7 +446,7 @@ def delete_user_file(username, filename):
os.remove(file_path) os.remove(file_path)
return redirect(url_for('user_files', username=username)) return redirect(url_for('user_files', username=username))
@app.route('/user/<username>/rename', methods=['POST']) @app.route('/dash/<username>/rename', methods=['POST'])
@login_required @login_required
def rename_user_file(username): def rename_user_file(username):
if current_user.username != username: if current_user.username != username:
@ -461,90 +459,100 @@ def rename_user_file(username):
os.rename(old_path, new_path) os.rename(old_path, new_path)
return redirect(url_for('user_files', username=username)) return redirect(url_for('user_files', username=username))
@app.route('/<username>') @app.route('/dash/<username>/create_folder', methods=['POST'])
@app.route('/<username>/') @login_required
@app.route('/<username>/<path:filename>') def create_folder(username):
def serve_user_page(username, filename=None): if current_user.username != username:
print(f"Accessing user page: {username}, filename: {filename}") # Debug print return "Unauthorized", 401
subpath = request.form.get('subpath', '').rstrip('/')
folder_name = secure_filename(request.form['folder_name'])
folder_path = os.path.join(app.config['UPLOAD_FOLDER'], username, subpath, folder_name)
if not os.path.exists(folder_path):
os.makedirs(folder_path)
return redirect(url_for('user_files', username=username, subpath=subpath))
# Check if the username exists in the database @app.route('/dash/<username>/delete_folder/<folder_name>', methods=['POST'])
db = get_db() @login_required
cursor = db.cursor() def delete_folder(username, folder_name):
cursor.execute("SELECT * FROM users WHERE username = ?", (username,)) if current_user.username != username:
user = cursor.fetchone() return "Unauthorized", 401
if not user: folder_path = os.path.join(app.config['UPLOAD_FOLDER'], username, folder_name)
print(f"User {username} not found") # Debug print if os.path.exists(folder_path):
return "User not found", 404 shutil.rmtree(folder_path)
return redirect(url_for('user_files', username=username))
user_folder = os.path.join(app.config['UPLOAD_FOLDER'], username) @app.route('/dash/<username>/rename_folder', methods=['POST'])
print(f"User folder path: {user_folder}") # Debug print @login_required
def rename_folder(username):
if current_user.username != username:
return "Unauthorized", 401
old_foldername = request.form['old_foldername']
new_foldername = secure_filename(request.form['new_foldername'])
old_path = os.path.join(app.config['UPLOAD_FOLDER'], username, old_foldername)
new_path = os.path.join(app.config['UPLOAD_FOLDER'], username, new_foldername)
if os.path.exists(old_path):
os.rename(old_path, new_path)
return redirect(url_for('user_files', username=username))
if not os.path.exists(user_folder): @app.route('/dash/<username>/move_item', methods=['POST'])
print(f"User folder does not exist for {username}") # Debug print @login_required
os.makedirs(user_folder) # Create the folder if it doesn't exist def move_item(username):
if current_user.username != username:
return "Unauthorized", 401
item_name = request.form['item_name']
item_type = request.form['item_type']
destination_folder = request.form['destination_folder']
source_path = os.path.join(app.config['UPLOAD_FOLDER'], username, item_name)
dest_path = os.path.join(app.config['UPLOAD_FOLDER'], username, destination_folder, item_name)
if os.path.exists(source_path):
shutil.move(source_path, dest_path)
return redirect(url_for('user_files', username=username))
if filename is None or filename == '': @app.route('/dash/<username>/copy_item', methods=['POST'])
# Try to serve index.html @login_required
index_path = os.path.join(user_folder, 'index.html') def copy_item(username):
print(f"Checking for index.html at: {index_path}") # Debug print if current_user.username != username:
if os.path.exists(index_path): return "Unauthorized", 401
print(f"Serving index.html for {username}") # Debug print item_name = request.form['item_name']
return send_file(index_path) item_type = request.form['item_type']
destination_folder = request.form['destination_folder']
source_path = os.path.join(app.config['UPLOAD_FOLDER'], username, item_name)
dest_path = os.path.join(app.config['UPLOAD_FOLDER'], username, destination_folder, item_name)
if os.path.exists(source_path):
if item_type == 'file':
shutil.copy2(source_path, dest_path)
else: else:
print(f"No index.html found, listing files for {username}") # Debug print shutil.copytree(source_path, dest_path)
# If no index.html, list all files return redirect(url_for('user_files', username=username))
files = os.listdir(user_folder)
print(f"Files in {username}'s folder: {files}") # Debug print
return render_template('user_files_public.html', username=username, files=files)
else:
# Serve the requested file
file_path = os.path.join(user_folder, filename)
print(f"Attempting to serve file: {file_path}") # Debug print
if os.path.exists(file_path) and os.path.isfile(file_path):
print(f"Serving file: {file_path}") # Debug print
return send_file(file_path)
else:
print(f"File not found: {file_path}") # Debug print
return "File not found", 404
@app.route('/debug/users') @app.route('/dash/<username>/edit/<path:filename>', methods=['GET', 'POST'])
def debug_users():
db = get_db()
cursor = db.cursor()
cursor.execute("SELECT username FROM users")
users = cursor.fetchall()
user_files = {}
for user in users:
username = user[0]
user_folder = os.path.join(app.config['UPLOAD_FOLDER'], username)
if os.path.exists(user_folder):
user_files[username] = os.listdir(user_folder)
else:
user_files[username] = []
return jsonify(user_files)
@app.route('/user/<username>/edit/<path:filename>', methods=['GET', 'POST'])
@login_required @login_required
def edit_file(username, filename): def edit_file(username, filename):
if current_user.username != username: if current_user.username != username:
return "Unauthorized", 401 return "Unauthorized", 401
file_path = os.path.join(app.config['UPLOAD_FOLDER'], username, filename) file_path = os.path.join(app.config['UPLOAD_FOLDER'], username, filename)
if not os.path.exists(file_path):
return "File not found", 404
if request.method == 'POST': if request.method == 'POST':
content = request.form['content'] content = request.form['content']
with open(file_path, 'w') as file: with open(file_path, 'w') as f:
file.write(content) f.write(content)
return redirect(url_for('user_files', username=username)) return redirect(url_for('user_files', username=username))
if os.path.exists(file_path) and os.path.isfile(file_path): with open(file_path, 'r') as f:
with open(file_path, 'r') as file: content = f.read()
content = file.read()
return render_template('edit_file.html', username=username, filename=filename, content=content) return render_template('edit_file.html', filename=filename, content=content)
else:
return "File not found", 404 @app.route('/debug/users')
def debug_users():
db = get_db()
cursor = db.cursor()
cursor.execute("SELECT * FROM users")
users = cursor.fetchall()
return jsonify(users)
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True, port=7123) app.run(debug=True)

View File

@ -2,7 +2,8 @@ CREATE TABLE IF NOT EXISTS content (
vanity TEXT PRIMARY KEY, vanity TEXT PRIMARY KEY,
type TEXT NOT NULL, type TEXT NOT NULL,
data TEXT NOT NULL, data TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
user_id INTEGER
); );
CREATE TABLE IF NOT EXISTS users ( CREATE TABLE IF NOT EXISTS users (

View File

@ -154,24 +154,29 @@
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<h1>Content</h1> <h2>Content</h2>
{% if created_at %} {% if content.user_id %}
<p>Created at: {{ created_at }}</p> <p>Uploaded by: {{ content.username }}</p>
{% endif %}
{% if language %}
<p>Detected Language: {{ language }}</p>
{% endif %}
<div class="button-container">
<button id="copy-button" onclick="copyToClipboard()">Copy Raw</button>
<a href="{{ url_for('raw_vanity', vanity=vanity) }}" target="_blank"><button>View Raw</button></a>
</div>
<div class="highlight">
{% if highlighted_content %}
{{ highlighted_content|safe }}
{% else %} {% else %}
<pre>{{ content }}</pre> <p>Uploaded by: Anonymous</p>
{% endif %}
<p>Created at: {{ content.created_at }}</p>
{% if highlighted_content %}
<style>{{ css }}</style>
{{ highlighted_content|safe }}
{% elif url %}
<p>Shortened URL: <a href="{{ url }}">{{ url }}</a></p>
{% else %}
<pre>{{ raw_content }}</pre>
{% endif %}
{% if current_user.is_authenticated and current_user.id == content.user_id %}
<a href="{{ url_for('edit_content', vanity=content.vanity) }}" class="btn">Edit</a>
<form action="{{ url_for('delete_content', vanity=content.vanity) }}" method="post" style="display: inline;">
<button type="submit" class="btn">Delete</button>
</form>
{% endif %} {% endif %}
</div>
</div> </div>
<button id="theme-toggle">Toggle Theme</button> <button id="theme-toggle">Toggle Theme</button>

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Edit Content</title>
<style>
/* ... (use the same style as other pages) ... */
</style>
</head>
<body>
<div class="container">
<h2>Edit Content</h2>
<form method="post">
<textarea name="content" rows="10" cols="50">{{ content.data }}</textarea>
<br>
<input type="submit" value="Save" class="btn">
</form>
<a href="{{ url_for('user_files', username=current_user.username) }}" class="btn">Back to Dashboard</a>
</div>
</body>
</html>

View File

@ -112,8 +112,13 @@
<body> <body>
<div class="container"> <div class="container">
<nav> <nav>
{% if user %}
<a href="{{ url_for('user_files', username=user.username) }}">View Dashboard</a>
<a href="{{ url_for('logout') }}">Logout</a>
{% else %}
<a href="{{ url_for('login') }}">Login</a> <a href="{{ url_for('login') }}">Login</a>
<a href="{{ url_for('register') }}">Register</a> <a href="{{ url_for('register') }}">Register</a>
{% endif %}
</nav> </nav>
<div class="typewriter-container"> <div class="typewriter-container">

View File

@ -1,6 +1,68 @@
<h2>Login</h2> <!DOCTYPE html>
<form method="post"> <html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 20px;
background-color: #1a1a1a;
color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.login-container {
background-color: #2a2a2a;
padding: 20px;
border-radius: 5px;
width: 300px;
}
h2 {
color: #4CAF50;
text-align: center;
}
form {
display: flex;
flex-direction: column;
}
input {
margin: 10px 0;
padding: 10px;
border-radius: 4px;
border: 1px solid #4CAF50;
background-color: #333;
color: #f0f0f0;
}
input[type="submit"] {
background-color: #4CAF50;
color: white;
cursor: pointer;
}
input[type="submit"]:hover {
background-color: #45a049;
}
label {
margin-top: 10px;
}
</style>
</head>
<body>
<div class="login-container">
<h2>Login</h2>
<form method="post">
<input type="text" name="username" placeholder="Username" required> <input type="text" name="username" placeholder="Username" required>
<input type="password" name="password" placeholder="Password" required> <input type="password" name="password" placeholder="Password" required>
<label>
<input type="checkbox" name="remember"> Remember Me
</label>
<input type="submit" value="Login"> <input type="submit" value="Login">
</form> </form>
</div>
</body>
</html>

View File

@ -1,6 +1,62 @@
<h2>Register</h2> <!DOCTYPE html>
<form method="post"> <html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 20px;
background-color: #1a1a1a;
color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.register-container {
background-color: #2a2a2a;
padding: 20px;
border-radius: 5px;
width: 300px;
}
h2 {
color: #4CAF50;
text-align: center;
}
form {
display: flex;
flex-direction: column;
}
input {
margin: 10px 0;
padding: 10px;
border-radius: 4px;
border: 1px solid #4CAF50;
background-color: #333;
color: #f0f0f0;
}
input[type="submit"] {
background-color: #4CAF50;
color: white;
cursor: pointer;
}
input[type="submit"]:hover {
background-color: #45a049;
}
</style>
</head>
<body>
<div class="register-container">
<h2>Register</h2>
<form method="post">
<input type="text" name="username" placeholder="Username" required> <input type="text" name="username" placeholder="Username" required>
<input type="password" name="password" placeholder="Password" required> <input type="password" name="password" placeholder="Password" required>
<input type="submit" value="Register"> <input type="submit" value="Register">
</form> </form>
</div>
</body>
</html>

View File

@ -1,21 +1,269 @@
<h2>{{ username }}'s Files</h2> <!DOCTYPE html>
<form action="{{ url_for('upload_user_file', username=username) }}" method="post" enctype="multipart/form-data"> <html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ username }}'s Dashboard</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 20px;
background-color: #1a1a1a;
color: #f0f0f0;
display: flex;
justify-content: center;
}
.container {
max-width: 800px;
width: 100%;
}
h2, h3 {
color: #4CAF50;
text-align: center;
}
nav {
margin-bottom: 20px;
text-align: center;
}
nav a, .btn {
display: inline-block;
background-color: #4CAF50;
color: white;
padding: 8px 12px;
text-decoration: none;
border-radius: 4px;
margin: 0 5px;
border: none;
cursor: pointer;
font-size: 14px;
}
nav a:hover, .btn:hover {
background-color: #45a049;
}
form {
margin-bottom: 20px;
text-align: center;
}
input[type="text"], input[type="file"] {
padding: 8px;
margin-right: 10px;
border-radius: 4px;
border: 1px solid #4CAF50;
background-color: #333;
color: #f0f0f0;
}
.file-list {
list-style-type: none;
padding: 0;
}
.file-item {
background-color: #2a2a2a;
padding: 10px;
border-radius: 5px;
margin-bottom: 5px;
display: flex;
align-items: center;
justify-content: space-between;
}
.file-icon {
margin-right: 10px;
}
.file-name {
flex-grow: 1;
}
.file-actions {
display: flex;
gap: 5px;
}
.folder {
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<h2>{{ username }}'s Dashboard</h2>
<nav>
<a href="{{ url_for('index') }}">Home</a>
<a href="{{ url_for('logout') }}">Logout</a>
</nav>
<form action="{{ url_for('toggle_index', username=username) }}" method="get" style="text-align: center;">
<label>
<input type="checkbox" onchange="this.form.submit()" {% if ignore_index %}checked{% endif %}>
Ignore index.html and always show file listing
</label>
</form>
{% if index_exists and not ignore_index %}
<p style="text-align: center;">An index.html file exists in this folder. When viewing publicly, this file will be displayed instead of the file listing.</p>
{% endif %}
<h3>Upload File</h3>
<form action="{{ url_for('upload_user_file', username=username) }}" method="post" enctype="multipart/form-data">
<input type="hidden" name="subpath" value="{{ current_path }}">
<input type="file" name="file" required> <input type="file" name="file" required>
<input type="submit" value="Upload"> <input type="submit" value="Upload" class="btn">
</form>
<ul>
{% for file in files %}
<li>
{{ file }}
<form action="{{ url_for('delete_user_file', username=username, filename=file) }}" method="post" style="display: inline;">
<input type="submit" value="Delete">
</form> </form>
<form action="{{ url_for('rename_user_file', username=username) }}" method="post" style="display: inline;">
<input type="hidden" name="old_filename" value="{{ file }}"> <h3>Create Folder</h3>
<input type="text" name="new_filename" placeholder="New filename" required> <form action="{{ url_for('create_folder', username=username) }}" method="post">
<input type="submit" value="Rename"> <input type="hidden" name="subpath" value="{{ current_path }}">
<input type="text" name="folder_name" placeholder="New folder name" required>
<input type="submit" value="Create Folder" class="btn">
</form> </form>
<a href="{{ url_for('edit_file', username=username, filename=file) }}">Edit</a>
<h3>Files and Folders</h3>
<p style="text-align: center;">Current folder: {{ current_folder or 'Root' }}</p>
<ul class="file-list">
{% if parent_folder is not none %}
<li class="file-item folder">
<span class="file-icon">📁</span>
<span class="file-name">
<a href="{{ url_for('user_files', username=username, subpath=parent_folder) }}">..</a>
</span>
<div class="file-actions">
<!-- No actions for parent directory -->
</div>
</li> </li>
{% endfor %} {% endif %}
</ul> {% for item in items %}
<li class="file-item {% if item.type == 'folder' %}folder{% endif %}">
<span class="file-icon">{% if item.type == 'folder' %}📁{% else %}📄{% endif %}</span>
<span class="file-name">
{% if item.type == 'folder' %}
<a href="{{ url_for('user_files', username=username, subpath=item.path) }}">{{ item.name }}</a>
{% else %}
{{ item.name }}
{% endif %}
</span>
<div class="file-actions">
<button onclick="deleteItem('{{ item.name }}', '{{ item.type }}')" class="btn">Delete</button>
<button onclick="renameItem('{{ item.name }}', '{{ item.type }}')" class="btn">Rename</button>
<button onclick="moveItem('{{ item.name }}', '{{ item.type }}')" class="btn">Move</button>
<button onclick="copyItem('{{ item.name }}', '{{ item.type }}')" class="btn">Copy</button>
{% if item.type == 'file' %}
<a href="{{ url_for('edit_file', username=username, filename=item.path) }}" class="btn">Edit</a>
{% endif %}
</div>
</li>
{% endfor %}
</ul>
<h3>Your Uploads</h3>
<ul class="file-list">
{% for upload in uploads %}
<li class="file-item">
<span class="file-icon">
{% if upload.type == 'pastebin' %}📝
{% elif upload.type == 'file' %}📄
{% elif upload.type == 'folder' %}📁
{% elif upload.type == 'url' %}🔗
{% endif %}
</span>
<span class="file-name">
<a href="{{ url_for('redirect_vanity', path=upload.vanity) }}">{{ upload.vanity }}</a>
({{ upload.type }})
</span>
<div class="file-actions">
{% if upload.type in ['pastebin', 'url'] %}
<a href="{{ url_for('edit_content', vanity=upload.vanity) }}" class="btn">Edit</a>
{% endif %}
<form action="{{ url_for('delete_content', vanity=upload.vanity) }}" method="post" style="display: inline;">
<button type="submit" class="btn">Delete</button>
</form>
</div>
</li>
{% endfor %}
</ul>
</div>
<script>
function deleteItem(name, type) {
if (confirm(`Are you sure you want to delete this ${type}?`)) {
const form = document.createElement('form');
form.method = 'POST';
form.action = "{{ url_for('delete_user_file', username=username, filename='') }}" + name;
document.body.appendChild(form);
form.submit();
}
}
function renameItem(name, type) {
const newName = prompt(`Enter new name for this ${type}:`, name);
if (newName && newName !== name) {
const form = document.createElement('form');
form.method = 'POST';
form.action = "{{ url_for('rename_user_file', username=username, subpath=current_path) }}";
const oldInput = document.createElement('input');
oldInput.type = 'hidden';
oldInput.name = 'old_filename';
oldInput.value = name;
const newInput = document.createElement('input');
newInput.type = 'hidden';
newInput.name = 'new_filename';
newInput.value = newName;
form.appendChild(oldInput);
form.appendChild(newInput);
document.body.appendChild(form);
form.submit();
}
}
function moveItem(name, type) {
const destination = prompt(`Enter destination path for this ${type}:`, '/');
if (destination) {
const form = document.createElement('form');
form.method = 'POST';
form.action = "{{ url_for('move_item', username=username, subpath=current_path) }}";
const nameInput = document.createElement('input');
nameInput.type = 'hidden';
nameInput.name = 'item_name';
nameInput.value = name;
const typeInput = document.createElement('input');
typeInput.type = 'hidden';
typeInput.name = 'item_type';
typeInput.value = type;
const destInput = document.createElement('input');
destInput.type = 'hidden';
destInput.name = 'destination_folder';
destInput.value = destination;
form.appendChild(nameInput);
form.appendChild(typeInput);
form.appendChild(destInput);
document.body.appendChild(form);
form.submit();
}
}
function copyItem(name, type) {
const destination = prompt(`Enter destination path to copy this ${type}:`, '/');
if (destination) {
const form = document.createElement('form');
form.method = 'POST';
form.action = "{{ url_for('copy_item', username=username, subpath=current_path) }}";
const nameInput = document.createElement('input');
nameInput.type = 'hidden';
nameInput.name = 'item_name';
nameInput.value = name;
const typeInput = document.createElement('input');
typeInput.type = 'hidden';
typeInput.name = 'item_type';
typeInput.value = type;
const destInput = document.createElement('input');
destInput.type = 'hidden';
destInput.name = 'destination_folder';
destInput.value = destination;
form.appendChild(nameInput);
form.appendChild(typeInput);
form.appendChild(destInput);
document.body.appendChild(form);
form.submit();
}
}
</script>
</body>
</html>

View File

@ -16,12 +16,19 @@
h2 { h2 {
color: #4CAF50; color: #4CAF50;
} }
ul { .file-list {
list-style-type: none; display: flex;
flex-wrap: wrap;
gap: 10px;
padding: 0; padding: 0;
list-style-type: none;
} }
li { .file-item {
margin-bottom: 10px; background-color: #2a2a2a;
padding: 10px;
border-radius: 5px;
display: flex;
align-items: center;
} }
a { a {
color: #4CAF50; color: #4CAF50;
@ -30,13 +37,34 @@
a:hover { a:hover {
text-decoration: underline; text-decoration: underline;
} }
.folder {
font-weight: bold;
}
.file-icon {
margin-right: 5px;
}
</style> </style>
</head> </head>
<body> <body>
<h2>{{ username }}'s Files</h2> <h2>{{ username }}'s Files</h2>
<ul> <p>Current folder: {{ current_folder or 'Root' }}</p>
{% if parent_url is not none %}
<p><a href="{{ parent_url }}">Parent Directory</a></p>
{% endif %}
<ul class="file-list">
{% for folder in folders %}
<li class="file-item folder">
<span class="file-icon">📁</span>
<a href="{{ url_for('serve_user_page', username=username, filename=folder.path) }}">{{ folder.name }}</a>
</li>
{% endfor %}
{% for file in files %} {% for file in files %}
<li><a href="{{ url_for('download_folder_file', vanity=username, file_name=file) }}">{{ file }}</a></li> <li class="file-item">
<span class="file-icon">📄</span>
<a href="{{ url_for('serve_user_page', username=username, filename=file.path) }}">{{ file.name }}</a>
</li>
{% endfor %} {% endfor %}
</ul> </ul>
</body> </body>

View File

@ -1,27 +0,0 @@
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>&#80;&#121;&#116;&#104;&#111;&#110;&#32;&#73;&#68;&#69;</title><script src="https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.0/brython.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.0/brython_stdlib.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/codemirror.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/mode/python/python.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/addon/hint/show-hint.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/addon/hint/python-hint.js"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/codemirror.min.css"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/theme/monokai.min.css"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/addon/hint/show-hint.css"><style>body{background-color:#1e1e1e;color:#d4d4d4;font-family:'Consolas','Courier New',monospace;margin:0;padding:20px}h1{color:#569cd6}#code{width:100%;height:300px}#output{width:100%;height:200px;background-color:#1e1e1e;border:1px solid #3c3c3c;padding:10px;margin-top:10px;overflow-y:auto;font-family:'Consolas','Courier New',monospace}#run-button,#save-button{background-color:#0e639c;color:white;border:none;padding:10px 20px;margin-top:10px;cursor:pointer}#run-button:hover,#save-button:hover{background-color:#1177bb}.toolbar{margin-bottom:10px}.toolbar button{background-color:#3c3c3c;color:#d4d4d4;border:none;padding:5px 10px;margin-right:5px;cursor:pointer}.toolbar button:hover{background-color:#4e4e4e}</style></head><body onload="brython()"><h1>&#80;&#121;&#116;&#104;&#111;&#110;&#32;&#73;&#68;&#69;</h1><div class="toolbar"><button id="undo-button">&#85;&#110;&#100;&#111;</button><button id="redo-button">&#82;&#101;&#100;&#111;</button><button id="save-button">&#83;&#97;&#118;&#101;</button></div><textarea id="code" placeholder="&#69;&#110;&#116;&#101;&#114;&#32;&#121;&#111;&#117;&#114;&#32;&#80;&#121;&#116;&#104;&#111;&#110;&#32;&#99;&#111;&#100;&#101;&#32;&#104;&#101;&#114;&#101;"></textarea><br><button id="run-button">&#82;&#117;&#110;</button><div id="output"></div><script type="text/python">from browser import document,window
import sys
class _0x1234:
def __init__(_0x5678):_0x5678._0x9abc=document["output"]
def write(_0x5678,_0xdef0):_0x5678._0x9abc.innerHTML+=_0xdef0
sys.stdout=_0x1234()
sys.stderr=_0x1234()
def _0x2345(_0x6789):
document["output"].innerHTML=""
_0xabcd=window.editor.getValue()
try:exec(_0xabcd)
except Exception as _0xef01:print(f"Error: {str(_0xef01)}")
document["run-button"].bind("click",_0x2345)
def _0x3456(_0x789a):window.editor.undo()
def _0x4567(_0x89ab):window.editor.redo()
document["undo-button"].bind("click",_0x3456)
document["redo-button"].bind("click",_0x4567)
def _0x5678(_0x9abc):
_0xbcde=window.editor.getValue()
_0xcdef=window.Blob.new([_0xbcde],{'type':'text/plain'})
_0xdef0=window.URL.createObjectURL(_0xcdef)
_0xef01=document.createElement('a')
_0xef01.href=_0xdef0
_0xef01.download='python_code.py'
_0xef01.click()
window.URL.revokeObjectURL(_0xdef0)
document["save-button"].bind("click",_0x5678)</script><script>var _0x1234=CodeMirror.fromTextArea(document.getElementById("code"),{mode:"python",theme:"monokai",lineNumbers:!0,autoCloseBrackets:!0,matchBrackets:!0,indentUnit:4,tabSize:4,indentWithTabs:!1,extraKeys:{"Ctrl-Space":"autocomplete","Tab":function(_0x5678){_0x5678.somethingSelected()?_0x5678.indentSelection("add"):_0x5678.replaceSelection(_0x5678.getOption("indentWithTabs")?"\t":Array(_0x5678.getOption("indentUnit")+1).join(" "),"end","+input")}},hintOptions:{completeSingle:!1}});_0x1234.on("inputRead",function(_0x2345,_0x3456){if("+input"===_0x3456.origin){var _0x4567=_0x2345.getCursor(),_0x5678=_0x2345.getTokenAt(_0x4567);("variable"===_0x5678.type||"."===_0x5678.string)&&_0x2345.showHint({completeSingle:!1})}})</script></body></html>