Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -94,16 +94,26 @@ class KDChecker:
|
|
| 94 |
|
| 95 |
def find_all_decimal_numbers(self, text):
|
| 96 |
matches = []
|
|
|
|
|
|
|
|
|
|
| 97 |
pattern_custom = r"(РЛТ|ЛДАР|ВНАР|ШТМ)[\s\.]*\d{1}[\s\.]*\d{3}[\s\.]*[А-ЯA-Z]{1,4}[\s\.]*\d{3}(-[\d]+)?"
|
|
|
|
|
|
|
|
|
|
| 98 |
pattern_gost = r"(РЛТ|ЛДАР|ВНАР|ШТМ)[\s\.]*\d{6}[\s\.]*\d{3}"
|
| 99 |
|
|
|
|
| 100 |
for match in re.finditer(pattern_custom, text):
|
| 101 |
clean_num = match.group(0).replace(" ", "").replace("\n", "")
|
| 102 |
-
if clean_num not in matches:
|
|
|
|
| 103 |
|
|
|
|
| 104 |
for match in re.finditer(pattern_gost, text):
|
| 105 |
clean_num = match.group(0).replace(" ", "").replace("\n", "")
|
| 106 |
-
if clean_num not in matches:
|
|
|
|
| 107 |
|
| 108 |
return matches
|
| 109 |
|
|
@@ -181,7 +191,7 @@ class KDChecker:
|
|
| 181 |
for file_path in progress.tqdm(files, desc="Поиск номера шкафа"):
|
| 182 |
raw_text = self.extract_text(file_path)
|
| 183 |
|
| 184 |
-
#
|
| 185 |
pdf_numbers = self.find_all_decimal_numbers(raw_text)
|
| 186 |
for cand in pdf_numbers:
|
| 187 |
if cand in db_clean_keys:
|
|
@@ -193,11 +203,16 @@ class KDChecker:
|
|
| 193 |
print(f"✅ Шкаф найден по номеру: {detected_cabinet}")
|
| 194 |
break
|
| 195 |
|
| 196 |
-
#
|
|
|
|
| 197 |
flat_text = raw_text.replace("\n", " ").replace(" ", " ").lower()
|
|
|
|
| 198 |
unique_cabinets = self.excel_db["Cabinet"].unique()
|
| 199 |
for cab_name in unique_cabinets:
|
|
|
|
| 200 |
if "ЛДАР" in cab_name or "РЛТ" in cab_name: continue
|
|
|
|
|
|
|
| 201 |
clean_name = cab_name.lower().strip()
|
| 202 |
if len(clean_name) > 5 and clean_name in flat_text:
|
| 203 |
detected_cabinet = cab_name
|
|
@@ -205,7 +220,8 @@ class KDChecker:
|
|
| 205 |
print(f"✅ Шкаф найден по имени: {cab_name}")
|
| 206 |
break
|
| 207 |
|
| 208 |
-
if found_by_method == "name":
|
|
|
|
| 209 |
|
| 210 |
print(f"Определен шкаф: {detected_cabinet}")
|
| 211 |
|
|
@@ -245,9 +261,7 @@ class KDChecker:
|
|
| 245 |
return f"✅ Готово!\n📂 Шкаф: {detected_cabinet}\n🔍 Метод: {method_str}\n📄 Файлов: {processed_count}\n🚩 Замечаний: {total}", pdf
|
| 246 |
|
| 247 |
def create_pdf(self, cabinet, data):
|
| 248 |
-
|
| 249 |
-
fname = f"Checklist_{safe_name}.pdf"
|
| 250 |
-
|
| 251 |
path = os.path.join(tempfile.gettempdir(), fname)
|
| 252 |
c = canvas.Canvas(path, pagesize=A4)
|
| 253 |
form = c.acroForm
|
|
@@ -330,40 +344,20 @@ class KDChecker:
|
|
| 330 |
return path
|
| 331 |
|
| 332 |
|
| 333 |
-
# --- ИНТЕРФЕЙС
|
| 334 |
|
| 335 |
css = """
|
| 336 |
-
|
| 337 |
-
.compact_file {
|
| 338 |
-
|
| 339 |
-
min-height: 100px !important;
|
| 340 |
-
}
|
| 341 |
-
|
| 342 |
-
/* Принудительно уменьшаем внутреннюю область загрузки */
|
| 343 |
-
.compact_file .file-container, .compact_file .upload-container {
|
| 344 |
-
height: 120px !important;
|
| 345 |
-
min-height: 120px !important;
|
| 346 |
-
}
|
| 347 |
-
|
| 348 |
-
/* Оранжевая кнопка */
|
| 349 |
-
.orange_btn {
|
| 350 |
-
background: #FF7F27 !important;
|
| 351 |
-
border: none !important;
|
| 352 |
-
color: white !important;
|
| 353 |
-
font-weight: bold;
|
| 354 |
-
font-size: 16px !important;
|
| 355 |
-
}
|
| 356 |
.orange_btn:hover { background: #E06010 !important; }
|
| 357 |
-
|
| 358 |
-
/* Убираем футер */
|
| 359 |
footer { display: none !important; }
|
| 360 |
"""
|
| 361 |
|
| 362 |
def create_app():
|
| 363 |
checker = KDChecker()
|
| 364 |
|
| 365 |
-
|
| 366 |
-
with gr.Blocks(title="Генератор чек-листов КД", theme=gr.themes.Soft(), css=css) as app:
|
| 367 |
gr.Markdown("## ✅ Генератор чек-листов КД")
|
| 368 |
|
| 369 |
with gr.Row():
|
|
@@ -398,9 +392,4 @@ def create_app():
|
|
| 398 |
|
| 399 |
if __name__ == "__main__":
|
| 400 |
app = create_app()
|
| 401 |
-
|
| 402 |
-
app.launch(
|
| 403 |
-
server_name="0.0.0.0",
|
| 404 |
-
server_port=7860,
|
| 405 |
-
auth=("admin", "12345")
|
| 406 |
-
)
|
|
|
|
| 94 |
|
| 95 |
def find_all_decimal_numbers(self, text):
|
| 96 |
matches = []
|
| 97 |
+
|
| 98 |
+
# Шаблон 1: Специфичный (РЛТ.1.006.ША.030)
|
| 99 |
+
# Ищет: Префикс + цифра + 3 цифры + буквы + 3 цифры
|
| 100 |
pattern_custom = r"(РЛТ|ЛДАР|ВНАР|ШТМ)[\s\.]*\d{1}[\s\.]*\d{3}[\s\.]*[А-ЯA-Z]{1,4}[\s\.]*\d{3}(-[\d]+)?"
|
| 101 |
+
|
| 102 |
+
# Шаблон 2: Стандартный ГОСТ (ЛДАР.421246.337)
|
| 103 |
+
# Ищет: Префикс + точка + 6 цифр + точка + 3 цифры (допускаются пробелы вместо точек)
|
| 104 |
pattern_gost = r"(РЛТ|ЛДАР|ВНАР|ШТМ)[\s\.]*\d{6}[\s\.]*\d{3}"
|
| 105 |
|
| 106 |
+
# Ищем по первому шаблону
|
| 107 |
for match in re.finditer(pattern_custom, text):
|
| 108 |
clean_num = match.group(0).replace(" ", "").replace("\n", "")
|
| 109 |
+
if clean_num not in matches:
|
| 110 |
+
matches.append(clean_num)
|
| 111 |
|
| 112 |
+
# Ищем по второму шаблону
|
| 113 |
for match in re.finditer(pattern_gost, text):
|
| 114 |
clean_num = match.group(0).replace(" ", "").replace("\n", "")
|
| 115 |
+
if clean_num not in matches:
|
| 116 |
+
matches.append(clean_num)
|
| 117 |
|
| 118 |
return matches
|
| 119 |
|
|
|
|
| 191 |
for file_path in progress.tqdm(files, desc="Поиск номера шкафа"):
|
| 192 |
raw_text = self.extract_text(file_path)
|
| 193 |
|
| 194 |
+
# --- ПОИСК ПО НОМЕРУ (2 ШАБЛОНА) ---
|
| 195 |
pdf_numbers = self.find_all_decimal_numbers(raw_text)
|
| 196 |
for cand in pdf_numbers:
|
| 197 |
if cand in db_clean_keys:
|
|
|
|
| 203 |
print(f"✅ Шкаф найден по номеру: {detected_cabinet}")
|
| 204 |
break
|
| 205 |
|
| 206 |
+
# --- ПОИСК ПО ИМЕНИ (УЛУЧШЕННЫЙ) ---
|
| 207 |
+
# Убираем переносы строк, чтобы "Шкаф\nСАУ" стало "Шкаф САУ"
|
| 208 |
flat_text = raw_text.replace("\n", " ").replace(" ", " ").lower()
|
| 209 |
+
|
| 210 |
unique_cabinets = self.excel_db["Cabinet"].unique()
|
| 211 |
for cab_name in unique_cabinets:
|
| 212 |
+
# Ищем только если это похоже на название, а не на код
|
| 213 |
if "ЛДАР" in cab_name or "РЛТ" in cab_name: continue
|
| 214 |
+
|
| 215 |
+
# Проверяем точное вхождение названия
|
| 216 |
clean_name = cab_name.lower().strip()
|
| 217 |
if len(clean_name) > 5 and clean_name in flat_text:
|
| 218 |
detected_cabinet = cab_name
|
|
|
|
| 220 |
print(f"✅ Шкаф найден по имени: {cab_name}")
|
| 221 |
break
|
| 222 |
|
| 223 |
+
if found_by_method == "name":
|
| 224 |
+
break
|
| 225 |
|
| 226 |
print(f"Определен шкаф: {detected_cabinet}")
|
| 227 |
|
|
|
|
| 261 |
return f"✅ Готово!\n📂 Шкаф: {detected_cabinet}\n🔍 Метод: {method_str}\n📄 Файлов: {processed_count}\n🚩 Замечаний: {total}", pdf
|
| 262 |
|
| 263 |
def create_pdf(self, cabinet, data):
|
| 264 |
+
fname = f"CheckList_Result.pdf"
|
|
|
|
|
|
|
| 265 |
path = os.path.join(tempfile.gettempdir(), fname)
|
| 266 |
c = canvas.Canvas(path, pagesize=A4)
|
| 267 |
form = c.acroForm
|
|
|
|
| 344 |
return path
|
| 345 |
|
| 346 |
|
| 347 |
+
# --- ИНТЕРФЕЙС ---
|
| 348 |
|
| 349 |
css = """
|
| 350 |
+
.gradio-container { max-width: 95% !important; }
|
| 351 |
+
.compact_file { height: 150px !important; min-height: 150px !important; max-height: 150px !important; overflow: hidden !important; }
|
| 352 |
+
.orange_btn { background: #FF7F27 !important; border: none !important; color: white !important; font-weight: bold; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 353 |
.orange_btn:hover { background: #E06010 !important; }
|
|
|
|
|
|
|
| 354 |
footer { display: none !important; }
|
| 355 |
"""
|
| 356 |
|
| 357 |
def create_app():
|
| 358 |
checker = KDChecker()
|
| 359 |
|
| 360 |
+
with gr.Blocks(title="Генератор чек-листов КД") as app:
|
|
|
|
| 361 |
gr.Markdown("## ✅ Генератор чек-листов КД")
|
| 362 |
|
| 363 |
with gr.Row():
|
|
|
|
| 392 |
|
| 393 |
if __name__ == "__main__":
|
| 394 |
app = create_app()
|
| 395 |
+
app.launch(server_name="0.0.0.0", server_port=7860, css=css, theme=gr.themes.Soft())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|