diff --git a/app.py b/app.py
index a34e2ed..e942a6c 100644
--- a/app.py
+++ b/app.py
@@ -3,12 +3,12 @@ from werkzeug.utils import secure_filename
import shortuuid
import os
from datetime import datetime
+import zipfile
app = Flask(__name__)
UPLOAD_FOLDER = './uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
-
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)
@@ -52,16 +52,11 @@ def upload_pastebin():
created_at = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
data_store[vanity] = {'type': 'pastebin', 'content': content, 'created_at': created_at}
-
html_content = render_template('content.html', content=content, created_at=created_at)
html_file_path = os.path.join('templates', f'{vanity}.html')
with open(html_file_path, 'w') as f:
f.write(html_content)
- html_content = render_template('raw.html', content=content)
- html_file_path = os.path.join('templates', f'{vanity}raw.html')
- with open(html_file_path, 'w') as f:
- f.write(html_content)
-
+
return jsonify({'vanity': vanity})
@app.route('/upload/file', methods=['POST'])
@@ -78,7 +73,6 @@ def upload_file():
file.save(filepath)
data_store[vanity] = {'type': 'file', 'filename': filename}
-
file_info = {
'name': filename,
'size': os.path.getsize(filepath),
@@ -92,13 +86,45 @@ def upload_file():
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:
+ save_file(file, base_path)
+
+@app.route('/upload/folder', methods=['POST'])
+def upload_folder():
+ if 'file' not in request.files:
+ return 'No files uploaded', 400
+
+ files = request.files.getlist('file')
+ if not files:
+ return 'No files selected', 400
+
+ vanity = shortuuid.uuid()[:6]
+ folder_path = os.path.join(app.config['UPLOAD_FOLDER'], vanity)
+ os.makedirs(folder_path)
+
+ handle_uploaded_folder(files, folder_path)
+
+ data_store[vanity] = {'type': 'folder', 'files': [file.filename for file in files]}
+
+ return jsonify({'vanity': vanity})
+
@app.route('/shorten', methods=['POST'])
def shorten_url():
original_url = request.form['url']
vanity = shortuuid.uuid()[:6]
data_store[vanity] = {'type': 'url', 'url': original_url}
-
html_content = f'
'
html_file_path = os.path.join('templates', f'{vanity}.html')
with open(html_file_path, 'w') as f:
@@ -112,10 +138,8 @@ def redirect_vanity(vanity):
if target:
if target['type'] == 'pastebin':
-
return render_template(f'{vanity}.html')
elif target['type'] == 'file':
-
file_path = os.path.join(app.config['UPLOAD_FOLDER'], f'{vanity}_{target["filename"]}')
file_info = {
'name': target['filename'],
@@ -123,9 +147,11 @@ def redirect_vanity(vanity):
'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 target['type'] == 'folder':
+ return redirect(url_for('folder_content', vanity=vanity))
+ elif target['type'] == 'url':
+ return render_template('content.html', url=target['url'])
return render_template('404.html'), 404
@app.route('//raw', methods=['GET'])
@@ -134,11 +160,61 @@ def raw_vanity(vanity):
if target:
if target['type'] == 'pastebin':
-
return render_template(f'{vanity}raw.html')
-
return render_template('404.html'), 404
+@app.route('/folder/', methods=['GET'])
+def folder_content(vanity):
+ target = data_store.get(vanity)
+ if target and target['type'] == 'folder':
+ folder_path = os.path.join(app.config['UPLOAD_FOLDER'], vanity)
+ files = []
+ for root, _, filenames in os.walk(folder_path):
+ for filename in filenames:
+ file_path = os.path.join(root, filename)
+ relative_path = os.path.relpath(file_path, folder_path)
+ file_url = url_for('download_folder_file', vanity=vanity, file_name=relative_path)
+ files.append({'name': relative_path, 'url': file_url})
+
+ # Pagination
+ per_page = 10
+ page = int(request.args.get('page', 1))
+ start = (page - 1) * per_page
+ end = start + per_page
+ total_files = len(files)
+ files = files[start:end]
+
+ prev_url = url_for('folder_content', vanity=vanity, page=page-1) if page > 1 else None
+ next_url = url_for('folder_content', vanity=vanity, page=page+1) if end < total_files else None
+
+ return render_template('folder.html', files=files, prev_url=prev_url, next_url=next_url)
+
+ return 'Not Found', 404
+
+@app.route('/folder//download', methods=['GET'])
+def download_folder_as_zip(vanity):
+ target = data_store.get(vanity)
+ if target and target['type'] == 'folder':
+ folder_path = os.path.join(app.config['UPLOAD_FOLDER'], vanity)
+ zip_path = os.path.join(app.config['UPLOAD_FOLDER'], f'{vanity}.zip')
+
+ with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
+ for root, _, files in os.walk(folder_path):
+ for file in files:
+ file_path = os.path.join(root, file)
+ zipf.write(file_path, os.path.relpath(file_path, folder_path))
+
+ return send_from_directory(app.config['UPLOAD_FOLDER'], f'{vanity}.zip', as_attachment=True)
+ return 'Not Found', 404
+
+@app.route('/folder//', methods=['GET'])
+def download_folder_file(vanity, file_name):
+ folder_path = os.path.join(app.config['UPLOAD_FOLDER'], vanity)
+ file_path = os.path.join(folder_path, file_name)
+ if os.path.isfile(file_path):
+ return send_from_directory(folder_path, file_name, as_attachment=True)
+ return 'Not Found', 404
+
if __name__ == '__main__':
- app.run(debug=True,port=7123)
\ No newline at end of file
+ app.run(debug=True, port=7123)
diff --git a/templates/folder.html b/templates/folder.html
new file mode 100644
index 0000000..e6b5340
--- /dev/null
+++ b/templates/folder.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Folder
+
+
+
+
+
+
diff --git a/templates/index.html b/templates/index.html
index 445bcce..9ff8997 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -75,33 +75,31 @@
color: #f5f5f5;
}
+ .footer {
+ background-color: #2c2f33;
+ color: #99aab5;
+ padding: 10px 0;
+ position: fixed;
+ bottom: 0;
+ width: 100%;
+ text-align: center;
+ font-size: 14px;
+ }
-.footer {
- background-color: #2c2f33;
- color: #99aab5;
- padding: 10px 0;
- position: fixed;
- bottom: 0;
- width: 100%;
- text-align: center;
- font-size: 14px;
-}
+ .footer a {
+ color: #61afef;
+ text-decoration: none;
+ }
-.footer a {
- color: #61afef;
- text-decoration: none;
-}
-
-.footer a:hover {
- text-decoration: underline;
-}
-
-.footer .container {
- max-width: 1200px;
- margin: 0 auto;
- padding: 0 15px;
-}
+ .footer a:hover {
+ text-decoration: underline;
+ }
+ .footer .container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 0 15px;
+ }
@@ -111,6 +109,7 @@
+
+
Shorten URL
-