From d4044904426c02dd1110927f861d64c489693e8d Mon Sep 17 00:00:00 2001 From: spitkov Date: Wed, 11 Sep 2024 19:29:29 +0200 Subject: [PATCH] minor improvement to user dashboard --- .gitignore | 29 +++ app.py | 176 +++++++--------- templates/user_files.html | 421 ++++++++++++++++++++++++++++++-------- 3 files changed, 443 insertions(+), 183 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b34497f --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Ignore SQLite database +data.db + +# Ignore uploads directory +/uploads/ + +# Python-related files +__pycache__/ +*.py[cod] +*$py.class + +# Virtual environment +venv/ +env/ +.env + +# IDE-specific files +.vscode/ +.idea/ + +# OS-specific files +.DS_Store +Thumbs.db + +# Log files +*.log + +# Temporary files +*.tmp \ No newline at end of file diff --git a/app.py b/app.py index 6385246..a174e73 100644 --- a/app.py +++ b/app.py @@ -22,7 +22,7 @@ app.secret_key = 'your_secret_key_here' # Add this line UPLOAD_FOLDER = './uploads' app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER DATABASE = 'data.db' -app.config['REMEMBER_COOKIE_DURATION'] = timedelta(days=30) # Set cookie to expire after 30 days +app.config['REMEMBER_COOKIE_DURATION'] = timedelta(days=30) # Set cookie to expire after 30 day if not os.path.exists(UPLOAD_FOLDER): os.makedirs(UPLOAD_FOLDER) @@ -501,17 +501,6 @@ def rename_user_file(username): os.rename(old_path, new_path) return redirect(url_for('user_files', username=username)) -@app.route('/dash//create_folder', methods=['POST']) -@login_required -def create_folder(username): - if current_user.username != username: - 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)) @app.route('/dash//delete_folder/', methods=['POST']) @login_required @@ -880,7 +869,7 @@ def create_new_file(username): if current_user.username != username: return "Unauthorized", 401 subpath = request.form.get('subpath', '').rstrip('/') - file_name = secure_filename(request.form['file_name']) + file_name = request.form['file_name'] file_path = os.path.join(app.config['UPLOAD_FOLDER'], username, subpath, file_name) if not os.path.exists(file_path): with open(file_path, 'w') as f: @@ -890,95 +879,84 @@ def create_new_file(username): flash(f"File '{file_name}' already exists.", 'error') return redirect(url_for('user_files', username=username, subpath=subpath)) +@app.route('/dash//get_folders') +@login_required +def get_folders(username): + if current_user.username != username: + return jsonify({'error': 'Unauthorized'}), 401 + + subpath = request.args.get('path', '') + folder_path = os.path.join(app.config['UPLOAD_FOLDER'], username, subpath) + + if not os.path.exists(folder_path): + return jsonify({'error': 'Folder not found'}), 404 + + folders = [f for f in os.listdir(folder_path) if os.path.isdir(os.path.join(folder_path, f))] + return jsonify(folders) + +@app.route('/dash//get_folders_and_files') +@login_required +def get_folders_and_files(username): + if current_user.username != username: + return jsonify({'error': 'Unauthorized'}), 401 + + subpath = request.args.get('path', '') + folder_path = os.path.join(app.config['UPLOAD_FOLDER'], username, subpath) + + if not os.path.exists(folder_path): + return jsonify({'error': 'Folder not found'}), 404 + + folders = [] + files = [] + for item in os.listdir(folder_path): + item_path = os.path.join(folder_path, item) + if os.path.isdir(item_path): + folders.append(item) + else: + files.append(item) + + return jsonify({'folders': folders, 'files': files}) + +@app.route('/dash//create_folder', methods=['POST']) +@login_required +def create_folder(username): + if current_user.username != username: + return jsonify({'error': 'Unauthorized'}), 401 + + if request.is_json: + data = request.get_json() + folder_name = data.get('folder_name') + subpath = data.get('subpath', '').rstrip('/') + else: + folder_name = request.form.get('folder_name') + subpath = request.form.get('subpath', '').rstrip('/') + + if not folder_name: + return jsonify({'error': 'Folder name is required'}), 400 + + folder_path = os.path.join(app.config['UPLOAD_FOLDER'], username, subpath, folder_name) + + if os.path.exists(folder_path): + return jsonify({'error': 'Folder already exists'}), 400 + + try: + os.makedirs(folder_path) + if request.is_json: + return jsonify({'success': True, 'message': 'Folder created successfully'}) + else: + flash(f"Folder '{folder_name}' created successfully.", 'success') + return redirect(url_for('user_files', username=username, subpath=subpath)) + except Exception as e: + if request.is_json: + return jsonify({'error': str(e)}), 500 + else: + flash(f"Error creating folder: {str(e)}", 'error') + return redirect(url_for('user_files', username=username, subpath=subpath)) + if __name__ == '__main__': # Start the cleanup thread cleanup_thread = threading.Thread(target=delete_old_files) cleanup_thread.daemon = True cleanup_thread.start() - app.run(host='0.0.0.0', port=7123, debug=True) -def api_upload(): - api_key = request.headers.get('X-API-Key') - if not api_key: - return jsonify({'error': 'API key is missing'}), 401 - - db = get_db() - cursor = db.cursor() - cursor.execute("SELECT * FROM users WHERE api_key = ?", (api_key,)) - user = cursor.fetchone() - - if not user: - return jsonify({'error': 'Invalid API key'}), 401 - - if 'file' in request.files: - file = request.files['file'] - if file.filename == '': - return jsonify({'error': 'No selected file'}), 400 - if file: - filename = secure_filename(file.filename) - extension = os.path.splitext(filename)[1].lower() - - if extension == '.txt': - # Handle text files as pastebins - content = file.read().decode('utf-8') - vanity = shortuuid.uuid()[:8] - - cursor.execute("INSERT INTO content (vanity, type, data, created_at, user_id) VALUES (?, ?, ?, ?, ?)", - (vanity, 'pastebin', content, datetime.now(), user[0])) - db.commit() - - url = url_for('redirect_vanity', vanity=vanity, _external=True, _scheme='https') - delete_url = url_for('delete_content', vanity=vanity, _external=True, _scheme='https') - else: - # Handle other file types - vanity = shortuuid.uuid()[:8] - new_filename = f"{vanity}{extension}" - file_path = os.path.join(app.config['UPLOAD_FOLDER'], new_filename) - file.save(file_path) - - cursor.execute("INSERT INTO content (vanity, type, data, created_at, user_id) VALUES (?, ?, ?, ?, ?)", - (new_filename, 'file', new_filename, datetime.now(), user[0])) - db.commit() - - url = url_for('redirect_vanity', vanity=new_filename, _external=True, _scheme='https') - delete_url = url_for('delete_content', vanity=new_filename, _external=True, _scheme='https') - - return json.dumps({ - 'status': 'success', - 'url': url.replace('/download', ''), - 'deletion_url': delete_url, - }) - elif 'text' in request.form: - content = request.form['text'] - vanity = shortuuid.uuid()[:8] - - cursor.execute("INSERT INTO content (vanity, type, data, created_at, user_id) VALUES (?, ?, ?, ?, ?)", - (vanity, 'pastebin', content, datetime.now(), user[0])) - db.commit() - - url = url_for('redirect_vanity', vanity=vanity, _external=True, _scheme='https') - delete_url = url_for('delete_content', vanity=vanity, _external=True, _scheme='https') - - return json.dumps({ - 'status': 'success', - 'url': url.replace('/download', ''), - 'deletion_url': delete_url, - }) - elif 'url' in request.form: - long_url = request.form['url'] - vanity = shortuuid.uuid()[:8] - - cursor.execute("INSERT INTO content (vanity, type, data, created_at, user_id) VALUES (?, ?, ?, ?, ?)", - (vanity, 'url', long_url, datetime.now(), user[0])) - db.commit() - - short_url = url_for('redirect_vanity', vanity=vanity, _external=True, _scheme='https') - delete_url = url_for('delete_content', vanity=vanity, _external=True, _scheme='https') - - return json.dumps({ - 'status': 'success', - 'url': short_url.replace('/download', ''), - 'deletion_url': delete_url, - }) - - return jsonify({'error': 'No file, text, or URL content provided'}), 400 \ No newline at end of file + app.run(host='0.0.0.0', port=7123, debug=True) \ No newline at end of file diff --git a/templates/user_files.html b/templates/user_files.html index bc1e691..bfc0103 100644 --- a/templates/user_files.html +++ b/templates/user_files.html @@ -107,6 +107,61 @@ .tab-content.active { display: block; } + .modal { + display: none; + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0,0,0,0.5); + } + .modal-content { + background-color: #2a2a2a; + margin: 15% auto; + padding: 20px; + border-radius: 8px; + width: 300px; + box-shadow: 0 4px 8px rgba(0,0,0,0.2); + } + .modal-input { + width: 100%; + padding: 8px; + margin: 10px 0; + border-radius: 4px; + border: 1px solid #4CAF50; + background-color: #333; + color: #f0f0f0; + } + .modal-buttons { + display: flex; + justify-content: flex-end; + gap: 10px; + margin-top: 15px; + } + .action-buttons { + display: flex; + justify-content: center; + gap: 10px; + margin: 20px 0; + } + .file-list { + border-radius: 8px; + overflow: hidden; + } + .file-item { + border-radius: 0; + margin-bottom: 0; + border-bottom: 1px solid #3a3a3a; + } + .file-item:last-child { + border-bottom: none; + } + .file-actions .btn { + padding: 4px 8px; + font-size: 12px; + } @@ -145,19 +200,10 @@ -

Create Folder

-
- - - -
- -

Create New File

-
- - - -
+
+ + +

Files and Folders

Current folder: {{ current_folder or 'Root' }}

@@ -169,9 +215,6 @@ .. -
- -
{% endif %} {% for item in items %} @@ -185,10 +228,10 @@ {% endif %}
+ + + - - - {% if item.type == 'file' %} Edit {% endif %} @@ -237,6 +280,36 @@
+ + + + \ No newline at end of file