Nyanpre commited on
Commit
7341186
·
verified ·
1 Parent(s): 0df88db

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +27 -186
app.py CHANGED
@@ -1,353 +1,194 @@
1
  import gradio as gr
2
-
3
  import random
4
-
5
  from datetime import datetime, timedelta, timezone
6
 
7
-
8
-
9
  # 12名の聖職者リスト
10
-
11
  members = ["かほ", "さや", "こず", "るり", "めぐ", "つづ", "ぎん", "すず", "ひめ", "せら", "いず", "さち"]
12
 
13
-
14
-
15
  def get_personal_daily_oracle(device_id):
16
-
17
  seed_base = device_id if device_id else "default_fate"
18
-
19
  jst = timezone(timedelta(hours=9))
20
-
21
  today_str = datetime.now(jst).strftime("%Y-%m-%d")
22
-
23
 
24
-
25
  random.seed(f"{seed_base}_{today_str}")
26
-
27
 
28
-
29
  selected = random.sample(members, 2)
30
-
31
  random.shuffle(selected)
32
-
33
  pair_name = f"{selected[0]}{selected[1]}"
34
-
35
 
36
-
37
  oracle_html = (
38
-
39
  f"<div id='pair-raw' style='display:none;'>{pair_name}</div>"
40
-
41
  f"<div style='font-size: 38px; font-weight: normal; margin-bottom: 2px;'>本日の神託</div>"
42
-
43
  f"<div style='font-size: 52px; font-weight: 900; letter-spacing: 2px;'>{pair_name}</div>"
44
-
45
  )
46
-
47
  peace_msg = "これにより、不毛なカップリング論争は終結しました。"
48
-
49
 
50
-
51
  return oracle_html, peace_msg, gr.update(visible=True), gr.update(visible=True)
52
 
53
-
54
-
55
  # JS: 状態チェックと復元
56
-
57
  js_logic = """
58
-
59
  function(deviceId) {
60
-
61
  const lastDraw = localStorage.getItem('lastOracleDate');
62
-
63
  const lastPair = localStorage.getItem('lastPairText');
64
-
65
  const today = new Date().toLocaleDateString('ja-JP');
66
 
67
-
68
-
69
  if (lastDraw === today && lastPair) {
70
-
71
  alert("本日の神託は既に下されています。\\n明日の更新まで、今の思想を維持しなさい。");
72
-
73
  return [lastPair, "これにより、不毛なカップリング論争は終結しました。", { "visible": true, "__type__": "update" }, { "visible": true, "__type__": "update" }];
74
-
75
  }
76
-
77
 
78
-
79
  localStorage.setItem('lastOracleDate', today);
80
-
81
  return [null, null, null, null];
82
-
83
  }
84
-
85
  """
86
 
87
-
88
-
89
  # JS: 結果の保存
90
-
91
  js_save_result = """
92
-
93
- function(oracleHtml, peaceMsg, shareBtn, resultBox) {
94
-
95
  if (oracleHtml && oracleHtml.includes("本日の神託")) {
96
-
97
  localStorage.setItem('lastPairText', oracleHtml);
98
-
99
  }
100
-
101
  }
102
-
103
  """
104
 
105
-
106
-
107
  # JS: Bluesky投稿
108
-
109
  js_share_bluesky = """
110
-
111
  function() {
112
-
113
  const pairRawEl = document.getElementById('pair-raw');
114
-
115
  let pairName = "";
116
-
117
 
118
-
119
  if (pairRawEl) {
120
-
121
  pairName = pairRawEl.innerText;
122
-
123
  } else {
124
-
125
  const lastPair = localStorage.getItem('lastPairText') || "";
126
-
127
  const match = lastPair.match(/>([^<]{4,})<\\/div>$/);
128
-
129
  pairName = match ? match[1] : "運命";
130
-
131
  }
132
 
133
-
134
-
135
  const currentUrl = window.location.href;
136
-
137
  const text = `私は「${pairName}」を信仰しています。\\n\\n蓮ノ空聖書正典:${currentUrl}`;
138
-
139
  const intentUrl = `https://bsky.app/intent/compose?text=${encodeURIComponent(text)}`;
140
-
141
  window.open(intentUrl, '_blank');
142
-
143
  }
144
-
145
  """
146
 
147
-
148
-
149
  custom_css = """
150
-
151
  .gradio-container { max-width: 600px !important; text-align: center !important; }
152
 
153
-
154
-
155
- /* 1. 最上部の空白を40pxに設定 */
156
-
157
  .center-content {
158
-
159
  display: flex !important;
160
-
161
  flex-direction: column !important;
162
-
163
  align-items: center !important;
164
-
165
  padding-top: 40px !important;
166
-
167
  }
168
 
169
-
170
-
171
- /* 2. タイトルと教義の間を-5px */
172
-
173
  h1 {
174
-
175
  margin-top: 0px !important;
176
-
177
  margin-bottom: -5px !important;
178
-
179
  font-size: 32px !important;
180
-
181
  }
182
 
183
-
184
-
185
- /* 3. 教義と結果の間を-5px */
186
-
187
  #doctrine {
188
-
189
  font-size: 1.5em !important;
190
-
191
  line-height: 1.4 !important;
192
-
193
  font-weight: bold !important;
194
-
195
  margin-bottom: -5px !important;
196
-
197
  text-align: center !important;
198
-
199
  }
200
 
201
-
202
-
203
- /* 4. 結果ボックスと終結文の間を-5px */
204
-
205
  #oracle-box {
206
-
207
  color: #000 !important;
208
-
209
  background: #fff !important;
210
-
211
  border: 4px solid #000 !important;
212
-
213
  padding: 25px 10px !important;
214
-
215
  line-height: 1.1 !important;
216
-
217
  min-height: 130px !important;
218
-
219
  display: flex !important;
220
-
221
  flex-direction: column !important;
222
-
223
  justify-content: center !important;
224
-
225
  margin: 0px auto -5px auto !important;
226
-
227
  }
228
 
229
-
230
-
231
- /* 5. 終結文とボタンの間を-5px */
232
-
233
  #peace-msg {
234
-
235
  font-size: 20px !important;
236
-
237
  font-weight: bold !important;
238
-
239
  color: #d63031 !important;
240
-
241
  margin: 0px auto -5px auto !important;
242
-
243
  }
244
 
245
-
246
-
247
- /* 6. ボタン同士の間を-5px */
248
-
249
  .action-btn {
250
-
251
  font-size: 26px !important;
252
-
253
  font-weight: bold !important;
254
-
255
  height: 70px !important;
256
-
257
  width: 320px !important;
258
-
259
  border: 2px solid #000 !important;
260
-
261
  }
262
 
263
-
264
-
265
  #draw-btn { margin: 0px auto -5px auto !important; }
266
-
267
  #share-btn { margin: 0px auto 10px auto !important; }
268
 
 
 
 
 
 
 
 
 
 
 
269
  """
270
 
271
-
272
-
273
  with gr.Blocks(title="蓮ノ空聖書正典", css=custom_css, theme=gr.themes.Monochrome()) as demo:
274
-
275
- device_id_storage = gr.State()
276
-
277
-
278
 
279
  demo.load(None, None, device_id_storage, js="""
280
-
281
  () => {
282
-
283
  let id = localStorage.getItem('cp_oracle_device_id');
284
-
285
  if(!id) {
286
-
287
- id = Math.random().toString(36).substring(2, 15);
288
-
289
  localStorage.setItem('cp_oracle_device_id', id);
290
-
291
  }
292
-
293
  return id;
294
-
295
  }
296
-
297
  """)
298
 
299
-
300
-
301
  with gr.Column(elem_classes="center-content"):
302
-
303
  gr.Markdown("# ⚖️ 蓮ノ空聖書正典")
304
-
305
 
306
-
307
  gr.Markdown("日付が変わるまであなたの思想は<br>統一されます。", elem_id="doctrine")
308
-
309
 
310
-
311
  result_display = gr.HTML(elem_id="oracle-box", visible=False)
312
-
313
  peace_display = gr.Markdown(elem_id="peace-msg")
314
-
315
 
316
-
317
  draw_btn = gr.Button("神託を受ける", variant="primary", elem_id="draw-btn", elem_classes="action-btn")
318
-
319
  share_btn = gr.Button("信仰を広める", variant="secondary", elem_id="share-btn", elem_classes="action-btn", visible=False)
320
-
321
-
 
 
 
 
 
322
 
323
  draw_btn.click(
324
-
325
  fn=get_personal_daily_oracle,
326
-
327
  inputs=[device_id_storage],
328
-
329
- outputs=[result_display, peace_display, share_btn, result_display],
330
-
331
  js=js_logic
332
-
333
  ).then(
334
-
335
  fn=None,
336
-
337
- inputs=[result_display, peace_display, share_btn, result_display],
338
-
339
  outputs=None,
340
-
341
  js=js_save_result
342
-
343
  )
344
 
345
-
346
-
347
  share_btn.click(fn=None, inputs=None, outputs=None, js=js_share_bluesky)
348
 
349
-
350
-
351
  if __name__ == "__main__":
352
-
353
  demo.launch()
 
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
+ # device_idが空の場合はセッション固定を防ぐためデフォルト値を使用
10
  seed_base = device_id if device_id else "default_fate"
 
11
  jst = timezone(timedelta(hours=9))
 
12
  today_str = datetime.now(jst).strftime("%Y-%m-%d")
 
13
 
 
14
  random.seed(f"{seed_base}_{today_str}")
 
15
 
 
16
  selected = random.sample(members, 2)
 
17
  random.shuffle(selected)
 
18
  pair_name = f"{selected[0]}{selected[1]}"
 
19
 
 
20
  oracle_html = (
 
21
  f"<div id='pair-raw' style='display:none;'>{pair_name}</div>"
 
22
  f"<div style='font-size: 38px; font-weight: normal; margin-bottom: 2px;'>本日の神託</div>"
 
23
  f"<div style='font-size: 52px; font-weight: 900; letter-spacing: 2px;'>{pair_name}</div>"
 
24
  )
 
25
  peace_msg = "これにより、不毛なカップリング論争は終結しました。"
 
26
 
27
+ # [結果HTML, 終結文, 共有ボタン表示, 案内文表示]
28
  return oracle_html, peace_msg, gr.update(visible=True), gr.update(visible=True)
29
 
 
 
30
  # JS: 状態チェックと復元
 
31
  js_logic = """
 
32
  function(deviceId) {
 
33
  const lastDraw = localStorage.getItem('lastOracleDate');
 
34
  const lastPair = localStorage.getItem('lastPairText');
 
35
  const today = new Date().toLocaleDateString('ja-JP');
36
 
 
 
37
  if (lastDraw === today && lastPair) {
 
38
  alert("本日の神託は既に下されています。\\n明日の更新まで、今の思想を維持しなさい。");
39
+ // 戻り値を4つ(HTML, 終結文, 共有ボタン, 案内文)に対応
40
  return [lastPair, "これにより、不毛なカップリング論争は終結しました。", { "visible": true, "__type__": "update" }, { "visible": true, "__type__": "update" }];
 
41
  }
 
42
 
 
43
  localStorage.setItem('lastOracleDate', today);
 
44
  return [null, null, null, null];
 
45
  }
 
46
  """
47
 
 
 
48
  # JS: 結果の保存
 
49
  js_save_result = """
50
+ function(oracleHtml, peaceMsg, shareBtn, instructMsg) {
 
 
51
  if (oracleHtml && oracleHtml.includes("本日の神託")) {
 
52
  localStorage.setItem('lastPairText', oracleHtml);
 
53
  }
 
54
  }
 
55
  """
56
 
 
 
57
  # JS: Bluesky投稿
 
58
  js_share_bluesky = """
 
59
  function() {
 
60
  const pairRawEl = document.getElementById('pair-raw');
 
61
  let pairName = "";
 
62
 
 
63
  if (pairRawEl) {
 
64
  pairName = pairRawEl.innerText;
 
65
  } else {
 
66
  const lastPair = localStorage.getItem('lastPairText') || "";
 
67
  const match = lastPair.match(/>([^<]{4,})<\\/div>$/);
 
68
  pairName = match ? match[1] : "運命";
 
69
  }
70
 
 
 
71
  const currentUrl = window.location.href;
 
72
  const text = `私は「${pairName}」を信仰しています。\\n\\n蓮ノ空聖書正典:${currentUrl}`;
 
73
  const intentUrl = `https://bsky.app/intent/compose?text=${encodeURIComponent(text)}`;
 
74
  window.open(intentUrl, '_blank');
 
75
  }
 
76
  """
77
 
 
 
78
  custom_css = """
 
79
  .gradio-container { max-width: 600px !important; text-align: center !important; }
80
 
 
 
 
 
81
  .center-content {
 
82
  display: flex !important;
 
83
  flex-direction: column !important;
 
84
  align-items: center !important;
 
85
  padding-top: 40px !important;
 
86
  }
87
 
 
 
 
 
88
  h1 {
 
89
  margin-top: 0px !important;
 
90
  margin-bottom: -5px !important;
 
91
  font-size: 32px !important;
 
92
  }
93
 
 
 
 
 
94
  #doctrine {
 
95
  font-size: 1.5em !important;
 
96
  line-height: 1.4 !important;
 
97
  font-weight: bold !important;
 
98
  margin-bottom: -5px !important;
 
99
  text-align: center !important;
 
100
  }
101
 
 
 
 
 
102
  #oracle-box {
 
103
  color: #000 !important;
 
104
  background: #fff !important;
 
105
  border: 4px solid #000 !important;
 
106
  padding: 25px 10px !important;
 
107
  line-height: 1.1 !important;
 
108
  min-height: 130px !important;
 
109
  display: flex !important;
 
110
  flex-direction: column !important;
 
111
  justify-content: center !important;
 
112
  margin: 0px auto -5px auto !important;
 
113
  }
114
 
 
 
 
 
115
  #peace-msg {
 
116
  font-size: 20px !important;
 
117
  font-weight: bold !important;
 
118
  color: #d63031 !important;
 
119
  margin: 0px auto -5px auto !important;
 
120
  }
121
 
 
 
 
 
122
  .action-btn {
 
123
  font-size: 26px !important;
 
124
  font-weight: bold !important;
 
125
  height: 70px !important;
 
126
  width: 320px !important;
 
127
  border: 2px solid #000 !important;
 
128
  }
129
 
 
 
130
  #draw-btn { margin: 0px auto -5px auto !important; }
 
131
  #share-btn { margin: 0px auto 10px auto !important; }
132
 
133
+ /* 案内文のスタイル:他のテキストと同様に黒く表示 */
134
+ #instruct-msg {
135
+ font-size: 18px !important;
136
+ font-weight: bold !important;
137
+ color: #000 !important;
138
+ margin: 0px auto 10px auto !important;
139
+ line-height: 1.5 !important;
140
+ background: transparent !important;
141
+ border: none !important;
142
+ }
143
  """
144
 
 
 
145
  with gr.Blocks(title="蓮ノ空聖書正典", css=custom_css, theme=gr.themes.Monochrome()) as demo:
146
+ # 修正ポイント: gr.State から gr.Textbox(visible=False) に変更
147
+ device_id_storage = gr.Textbox(visible=False)
 
 
148
 
149
  demo.load(None, None, device_id_storage, js="""
 
150
  () => {
 
151
  let id = localStorage.getItem('cp_oracle_device_id');
 
152
  if(!id) {
153
+ id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
 
 
154
  localStorage.setItem('cp_oracle_device_id', id);
 
155
  }
 
156
  return id;
 
157
  }
 
158
  """)
159
 
 
 
160
  with gr.Column(elem_classes="center-content"):
 
161
  gr.Markdown("# ⚖️ 蓮ノ空聖書正典")
 
162
 
 
163
  gr.Markdown("日付が変わるまであなたの思想は<br>統一されます。", elem_id="doctrine")
 
164
 
 
165
  result_display = gr.HTML(elem_id="oracle-box", visible=False)
 
166
  peace_display = gr.Markdown(elem_id="peace-msg")
 
167
 
 
168
  draw_btn = gr.Button("神託を受ける", variant="primary", elem_id="draw-btn", elem_classes="action-btn")
169
+
170
  share_btn = gr.Button("信仰を広める", variant="secondary", elem_id="share-btn", elem_classes="action-btn", visible=False)
171
+
172
+ # 案内文の追加
173
+ instruct_msg = gr.HTML(
174
+ "画像を添えて<br>その導きを世界へ示しなさい。",
175
+ elem_id="instruct-msg",
176
+ visible=False
177
+ )
178
 
179
  draw_btn.click(
 
180
  fn=get_personal_daily_oracle,
 
181
  inputs=[device_id_storage],
182
+ outputs=[result_display, peace_display, share_btn, instruct_msg],
 
 
183
  js=js_logic
 
184
  ).then(
 
185
  fn=None,
186
+ inputs=[result_display, peace_display, share_btn, instruct_msg],
 
 
187
  outputs=None,
 
188
  js=js_save_result
 
189
  )
190
 
 
 
191
  share_btn.click(fn=None, inputs=None, outputs=None, js=js_share_bluesky)
192
 
 
 
193
  if __name__ == "__main__":
 
194
  demo.launch()