From 1b03e5d0e7bdc850a13132c8e3d1ef521445f474 Mon Sep 17 00:00:00 2001 From: yuuki <> Date: Tue, 13 Feb 2024 11:58:04 +0900 Subject: [PATCH] =?UTF-8?q?=E6=9B=B2=E3=82=92=E6=8A=95=E7=A8=BF=E3=81=A7?= =?UTF-8?q?=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.py | 78 ++++++++++++++++++++++++++++++++++--- public/src/js/songselect.js | 26 +++++++------ public/upload/index.html | 27 +++++++++++++ public/upload/style.css | 3 ++ public/upload/upload.js | 27 +++++++++++++ requirements.txt | 2 + 6 files changed, 146 insertions(+), 17 deletions(-) create mode 100644 public/upload/index.html create mode 100644 public/upload/style.css create mode 100644 public/upload/upload.js diff --git a/app.py b/app.py index a04ec12..88da211 100644 --- a/app.py +++ b/app.py @@ -14,7 +14,13 @@ import schema import os import time +import traceback +import pprint +import pathlib + import flask +import nkf +import tjaf from functools import wraps from flask import Flask, g, jsonify, render_template, request, abort, redirect, session, flash, make_response, send_from_directory @@ -50,7 +56,7 @@ app.config['SESSION_REDIS'] = Redis( app.cache = Cache(app, config=redis_config) sess = Session() sess.init_app(app) -csrf = CSRFProtect(app) +#csrf = CSRFProtect(app) db = client[take_config('MONGO', required=True)['database']] db.users.create_index('username', unique=True) @@ -741,19 +747,81 @@ def cache_wrap(res_from, secs): @app.route(basedir + "src/") def send_src(ref): - return cache_wrap(send_from_directory("public/src", ref), 3600) + return cache_wrap(flask.send_from_directory("public/src", ref), 3600) @app.route(basedir + "assets/") def send_assets(ref): - return cache_wrap(send_from_directory("public/assets", ref), 3600) + return cache_wrap(flask.send_from_directory("public/assets", ref), 3600) @app.route(basedir + "songs/") def send_songs(ref): - return cache_wrap(send_from_directory("public/songs", ref), 604800) + return cache_wrap(flask.send_from_directory("public/songs", ref), 604800) @app.route(basedir + "manifest.json") def send_manifest(): - return cache_wrap(send_from_directory("public", "manifest.json"), 3600) + return cache_wrap(flask.send_from_directory("public", "manifest.json"), 3600) + +@app.route("/upload/") +def send_upload(): + return cache_wrap(flask.send_from_directory("public/upload", "index.html"), 3600) + +@app.route("/upload/") +def send_upload_sub(ref): + return cache_wrap(flask.send_from_directory("public/upload", ref), 3600) + +@app.route("/upload", methods=["POST"]) +def upload_file(): + try: + # POSTリクエストにファイルの部分がない場合 + if 'file_tja' not in flask.request.files or 'file_music' not in flask.request.files: + return flask.jsonify({'error': 'リクエストにファイルの部分がありません'}) + + file_tja = flask.request.files['file_tja'] + file_music = flask.request.files['file_music'] + + # ファイルが選択されておらず空のファイルを受け取った場合 + if file_tja.filename == '' or file_music.filename == '': + return flask.jsonify({'error': 'ファイルが選択されていません'}) + + # TJAファイルをテキストUTF-8/LFに変換 + tja_data = nkf.nkf('-wd', file_tja.read()) + tja_text = tja_data.decode("utf-8") + print("TJAのサイズ:",len(tja_text)) + # TJAファイルの内容を解析 + tja = tjaf.Tja(tja_text) + # TJAファイルのハッシュ値を生成 + msg = hashlib.sha256() + msg.update(tja_data) + tja_hash = msg.hexdigest() + print("TJA:",tja_hash) + # 音楽ファイルのハッシュ値を生成 + music_data = file_music.read() + msg2 = hashlib.sha256() + msg2.update(music_data) + music_hash = msg2.hexdigest() + print("音楽:",music_hash) + # IDを生成 + generated_id = f"{tja_hash}-{music_hash}" + # MongoDBのデータも作成 + db_entry = tja.to_mongo(generated_id, time.time_ns()) + pprint.pprint(db_entry) + + # mongoDBにデータをぶち込む + client['taiko']["songs"].insert_one(db_entry) + + # ディレクトリを作成 + target_dir = pathlib.Path(os.getenv("TAIKO_WEB_SONGS_DIR", "public/songs")) / generated_id + target_dir.mkdir(parents=True,exist_ok=True) + + # TJAを保存 + (target_dir / "main.tja").write_bytes(tja_data) + # 曲ファイルも保存 + (target_dir / f"main.{db_entry['music_type']}").write_bytes(music_data) + except Exception as e: + error_str = ''.join(traceback.TracebackException.from_exception(e).format()) + return flask.jsonify({'error': error_str}) + + return flask.jsonify({'success': True}) if __name__ == '__main__': import argparse diff --git a/public/src/js/songselect.js b/public/src/js/songselect.js index 043774e..d4d1fd6 100644 --- a/public/src/js/songselect.js +++ b/public/src/js/songselect.js @@ -203,16 +203,18 @@ class SongSelect{ }) // カスタムメニュー - this.songs.push({ - title: "ソースコード", - skin: this.songSkin.sourceCode, - action: "sourceCode", - }); - this.songs.push({ - title: "曲を投稿", - skin: this.songSkin.upload, - action: "upload", - }); + // this.songs.push({ + // title: "ソースコード", + // skin: this.songSkin.sourceCode, + // action: "sourceCode", + // }); + for (let i = 0; i < 10; i++) { + this.songs.push({ + title: "曲を投稿!", + skin: this.songSkin.upload, + action: "upload", + }); + } this.songs.push({ title: strings.back, @@ -842,8 +844,8 @@ class SongSelect{ } else if (currentSong.action === "upload") { this.playSound("se_don"); setTimeout(() => { - open("https://upload.taikoapp.uk/","_blank"); - }, 500); + window.location.href = "/upload/"; + }, 20); } } this.pointer(false) diff --git a/public/upload/index.html b/public/upload/index.html new file mode 100644 index 0000000..c48ff29 --- /dev/null +++ b/public/upload/index.html @@ -0,0 +1,27 @@ + + + + + + 太鼓ウェブあっぷろーだー + + + + +

太鼓ウェブあっぷろーだー

+ +
+ +
+ + +
+ +
+ +
+ +
+
+ + diff --git a/public/upload/style.css b/public/upload/style.css new file mode 100644 index 0000000..89b8d63 --- /dev/null +++ b/public/upload/style.css @@ -0,0 +1,3 @@ +#error-view { + white-space: pre-line; +} diff --git a/public/upload/upload.js b/public/upload/upload.js new file mode 100644 index 0000000..9842d2c --- /dev/null +++ b/public/upload/upload.js @@ -0,0 +1,27 @@ +function uploadFiles() { + const form = document.getElementById('upload-form'); + const formData = new FormData(form); + + fetch('/upload', { + method: 'POST', + body: formData, + }) + .then(res => { + if (res.ok) { + return res.json(); + } else { + throw new Error(res.url + " で " + res.status.toString() + " が発生しました。"); + } + }) + .then(data => { + if (data.success) { + alert("おめでとう!ファイルの投稿に成功しました!"); + } else { + throw new Error(data.error); + } + }) + .catch(error => { + console.error('エラー:', error); + document.getElementById("error-view").textContent = error; + }); +} diff --git a/requirements.txt b/requirements.txt index 732f5e7..b2ba05c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,3 +12,5 @@ requests==2.31.0 websockets==12.0 Werkzeug==3.0.1 jinja2==3.1.3 +git+https://github.com/nurse/nkf.git#egg=nkf&subdirectory=NKF.python3 +tjaf==1.0.6