MeysamSh commited on
Commit
b55935c
·
1 Parent(s): 923b516

First working version

Browse files
Files changed (2) hide show
  1. annotations.csv +14 -5
  2. app.py +72 -45
annotations.csv CHANGED
@@ -1,6 +1,15 @@
1
  user_id,gender,audio_file,score
2
- ,[],audio1.wav,3
3
- ,[],audio2.wav,3
4
- dkl.,Female,audio1.wav,3
5
- dkl.,Female,audio2.wav,3
6
- ,Other,audio1.wav,1
 
 
 
 
 
 
 
 
 
 
1
  user_id,gender,audio_file,score
2
+ ,[],audio1.wav,3.0
3
+ ,[],audio2.wav,3.0
4
+ dkl.,Female,audio1.wav,3.0
5
+ dkl.,Female,audio2.wav,3.0
6
+ ,Other,audio1.wav,1.0
7
+ jhgs,Other,audio1.wav,3.0
8
+ ermjb,Other,audio1.wav,
9
+ ermjb,Other,audio2.wav,1.0
10
+ gvsdg,Other,audio1.wav,
11
+ gvsdg,Other,audio2.wav,
12
+ dsfsd,Other,audio1.wav,
13
+ dsfsd,Other,audio2.wav,1.0
14
+ fdsfsd,Other,audio1.wav,3.0
15
+ dfsd,Other,audio1.wav,2
app.py CHANGED
@@ -12,12 +12,8 @@ audio_files = sorted(os.listdir(AUDIO_FOLDER))
12
 
13
  ANNOTATION_FILE = "annotations.csv"
14
 
15
- # IMPORTANT: Replace with your SHA-256 hashed password
16
- # Example of hash for "admin123":
17
- # 240be518fa2dd6f69f6c16aa1a623a48d2c3d14a454f93a49a38d7b38e8e9a36
18
  ADMIN_PASSWORD_HASH = "eb32da077dfaf326cd6f73e0716b628da6427aa318a2d0b9fafa9ef315b5e885"
19
 
20
-
21
  # ============================
22
  # STORAGE INITIALIZATION
23
  # ============================
@@ -26,27 +22,25 @@ if not os.path.exists(ANNOTATION_FILE):
26
  df = pd.DataFrame(columns=["user_id", "gender", "audio_file", "score"])
27
  df.to_csv(ANNOTATION_FILE, index=False)
28
 
29
-
30
  # ============================
31
  # USER FUNCTIONS
32
  # ============================
33
 
34
  def load_next_audio(state):
35
- """Loads the next audio file for the user session."""
36
  if state is None:
37
  state = {"index": 0}
38
 
39
  idx = state["index"]
40
 
41
  if idx >= len(audio_files):
42
- return None, state, "All audio files annotated."
43
 
44
  filepath = os.path.join(AUDIO_FOLDER, audio_files[idx])
45
- return filepath, state, f"Loaded {audio_files[idx]}"
 
46
 
47
 
48
  def submit_annotation(user_id, gender, score, state):
49
- """Saves annotation to CSV."""
50
  if state is None:
51
  state = {"index": 0}
52
 
@@ -67,27 +61,33 @@ def submit_annotation(user_id, gender, score, state):
67
  df.to_csv(ANNOTATION_FILE, index=False)
68
 
69
  state["index"] += 1
70
-
71
  return state, f"Saved rating for {audio_file}."
72
 
 
 
 
 
 
 
 
 
 
 
73
 
74
  # ============================
75
  # ADMIN FUNCTIONS
76
  # ============================
77
 
78
  def hash_password(password: str) -> str:
79
- """Hash input using SHA-256."""
80
  return hashlib.sha256(password.encode()).hexdigest()
81
 
82
-
83
  def admin_login(input_password):
84
- """Validates admin password."""
85
  if hash_password(input_password) == ADMIN_PASSWORD_HASH:
86
  df = pd.read_csv(ANNOTATION_FILE)
87
  return (
88
- gr.update(visible=True), # dashboard container
89
- gr.update(value=df), # show table
90
- gr.update(value=ANNOTATION_FILE), # file download
91
  "Admin authentication successful."
92
  )
93
  else:
@@ -98,7 +98,6 @@ def admin_login(input_password):
98
  "Incorrect password."
99
  )
100
 
101
-
102
  # ============================
103
  # GRADIO UI
104
  # ============================
@@ -112,59 +111,86 @@ with gr.Blocks() as demo:
112
  # --------------------------
113
 
114
  state = gr.State({"index": 0})
 
115
 
116
  with gr.Row():
117
  user_id = gr.Textbox(label="User ID")
118
  gender = gr.Dropdown(["Male", "Female", "Other"], label="Gender", value="Other")
119
 
120
- audio_player = gr.Audio(label="Audio File", autoplay=False)
 
 
121
  with gr.Row():
122
- score = gr.Dropdown(choices=["1", "2", "3", "4", "5"], label="MOS Score (1–5)")
123
- submit_btn = gr.Button("Submit Score")
124
- status = gr.Textbox(label="Status", interactive=False)
125
 
126
- # download_btn = gr.File(label="Download annotations.csv")
127
 
128
  # Load first audio
129
- demo.load(load_next_audio, inputs=state,
130
- outputs=[audio_player, state, status])
 
 
 
131
 
132
- # Save and load next
133
- submit_btn.click(submit_annotation,
134
- inputs=[user_id, gender, score, state],
135
- outputs=[state, status])
 
 
136
 
137
- submit_btn.click(load_next_audio,
138
- inputs=state,
139
- outputs=[audio_player, state, status])
 
 
 
 
 
 
 
 
 
140
 
141
- # CSV Download always updated
142
- # submit_btn.click(lambda: ANNOTATION_FILE, None, download_admin)
 
 
 
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
  # ============================
146
  # ADMIN DASHBOARD
147
  # ============================
148
 
149
  gr.Markdown("## Admin Dashboard (Restricted Access)")
 
150
  with gr.Row():
151
  admin_password = gr.Textbox(
152
  label="Admin Password",
153
- type="password",
154
- placeholder="Enter admin password to access dashboard"
155
  )
156
-
157
  admin_login_btn = gr.Button("Login")
158
 
159
- # Hidden dashboard container
160
  with gr.Column(visible=False) as admin_panel:
161
  gr.Markdown("### Annotation Results")
162
-
163
- results_table = gr.DataFrame(label="Annotation Table", interactive=False)
164
  download_admin = gr.File(label="Download annotations.csv")
165
- demo.load(lambda: ANNOTATION_FILE, None, download_admin)
166
-
167
- login_status = gr.Textbox(label="Login Status", interactive=False)
168
 
169
  admin_login_btn.click(
170
  admin_login,
@@ -172,6 +198,7 @@ with gr.Blocks() as demo:
172
  outputs=[admin_panel, results_table, download_admin, login_status]
173
  )
174
 
175
-
176
- demo.launch(share=True)
177
-
 
 
12
 
13
  ANNOTATION_FILE = "annotations.csv"
14
 
 
 
 
15
  ADMIN_PASSWORD_HASH = "eb32da077dfaf326cd6f73e0716b628da6427aa318a2d0b9fafa9ef315b5e885"
16
 
 
17
  # ============================
18
  # STORAGE INITIALIZATION
19
  # ============================
 
22
  df = pd.DataFrame(columns=["user_id", "gender", "audio_file", "score"])
23
  df.to_csv(ANNOTATION_FILE, index=False)
24
 
 
25
  # ============================
26
  # USER FUNCTIONS
27
  # ============================
28
 
29
  def load_next_audio(state):
 
30
  if state is None:
31
  state = {"index": 0}
32
 
33
  idx = state["index"]
34
 
35
  if idx >= len(audio_files):
36
+ return None, state, False, "All audio files annotated."
37
 
38
  filepath = os.path.join(AUDIO_FOLDER, audio_files[idx])
39
+ # return filepath, state, False, f"Loaded {audio_files[idx]}"
40
+ return filepath, state, {"played": 0}, f"Loaded {audio_files[idx]}"
41
 
42
 
43
  def submit_annotation(user_id, gender, score, state):
 
44
  if state is None:
45
  state = {"index": 0}
46
 
 
61
  df.to_csv(ANNOTATION_FILE, index=False)
62
 
63
  state["index"] += 1
 
64
  return state, f"Saved rating for {audio_file}."
65
 
66
+ # ============================
67
+ # SUBMIT BUTTON CONTROL
68
+ # ============================
69
+
70
+ def check_submit_ready(user_id, audio_played,score):
71
+ ready = len(user_id.strip())>1 and audio_played['played'] == 1 and score != "None"
72
+ return gr.update(interactive=ready)
73
+
74
+ def mark_audio_played():
75
+ return {"played": 1}
76
 
77
  # ============================
78
  # ADMIN FUNCTIONS
79
  # ============================
80
 
81
  def hash_password(password: str) -> str:
 
82
  return hashlib.sha256(password.encode()).hexdigest()
83
 
 
84
  def admin_login(input_password):
 
85
  if hash_password(input_password) == ADMIN_PASSWORD_HASH:
86
  df = pd.read_csv(ANNOTATION_FILE)
87
  return (
88
+ gr.update(visible=True),
89
+ df,
90
+ ANNOTATION_FILE,
91
  "Admin authentication successful."
92
  )
93
  else:
 
98
  "Incorrect password."
99
  )
100
 
 
101
  # ============================
102
  # GRADIO UI
103
  # ============================
 
111
  # --------------------------
112
 
113
  state = gr.State({"index": 0})
114
+ audio_played = gr.State({"played": 0})
115
 
116
  with gr.Row():
117
  user_id = gr.Textbox(label="User ID")
118
  gender = gr.Dropdown(["Male", "Female", "Other"], label="Gender", value="Other")
119
 
120
+ audio_player = gr.Audio(
121
+ label="Audio File")
122
+
123
  with gr.Row():
124
+ score = gr.Dropdown(choices=["None","1", "2", "3", "4", "5"], value="None", label="MOS Score (1–5)")
125
+ submit_btn = gr.Button("Submit Score", interactive=False)
 
126
 
127
+ status = gr.Textbox(label="Status", interactive=False)
128
 
129
  # Load first audio
130
+ demo.load(
131
+ load_next_audio,
132
+ inputs=state,
133
+ outputs=[audio_player, state, audio_played, status]
134
+ )
135
 
136
+ # Mark audio as played
137
+ audio_player.play(
138
+ mark_audio_played,
139
+ None,
140
+ audio_played
141
+ )
142
 
143
+ # Enable submit button only when conditions are met
144
+ user_id.change(
145
+ check_submit_ready,
146
+ inputs=[user_id, audio_played,score],
147
+ outputs=submit_btn
148
+ )
149
+
150
+ audio_played.change(
151
+ check_submit_ready,
152
+ inputs=[user_id, audio_played,score],
153
+ outputs=submit_btn
154
+ )
155
 
156
+ score.change(
157
+ check_submit_ready,
158
+ inputs=[user_id, audio_played,score],
159
+ outputs=submit_btn
160
+ )
161
 
162
+ # Save annotation
163
+ submit_btn.click(
164
+ submit_annotation,
165
+ inputs=[user_id, gender, score, state],
166
+ outputs=[state, status]
167
+ )
168
+
169
+ # Load next audio
170
+ submit_btn.click(
171
+ load_next_audio,
172
+ inputs=state,
173
+ outputs=[audio_player, state, audio_played, status]
174
+ )
175
 
176
  # ============================
177
  # ADMIN DASHBOARD
178
  # ============================
179
 
180
  gr.Markdown("## Admin Dashboard (Restricted Access)")
181
+
182
  with gr.Row():
183
  admin_password = gr.Textbox(
184
  label="Admin Password",
185
+ type="password"
 
186
  )
 
187
  admin_login_btn = gr.Button("Login")
188
 
 
189
  with gr.Column(visible=False) as admin_panel:
190
  gr.Markdown("### Annotation Results")
191
+ results_table = gr.DataFrame(interactive=False)
 
192
  download_admin = gr.File(label="Download annotations.csv")
193
+ login_status = gr.Textbox(interactive=False)
 
 
194
 
195
  admin_login_btn.click(
196
  admin_login,
 
198
  outputs=[admin_panel, results_table, download_admin, login_status]
199
  )
200
 
201
+ if __name__ == "__main__":
202
+ demo.launch(share=True)
203
+ # demo.launch(server_name="0.0.0.0", server_port=7860)
204
+ # demo.launch(server_name="0.0.0.0", server_port=7860, prevent_thread_lock=True)