eruda3 / app.py
soiz1's picture
Update app.py
f4b8aa7 verified
from flask import Flask, request, jsonify, make_response, render_template_string, send_from_directory
import random
import string
import json
app = Flask(__name__, static_folder='dist')
def generate_random_id():
chars = string.ascii_lowercase + string.digits
return ''.join(random.choices(chars, k=5))
# --- CORSヘッダーを全レスポンスに追加 ---
@app.after_request
def add_cors_headers(response):
origin = request.headers.get('Origin')
if origin:
response.headers['Access-Control-Allow-Origin'] = origin
response.headers['Access-Control-Allow-Credentials'] = 'true'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type'
return response
@app.route('/')
def index():
id_list = request.cookies.get('ids')
ids = json.loads(id_list) if id_list else []
html = '''
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>IDリスト</title>
</head>
<body>
<h1>IDリスト</h1>
<ul>
{% for id in ids %}
<li>
{{ id }}
<button onclick="copyToClipboard('{{ id }}')">コピー</button>
<form method="post" action="/delete" style="display:inline;">
<input type="hidden" name="id" value="{{ id }}">
<button type="submit">削除</button>
</form>
</li>
{% endfor %}
</ul>
<form method="post" action="/add">
<button type="submit">IDを追加</button>
</form>
<a href="/eruda.js">/eruda.js</a>
<script src="/eruda.js"></script>
<script>eruda.init();</script>
<hr>
<h2>getid のデータ</h2>
<pre id="id-data">ここにデータが表示されます</pre>
<button onclick="updateServiceWorker()">getid のサービスワーカーを設定・更新</button>
<button onclick="loadGetID()">getid を取得</button>
<script>
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
alert('コピーしました: ' + text);
}).catch(() => {
alert('コピーに失敗しました');
});
}
async function updateServiceWorker() {
if ('serviceWorker' in navigator) {
try {
await navigator.serviceWorker.register('/service-worker.js');
alert("サービスワーカーを登録しました。");
} catch (e) {
console.error("サービスワーカーの登録に失敗しました:", e);
}
} else {
alert("このブラウザはサービスワーカーに対応していません。");
}
}
async function loadGetID() {
try {
const res = await fetch('/getid');
const data = await res.json();
document.getElementById('id-data').textContent = JSON.stringify(data, null, 2);
} catch (e) {
console.error("データの取得に失敗しました:", e);
document.getElementById('id-data').textContent = "取得に失敗しました";
}
}
</script>
</body>
</html>
'''
return render_template_string(html, ids=ids)
@app.route("/load.js")
def load_js():
js_code = """
(async () => {
const script = document.currentScript;
if (!script) {
console.error('currentScriptが取得できませんでした。');
return;
}
const debugMode = script.getAttribute('debug') === 'alert';
const activeValue = script.getAttribute('active');
if (!activeValue) {
console.log('active属性が見つかりません。処理を終了します。');
return;
}
const ids = activeValue.trim().split(/\\s+/).filter(id => /^[a-zA-Z0-9]{5}$/.test(id));
if (ids.length === 0) {
console.warn('active属性に5桁の番号または文字列が見つかりません。処理を終了します。');
return;
}
try {
const url = 'https://soiz1-eruda3.hf.space/getid';
const res = await fetch(url, { method: 'GET', credentials: 'include' });
if (!res.ok) {
const msg = `Fetchエラー: ステータス ${res.status} ${res.statusText}`;
console.error(msg);
if (debugMode) alert(msg);
return;
}
const data = await res.json();
console.log('fetchレスポンス:', data);
if (debugMode) alert(`fetchレスポンス:\\n${JSON.stringify(data)}`);
if (!Array.isArray(data)) {
const msg = 'fetchレスポンスが配列ではありません。認証失敗とみなします。';
console.error(msg);
if (debugMode) alert(msg);
return;
}
const hasAuthorized = ids.some(id => data.includes(id));
if (hasAuthorized) {
const msg = '認証成功: 対象IDがfetchレスポンスに含まれています。runeruda()を実行します。';
console.log(msg);
if (debugMode) alert(msg);
runeruda();
} else {
const msg = '認証失敗: 対象IDがfetchレスポンスに含まれていません。';
console.warn(msg);
if (debugMode) alert(msg);
}
} catch (err) {
const msg = `例外発生: ${err.message}`;
console.error(msg, err);
if (debugMode) alert(msg);
}
})();
"""
return Response(js_code, mimetype='application/javascript')
@app.route('/add', methods=['POST'])
def add_id():
id_list = request.cookies.get('ids')
ids = json.loads(id_list) if id_list else []
new_id = generate_random_id()
ids.append(new_id)
resp = make_response('', 303)
resp.headers['Location'] = '/'
resp.set_cookie(
'ids',
json.dumps(ids),
samesite='None', # ← クロスオリジンには必要
secure=True # ← 'None' にすると secure も必要
)
return resp
@app.route('/delete', methods=['POST'])
def delete_id():
id_to_delete = request.form.get('id')
id_list = request.cookies.get('ids')
ids = json.loads(id_list) if id_list else []
if id_to_delete in ids:
ids.remove(id_to_delete)
resp = make_response('', 303)
resp.headers['Location'] = '/'
resp.set_cookie(
'ids',
json.dumps(ids),
samesite='None', # ← クロスオリジンには必要
secure=True # ← 'None' にすると secure も必要
)
return resp
@app.route('/getid')
def get_ids():
id_list = request.cookies.get('ids')
ids = json.loads(id_list) if id_list else []
return jsonify(ids)
@app.route('/service-worker.js')
def service_worker():
response = make_response(send_from_directory('.', 'service-worker.js'))
response.headers['Content-Type'] = 'application/javascript'
return response
@app.route('/<path:filename>')
def serve_static(filename):
return send_from_directory(app.static_folder, filename)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860, debug=True)