forked from spitkov/sxbin
fixes v69
This commit is contained in:
parent
052acdb394
commit
a33bf8f665
167
app.py
167
app.py
@ -233,8 +233,6 @@ def serve_user_page(username, filename=None):
|
|||||||
@app.route('/<vanity>/<password>', methods=['GET', 'POST'])
|
@app.route('/<vanity>/<password>', methods=['GET', 'POST'])
|
||||||
@app.route('/<vanity>/download', methods=['GET', 'POST'])
|
@app.route('/<vanity>/download', methods=['GET', 'POST'])
|
||||||
@app.route('/<vanity>/download/<password>', methods=['GET', 'POST'])
|
@app.route('/<vanity>/download/<password>', methods=['GET', 'POST'])
|
||||||
@app.route('/<vanity>/raw', methods=['GET', 'POST'])
|
|
||||||
@app.route('/<vanity>/raw/<password>', methods=['GET', 'POST'])
|
|
||||||
def redirect_vanity(vanity, password=None):
|
def redirect_vanity(vanity, password=None):
|
||||||
app.logger.info(f"Accessing redirect_vanity: vanity={vanity}, password={password}")
|
app.logger.info(f"Accessing redirect_vanity: vanity={vanity}, password={password}")
|
||||||
app.logger.info(f"Request path: {request.path}")
|
app.logger.info(f"Request path: {request.path}")
|
||||||
@ -247,11 +245,17 @@ def redirect_vanity(vanity, password=None):
|
|||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
|
|
||||||
is_download = 'download' in request.path
|
is_download = 'download' in request.path
|
||||||
is_raw = 'raw' in request.path
|
|
||||||
|
|
||||||
|
# First, try to find the content with the full vanity (including extension)
|
||||||
cursor.execute("SELECT content.*, users.username FROM content LEFT JOIN users ON content.user_id = users.id WHERE content.vanity = ?", (vanity,))
|
cursor.execute("SELECT content.*, users.username FROM content LEFT JOIN users ON content.user_id = users.id WHERE content.vanity = ?", (vanity,))
|
||||||
content = cursor.fetchone()
|
content = cursor.fetchone()
|
||||||
|
|
||||||
|
# If not found, try without the extension
|
||||||
|
if not content:
|
||||||
|
vanity_without_extension = os.path.splitext(vanity)[0]
|
||||||
|
cursor.execute("SELECT content.*, users.username FROM content LEFT JOIN users ON content.user_id = users.id WHERE content.vanity LIKE ?", (f"{vanity_without_extension}%",))
|
||||||
|
content = cursor.fetchone()
|
||||||
|
|
||||||
if content:
|
if content:
|
||||||
content_type, content_data, created_at, user_id, is_private, stored_password, username = content[1], content[2], content[3], content[4], content[5], content[6], content[7]
|
content_type, content_data, created_at, user_id, is_private, stored_password, username = content[1], content[2], content[3], content[4], content[5], content[6], content[7]
|
||||||
app.logger.info(f"Content found: type={content_type}, data={content_data}, is_private={is_private}")
|
app.logger.info(f"Content found: type={content_type}, data={content_data}, is_private={is_private}")
|
||||||
@ -284,8 +288,6 @@ def redirect_vanity(vanity, password=None):
|
|||||||
|
|
||||||
if is_download:
|
if is_download:
|
||||||
return send_file(file_path, as_attachment=True)
|
return send_file(file_path, as_attachment=True)
|
||||||
elif is_raw:
|
|
||||||
return send_file(file_path)
|
|
||||||
else:
|
else:
|
||||||
return render_template('file_info.html',
|
return render_template('file_info.html',
|
||||||
filename=content_data,
|
filename=content_data,
|
||||||
@ -455,12 +457,16 @@ def user_files(username, subpath=''):
|
|||||||
|
|
||||||
uploads = []
|
uploads = []
|
||||||
for upload in user_uploads:
|
for upload in user_uploads:
|
||||||
|
vanity, content_type, data, created_at, _, is_private = upload[:6]
|
||||||
|
url = url_for('redirect_vanity', vanity=vanity, _external=True)
|
||||||
uploads.append({
|
uploads.append({
|
||||||
'type': upload[1],
|
'type': content_type,
|
||||||
'vanity': upload[0],
|
'vanity': vanity,
|
||||||
'data': upload[2],
|
'data': data,
|
||||||
'created_at': upload[3],
|
'created_at': created_at,
|
||||||
'is_private': upload[5]
|
'is_private': is_private,
|
||||||
|
'url': url,
|
||||||
|
'download_url': url + '/download' if content_type == 'file' else None
|
||||||
})
|
})
|
||||||
|
|
||||||
parent_folder = os.path.dirname(subpath.rstrip('/')) if subpath else None
|
parent_folder = os.path.dirname(subpath.rstrip('/')) if subpath else None
|
||||||
@ -798,11 +804,19 @@ def delete_content(vanity):
|
|||||||
def content_info(vanity):
|
def content_info(vanity):
|
||||||
db = get_db()
|
db = get_db()
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
cursor.execute("SELECT * FROM content WHERE vanity = ?", (vanity,))
|
|
||||||
|
# First, try to find the content with the full vanity (including extension)
|
||||||
|
cursor.execute("SELECT content.*, users.username FROM content LEFT JOIN users ON content.user_id = users.id WHERE content.vanity = ?", (vanity,))
|
||||||
content = cursor.fetchone()
|
content = cursor.fetchone()
|
||||||
|
|
||||||
|
# If not found, try without the extension
|
||||||
|
if not content:
|
||||||
|
vanity_without_extension = os.path.splitext(vanity)[0]
|
||||||
|
cursor.execute("SELECT content.*, users.username FROM content LEFT JOIN users ON content.user_id = users.id WHERE content.vanity LIKE ?", (f"{vanity_without_extension}%",))
|
||||||
|
content = cursor.fetchone()
|
||||||
|
|
||||||
if content:
|
if content:
|
||||||
content_type, content_data, created_at, user_id, is_private, password = content[1], content[2], content[3], content[4], content[5], content[6]
|
content_type, content_data, created_at, user_id, is_private, password, username = content[1], content[2], content[3], content[4], content[5], content[6], content[7]
|
||||||
|
|
||||||
if is_private and password:
|
if is_private and password:
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
@ -812,8 +826,6 @@ def content_info(vanity):
|
|||||||
else:
|
else:
|
||||||
return render_template('password_prompt.html', vanity=vanity, error=None)
|
return render_template('password_prompt.html', vanity=vanity, error=None)
|
||||||
|
|
||||||
username = get_username(user_id)
|
|
||||||
|
|
||||||
file_size = None
|
file_size = None
|
||||||
is_media = False
|
is_media = False
|
||||||
if content_type == 'file':
|
if content_type == 'file':
|
||||||
@ -1072,101 +1084,122 @@ def rename_user_file(username):
|
|||||||
|
|
||||||
@app.route('/upload/file', methods=['POST'])
|
@app.route('/upload/file', methods=['POST'])
|
||||||
def upload_file():
|
def upload_file():
|
||||||
app.logger.info("Starting file upload process")
|
app.logger.info("Starting upload_file function")
|
||||||
|
app.logger.info("Code: if 'file' not in request.files:")
|
||||||
if 'file' not in request.files:
|
if 'file' not in request.files:
|
||||||
app.logger.error("No file part in the request")
|
app.logger.error("No file part in the request")
|
||||||
return jsonify({'success': False, 'error': 'No file part'}), 400
|
return jsonify({'success': False, 'error': 'No file part'}), 400
|
||||||
|
|
||||||
|
app.logger.info("Code: file = request.files['file']")
|
||||||
file = request.files['file']
|
file = request.files['file']
|
||||||
|
app.logger.info(f"File object: {file}")
|
||||||
|
|
||||||
|
app.logger.info("Code: if file.filename == '':")
|
||||||
if file.filename == '':
|
if file.filename == '':
|
||||||
app.logger.error("No selected file")
|
app.logger.error("No selected file")
|
||||||
return jsonify({'success': False, 'error': 'No selected file'}), 400
|
return jsonify({'success': False, 'error': 'No selected file'}), 400
|
||||||
|
|
||||||
|
app.logger.info("Code: if file:")
|
||||||
if file:
|
if file:
|
||||||
try:
|
try:
|
||||||
app.logger.info(f"Processing file: {file.filename}")
|
app.logger.info(f"Processing file: {file.filename}")
|
||||||
|
|
||||||
|
app.logger.info("Code: filename = secure_filename(file.filename)")
|
||||||
filename = secure_filename(file.filename)
|
filename = secure_filename(file.filename)
|
||||||
|
app.logger.info(f"Secure filename: {filename}")
|
||||||
|
|
||||||
|
app.logger.info("Code: extension = os.path.splitext(filename)[1].lower()")
|
||||||
extension = os.path.splitext(filename)[1].lower()
|
extension = os.path.splitext(filename)[1].lower()
|
||||||
|
app.logger.info(f"File extension: {extension}")
|
||||||
|
|
||||||
|
app.logger.info("Code: vanity = shortuuid.uuid()[:8]")
|
||||||
vanity = shortuuid.uuid()[:8]
|
vanity = shortuuid.uuid()[:8]
|
||||||
|
app.logger.info(f"Generated vanity: {vanity}")
|
||||||
|
|
||||||
|
app.logger.info("Code: vanity_with_extension = f'{vanity}{extension}'")
|
||||||
vanity_with_extension = f"{vanity}{extension}"
|
vanity_with_extension = f"{vanity}{extension}"
|
||||||
|
app.logger.info(f"Vanity with extension: {vanity_with_extension}")
|
||||||
|
|
||||||
|
app.logger.info("Code: new_filename = vanity_with_extension")
|
||||||
new_filename = vanity_with_extension
|
new_filename = vanity_with_extension
|
||||||
|
app.logger.info(f"New filename: {new_filename}")
|
||||||
|
|
||||||
|
app.logger.info("Code: file_path = os.path.join(current_app.config['UPLOAD_FOLDER'], new_filename)")
|
||||||
file_path = os.path.join(current_app.config['UPLOAD_FOLDER'], new_filename)
|
file_path = os.path.join(current_app.config['UPLOAD_FOLDER'], new_filename)
|
||||||
|
app.logger.info(f"File path: {file_path}")
|
||||||
|
|
||||||
app.logger.info(f"Saving file to: {file_path}")
|
app.logger.info("Code: file.save(file_path)")
|
||||||
file.save(file_path)
|
file.save(file_path)
|
||||||
|
app.logger.info("File saved successfully")
|
||||||
|
|
||||||
|
app.logger.info("Code: user_id = current_user.id if current_user.is_authenticated else None")
|
||||||
user_id = current_user.id if current_user.is_authenticated else None
|
user_id = current_user.id if current_user.is_authenticated else None
|
||||||
app.logger.info(f"User ID: {user_id}")
|
app.logger.info(f"User ID: {user_id}")
|
||||||
|
|
||||||
|
app.logger.info("Code: password = request.form.get('password')")
|
||||||
password = request.form.get('password')
|
password = request.form.get('password')
|
||||||
|
app.logger.info(f"Password: {'Set' if password else 'Not set'}")
|
||||||
|
|
||||||
|
app.logger.info("Code: is_private = 1 if password else 0")
|
||||||
is_private = 1 if password else 0
|
is_private = 1 if password else 0
|
||||||
app.logger.info(f"Is private: {is_private}")
|
app.logger.info(f"Is private: {is_private}")
|
||||||
|
|
||||||
|
app.logger.info("Code: db = get_db()")
|
||||||
db = get_db()
|
db = get_db()
|
||||||
cursor = db.cursor()
|
app.logger.info("Database connection established")
|
||||||
app.logger.info("Inserting file info into database")
|
|
||||||
cursor.execute("INSERT INTO content (vanity, type, data, created_at, user_id, is_private, password) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
||||||
(vanity_with_extension, 'file', new_filename, datetime.now(), user_id, is_private, password))
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
# Determine the scheme based on the original request
|
app.logger.info("Code: cursor = db.cursor()")
|
||||||
|
cursor = db.cursor()
|
||||||
|
app.logger.info("Database cursor created")
|
||||||
|
|
||||||
|
app.logger.info("Inserting file info into database")
|
||||||
|
app.logger.info("Code: vanity_for_db = vanity_with_extension")
|
||||||
|
vanity_for_db = vanity_with_extension
|
||||||
|
app.logger.info(f"Vanity for DB: {vanity_for_db}")
|
||||||
|
|
||||||
|
app.logger.info("Code: cursor.execute(...)")
|
||||||
|
cursor.execute("INSERT INTO content (vanity, type, data, created_at, user_id, is_private, password) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
(vanity_for_db, 'file', new_filename, datetime.now(), user_id, is_private, password))
|
||||||
|
app.logger.info("SQL query executed")
|
||||||
|
|
||||||
|
app.logger.info("Code: db.commit()")
|
||||||
|
db.commit()
|
||||||
|
app.logger.info("Database changes committed")
|
||||||
|
|
||||||
|
app.logger.info("Code: scheme = 'https' if request.is_secure else 'http'")
|
||||||
scheme = 'https' if request.is_secure else 'http'
|
scheme = 'https' if request.is_secure else 'http'
|
||||||
app.logger.info(f"Using scheme: {scheme}")
|
app.logger.info(f"Using scheme: {scheme}")
|
||||||
|
|
||||||
app.logger.info("Generating URLs")
|
app.logger.info("Generating URLs")
|
||||||
app.logger.info(f"vanity_with_extension: {vanity_with_extension}")
|
app.logger.info("Code: short_url = url_for('redirect_vanity', vanity=vanity_with_extension, _external=True, _scheme=scheme)")
|
||||||
|
|
||||||
# Log the URL generation process step by step
|
|
||||||
app.logger.info("Generating short URL:")
|
|
||||||
app.logger.info(f"1. Calling url_for with: 'redirect_vanity', vanity={vanity_with_extension}")
|
|
||||||
app.logger.info(f" Full parameters: endpoint='redirect_vanity', vanity={vanity_with_extension}, _external=True, _scheme={scheme}")
|
|
||||||
|
|
||||||
# Capture the result of url_for and remove the /raw suffix
|
|
||||||
short_url = url_for('redirect_vanity', vanity=vanity_with_extension, _external=True, _scheme=scheme)
|
short_url = url_for('redirect_vanity', vanity=vanity_with_extension, _external=True, _scheme=scheme)
|
||||||
short_url = short_url.rstrip('/raw')
|
short_url = short_url.rstrip('/download') # Remove the '/download' suffix if present
|
||||||
|
app.logger.info(f"Generated short URL: {short_url}")
|
||||||
|
|
||||||
app.logger.info(f"2. Result of url_for (after removing /raw): {short_url}")
|
app.logger.info("Code: download_url = short_url + '/download'")
|
||||||
app.logger.info(f"3. Inspecting short_url:")
|
|
||||||
app.logger.info(f" - Base: {short_url.split('?')[0]}")
|
|
||||||
app.logger.info(f" - Query parameters: {short_url.split('?')[1] if '?' in short_url else 'None'}")
|
|
||||||
|
|
||||||
app.logger.info("Generating download URL:")
|
|
||||||
download_url = short_url + '/download'
|
download_url = short_url + '/download'
|
||||||
app.logger.info(f"4. Download URL: {download_url}")
|
app.logger.info(f"Generated download URL: {download_url}")
|
||||||
|
|
||||||
app.logger.info("Generating deletion URL:")
|
app.logger.info("Code: deletion_url = url_for('delete_content', vanity=vanity_with_extension, _external=True, _scheme=scheme)")
|
||||||
app.logger.info(f"5. Calling url_for with: 'delete_content', vanity={vanity_with_extension}")
|
|
||||||
app.logger.info(f" Full parameters: endpoint='delete_content', vanity={vanity_with_extension}, _external=True, _scheme={scheme}")
|
|
||||||
|
|
||||||
# Capture the result of url_for for deletion
|
|
||||||
deletion_url = url_for('delete_content', vanity=vanity_with_extension, _external=True, _scheme=scheme)
|
deletion_url = url_for('delete_content', vanity=vanity_with_extension, _external=True, _scheme=scheme)
|
||||||
|
app.logger.info(f"Generated deletion URL: {deletion_url}")
|
||||||
|
|
||||||
app.logger.info(f"6. Result of deletion url_for: {deletion_url}")
|
app.logger.info("Preparing JSON response")
|
||||||
|
response_data = {
|
||||||
|
'success': True,
|
||||||
|
'vanity': vanity_with_extension,
|
||||||
|
'url': short_url,
|
||||||
|
'download_url': download_url,
|
||||||
|
'deletion_url': deletion_url,
|
||||||
|
'filename': new_filename
|
||||||
|
}
|
||||||
|
app.logger.info(f"Response data: {response_data}")
|
||||||
|
|
||||||
# Add debug logging
|
return jsonify(response_data)
|
||||||
app.logger.info(f"File uploaded: {new_filename}")
|
|
||||||
app.logger.info(f"File path: {file_path}")
|
|
||||||
app.logger.info(f"Short URL: {short_url}")
|
|
||||||
app.logger.info(f"Download URL: {download_url}")
|
|
||||||
|
|
||||||
# Check if the request is from ShareX
|
|
||||||
if 'X-API-Key' in request.headers:
|
|
||||||
app.logger.info("Request from ShareX detected")
|
|
||||||
return json.dumps({
|
|
||||||
'status': 'success',
|
|
||||||
'url': short_url,
|
|
||||||
'deletion_url': deletion_url,
|
|
||||||
})
|
|
||||||
else:
|
|
||||||
app.logger.info("Returning JSON response")
|
|
||||||
return jsonify({
|
|
||||||
'success': True,
|
|
||||||
'vanity': vanity_with_extension,
|
|
||||||
'url': short_url,
|
|
||||||
'download_url': download_url,
|
|
||||||
'deletion_url': deletion_url,
|
|
||||||
'filename': new_filename
|
|
||||||
})
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
app.logger.error(f"Error uploading file: {str(e)}")
|
app.logger.error(f"Error uploading file: {str(e)}")
|
||||||
|
app.logger.exception("Exception traceback:")
|
||||||
return jsonify({'success': False, 'error': str(e)}), 500
|
return jsonify({'success': False, 'error': str(e)}), 500
|
||||||
|
|
||||||
app.logger.error("Unknown error occurred")
|
app.logger.error("Unknown error occurred")
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<meta property="og:url" content="{{ request.url }}">
|
<meta property="og:url" content="{{ request.url }}">
|
||||||
<meta property="og:description" content="File size: {{ file_size|filesizeformat }} | Uploaded by: {{ username }} | Date: {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}">
|
<meta property="og:description" content="File size: {{ file_size|filesizeformat }} | Uploaded by: {{ username }} | Date: {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}">
|
||||||
{% if is_embeddable %}
|
{% if is_embeddable %}
|
||||||
<meta property="og:image" content="{{ file_url }}/raw">
|
<meta property="og:image" content="{{ file_url }}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<meta property="og:site_name" content="sxbin">
|
<meta property="og:site_name" content="sxbin">
|
||||||
<meta property="theme-color" content="#4CAF50">
|
<meta property="theme-color" content="#4CAF50">
|
||||||
@ -115,16 +115,16 @@
|
|||||||
{% if is_embeddable %}
|
{% if is_embeddable %}
|
||||||
<div class="embed-container">
|
<div class="embed-container">
|
||||||
{% if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.svg')) %}
|
{% if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.svg')) %}
|
||||||
<img src="{{ file_url }}/raw" alt="{{ filename }}">
|
<img src="{{ file_url }}" alt="{{ filename }}">
|
||||||
{% elif filename.lower().endswith('.pdf') %}
|
{% elif filename.lower().endswith('.pdf') %}
|
||||||
<embed src="{{ file_url }}/raw" type="application/pdf" width="100%" height="600px">
|
<embed src="{{ file_url }}" type="application/pdf" width="100%" height="600px">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
<a href="{{ file_url }}/download" class="btn">Download</a>
|
<a href="{{ file_url }}/download" class="btn">Download</a>
|
||||||
<a href="{{ file_url }}/raw" class="btn">View Raw</a>
|
<a href="{{ file_url }}" class="btn">View Raw</a>
|
||||||
{% if current_user.is_authenticated and current_user.id == user_id %}
|
{% if current_user.is_authenticated and current_user.id == user_id %}
|
||||||
{% if filename.lower().endswith(('.txt', '.html', '.css', '.js', '.py', '.md')) or '.' not in filename %}
|
{% if filename.lower().endswith(('.txt', '.html', '.css', '.js', '.py', '.md')) or '.' not in filename %}
|
||||||
<a href="{{ url_for('edit_content', vanity=vanity) }}" class="btn edit-btn">Edit</a>
|
<a href="{{ url_for('edit_content', vanity=vanity) }}" class="btn edit-btn">Edit</a>
|
||||||
|
@ -3,14 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{{ filename }} - sxbin</title>
|
<title>Pastebin {{ vanity }} - sxbin</title>
|
||||||
<meta property="og:title" content="{{ filename }}">
|
<meta property="og:title" content="Pastebin {{ vanity }} - sxbin">
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
<meta property="og:url" content="{{ request.url }}">
|
<meta property="og:url" content="{{ request.url }}">
|
||||||
<meta property="og:description" content="File size: {{ file_size|filesizeformat }} | Uploaded by: {{ username }} | Date: {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}">
|
<meta property="og:description" content="Uploaded by: {{ content.username }} | Date: {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}">
|
||||||
{% if is_embeddable %}
|
|
||||||
<meta property="og:image" content="{{ file_url }}">
|
|
||||||
{% endif %}
|
|
||||||
<meta property="og:site_name" content="sxbin">
|
<meta property="og:site_name" content="sxbin">
|
||||||
<meta property="theme-color" content="#4CAF50">
|
<meta property="theme-color" content="#4CAF50">
|
||||||
<style>
|
<style>
|
||||||
@ -152,32 +149,25 @@
|
|||||||
<body>
|
<body>
|
||||||
<a href="/" class="home-button">⌂</a>
|
<a href="/" class="home-button">⌂</a>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>{{ filename }}</h2>
|
<h2>Content</h2>
|
||||||
<div class="info-item"><strong>File size:</strong> {{ file_size|filesizeformat }}</div>
|
<p>Uploaded by: {{ content.username }}</p>
|
||||||
<div class="info-item"><strong>Uploaded by:</strong> {{ username }}</div>
|
<p>Created at: {{ created_at }}</p>
|
||||||
<div class="info-item"><strong>Date:</strong> {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}</div>
|
|
||||||
|
|
||||||
{% if is_embeddable %}
|
<div class="highlight">
|
||||||
<div class="embed-container">
|
{{ highlighted_content|safe }}
|
||||||
{% if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.svg')) %}
|
|
||||||
<img src="{{ file_url }}/raw" alt="{{ filename }}">
|
|
||||||
{% elif filename.lower().endswith('.pdf') %}
|
|
||||||
<embed src="{{ file_url }}/raw" type="application/pdf" width="100%" height="600px">
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
|
||||||
<div class="info-item"><strong>File type:</strong> {{ filename.split('.')[-1].upper() if '.' in filename else 'Unknown' }}</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
<a href="{{ file_url }}/download" class="btn">Download</a>
|
<button onclick="copyToClipboard()" class="btn">Copy</button>
|
||||||
<a href="{{ file_url }}/raw" class="btn">View Raw</a>
|
<a href="{{ url_for('raw_vanity', vanity=vanity) }}" class="btn">View Raw</a>
|
||||||
{% if current_user.is_authenticated and current_user.id == user_id %}
|
{% if current_user.is_authenticated and current_user.id == content.user_id %}
|
||||||
{% if filename.lower().endswith(('.txt', '.html', '.css', '.js', '.py', '.md')) or '.' not in filename %}
|
<a href="{{ url_for('edit_content', vanity=vanity) }}" class="btn">Edit</a>
|
||||||
<a href="{{ url_for('edit_content', vanity=vanity) }}" class="btn edit-btn">Edit</a>
|
{% if is_private %}
|
||||||
|
<button onclick="openEditPasswordModal()" class="btn">Edit Password</button>
|
||||||
|
{% else %}
|
||||||
|
<button onclick="openAddPasswordModal()" class="btn">Add Password</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<form action="{{ url_for('delete_content', vanity=vanity) }}" method="post" style="display: inline;">
|
<form action="{{ url_for('delete_content', vanity=vanity) }}" method="post">
|
||||||
<button type="submit" class="btn delete-btn" onclick="return confirm('Are you sure you want to delete this file?')">Delete</button>
|
<button type="submit" class="btn">Delete</button>
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
@ -194,6 +184,16 @@
|
|||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
const rawContent = {{ raw_content|tojson }};
|
||||||
|
|
||||||
|
function copyToClipboard() {
|
||||||
|
navigator.clipboard.writeText(rawContent).then(() => {
|
||||||
|
alert('Copied to clipboard!');
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('Failed to copy text: ', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const themeToggle = document.getElementById('theme-toggle');
|
const themeToggle = document.getElementById('theme-toggle');
|
||||||
const html = document.documentElement;
|
const html = document.documentElement;
|
||||||
|
|
||||||
|
@ -954,7 +954,7 @@
|
|||||||
{% elif upload.type == 'url' %}
|
{% elif upload.type == 'url' %}
|
||||||
Shortened URL:
|
Shortened URL:
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{{ url_for('redirect_vanity', vanity=upload.vanity) }}" target="_blank">
|
<a href="{{ upload.url }}" target="_blank">
|
||||||
{% if upload.type == 'file' %}
|
{% if upload.type == 'file' %}
|
||||||
{{ upload.data }}
|
{{ upload.data }}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
Loading…
Reference in New Issue
Block a user