Spaces:
Sleeping
Sleeping
import os | |
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, abort, session, Response, jsonify | |
from werkzeug.utils import secure_filename | |
import mimetypes | |
from flask_httpauth import HTTPBasicAuth | |
from werkzeug.security import generate_password_hash, check_password_hash | |
import shutil | |
app = Flask(__name__) | |
app.secret_key = 'your_secret_key_here' | |
app.config['UPLOAD_FOLDER'] = 'shared_files' | |
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 * 1024 # 16GB | |
app.config['BASIC_AUTH_USERNAME'] = 'admin' | |
app.config['BASIC_AUTH_PASSWORD'] = 'password' | |
app.config['BASIC_AUTH_FORCE'] = True | |
auth = HTTPBasicAuth() | |
app.jinja_env.globals['os'] = os | |
users = { | |
"admin": generate_password_hash("password"), | |
"user": generate_password_hash("userpass") | |
} | |
def verify_password(username, password): | |
if username in users and check_password_hash(users.get(username), password): | |
session['username'] = username | |
return username | |
return None | |
def ensure_upload_folder(): | |
if not os.path.exists(app.config['UPLOAD_FOLDER']): | |
os.makedirs(app.config['UPLOAD_FOLDER']) | |
def get_current_directory(): | |
return session.get('current_directory', '') | |
def set_current_directory(directory): | |
session['current_directory'] = directory | |
def get_file_json(): | |
directory = request.args.get('dir', '') | |
full_path = os.path.join(app.config['UPLOAD_FOLDER'], directory) | |
if not os.path.isdir(full_path): | |
return jsonify({'error': 'Directory not found'}), 404 | |
files = [] | |
dirs = [] | |
# 指定ディレクトリ内のファイルとサブディレクトリを再帰的に探索 | |
for root, _, filenames in os.walk(full_path): | |
relative_root = os.path.relpath(root, app.config['UPLOAD_FOLDER']) | |
# サブディレクトリ情報を追加 | |
if root != full_path: # 現在のディレクトリ自体は除く | |
dirs.append({ | |
'name': os.path.basename(root), | |
'path': relative_root.replace('\\', '/'), # Windows対策 | |
'type': 'directory' | |
}) | |
# ファイル情報を追加 | |
for filename in filenames: | |
file_path = os.path.join(root, filename) | |
relative_path = os.path.join(relative_root, filename).replace('\\', '/') # Windows対策 | |
files.append({ | |
'name': filename, | |
'path': relative_path, | |
'size': os.path.getsize(file_path), | |
'modified': os.path.getmtime(file_path), | |
'type': 'file' | |
}) | |
# 親ディレクトリのパスを準備 | |
parent_dir = os.path.dirname(directory) if directory else '' | |
return jsonify({ | |
'current_dir': directory, | |
'files': files, | |
'dirs': dirs, | |
'parent_dir': parent_dir, | |
'all_files': files, # すべてのファイルを含む | |
'all_dirs': dirs # すべてのディレクトリを含む | |
}) | |
def get_full_path(path=''): | |
return os.path.join(app.config['UPLOAD_FOLDER'], get_current_directory(), path) | |
def sw(): | |
js_content = render_template('sw.js') | |
return Response(js_content, mimetype='application/javascript') | |
# shared_files ルートを修正 | |
def shared_files(filename): | |
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) | |
if not os.path.exists(file_path): | |
abort(404) | |
# PDFの場合はインライン表示 | |
if filename.lower().endswith('.pdf'): | |
return send_from_directory( | |
app.config['UPLOAD_FOLDER'], | |
filename, | |
as_attachment=False, | |
mimetype='application/pdf' | |
) | |
mimetype, _ = mimetypes.guess_type(file_path) | |
if not mimetype: | |
mimetype = 'application/octet-stream' | |
response = send_from_directory( | |
app.config['UPLOAD_FOLDER'], | |
filename, | |
as_attachment=False, | |
mimetype=mimetype | |
) | |
response.headers.update({ | |
'X-Content-Type-Options': 'nosniff', | |
'Cache-Control': 'no-cache, must-revalidate' | |
}) | |
return response | |
def index(): | |
ensure_upload_folder() | |
current_dir = get_current_directory() | |
full_path = get_full_path() | |
# ディレクトリが存在しない場合はルートにリセット | |
if not os.path.exists(full_path): | |
set_current_directory('') | |
return redirect(url_for('dev')) | |
files = [] | |
dirs = [] | |
for item in os.listdir(full_path): | |
item_path = os.path.join(full_path, item) | |
if os.path.isfile(item_path): | |
files.append(item) | |
else: | |
dirs.append(item) | |
return render_template('index.html', files=files, dirs=dirs, current_dir=current_dir) | |
def get_files_list(): | |
file_list = [] | |
for root, dirs, files in os.walk(app.config['UPLOAD_FOLDER']): | |
for file in files: | |
file_path = os.path.join(root, file) | |
relative_path = os.path.relpath(file_path, app.config['UPLOAD_FOLDER']) | |
file_list.append({ | |
'path': relative_path, | |
'size': os.path.getsize(file_path), | |
'modified': os.path.getmtime(file_path) | |
}) | |
return jsonify(file_list) | |
def dev(): | |
ensure_upload_folder() | |
current_dir = get_current_directory() | |
full_path = get_full_path() | |
# ディレクトリが存在しない場合はルートにリセット | |
if not os.path.exists(full_path): | |
set_current_directory('') | |
return redirect(url_for('dev')) | |
files = [] | |
dirs = [] | |
try: | |
for item in os.listdir(full_path): | |
item_path = os.path.join(full_path, item) | |
if os.path.isfile(item_path): | |
files.append(item) | |
else: | |
dirs.append(item) | |
except FileNotFoundError: | |
set_current_directory('') | |
return redirect(url_for('dev')) | |
return render_template('dev.html', files=files, dirs=dirs, current_dir=current_dir) | |
def change_dir(directory): | |
full_path = os.path.join(app.config['UPLOAD_FOLDER'], directory) | |
# ディレクトリが存在する場合のみ変更 | |
if os.path.isdir(full_path): | |
set_current_directory(directory) | |
if request.referrer and 'dev' in request.referrer: | |
return redirect(url_for('dev')) | |
return redirect(url_for('index')) | |
def upload_file(): | |
if 'file' not in request.files: | |
return redirect(request.referrer) | |
file = request.files['file'] | |
if file.filename == '': | |
return redirect(request.referrer) | |
if file: | |
filename = secure_filename(file.filename) | |
# 現在のディレクトリを取得 | |
current_dir = request.form.get('dir', '') | |
# フルパスを構築 | |
upload_path = os.path.join(app.config['UPLOAD_FOLDER'], current_dir) | |
os.makedirs(upload_path, exist_ok=True) | |
full_path = os.path.join(upload_path, filename) | |
file.save(full_path) | |
return redirect(request.referrer) | |
def create_folder(): | |
folder_name = request.form.get('folder_name') | |
if folder_name: | |
folder_name = secure_filename(folder_name) | |
full_path = os.path.join(app.config['UPLOAD_FOLDER'], get_current_directory(), folder_name) | |
try: | |
if not os.path.exists(full_path): | |
os.makedirs(full_path, exist_ok=True) | |
# 変更: 作成したフォルダのパスを返す | |
return jsonify({ | |
'success': True, | |
'folder_path': os.path.join(get_current_directory(), folder_name) | |
}) | |
else: | |
return jsonify({'success': False, 'error': 'Folder already exists'}), 400 | |
except Exception as e: | |
return jsonify({'success': False, 'error': str(e)}), 500 | |
return jsonify({'success': False, 'error': 'No folder name provided'}), 400 | |
def delete_file(filename): | |
full_path = get_full_path(filename) | |
if os.path.isfile(full_path): | |
os.remove(full_path) | |
elif os.path.isdir(full_path): | |
shutil.rmtree(full_path) | |
return redirect(request.referrer) | |
def rename_file(): | |
old_name = request.form.get('old_name') | |
new_name = request.form.get('new_name') | |
if old_name and new_name: | |
old_path = get_full_path(old_name) | |
new_path = get_full_path(secure_filename(new_name)) | |
os.rename(old_path, new_path) | |
return redirect(request.referrer) | |
def move_file(): | |
filename = request.form.get('filename') | |
destination = request.form.get('destination') | |
if not filename or not destination: | |
return jsonify({'success': False, 'error': 'Missing parameters'}), 400 | |
try: | |
# パスを正規化 | |
src_path = os.path.normpath(os.path.join(app.config['UPLOAD_FOLDER'], filename)) | |
dest_dir = os.path.normpath(os.path.join(app.config['UPLOAD_FOLDER'], destination)) | |
# 移動先ディレクトリが存在しない場合は作成 | |
os.makedirs(dest_dir, exist_ok=True) | |
# 移動先の完全なパス | |
dest_path = os.path.join(dest_dir, os.path.basename(filename)) | |
# 移動実行 | |
shutil.move(src_path, dest_path) | |
# JSONレスポンスではなくリダイレクト | |
return redirect(url_for('dev')) | |
except Exception as e: | |
return jsonify({'success': False, 'error': str(e)}), 500 | |
def download_file(filename): | |
full_path = get_full_path(filename) | |
if not os.path.isfile(full_path): | |
abort(404) | |
return send_from_directory(os.path.dirname(full_path), os.path.basename(full_path), as_attachment=True) | |
def serve_file(filename): | |
return send_from_directory(app.config['UPLOAD_FOLDER'], filename) | |
if __name__ == '__main__': | |
ensure_upload_folder() | |
app.run(host='0.0.0.0', port=7860) |