clementBE commited on
Commit
80a08f1
·
verified ·
1 Parent(s): 64f3462

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +196 -0
app.py ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import io
4
+ from datetime import date
5
+
6
+ # Global variables
7
+ sentences = []
8
+ annotations = []
9
+ categories = {}
10
+ main_categories = []
11
+
12
+
13
+ # ------------------------
14
+ # Load categories.txt
15
+ # ------------------------
16
+ def load_categories(file):
17
+ global categories, main_categories
18
+ if file is None:
19
+ return "⚠️ No file uploaded", []
20
+
21
+ categories = {}
22
+ main_categories = []
23
+ current = None
24
+
25
+ with open(file.name, "r", encoding="utf-8") as f:
26
+ for line in f:
27
+ line = line.strip()
28
+ if not line:
29
+ continue
30
+ if line.endswith(":"):
31
+ current = line[:-1].strip()
32
+ main_categories.append(current)
33
+ categories[current] = []
34
+ elif current:
35
+ categories[current].append(line)
36
+
37
+ return "✅ Categories loaded", main_categories
38
+
39
+
40
+ # ------------------------
41
+ # Load sentences from TXT
42
+ # ------------------------
43
+ def load_txt(file):
44
+ global sentences, annotations
45
+ if file is None:
46
+ return "⚠️ No file uploaded", "", 0, 0, "", "", gr.update(visible=False)
47
+
48
+ with open(file.name, "r", encoding="utf-8") as f:
49
+ text = f.read()
50
+
51
+ sentences = [s.strip() for s in text.split(".") if s.strip()]
52
+ annotations = [["", "", ""] for _ in sentences] # Cat A, Cat B, Comments
53
+
54
+ base_name = file.name.split("/")[-1].replace(".txt", "")
55
+ youtube_url = f"https://www.youtube.com/watch?v={base_name}"
56
+
57
+ return (
58
+ f"✅ {len(sentences)} sentences loaded",
59
+ sentences[0],
60
+ 1,
61
+ len(sentences),
62
+ "",
63
+ youtube_url,
64
+ gr.update(visible=True),
65
+ )
66
+
67
+
68
+ # ------------------------
69
+ # Save annotation for current sentence
70
+ # ------------------------
71
+ def save_annotation(idx, catA, catB, comment):
72
+ global annotations
73
+ if 0 <= idx - 1 < len(annotations):
74
+ annotations[idx - 1] = [catA, catB, comment]
75
+ return "💾 Saved!"
76
+
77
+
78
+ # ------------------------
79
+ # Move to next/previous sentence
80
+ # ------------------------
81
+ def change_sentence(idx, direction, catA, catB, comment):
82
+ global sentences, annotations
83
+ save_annotation(idx, catA, catB, comment)
84
+
85
+ if direction == "next" and idx < len(sentences):
86
+ idx += 1
87
+ elif direction == "prev" and idx > 1:
88
+ idx -= 1
89
+
90
+ sentence = sentences[idx - 1]
91
+ catA, catB, comment = annotations[idx - 1]
92
+ return sentence, idx, catA, update_catB(catA), catB, comment
93
+
94
+
95
+ # ------------------------
96
+ # Update subcategories dynamically
97
+ # ------------------------
98
+ def update_catB(catA):
99
+ return gr.update(choices=categories.get(catA, []), value=None)
100
+
101
+
102
+ # ------------------------
103
+ # Export to Excel
104
+ # ------------------------
105
+ def export_excel(codeur, comments, youtube_link):
106
+ global sentences, annotations
107
+ rows = [
108
+ [s, ann[0], ann[1], ann[2]] for s, ann in zip(sentences, annotations)
109
+ ]
110
+ df = pd.DataFrame(rows, columns=["Sentence", "Category A", "Category B", "Comments"])
111
+
112
+ output = io.BytesIO()
113
+ with pd.ExcelWriter(output, engine="xlsxwriter") as writer:
114
+ df.to_excel(writer, index=False, sheet_name="Sentences")
115
+ meta = pd.DataFrame([[comments, youtube_link]], columns=["General Comments", "YouTube Link"])
116
+ meta.to_excel(writer, index=False, sheet_name="Metadata")
117
+ output.seek(0)
118
+
119
+ filename = f"Annotation_{codeur}_{date.today()}.xlsx"
120
+ return output, filename
121
+
122
+
123
+ # ------------------------
124
+ # Gradio UI
125
+ # ------------------------
126
+ with gr.Blocks() as demo:
127
+ gr.Markdown("# 🐱 My Little Cute Cat - Annotation Tool")
128
+
129
+ with gr.Tabs():
130
+ # -------- Instructions --------
131
+ with gr.Tab("📘 Instructions"):
132
+ gr.Markdown("""
133
+ ## How to Create Categories File
134
+ Write your categories in a text file like this:
135
+ ```
136
+ MainCategory1:
137
+ Subcat 1
138
+ Subcat 2
139
+
140
+ MainCategory2:
141
+ Subcat A
142
+ Subcat B
143
+ ```
144
+ Save as **categories.txt** and load it in the interface.
145
+ """)
146
+
147
+ # -------- Annotation --------
148
+ with gr.Tab("✍️ Annotation"):
149
+ status = gr.Label()
150
+
151
+ codeur = gr.Dropdown([f"Codeur {i}" for i in range(1, 11)], label="Select Codeur")
152
+ cat_file = gr.File(label="Load Categories File (.txt)", file_types=[".txt"])
153
+ file_input = gr.File(label="Upload TXT File (sentences)", file_types=[".txt"])
154
+
155
+ sentence_box = gr.Textbox(label="Sentence", interactive=False, lines=2)
156
+
157
+ with gr.Row():
158
+ catA = gr.Dropdown(label="Category A", choices=[])
159
+ catB = gr.Dropdown(label="Category B", choices=[])
160
+
161
+ comment = gr.Textbox(label="Comment for this sentence", lines=2)
162
+
163
+ with gr.Row():
164
+ prev_btn = gr.Button("⬅️ Previous")
165
+ save_btn = gr.Button("💾 Save")
166
+ next_btn = gr.Button("Next ➡️")
167
+
168
+ progress = gr.Label("")
169
+
170
+ general_comments = gr.Textbox(label="General Comments", lines=3)
171
+ youtube_link = gr.Textbox(label="YouTube Link")
172
+
173
+ export_btn = gr.Button("Export to Excel")
174
+ download_file = gr.File(label="Download Excel", visible=False)
175
+
176
+ # Events
177
+ cat_file.change(load_categories, inputs=cat_file, outputs=[status, catA])
178
+ file_input.change(load_txt, inputs=file_input,
179
+ outputs=[status, sentence_box, progress, progress, comment, youtube_link, download_file])
180
+
181
+ catA.change(update_catB, inputs=catA, outputs=catB)
182
+
183
+ prev_btn.click(change_sentence,
184
+ inputs=[progress, gr.State("prev"), catA, catB, comment],
185
+ outputs=[sentence_box, progress, catA, catB, catB, comment])
186
+ next_btn.click(change_sentence,
187
+ inputs=[progress, gr.State("next"), catA, catB, comment],
188
+ outputs=[sentence_box, progress, catA, catB, catB, comment])
189
+
190
+ save_btn.click(save_annotation, inputs=[progress, catA, catB, comment], outputs=status)
191
+
192
+ export_btn.click(export_excel,
193
+ inputs=[codeur, general_comments, youtube_link],
194
+ outputs=[download_file, download_file])
195
+
196
+ demo.launch()