taigasan commited on
Commit
bf7eb4a
·
verified ·
1 Parent(s): 0aebc50

deploy app, storage, readme

Browse files
Files changed (1) hide show
  1. app.py +42 -4
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import gradio as gr
2
  import random
3
  import threading
 
4
  import uuid
5
  import os
6
  import html
@@ -18,6 +19,8 @@ SUBMIT_KEY = os.getenv("RATINGS_SUBMIT_KEY")
18
  assert SUBMIT_KEY, "Missing required env var: RATINGS_SUBMIT_KEY"
19
  POOL_REPO_ID = "taigasan/e6-visual-ratings"
20
  VOTE_STORAGE = VoteStorage(mode="local" if DEBUG_MODE else "hf", local_dir=LOCAL_DATA_DIR, token=RATINGS_APP_TOKEN)
 
 
21
 
22
  # -- Pool dataset -----------------------------------------------------------
23
  if DEBUG_MODE:
@@ -32,6 +35,32 @@ else:
32
  )
33
  _pool_df = pd.read_parquet(_pool_path)
34
  _pool_group_dfs = {g: gdf for g, gdf in _pool_df.groupby("group")}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
  def _pool_fetch_pair(group_name: str) -> tuple:
37
  gdf = _pool_group_dfs[group_name]
@@ -73,10 +102,19 @@ def _commit_oldest_pending(state: dict):
73
  threading.Thread(target=VOTE_STORAGE.append_vote_row, args=(oldest.copy(), oldest.get("winner")), daemon=True).start()
74
 
75
  def _render_current(state: dict, submit_status: str = "") -> tuple:
76
- img_a_html = f"<div class=\"rating-card\"><div class=\"rating-card-title\"><strong>Image A</strong></div><div class=\"rating-image-frame\"><img src=\"{html.escape(state['url_a'])}\" class=\"rating-image\" loading=\"eager\" referrerpolicy=\"no-referrer\"></div></div>"
77
- img_b_html = f"<div class=\"rating-card\"><div class=\"rating-card-title\"><strong>Image B</strong></div><div class=\"rating-image-frame\"><img src=\"{html.escape(state['url_b'])}\" class=\"rating-image\" loading=\"eager\" referrerpolicy=\"no-referrer\"></div></div>"
78
- link_a = f"Image A: https://e621.net/posts/{state['id_a']}"
79
- link_b = f"Image B: https://e621.net/posts/{state['id_b']}"
 
 
 
 
 
 
 
 
 
80
  can_go_back = bool(state.get("can_go_back"))
81
  back_md = "[back](#back)" if can_go_back else "<span class='subtle-back-link-disabled'>back</span>"
82
  details = f"<span class='subtle-note'>Group: {state['group']}</span>"
 
1
  import gradio as gr
2
  import random
3
  import threading
4
+ import time
5
  import uuid
6
  import os
7
  import html
 
19
  assert SUBMIT_KEY, "Missing required env var: RATINGS_SUBMIT_KEY"
20
  POOL_REPO_ID = "taigasan/e6-visual-ratings"
21
  VOTE_STORAGE = VoteStorage(mode="local" if DEBUG_MODE else "hf", local_dir=LOCAL_DATA_DIR, token=RATINGS_APP_TOKEN)
22
+ STATS_PATH = Path(__file__).resolve().parent.parent / "stats.parquet"
23
+ STATS_RELOAD_S = 30 * 60
24
 
25
  # -- Pool dataset -----------------------------------------------------------
26
  if DEBUG_MODE:
 
35
  )
36
  _pool_df = pd.read_parquet(_pool_path)
37
  _pool_group_dfs = {g: gdf for g, gdf in _pool_df.groupby("group")}
38
+ _stats_lock = threading.Lock()
39
+ _stats_last_loaded_at = 0.0
40
+ _stats_by_key: dict[str, tuple[int, int]] = {}
41
+
42
+
43
+ def _reload_stats_if_due(force: bool = False):
44
+ global _stats_last_loaded_at, _stats_by_key
45
+ now = time.time()
46
+ if not force and (now - _stats_last_loaded_at) < STATS_RELOAD_S:
47
+ return
48
+ with _stats_lock:
49
+ now = time.time()
50
+ if not force and (now - _stats_last_loaded_at) < STATS_RELOAD_S:
51
+ return
52
+ if STATS_PATH.exists():
53
+ _stats_df = pd.read_parquet(STATS_PATH, columns=["item_key", "wins", "losses"]) # [n, 3]
54
+ _stats_by_key = {
55
+ str(r.item_key): (int(r.wins), int(r.losses))
56
+ for r in _stats_df.itertuples(index=False)
57
+ }
58
+ else:
59
+ _stats_by_key = {}
60
+ _stats_last_loaded_at = now
61
+
62
+
63
+ _reload_stats_if_due(force=True)
64
 
65
  def _pool_fetch_pair(group_name: str) -> tuple:
66
  gdf = _pool_group_dfs[group_name]
 
102
  threading.Thread(target=VOTE_STORAGE.append_vote_row, args=(oldest.copy(), oldest.get("winner")), daemon=True).start()
103
 
104
  def _render_current(state: dict, submit_status: str = "") -> tuple:
105
+ _reload_stats_if_due()
106
+ wins_a, losses_a = _stats_by_key.get(str(state["key_a"]), (0, 0))
107
+ wins_b, losses_b = _stats_by_key.get(str(state["key_b"]), (0, 0))
108
+ total_a = wins_a + losses_a
109
+ total_b = wins_b + losses_b
110
+ win_pct_a = f"{(100.0 * wins_a / total_a):.1f}%" if total_a > 0 else "-"
111
+ win_pct_b = f"{(100.0 * wins_b / total_b):.1f}%" if total_b > 0 else "-"
112
+ title_a = "Image A"
113
+ title_b = "Image B"
114
+ img_a_html = f"<div class=\"rating-card\"><div class=\"rating-card-title\"><strong>{html.escape(title_a)}</strong></div><div class=\"rating-image-frame\"><img src=\"{html.escape(state['url_a'])}\" class=\"rating-image\" loading=\"eager\" referrerpolicy=\"no-referrer\"></div></div>"
115
+ img_b_html = f"<div class=\"rating-card\"><div class=\"rating-card-title\"><strong>{html.escape(title_b)}</strong></div><div class=\"rating-image-frame\"><img src=\"{html.escape(state['url_b'])}\" class=\"rating-image\" loading=\"eager\" referrerpolicy=\"no-referrer\"></div></div>"
116
+ link_a = f"Image A: https://e621.net/posts/{state['id_a']} | Wins: {wins_a} | Losses: {losses_a} | Win percentage: {win_pct_a}"
117
+ link_b = f"Image B: https://e621.net/posts/{state['id_b']} | Wins: {wins_b} | Losses: {losses_b} | Win percentage: {win_pct_b}"
118
  can_go_back = bool(state.get("can_go_back"))
119
  back_md = "[back](#back)" if can_go_back else "<span class='subtle-back-link-disabled'>back</span>"
120
  details = f"<span class='subtle-note'>Group: {state['group']}</span>"