Nyanpre commited on
Commit
191d187
·
verified ·
1 Parent(s): 8534885

Update apppp.txt

Browse files
Files changed (1) hide show
  1. apppp.txt +105 -31
apppp.txt CHANGED
@@ -1,21 +1,63 @@
1
  import gradio as gr
 
 
2
  import random
3
  from datetime import datetime, timedelta, timezone
4
-
5
- # 12名の聖職者リスト
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  members = ["かほ", "さや", "こず", "るり", "めぐ", "つづ", "ぎん", "すず", "ひめ", "せら", "いず", "さち"]
7
 
8
  def get_personal_daily_oracle(device_id):
9
  seed_base = device_id if device_id else "default_fate"
10
  jst = timezone(timedelta(hours=9))
11
- today_str = datetime.now(jst).strftime("%Y-%m-%d")
 
12
 
13
  random.seed(f"{seed_base}_{today_str}")
14
-
15
  selected = random.sample(members, 2)
16
  random.shuffle(selected)
17
  pair_name = f"{selected[0]}{selected[1]}"
18
 
 
 
 
 
 
 
 
 
19
  oracle_html = (
20
  f"<div id='pair-raw' style='display:none;'>{pair_name}</div>"
21
  f"<div style='font-size: 38px; font-weight: normal; margin-bottom: 2px;'>本日の神託</div>"
@@ -23,10 +65,35 @@ def get_personal_daily_oracle(device_id):
23
  )
24
  peace_msg = "これにより、不毛なカップリング論争は終結しました。"
25
 
26
- # 戻り値: oracle_html, peace_msg, bsky_btn_update, x_btn_update, result_box_update
27
  return oracle_html, peace_msg, gr.update(visible=True), gr.update(visible=True), gr.update(visible=True)
28
 
29
- # JS: 状態チェックと復元
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  js_logic = """
31
  function(deviceId) {
32
  const id = localStorage.getItem('cp_oracle_device_id') || "guest";
@@ -44,7 +111,6 @@ function(deviceId) {
44
  }
45
  """
46
 
47
- # JS: 結果の保存
48
  js_save_result = """
49
  function(oracleHtml, peaceMsg, bskyBtn, xBtn, resultBox) {
50
  if (oracleHtml && oracleHtml.includes("本日の神託")) {
@@ -53,7 +119,6 @@ function(oracleHtml, peaceMsg, bskyBtn, xBtn, resultBox) {
53
  }
54
  """
55
 
56
- # JS: 共通テキスト生成ロジック
57
  js_get_share_text = """
58
  function() {
59
  const pairRawEl = document.getElementById('pair-raw');
@@ -70,32 +135,26 @@ function() {
70
  }
71
  """
72
 
73
- # JS: 各SNSへの投稿
74
  js_share_bluesky = f"function() {{ const text = ({js_get_share_text})(); window.open(`https://bsky.app/intent/compose?text=${{encodeURIComponent(text)}}`, '_blank'); }}"
75
  js_share_x = f"function() {{ const text = ({js_get_share_text})(); window.open(`https://twitter.com/intent/tweet?text=${{encodeURIComponent(text)}}`, '_blank'); }}"
76
 
 
77
  custom_css = """
78
  .gradio-container { max-width: 600px !important; text-align: center !important; }
79
- .center-content { display: flex !important; flex-direction: column !important; align-items: center !important; padding-top: 45px !important; }
80
  h1 { margin-top: 0px !important; margin-bottom: -5px !important; font-size: 32px !important; }
81
- #doctrine { font-size: 1.5em !important; line-height: 1.4 !important; font-weight: bold !important; margin-bottom: -5px !important; text-align: center !important; }
82
 
83
  #oracle-box {
84
  color: #000 !important; background: #fff !important; border: 4px solid #000 !important;
85
  padding: 25px 10px !important; line-height: 1.1 !important; min-height: 130px !important;
86
  display: flex !important; flex-direction: column !important; justify-content: center !important;
87
- margin: 0px auto -5px auto !important;
88
  }
89
  .dark #oracle-box { color: #fff !important; background: #000 !important; border: 4px solid #fff !important; }
90
-
91
- #peace-msg { font-size: 20px !important; font-weight: bold !important; color: #d63031 !important; margin: 0px auto -5px auto !important; }
92
-
93
- .action-btn { font-size: 24px !important; font-weight: bold !important; width: 320px !important; border: 2px solid #000 !important; }
94
  .dark .action-btn { border: 2px solid #fff !important; }
95
-
96
- #draw-btn { margin: 0px auto -5px auto !important; height: 75px !important; font-size: 28px !important; }
97
- #share-bsky { margin: 0px auto -5px auto !important; height: 60px !important; }
98
- #share-x { margin: 0px auto 10px auto !important; height: 60px !important; }
99
  """
100
 
101
  with gr.Blocks(title="蓮ノ空聖書正典", css=custom_css, theme=gr.themes.Monochrome()) as demo:
@@ -112,17 +171,29 @@ with gr.Blocks(title="蓮ノ空聖書正典", css=custom_css, theme=gr.themes.Mo
112
  }
113
  """)
114
 
115
- with gr.Column(elem_classes="center-content"):
116
- gr.Markdown("# ⚖️ 蓮ノ空聖書正典")
117
- gr.Markdown("日付が変わるまであなたの思想は<br>統一されます。", elem_id="doctrine")
118
-
119
- result_display = gr.HTML(elem_id="oracle-box", visible=False)
120
- peace_display = gr.Markdown(elem_id="peace-msg")
121
-
122
- draw_btn = gr.Button("神託を受ける", variant="primary", elem_id="draw-btn", elem_classes="action-btn")
123
- share_btn_bsky = gr.Button("Blueskyで信仰を広める", variant="secondary", elem_id="share-bsky", elem_classes="action-btn", visible=False)
124
- share_btn_x = gr.Button("Xで信仰を広める", variant="secondary", elem_id="share-x", elem_classes="action-btn", visible=False)
125
-
 
 
 
 
 
 
 
 
 
 
 
 
126
  draw_btn.click(
127
  fn=get_personal_daily_oracle,
128
  inputs=[device_id_storage],
@@ -138,5 +209,8 @@ with gr.Blocks(title="蓮ノ空聖書正典", css=custom_css, theme=gr.themes.Mo
138
  share_btn_bsky.click(fn=None, inputs=None, outputs=None, js=js_share_bluesky)
139
  share_btn_x.click(fn=None, inputs=None, outputs=None, js=js_share_x)
140
 
 
 
 
141
  if __name__ == "__main__":
142
  demo.launch()
 
1
  import gradio as gr
2
+ import os
3
+ import json
4
  import random
5
  from datetime import datetime, timedelta, timezone
6
+ from pathlib import Path
7
+ from huggingface_hub import CommitScheduler
8
+
9
+ # --- ① 統計データ保存用の設定 ---
10
+ # 自分のリポジトリ名に合わせて変更、または環境変数から取得
11
+ DATASET_REPO_ID = "your-username/hasunosora-stats"
12
+ DATA_FILE = Path("data") / "stats.json"
13
+ DATA_FILE.parent.mkdir(parents=True, exist_ok=True)
14
+
15
+ # 初回起動時にファイルがない場合は空のデータを作成
16
+ if not DATA_FILE.exists():
17
+ with open(DATA_FILE, "w", encoding="utf-8") as f:
18
+ json.dump({"total": 0, "history": []}, f)
19
+
20
+ # Hugging Face Datasetへ自動保存するスケジューラー
21
+ # ※SpaceのSettingsで HF_TOKEN (write権限) の設定が必要です
22
+ scheduler = CommitScheduler(
23
+ repo_id=DATASET_REPO_ID,
24
+ repo_type="dataset",
25
+ folder_path=DATA_FILE.parent,
26
+ path_in_repo="stats.json",
27
+ token=os.getenv("HF_TOKEN")
28
+ )
29
+
30
+ def load_stats():
31
+ if DATA_FILE.exists():
32
+ try:
33
+ with open(DATA_FILE, "r", encoding="utf-8") as f:
34
+ return json.load(f)
35
+ except:
36
+ pass
37
+ return {"total": 0, "history": []}
38
+
39
+ # --- ② 既存ロジックと統計の統合 ---
40
  members = ["かほ", "さや", "こず", "るり", "めぐ", "つづ", "ぎん", "すず", "ひめ", "せら", "いず", "さち"]
41
 
42
  def get_personal_daily_oracle(device_id):
43
  seed_base = device_id if device_id else "default_fate"
44
  jst = timezone(timedelta(hours=9))
45
+ now = datetime.now(jst)
46
+ today_str = now.strftime("%Y-%m-%d")
47
 
48
  random.seed(f"{seed_base}_{today_str}")
 
49
  selected = random.sample(members, 2)
50
  random.shuffle(selected)
51
  pair_name = f"{selected[0]}{selected[1]}"
52
 
53
+ # --- ③ 統計の記録処理 ---
54
+ with scheduler.lock:
55
+ stats = load_stats()
56
+ stats["total"] += 1
57
+ stats["history"].append({"date": today_str, "pair": pair_name})
58
+ with open(DATA_FILE, "w", encoding="utf-8") as f:
59
+ json.dump(stats, f, ensure_ascii=False)
60
+
61
  oracle_html = (
62
  f"<div id='pair-raw' style='display:none;'>{pair_name}</div>"
63
  f"<div style='font-size: 38px; font-weight: normal; margin-bottom: 2px;'>本日の神託</div>"
 
65
  )
66
  peace_msg = "これにより、不毛なカップリング論争は終結しました。"
67
 
 
68
  return oracle_html, peace_msg, gr.update(visible=True), gr.update(visible=True), gr.update(visible=True)
69
 
70
+ # --- 神モード:集計ロジック ---
71
+ def update_stats_view():
72
+ stats = load_stats()
73
+ hist = stats.get("history", [])
74
+ jst = timezone(timedelta(hours=9))
75
+ today_str = datetime.now(jst).strftime("%Y-%m-%d")
76
+
77
+ counts_all = {}
78
+ counts_today = {}
79
+
80
+ for h in hist:
81
+ p = h['pair']
82
+ counts_all[p] = counts_all.get(p, 0) + 1
83
+ if h.get('date') == today_str:
84
+ counts_today[p] = counts_today.get(p, 0) + 1
85
+
86
+ def gen_rank_html(title, data_dict):
87
+ sorted_items = sorted(data_dict.items(), key=lambda x: x[1], reverse=True)[:5]
88
+ rows = "".join([f"<li>{i+1}位: <b>{p}</b> ({c}回)</li>" for i, (p, c) in enumerate(sorted_items)])
89
+ return f"<h4>{title}</h4><ul>{rows if rows else '<li>データなし</li>'}</ul>"
90
+
91
+ html_all = gen_rank_html("全人類神託カップリングTOP5【累計】", counts_all)
92
+ html_today = gen_rank_html("全人類神託カップリングTOP5【本日】", counts_today)
93
+
94
+ return f"<div style='text-align: left;'>{html_all}<hr>{html_today}<p>総神託数: {stats['total']}</p></div>"
95
+
96
+ # --- JS: 既存のものを維持 ---
97
  js_logic = """
98
  function(deviceId) {
99
  const id = localStorage.getItem('cp_oracle_device_id') || "guest";
 
111
  }
112
  """
113
 
 
114
  js_save_result = """
115
  function(oracleHtml, peaceMsg, bskyBtn, xBtn, resultBox) {
116
  if (oracleHtml && oracleHtml.includes("本日の神託")) {
 
119
  }
120
  """
121
 
 
122
  js_get_share_text = """
123
  function() {
124
  const pairRawEl = document.getElementById('pair-raw');
 
135
  }
136
  """
137
 
 
138
  js_share_bluesky = f"function() {{ const text = ({js_get_share_text})(); window.open(`https://bsky.app/intent/compose?text=${{encodeURIComponent(text)}}`, '_blank'); }}"
139
  js_share_x = f"function() {{ const text = ({js_get_share_text})(); window.open(`https://twitter.com/intent/tweet?text=${{encodeURIComponent(text)}}`, '_blank'); }}"
140
 
141
+ # --- CSS ---
142
  custom_css = """
143
  .gradio-container { max-width: 600px !important; text-align: center !important; }
144
+ .center-content { display: flex !important; flex-direction: column !important; align-items: center !important; padding-top: 20px !important; }
145
  h1 { margin-top: 0px !important; margin-bottom: -5px !important; font-size: 32px !important; }
146
+ #doctrine { font-size: 1.5em !important; line-height: 1.4 !important; font-weight: bold !important; margin-bottom: 10px !important; text-align: center !important; }
147
 
148
  #oracle-box {
149
  color: #000 !important; background: #fff !important; border: 4px solid #000 !important;
150
  padding: 25px 10px !important; line-height: 1.1 !important; min-height: 130px !important;
151
  display: flex !important; flex-direction: column !important; justify-content: center !important;
152
+ margin: 10px auto !important;
153
  }
154
  .dark #oracle-box { color: #fff !important; background: #000 !important; border: 4px solid #fff !important; }
155
+ #peace-msg { font-size: 20px !important; font-weight: bold !important; color: #d63031 !important; margin-top: 10px !important; }
156
+ .action-btn { font-size: 24px !important; font-weight: bold !important; width: 320px !important; border: 2px solid #000 !important; margin-bottom: 10px !important; }
 
 
157
  .dark .action-btn { border: 2px solid #fff !important; }
 
 
 
 
158
  """
159
 
160
  with gr.Blocks(title="蓮ノ空聖書正典", css=custom_css, theme=gr.themes.Monochrome()) as demo:
 
171
  }
172
  """)
173
 
174
+ gr.Markdown("# ⚖️ 蓮ノ空聖書正典")
175
+
176
+ with gr.Tabs():
177
+ # --- ① 信仰(メイン)タブ ---
178
+ with gr.TabItem("神託"):
179
+ with gr.Column(elem_classes="center-content"):
180
+ gr.Markdown("日付が変わるまであなたの思想は<br>統一されます。", elem_id="doctrine")
181
+
182
+ result_display = gr.HTML(elem_id="oracle-box", visible=False)
183
+ peace_display = gr.Markdown(elem_id="peace-msg")
184
+
185
+ draw_btn = gr.Button("神託を受ける", variant="primary", elem_id="draw-btn", elem_classes="action-btn")
186
+ share_btn_bsky = gr.Button("Blueskyで信仰を広める", variant="secondary", elem_id="share-bsky", elem_classes="action-btn", visible=False)
187
+ share_btn_x = gr.Button("Xで信仰を広める", variant="secondary", elem_id="share-x", elem_classes="action-btn", visible=False)
188
+
189
+ # --- ② 神モードタブ ---
190
+ with gr.TabItem("神モード"):
191
+ with gr.Column(elem_classes="center-content"):
192
+ gr.Markdown("### 全人類の信仰状況")
193
+ stats_display = gr.HTML("<p>ボタンを押して読み込み</p>")
194
+ refresh_stats = gr.Button("全人類の神託を見る", variant="primary", elem_classes="action-btn")
195
+
196
+ # --- 既存のクリックイベント ---
197
  draw_btn.click(
198
  fn=get_personal_daily_oracle,
199
  inputs=[device_id_storage],
 
209
  share_btn_bsky.click(fn=None, inputs=None, outputs=None, js=js_share_bluesky)
210
  share_btn_x.click(fn=None, inputs=None, outputs=None, js=js_share_x)
211
 
212
+ # --- 新機能のクリックイベント ---
213
+ refresh_stats.click(fn=update_stats_view, outputs=stats_display)
214
+
215
  if __name__ == "__main__":
216
  demo.launch()