youngtsai commited on
Commit
0aacc23
·
1 Parent(s): 9cb25c1

create_csv

Browse files
Files changed (1) hide show
  1. app.py +78 -51
app.py CHANGED
@@ -8,6 +8,8 @@ from google.cloud import storage
8
  from google.oauth2 import service_account
9
  from googleapiclient.http import MediaIoBaseDownload
10
  from storage_service import GoogleCloudStorage
 
 
11
 
12
 
13
  is_env_local = os.getenv("IS_ENV_LOCAL", "false") == "true"
@@ -37,6 +39,8 @@ bucket = GCS_CLIENT.bucket(bucket_name)
37
  GSHEET_KEY_DICT = json.loads(GSHEET_KEY)
38
  sheets_client = gspread.service_account_from_dict(GSHEET_KEY_DICT)
39
 
 
 
40
  # 函数定义
41
  def upload_image_to_gcs(image_path, bucket):
42
  # Extract the file name from the path and create a unique filename
@@ -125,58 +129,68 @@ def text_to_json(text):
125
  result = response_to_json.choices[0].message.content
126
  return result
127
 
128
- def upload_to_sheet(sheet, image_url, text, question_json):
129
- if image_url and text and question_json:
130
- q_id = question_json['q_id']
131
- question = question_json['question']
132
- choice_1 = question_json['choice_1']
133
- choice_2 = question_json['choice_2']
134
- choice_3 = question_json['choice_3']
135
- choice_4 = question_json['choice_4']
136
- perseus_text = """{"correct_nxt_qid": null, "wrong_nxt_qid": null, "itemDataVersion": {"major": 0, "minor": 1}, "question": {"content": "", "images": {}, "widgets": {"radio 1": {"version": {"major": 0, "minor": 0}, "type": "radio", "graded": true, "options": {"onePerLine": true, "noneOfTheAbove": false, "choices": [{"content": "", "correct": false}, {"content": "", "correct": false}, {"content": "", "correct": false}, {"content": "", "correct": false}], "displayCount": null, "multipleSelect": false, "randomize": false}}}}, "answerArea": {"calculator": false, "type": "multiple", "options": {}}, "is_start": false, "hints": [{"content": "", "images": {}, "widgets": {}}, {"content": "", "images": {}, "widgets": {}}]}"""
137
- perseus_json = json.loads(perseus_text)
138
- widget = "\n\n[[radio 1]]"
139
- perseus_json["question"]["content"] = question + widget
140
- perseus_json["question"]["widgets"]["radio 1"]["options"]["choices"][0]["content"] = "$\\mbox{(A)}$ " + choice_1
141
- perseus_json["question"]["widgets"]["radio 1"]["options"]["choices"][1]["content"] = "$\\mbox{(B)}$ " + choice_2
142
- perseus_json["question"]["widgets"]["radio 1"]["options"]["choices"][2]["content"] = "$\\mbox{(C)}$ " + choice_3
143
- perseus_json["question"]["widgets"]["radio 1"]["options"]["choices"][3]["content"] = "$\\mbox{(D)}$ " + choice_4
144
- perseus_json_str = json.dumps(perseus_json)
145
- sheet.append_row([image_url, text, q_id, question, choice_1, choice_2, choice_3, choice_4, perseus_json_str])
146
- else:
147
- print("圖片處理失敗,未上傳到Google Sheets")
148
-
149
- def process_and_upload(images, sheet_url):
150
- verify_password(password_input)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
- sheet = sheets_client.open_by_url(sheet_url).sheet1
153
- all_data = sheet.get_all_values()
154
- sheet_start = len(all_data) + 1 # 現有數據的下一行
155
  for image_file in images:
156
  image_url = upload_image_to_gcs(image_file, bucket)
157
- text, question_json = process_image(image_url)
158
- upload_to_sheet(sheet, image_url, text, question_json)
 
 
 
 
159
  print("======process_and_upload=====")
160
  print("image_url:", image_url)
161
-
162
- all_data = sheet.get_all_values()
163
- sheet_end = len(all_data) # 最後一個有數據的行
164
- question_count = sheet_end - sheet_start + 1
165
- result = f"""
166
- 圖片處理完成,已上傳到Google Sheets
167
- sheet_url: {sheet_url}
168
- 起始列: {sheet_start}
169
- 結束列: {sheet_end}
170
- 總共完成 {question_count} 道題目
171
- """
172
-
173
- return result
174
 
175
- def verify_password(password):
176
- if password == PASSWORD:
177
- return True
178
- else:
179
- return gr.Error("密码错误")
180
 
181
  # Gradio界面
182
  with gr.Blocks() as demo:
@@ -185,14 +199,27 @@ with gr.Blocks() as demo:
185
  password_input = gr.Textbox(label="密码", type="password")
186
  with gr.Row():
187
  image_input = gr.Files(label="选择图片", type="filepath")
188
- sheet_default_value = "https://docs.google.com/spreadsheets/d/1ygFGLxcnPad3LMVj4bZqfGZh1n2wqhs0-vOUjuVCkSY/edit#gid=0"
189
- sheet_input = gr.Textbox(label="Google Sheets URL", value=sheet_default_value)
190
  submit_button = gr.Button("開始處理圖片")
 
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
  submit_button.click(
193
- fn=process_and_upload,
194
- inputs=[image_input, sheet_input],
195
- outputs=gr.Markdown()
196
  )
197
 
198
  demo.launch()
 
8
  from google.oauth2 import service_account
9
  from googleapiclient.http import MediaIoBaseDownload
10
  from storage_service import GoogleCloudStorage
11
+ import csv
12
+ import io
13
 
14
 
15
  is_env_local = os.getenv("IS_ENV_LOCAL", "false") == "true"
 
39
  GSHEET_KEY_DICT = json.loads(GSHEET_KEY)
40
  sheets_client = gspread.service_account_from_dict(GSHEET_KEY_DICT)
41
 
42
+ CSV_DATA = []
43
+
44
  # 函数定义
45
  def upload_image_to_gcs(image_path, bucket):
46
  # Extract the file name from the path and create a unique filename
 
129
  result = response_to_json.choices[0].message.content
130
  return result
131
 
132
+ def build_perseus_json(question_json):
133
+ question = question_json['question']
134
+ choice_1 = question_json['choice_1']
135
+ choice_2 = question_json['choice_2']
136
+ choice_3 = question_json['choice_3']
137
+ choice_4 = question_json['choice_4']
138
+ perseus_text = """{"correct_nxt_qid": null, "wrong_nxt_qid": null, "itemDataVersion": {"major": 0, "minor": 1}, "question": {"content": "", "images": {}, "widgets": {"radio 1": {"version": {"major": 0, "minor": 0}, "type": "radio", "graded": true, "options": {"onePerLine": true, "noneOfTheAbove": false, "choices": [{"content": "", "correct": false}, {"content": "", "correct": false}, {"content": "", "correct": false}, {"content": "", "correct": false}], "displayCount": null, "multipleSelect": false, "randomize": false}}}}, "answerArea": {"calculator": false, "type": "multiple", "options": {}}, "is_start": false, "hints": [{"content": "", "images": {}, "widgets": {}}, {"content": "", "images": {}, "widgets": {}}]}"""
139
+ perseus_json = json.loads(perseus_text)
140
+ widget = "\n\n[[☃ radio 1]]"
141
+ perseus_json["question"]["content"] = question + widget
142
+ perseus_json["question"]["widgets"]["radio 1"]["options"]["choices"][0]["content"] = "$\\mbox{(A)}$ " + choice_1
143
+ perseus_json["question"]["widgets"]["radio 1"]["options"]["choices"][1]["content"] = "$\\mbox{(B)}$ " + choice_2
144
+ perseus_json["question"]["widgets"]["radio 1"]["options"]["choices"][2]["content"] = "$\\mbox{(C)}$ " + choice_3
145
+ perseus_json["question"]["widgets"]["radio 1"]["options"]["choices"][3]["content"] = "$\\mbox{(D)}$ " + choice_4
146
+ perseus_json_str = json.dumps(perseus_json)
147
+ return perseus_json_str
148
+
149
+ def create_csv(processed_data):
150
+ # 设定一个可写的目录路径
151
+ writable_directory = "/tmp/csv_files"
152
+ if not os.path.exists(writable_directory):
153
+ os.makedirs(writable_directory) # 如果目录不存在,创建它
154
+
155
+ timestamp = int(time.time())
156
+ file_name = f"csv_{timestamp}.csv"
157
+ file_path = os.path.join(writable_directory, file_name)
158
+
159
+ # 创建并写入 CSV 文件
160
+ with open(file_path, mode='w', newline='', encoding='utf-8') as file:
161
+ writer = csv.writer(file)
162
+
163
+ # 写入标题行
164
+ headers = ["圖片URL", "文字", "題號", "題目", "選項1", "選���2", "選項3", "選項4", "Perseus JSON"]
165
+ writer.writerow(headers)
166
+
167
+ # 写入数据行
168
+ for row in processed_data:
169
+ writer.writerow(row)
170
+
171
+ return file_path
172
+
173
+ def process_image_to_data(password, images):
174
+ if password != PASSWORD:
175
+ raise gr.Error("密码错误,请重新输入")
176
 
177
+ processed_data = []
 
 
178
  for image_file in images:
179
  image_url = upload_image_to_gcs(image_file, bucket)
180
+ text, question_json = process_image(image_url)
181
+ perseus_json_str = build_perseus_json(question_json)
182
+
183
+ # 添加數據到列表,用於後續顯示
184
+ processed_data.append([image_url, text] + list(question_json.values()) + [perseus_json_str])
185
+
186
  print("======process_and_upload=====")
187
  print("image_url:", image_url)
 
 
 
 
 
 
 
 
 
 
 
 
 
188
 
189
+ question_count = len(processed_data)
190
+ result = f"圖片處理完成,總共完成 {question_count} 道題目"
191
+ csv_file_path = create_csv(processed_data)
192
+
193
+ return processed_data, result, csv_file_path
194
 
195
  # Gradio界面
196
  with gr.Blocks() as demo:
 
199
  password_input = gr.Textbox(label="密码", type="password")
200
  with gr.Row():
201
  image_input = gr.Files(label="选择图片", type="filepath")
202
+ # sheet_default_value = "https://docs.google.com/spreadsheets/d/1ygFGLxcnPad3LMVj4bZqfGZh1n2wqhs0-vOUjuVCkSY/edit#gid=0"
203
+ # sheet_input = gr.Textbox(label="Google Sheets URL", value=sheet_default_value)
204
  submit_button = gr.Button("開始處理圖片")
205
+ with gr.Row():
206
+ result_text = gr.Textbox(label="處理結果")
207
+ with gr.Row():
208
+ result_table = gr.Dataframe(
209
+ headers=["圖片URL", "文字", "題號", "題目", "選項1", "選項2", "選項3", "選項4", "Perseus JSON"],
210
+ column_widths=[10, 25, 5, 20, 5, 5, 5, 5, 20],
211
+ wrap=True
212
+ )
213
+
214
+
215
+ with gr.Row():
216
+ download_csv_output = gr.File(label="下载 CSV")
217
+
218
 
219
  submit_button.click(
220
+ fn=process_image_to_data,
221
+ inputs=[password_input, image_input],
222
+ outputs=[result_table, result_text, download_csv_output]
223
  )
224
 
225
  demo.launch()