Ed5 commited on
Commit
eb423be
·
verified ·
1 Parent(s): 9565c60

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -37
app.py CHANGED
@@ -36,7 +36,7 @@ class KDChecker:
36
  import openpyxl
37
  log.append("Библиотека openpyxl найдена.")
38
  except ImportError:
39
- return "ОШИБКА: Библиотека openpyxl не установлена на сервере!", gr.update(choices=[], value=None)
40
 
41
  all_data = []
42
  sheets_log = []
@@ -56,8 +56,10 @@ class KDChecker:
56
  c_idx = -1
57
  r_idx = -1
58
  for idx, val in enumerate(row_values):
59
- if "шкаф" in val or "cabinet" in val: c_idx = idx
60
- if "примечание" in val or "remark" in val: r_idx = idx
 
 
61
  if c_idx != -1 and r_idx != -1:
62
  header_row_index = i
63
  cab_col_idx = c_idx
@@ -69,14 +71,11 @@ class KDChecker:
69
  if cab_col_idx < len(df.columns) and rem_col_idx < len(df.columns):
70
  df_subset = df.iloc[:, [cab_col_idx, rem_col_idx]]
71
  df_subset.columns = ["Cabinet", "Remark"]
72
-
73
  df_subset["Cabinet"] = df_subset["Cabinet"].ffill()
74
  df_subset = df_subset.dropna(subset=["Remark"]).astype(str)
75
-
76
  df_subset["Cabinet_Clean"] = df_subset["Cabinet"].apply(
77
  lambda x: x.strip().replace(" ", "").replace("\n", "").replace("\r", "")
78
  )
79
-
80
  all_data.append(df_subset)
81
  sheets_log.append(f"Лист '{sheet_name}': {len(df_subset)} стр.")
82
  else:
@@ -94,7 +93,6 @@ class KDChecker:
94
  log.append("Успешно объединили данные.")
95
  msg = f"✅ База знаний загружена успешно!\nВсего записей: {len(self.excel_db)}\nОбработаны листы: {', '.join(sheets_log)}"
96
 
97
- # ИЗМЕНЕНО: gr.update() вместо gr.Dropdown()
98
  return msg, gr.update(choices=self.cabinet_list, value=None)
99
 
100
  except Exception as e:
@@ -140,7 +138,8 @@ class KDChecker:
140
  return "UNKNOWN"
141
 
142
  def get_remarks(self, cabinet_key, is_clean_key=True):
143
- if self.excel_db.empty: return {}
 
144
  if is_clean_key:
145
  target = cabinet_key.replace(" ", "")
146
  mask = self.excel_db['Cabinet_Clean'].str.contains(re.escape(target), case=False, na=False)
@@ -148,14 +147,17 @@ class KDChecker:
148
  mask = self.excel_db['Cabinet'] == cabinet_key
149
 
150
  rows = self.excel_db[mask]
151
- if rows.empty: return {}
 
 
152
  parsed = {}
153
  for remark_cell in rows['Remark']:
154
  cell_text = str(remark_cell)
155
  cell_text = re.sub(r'(\d+)\.([А-ЯA-Z])', r'\1. \2', cell_text)
156
  items = re.split(r'(?:^|\n)\s*(?=\d+[\.\)])', cell_text)
157
  for item in items:
158
- if len(item) < 3: continue
 
159
  clean_item = item.strip()
160
  clean_item_no_num = re.sub(r'^\d+[\.\)]\s*', '', clean_item)
161
  doc_pattern = r'^(?:Документ\s+|В\s+)?([А-ЯA-Z0-9\s,\(\)\-]+?)(?:[\.\:\-]|\s+)(.*)'
@@ -170,15 +172,19 @@ class KDChecker:
170
  if valid_parts:
171
  detected_docs = valid_parts
172
  final_text = match.group(2).strip()
173
- if not detected_docs: detected_docs = ["ALL"]
 
174
  for doc in detected_docs:
175
- if doc not in parsed: parsed[doc] = []
 
176
  parsed[doc].append(final_text)
177
  return parsed
178
 
179
  def check_files(self, files, manual_cabinet):
180
- if not files: return "Файлы не загружены", None
181
- if self.excel_db.empty: return "Сначала загрузите Excel базу!", None
 
 
182
 
183
  checklist = {}
184
  detected_cabinet = "Не определен"
@@ -208,15 +214,17 @@ class KDChecker:
208
  for cab_name in unique_cabinets:
209
  sub_names = [n.strip() for n in cab_name.split(',')]
210
  for sub_name in sub_names:
211
- if len(sub_name) < 5: continue
 
212
  if sub_name.lower() in all_pdf_text.lower():
213
  detected_cabinet = cab_name
214
  found_by_method = "name"
215
  break
216
- if found_by_method == "name": break
 
217
 
218
  if detected_cabinet == "Не определен":
219
- return f"⚠️ Шкаф не опознан автоматически.\nСовет: Выберите похожий шкаф из выпадающего списка вручную.", None
220
 
221
  is_clean_search = (found_by_method == "number")
222
  remarks = self.get_remarks(detected_cabinet, is_clean_key=is_clean_search)
@@ -230,15 +238,18 @@ class KDChecker:
230
  dtype = self.determine_doc_type(fname)
231
 
232
  tasks = []
233
- if dtype in remarks: tasks.extend(remarks[dtype])
234
- if "ALL" in remarks and dtype != "С2": tasks.extend(remarks["ALL"])
 
 
235
 
236
  if tasks:
237
  checklist[fname] = list(dict.fromkeys(tasks))
238
  processed_count += 1
239
 
240
  pdf_title = detected_cabinet
241
- if is_manual: pdf_title += " (Выбор вручную)"
 
242
 
243
  try:
244
  pdf = self.create_pdf(pdf_title, checklist)
@@ -252,7 +263,7 @@ class KDChecker:
252
  return f"✅ Готово!\n\n📂 Шкаф: {detected_cabinet}\n🔍 Метод: {method_str}\n📄 Обработано файлов: {processed_count}\n🚩 Всего замечаний: {total}", pdf
253
 
254
  def create_pdf(self, cabinet, data):
255
- fname = f"CheckList_Result.pdf"
256
  path = os.path.join(tempfile.gettempdir(), fname)
257
  c = canvas.Canvas(path, pagesize=A4)
258
  form = c.acroForm
@@ -272,11 +283,11 @@ class KDChecker:
272
  c.setFont(font_name, 16)
273
 
274
  try:
275
- c.drawString(50, y, f"ЧЕК-ЛИСТ ПРОВЕРКИ КД")
276
  except:
277
- c.setFont("Helvetica", 16)
278
- c.drawString(50, y, "CHECK-LIST")
279
- c.setFont(font_name, 16)
280
 
281
  y -= 25
282
  c.setFont(font_name, 12)
@@ -285,9 +296,9 @@ class KDChecker:
285
  try:
286
  c.drawString(50, y, f"Шкаф: {disp_cab}")
287
  except:
288
- c.setFont("Helvetica", 12)
289
- c.drawString(50, y, "Cabinet name error (font)")
290
- c.setFont(font_name, 12)
291
 
292
  c.drawString(400, y, f"Дата: {datetime.now().strftime('%d.%m.%Y')}")
293
  y -= 20
@@ -301,7 +312,10 @@ class KDChecker:
301
 
302
  cb_id = 0
303
  for filename, tasks in data.items():
304
- if y < 100: c.showPage(); y = height - 50; c.setFont(font_name, 12)
 
 
 
305
 
306
  c.setFillColor(colors.darkblue)
307
  c.setFont(font_name, 11)
@@ -368,6 +382,7 @@ class KDChecker:
368
 
369
  def create_app():
370
  checker = KDChecker()
 
371
  with gr.Blocks(title="Генератор чек-листов КД") as app:
372
  gr.Markdown("# ✅ Генератор чек-листов КД")
373
  gr.Markdown("Автоматическая проверка конструкторской документации по базе знаний Excel.")
@@ -375,18 +390,13 @@ def create_app():
375
  with gr.Row():
376
  with gr.Column():
377
  gr.Markdown("### 1. База знаний")
378
-
379
  db_in = gr.File(label="Загрузить Excel (.xlsx)", type="filepath")
380
-
381
- # ИЗМЕНЕНО: choices=[] вместо choices=None
382
  manual_cab = gr.Dropdown(
383
  label="Или выберите шкаф-аналог вручную",
384
  choices=[],
385
  interactive=True
386
  )
387
-
388
- db_out = gr.Textbox(label="Статус загрузки", lines=8)
389
-
390
  db_in.upload(checker.load_excel_db, inputs=[db_in], outputs=[db_out, manual_cab])
391
 
392
  with gr.Column():
@@ -395,14 +405,21 @@ def create_app():
395
  btn = gr.Button("Сформировать чек-лист", variant="primary")
396
 
397
  with gr.Row():
398
- res_txt = gr.Textbox(label="Результат проверки", lines=8)
399
  res_pdf = gr.File(label="Скачать PDF чек-лист")
400
 
401
  btn.click(checker.check_files, inputs=[files_in, manual_cab], outputs=[res_txt, res_pdf])
 
402
  return app
403
 
404
 
 
405
  app = create_app()
406
 
 
407
  if __name__ == "__main__":
408
- app.launch(auth=("admin", "12345"))
 
 
 
 
 
36
  import openpyxl
37
  log.append("Библиотека openpyxl найдена.")
38
  except ImportError:
39
+ return "ОШИБКА: Библиотека openpyxl не установлена!", gr.update(choices=[], value=None)
40
 
41
  all_data = []
42
  sheets_log = []
 
56
  c_idx = -1
57
  r_idx = -1
58
  for idx, val in enumerate(row_values):
59
+ if "шкаф" in val or "cabinet" in val:
60
+ c_idx = idx
61
+ if "примечание" in val or "remark" in val:
62
+ r_idx = idx
63
  if c_idx != -1 and r_idx != -1:
64
  header_row_index = i
65
  cab_col_idx = c_idx
 
71
  if cab_col_idx < len(df.columns) and rem_col_idx < len(df.columns):
72
  df_subset = df.iloc[:, [cab_col_idx, rem_col_idx]]
73
  df_subset.columns = ["Cabinet", "Remark"]
 
74
  df_subset["Cabinet"] = df_subset["Cabinet"].ffill()
75
  df_subset = df_subset.dropna(subset=["Remark"]).astype(str)
 
76
  df_subset["Cabinet_Clean"] = df_subset["Cabinet"].apply(
77
  lambda x: x.strip().replace(" ", "").replace("\n", "").replace("\r", "")
78
  )
 
79
  all_data.append(df_subset)
80
  sheets_log.append(f"Лист '{sheet_name}': {len(df_subset)} стр.")
81
  else:
 
93
  log.append("Успешно объединили данные.")
94
  msg = f"✅ База знаний загружена успешно!\nВсего записей: {len(self.excel_db)}\nОбработаны листы: {', '.join(sheets_log)}"
95
 
 
96
  return msg, gr.update(choices=self.cabinet_list, value=None)
97
 
98
  except Exception as e:
 
138
  return "UNKNOWN"
139
 
140
  def get_remarks(self, cabinet_key, is_clean_key=True):
141
+ if self.excel_db.empty:
142
+ return {}
143
  if is_clean_key:
144
  target = cabinet_key.replace(" ", "")
145
  mask = self.excel_db['Cabinet_Clean'].str.contains(re.escape(target), case=False, na=False)
 
147
  mask = self.excel_db['Cabinet'] == cabinet_key
148
 
149
  rows = self.excel_db[mask]
150
+ if rows.empty:
151
+ return {}
152
+
153
  parsed = {}
154
  for remark_cell in rows['Remark']:
155
  cell_text = str(remark_cell)
156
  cell_text = re.sub(r'(\d+)\.([А-ЯA-Z])', r'\1. \2', cell_text)
157
  items = re.split(r'(?:^|\n)\s*(?=\d+[\.\)])', cell_text)
158
  for item in items:
159
+ if len(item) < 3:
160
+ continue
161
  clean_item = item.strip()
162
  clean_item_no_num = re.sub(r'^\d+[\.\)]\s*', '', clean_item)
163
  doc_pattern = r'^(?:Документ\s+|В\s+)?([А-ЯA-Z0-9\s,\(\)\-]+?)(?:[\.\:\-]|\s+)(.*)'
 
172
  if valid_parts:
173
  detected_docs = valid_parts
174
  final_text = match.group(2).strip()
175
+ if not detected_docs:
176
+ detected_docs = ["ALL"]
177
  for doc in detected_docs:
178
+ if doc not in parsed:
179
+ parsed[doc] = []
180
  parsed[doc].append(final_text)
181
  return parsed
182
 
183
  def check_files(self, files, manual_cabinet):
184
+ if not files:
185
+ return "Файлы не загружены", None
186
+ if self.excel_db.empty:
187
+ return "Сначала загрузите Excel базу!", None
188
 
189
  checklist = {}
190
  detected_cabinet = "Не определен"
 
214
  for cab_name in unique_cabinets:
215
  sub_names = [n.strip() for n in cab_name.split(',')]
216
  for sub_name in sub_names:
217
+ if len(sub_name) < 5:
218
+ continue
219
  if sub_name.lower() in all_pdf_text.lower():
220
  detected_cabinet = cab_name
221
  found_by_method = "name"
222
  break
223
+ if found_by_method == "name":
224
+ break
225
 
226
  if detected_cabinet == "Не определен":
227
+ return "⚠️ Шкаф не опознан автоматически.\nСовет: Выберите шкаф из выпадающего списка вручную.", None
228
 
229
  is_clean_search = (found_by_method == "number")
230
  remarks = self.get_remarks(detected_cabinet, is_clean_key=is_clean_search)
 
238
  dtype = self.determine_doc_type(fname)
239
 
240
  tasks = []
241
+ if dtype in remarks:
242
+ tasks.extend(remarks[dtype])
243
+ if "ALL" in remarks and dtype != "С2":
244
+ tasks.extend(remarks["ALL"])
245
 
246
  if tasks:
247
  checklist[fname] = list(dict.fromkeys(tasks))
248
  processed_count += 1
249
 
250
  pdf_title = detected_cabinet
251
+ if is_manual:
252
+ pdf_title += " (Выбор вручную)"
253
 
254
  try:
255
  pdf = self.create_pdf(pdf_title, checklist)
 
263
  return f"✅ Готово!\n\n📂 Шкаф: {detected_cabinet}\n🔍 Метод: {method_str}\n📄 Обработано файлов: {processed_count}\n🚩 Всего замечаний: {total}", pdf
264
 
265
  def create_pdf(self, cabinet, data):
266
+ fname = "CheckList_Result.pdf"
267
  path = os.path.join(tempfile.gettempdir(), fname)
268
  c = canvas.Canvas(path, pagesize=A4)
269
  form = c.acroForm
 
283
  c.setFont(font_name, 16)
284
 
285
  try:
286
+ c.drawString(50, y, "ЧЕК-ЛИСТ ПРОВЕРКИ КД")
287
  except:
288
+ c.setFont("Helvetica", 16)
289
+ c.drawString(50, y, "CHECK-LIST")
290
+ c.setFont(font_name, 16)
291
 
292
  y -= 25
293
  c.setFont(font_name, 12)
 
296
  try:
297
  c.drawString(50, y, f"Шкаф: {disp_cab}")
298
  except:
299
+ c.setFont("Helvetica", 12)
300
+ c.drawString(50, y, "Cabinet name error (font)")
301
+ c.setFont(font_name, 12)
302
 
303
  c.drawString(400, y, f"Дата: {datetime.now().strftime('%d.%m.%Y')}")
304
  y -= 20
 
312
 
313
  cb_id = 0
314
  for filename, tasks in data.items():
315
+ if y < 100:
316
+ c.showPage()
317
+ y = height - 50
318
+ c.setFont(font_name, 12)
319
 
320
  c.setFillColor(colors.darkblue)
321
  c.setFont(font_name, 11)
 
382
 
383
  def create_app():
384
  checker = KDChecker()
385
+
386
  with gr.Blocks(title="Генератор чек-листов КД") as app:
387
  gr.Markdown("# ✅ Генератор чек-листов КД")
388
  gr.Markdown("Автоматическая проверка конструкторской документации по базе знаний Excel.")
 
390
  with gr.Row():
391
  with gr.Column():
392
  gr.Markdown("### 1. База знаний")
 
393
  db_in = gr.File(label="Загрузить Excel (.xlsx)", type="filepath")
 
 
394
  manual_cab = gr.Dropdown(
395
  label="Или выберите шкаф-аналог вручную",
396
  choices=[],
397
  interactive=True
398
  )
399
+ db_out = gr.Textbox(label="Статус загрузки", lines=6)
 
 
400
  db_in.upload(checker.load_excel_db, inputs=[db_in], outputs=[db_out, manual_cab])
401
 
402
  with gr.Column():
 
405
  btn = gr.Button("Сформировать чек-лист", variant="primary")
406
 
407
  with gr.Row():
408
+ res_txt = gr.Textbox(label="Результат проверки", lines=6)
409
  res_pdf = gr.File(label="Скачать PDF чек-лист")
410
 
411
  btn.click(checker.check_files, inputs=[files_in, manual_cab], outputs=[res_txt, res_pdf])
412
+
413
  return app
414
 
415
 
416
+ # Создаём приложение
417
  app = create_app()
418
 
419
+ # Запуск для Hugging Face Spaces
420
  if __name__ == "__main__":
421
+ app.launch(
422
+ server_name="0.0.0.0",
423
+ server_port=7860,
424
+ share=False
425
+ )