diff --git a/app/main/check_packs/pack_config.py b/app/main/check_packs/pack_config.py
index 91e08134..008d3c99 100644
--- a/app/main/check_packs/pack_config.py
+++ b/app/main/check_packs/pack_config.py
@@ -22,6 +22,7 @@
['pres_image_capture'],
['task_tracker'],
['overview_in_tasks'],
+ ['abbreviations_check_pres'],
]
BASE_REPORT_CRITERION = [
["simple_check"],
@@ -50,6 +51,7 @@
["empty_task_page_check"],
["water_in_the_text_check"],
["report_task_tracker"],
+ ["abbreviations_check"],
]
DEFAULT_TYPE = 'pres'
diff --git a/app/main/checks/check_abbreviations.py b/app/main/checks/check_abbreviations.py
new file mode 100644
index 00000000..f810b1b1
--- /dev/null
+++ b/app/main/checks/check_abbreviations.py
@@ -0,0 +1,80 @@
+import re
+from pymorphy2 import MorphAnalyzer
+morph = MorphAnalyzer()
+
+
+def get_unexplained_abbrev(text):
+ abbreviations = find_abbreviations(text)
+
+ if not abbreviations:
+ return False, None
+
+ unexplained_abbr = []
+ for abbr in abbreviations:
+ if not is_abbreviation_explained(abbr, text):
+ unexplained_abbr.append(abbr)
+
+ return True, unexplained_abbr
+
+
+
+
+def find_abbreviations(text: str):
+ pattern = r'\b[А-ЯA-Z]{2,5}\b'
+ abbreviations = re.findall(pattern, text)
+
+ common_abbr = {
+ 'СССР', 'РФ', 'США', 'ВКР', 'ИТ', 'ПО', 'ООО', 'ЗАО', 'ОАО', 'HTML', 'CSS',
+ 'JS', 'ЛЭТИ', 'МОЕВМ', 'ЭВМ', 'ГОСТ', 'DVD'
+
+ 'SSD', 'PC', 'HDD',
+ 'AX', 'BX', 'CX', 'DX', 'SI', 'DI', 'BP', 'SP',
+ 'AH', 'AL', 'BH', 'BL', 'CH', 'CL', 'DH', 'DL',
+ 'CS', 'DS', 'ES', 'SS', 'FS', 'GS',
+ 'IP', 'EIP', 'RIP',
+ 'CF', 'PF', 'AF', 'ZF', 'SF', 'TF', 'IF', 'DF', 'OF',
+ 'EAX', 'EBX', 'ECX', 'EDX', 'ESI', 'EDI', 'EBP', 'ESP',
+ 'RAX', 'RBX', 'RCX', 'RDX', 'RSI', 'RDI', 'RBP', 'RSP',
+ 'DOS', 'OS', 'BIOS', 'UEFI', 'MBR', 'GPT',
+ 'ASCII', 'UTF', 'UNICODE', 'ANSI',
+ 'ЭВМ', 'МОЭВМ',
+ 'CPU', 'GPU', 'APU', 'RAM', 'ROM', 'PROM', 'EPROM', 'EEPROM',
+ 'USB', 'SATA', 'PCI', 'PCIe', 'AGP', 'ISA', 'VGA', 'HDMI', 'DP',
+ 'LAN', 'WAN', 'WLAN', 'VPN', 'ISP', 'DNS', 'DHCP', 'TCP', 'UDP', 'IP',
+ 'HTTP', 'HTTPS', 'FTP', 'SSH', 'SSL', 'TLS',
+ 'API', 'GUI', 'CLI', 'IDE', 'SDK', 'SQL', 'NoSQL', 'XML', 'JSON', 'YAML',
+ 'MAC', 'IBM', 'ГОСТ'
+ }
+ filtered_abbr = [abbr for abbr in abbreviations if abbr not in common_abbr and morph.parse(abbr.lower())[0].score != 0]
+
+ return list(set(filtered_abbr))
+
+
+def is_abbreviation_explained(abbr: str, text: str) -> bool:
+ patterns = [
+ rf'{abbr}\s*\(([^)]+)\)', # АААА (расшифровка)
+ rf'\(([^)]+)\)\s*{abbr}', # (расшифровка) АААА
+ rf'{abbr}\s*[—\-]\s*([^.,;!?]+)', # АААА — расшифровка
+ rf'{abbr}\s*-\s*([^.,;!?]+)', # АААА - расшифровка
+ rf'([^.,;!?]+)\s*[—\-]\s*{abbr}', # расшифровка — АААА
+ rf'([^.,;!?]+)\s*-\s*{abbr}' # расшифровка - АААА
+ ]
+
+
+ for pattern in patterns:
+ match = re.search(pattern, text, re.IGNORECASE)
+ if match and correctly_explained(abbr, match.group(1)):
+ return True
+
+ return False
+
+def correctly_explained(abbr, explan):
+ words = explan.split()
+
+ first_letter = ""
+ for word in words:
+ first_letter += word[0].upper()
+
+ if(first_letter == abbr[len(first_letter)]):
+ return True
+ return False
diff --git a/app/main/checks/presentation_checks/__init__.py b/app/main/checks/presentation_checks/__init__.py
index 52bd5f73..db54ae53 100644
--- a/app/main/checks/presentation_checks/__init__.py
+++ b/app/main/checks/presentation_checks/__init__.py
@@ -17,3 +17,4 @@
from .name_of_image_check import PresImageCaptureCheck
from .task_tracker import TaskTracker
from .overview_in_tasks import OverviewInTasks
+from .abbreviations_presentation import PresAbbreviationsCheck
diff --git a/app/main/checks/presentation_checks/abbreviations_presentation.py b/app/main/checks/presentation_checks/abbreviations_presentation.py
new file mode 100644
index 00000000..17c4a672
--- /dev/null
+++ b/app/main/checks/presentation_checks/abbreviations_presentation.py
@@ -0,0 +1,59 @@
+import re
+from ..base_check import BasePresCriterion, answer
+from ..check_abbreviations import get_unexplained_abbrev
+
+
+class PresAbbreviationsCheck(BasePresCriterion):
+ label = "Проверка расшифровки аббревиатур в презентации"
+ description = "Все аббревиатуры должны быть расшифрованы при первом использовании"
+ id = 'abbreviations_check_pres'
+
+ def __init__(self, file_info):
+ super().__init__(file_info)
+
+ def check(self):
+ try:
+ slides_text = self.file.get_text_from_slides()
+
+ if not slides_text:
+ return answer(False, "Не удалось получить текст презентации")
+
+ full_text = " ".join(slides_text)
+
+ abbr_is_finding, unexplained_abbr = get_unexplained_abbrev(text=full_text)
+
+ if not abbr_is_finding:
+ return answer(True, "Аббревиатуры не найдены в презентации")
+
+ if not unexplained_abbr:
+ return answer(True, "Все аббревиатуры правильно расшифрованы")
+
+ unexplained_abbr_with_slides = {}
+
+ for slide_num, slide_text in enumerate(slides_text, 1):
+ for abbr in unexplained_abbr:
+ if abbr in slide_text and abbr not in unexplained_abbr_with_slides:
+ unexplained_abbr_with_slides[abbr] = slide_num
+
+ result_str = "Найдены нерасшифрованные аббревиатуры при первом использовании:
"
+ slide_links = self.format_page_link(list(unexplained_abbr_with_slides.values()))
+ for index_links, abbr in enumerate(unexplained_abbr_with_slides):
+ result_str += f"- {abbr} на слайде {slide_links[index_links]}
"
+
+ result_str += "
Каждая аббревиатура должна быть расшифрована при первом использовании в презентации.
"
+ result_str += "Расшифровка должны быть по первыми буквам, например, МВД - Министерство внутренних дел.
"
+
+ return answer(False, result_str)
+
+ except Exception as e:
+ return answer(False, f"Ошибка при проверке аббревиатур: {str(e)}")
+
+ def _find_abbreviation_slides(self, abbr: str, slides_text: list) -> list:
+ found_slides = []
+
+ for slide_num, slide_text in enumerate(slides_text, 1):
+ pattern = rf'\b{re.escape(abbr)}\b'
+ if re.search(pattern, slide_text, re.IGNORECASE):
+ found_slides.append(slide_num)
+
+ return found_slides
diff --git a/app/main/checks/report_checks/__init__.py b/app/main/checks/report_checks/__init__.py
index 30f22617..bf5d475c 100644
--- a/app/main/checks/report_checks/__init__.py
+++ b/app/main/checks/report_checks/__init__.py
@@ -32,5 +32,6 @@
from .sw_section_size import SWSectionSizeCheck
from .sw_keywords_check import SWKeywordsCheck
from .task_tracker import ReportTaskTracker
+from .abbreviations_check import AbbreviationsCheckPres
from .paragraphs_count_check import ReportParagraphsCountCheck
from .template_name import ReportTemplateNameCheck
diff --git a/app/main/checks/report_checks/abbreviations_check.py b/app/main/checks/report_checks/abbreviations_check.py
new file mode 100644
index 00000000..20db6fac
--- /dev/null
+++ b/app/main/checks/report_checks/abbreviations_check.py
@@ -0,0 +1,65 @@
+from ..base_check import BaseReportCriterion, answer
+from ..check_abbreviations import get_unexplained_abbrev
+
+class AbbreviationsCheckPres(BaseReportCriterion):
+ label = "Проверка расшифровки аббревиатур"
+ description = "Все аббревиатуры должны быть расшифрованы при первом использовании"
+ id = 'abbreviations_check'
+
+ def __init__(self, file_info):
+ super().__init__(file_info)
+
+
+ def check(self):
+ try:
+ text = self._get_document_text()
+
+ if not text:
+ return answer(False, "Не удалось получить текст документа")
+
+ abbr_is_finding, unexplained_abbr = get_unexplained_abbrev(text=text)
+
+ if not abbr_is_finding:
+ return answer(True, "Аббревиатуры не найдены в документе")
+
+ if not unexplained_abbr:
+ return answer(True, "Все аббревиатуры правильно расшифрованы")
+
+ unexplained_abbr_with_page = {}
+
+ for page_num in range(1, self.file.page_counter() + 1):
+ text_on_page = self.file.pdf_file.text_on_page[page_num]
+
+ for abbr in unexplained_abbr:
+ if abbr in text_on_page and abbr not in unexplained_abbr_with_page:
+ unexplained_abbr_with_page[abbr] = page_num
+
+
+ result_str = "Найдены нерасшифрованные аббревиатуры при первом использовании:
"
+ page_links = self.format_page_link(list(unexplained_abbr_with_page.values()))
+ for index_links, abbr in enumerate(unexplained_abbr_with_page):
+ result_str += f"- {abbr} на странице {page_links[index_links]}
"
+ result_str += "Каждая аббревиатура должна быть расшифрована при первом использовании в тексте.
"
+ result_str += "Расшифровка должны быть по первыми буквам, например, МВД - Министерство внутренних дел.
"
+
+ return answer(False, result_str)
+
+ except Exception as e:
+ return answer(False, f"Ошибка при проверке аббревиатур: {str(e)}")
+
+
+
+ def _get_document_text(self):
+
+ if hasattr(self.file, 'pdf_file'):
+ page_texts = self.file.pdf_file.get_text_on_page()
+ return " ".join(page_texts.values())
+ elif hasattr(self.file, 'paragraphs'):
+ text_parts = []
+ for paragraph in self.file.paragraphs:
+ text = paragraph.to_string()
+ if '\n' in text:
+ text = text.split('\n')[1]
+ text_parts.append(text)
+ return "\n".join(text_parts)
+ return None