diff --git a/dokogen.spec b/dokogen.spec index 694527b..43b7926 100644 --- a/dokogen.spec +++ b/dokogen.spec @@ -11,7 +11,7 @@ from PyInstaller.utils.hooks import collect_data_files, collect_submodules datas = [ # Справочники (defense_tools.json, pd_actions.json, pd_items.json, pd_categories.json) ('dokogen/dictionaries', 'dokogen/dictionaries'), - # Пустой опросник 187-ФЗ (для «Справка → Пустой опросник») + # Пустой опросник KZI (для «Справка → Пустой опросник») ('dokogen/data', 'dokogen/data'), # Иконка приложения (для окна программы в exe) ('dokogen/icon.ico', 'dokogen'), diff --git a/dokogen/__init__.py b/dokogen/__init__.py index 1244144..ef585fd 100644 --- a/dokogen/__init__.py +++ b/dokogen/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"""DokoGen — Пакет генератора документов 187-ФЗ""" +"""DokoGen — Пакет генератора документов KZI""" from .models import Company, CommissionMember, InformationSystem, PaperDocument from .declension import inflect_name, decline, company_name_decline, get_short_fio, get_initials diff --git a/dokogen/data/Опросный_лист_187_ФЗ.xlsx b/dokogen/data/Опросный_лист_KZI.xlsx similarity index 100% rename from dokogen/data/Опросный_лист_187_ФЗ.xlsx rename to dokogen/data/Опросный_лист_KZI.xlsx diff --git a/dokogen/help_docs.py b/dokogen/help_docs.py index ec11dbe..db8b64b 100644 --- a/dokogen/help_docs.py +++ b/dokogen/help_docs.py @@ -5,7 +5,7 @@ рядом с программой (при сборке .exe — рядом с exe): - Инструкция_пользователя.docx - Инструкция_администратора.docx -- Опросный_лист_187_ФЗ.xlsx (пустой шаблон) +- Опросный_лист_KZI.xlsx (пустой шаблон) """ import os @@ -45,7 +45,7 @@ def variables_reference_path(): def survey_path(): - return os.path.join(docs_dir(), 'Опросный_лист_187_ФЗ.xlsx') + return os.path.join(docs_dir(), 'Опросный_лист_KZI.xlsx') def _h(doc, text, size=14): @@ -83,7 +83,7 @@ def _generate_variables_reference(path): _p(doc, 'Список переменных для шаблонов Word. Переменная подставляется в текст ' 'как есть: {{имя_переменной}}. Циклы: ... .') - groups = {'A': 'Общие переменные', 'B': '187-ФЗ (персональные данные)'} + groups = {'A': 'Общие переменные', 'B': 'KZI (персональные данные)'} by_group = {'A': [], 'B': []} for var, group, desc, _ in VARIABLE_DEFS: by_group.setdefault(group, []).append((var, desc)) @@ -108,11 +108,11 @@ def _generate_variables_reference(path): def _generate_user_manual(path): """Инструкция пользователя: программа, циклы, переменные, проверки.""" doc = docx.Document() - _h(doc, 'ДоКоГеНеРаТоР — 187-ФЗ') + _h(doc, 'ДоКоГеНеРаТоР — KZI') _h(doc, 'Инструкция пользователя', 13) _h(doc, '1. Что это за программа', 12) - _p(doc, 'Программа автоматически заполняет шаблоны документов по 187-ФЗ ' + _p(doc, 'Программа автоматически заполняет шаблоны документов по KZI ' '(акты обследования, политики, инструкции, приказы и т.д.) данными ' 'об организации, информационных системах, комиссии и сотрудниках. ' 'Данные можно ввести вручную на вкладках или импортировать из ' @@ -173,7 +173,7 @@ def _generate_user_manual(path): def _generate_admin_manual(path): """Инструкция администратора: словари, API-ключи, лимиты.""" doc = docx.Document() - _h(doc, 'ДоКоГеНеРаТоР — 187-ФЗ') + _h(doc, 'ДоКоГеНеРаТоР — KZI') _h(doc, 'Инструкция администратора', 13) _h(doc, '1. Файлы настроек рядом с программой', 12) @@ -240,8 +240,8 @@ def _ensure_survey(): return target # Ищем шаблон опросника: рядом с программой или встроенный candidates = [ - os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'Опросный_лист_187_ФЗ.xlsx'), - os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Опросный_лист_187_ФЗ.xlsx'), + os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'Опросный_лист_KZI.xlsx'), + os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Опросный_лист_KZI.xlsx'), ] for c in candidates: if os.path.exists(c): diff --git a/dokogen/importer.py b/dokogen/importer.py index ba51816..f96353b 100644 --- a/dokogen/importer.py +++ b/dokogen/importer.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"""DokoGen — Модуль импорта из Excel (опросный лист 187-ФЗ)""" +"""DokoGen — Модуль импорта из Excel (опросный лист KZI)""" import re import traceback @@ -122,8 +122,8 @@ def clean_value(val): return text -def import_187fz(filepath: str, log_fn: Optional[Callable] = None, settings_path: Optional[str] = None) -> dict: - """Импорт данных из опросного листа Excel (187-ФЗ). +def import_kzifz(filepath: str, log_fn: Optional[Callable] = None, settings_path: Optional[str] = None) -> dict: + """Импорт данных из опросного листа Excel (KZI). settings_path — путь к JSON-файлу настроек импорта (что и откуда брать). Если None — файл import_settings.json рядом с программой; если его нет — @@ -154,9 +154,9 @@ def import_187fz(filepath: str, log_fn: Optional[Callable] = None, settings_path return data try: - _import_187_common(wb, data, settings, log_fn) - _import_187_is_list(wb, data, settings, log_fn) - _import_187_employees(wb, data, settings, log_fn) + _import_kzi_common(wb, data, settings, log_fn) + _import_kzi_is_list(wb, data, settings, log_fn) + _import_kzi_employees(wb, data, settings, log_fn) except Exception as e: log_fn(f"❌ Ошибка при импорте: {e}") log_fn(traceback.format_exc()) @@ -179,7 +179,7 @@ def import_187fz(filepath: str, log_fn: Optional[Callable] = None, settings_path return data -def _import_187_common(wb, data, settings, log_fn): +def _import_kzi_common(wb, data, settings, log_fn): """Импорт общих сведений по словарю настроек. Для каждого поля: сначала пробуем конкретную ячейку (cell), @@ -247,7 +247,7 @@ def _import_187_common(wb, data, settings, log_fn): break -def _import_187_is_list(wb, data, settings, log_fn): +def _import_kzi_is_list(wb, data, settings, log_fn): """Импорт информационных систем из остальных листов.""" exclude_kws = settings.get('is_sheet_exclude_keywords', ['общие сведения', 'сотрудники']) is_sheets = [] @@ -447,7 +447,7 @@ def _import_187_is_list(wb, data, settings, log_fn): log_fn(f"\n✅ Всего импортировано ИС: {len(is_list)}") -def _import_187_employees(wb, data, settings, log_fn): +def _import_kzi_employees(wb, data, settings, log_fn): """Импорт комиссии и сотрудников из листа «Сотрудники».""" sheet_name = None sheet_kw = settings.get('employees_sheet_keyword', 'сотруд') diff --git a/dokogen/models.py b/dokogen/models.py index 88bed71..43f2fc9 100644 --- a/dokogen/models.py +++ b/dokogen/models.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"""DokoGen — Модели данных (только 187-ФЗ, только нужные поля)""" +"""DokoGen — Модели данных (только KZI, только нужные поля)""" from dataclasses import dataclass, field, asdict from typing import List, Dict, Any @@ -49,7 +49,7 @@ class PaperDocument: @dataclass class Company: - """Организация — основной объект (187-ФЗ)""" + """Организация — основной объект (KZI)""" # Полное название full_name: str = "" company_name_1: str = "" # именительный diff --git a/dokogen/ui.py b/dokogen/ui.py index a87746d..9ed8b6f 100644 --- a/dokogen/ui.py +++ b/dokogen/ui.py @@ -31,7 +31,7 @@ class DokoGenApp: def __init__(self, root: tk.Tk): self.root = root - root.title("ДоКоГеНеРаТоР — 187-ФЗ (КИИ)") + root.title("ДоКоГеНеРаТоР — KZI") root.geometry("1200x800") root.minsize(900, 600) self._set_app_icon() @@ -44,7 +44,7 @@ class DokoGenApp: self._last_template_dir: str = "" self._autosave_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), - '.autosave', 'autosave_187.json' + '.autosave', 'autosave_kzifz.json' ) # Путь к файлу настроек импорта (словарь «что и откуда брать») @@ -1757,7 +1757,7 @@ class DokoGenApp: is_list=self.model.information_systems, doc_number=self.doc_number_var.get(), doc_date=self.doc_date_var.get(), - direction='187fz', + direction='kzifz', ) results = [] @@ -1846,7 +1846,7 @@ class DokoGenApp: def import_from_survey(self): path = filedialog.askopenfilename( - title="Выберите опросный лист (187-ФЗ)", + title="Выберите опросный лист (KZI)", filetypes=[("Excel", "*.xlsx *.xls")] ) if not path: @@ -1856,8 +1856,8 @@ class DokoGenApp: # Импорт в отдельном потоке def _run(): try: - from .importer import import_187fz - data = import_187fz(path, self.log, settings_path=self.import_settings_path) + from .importer import import_kzifz + data = import_kzifz(path, self.log, settings_path=self.import_settings_path) if data: self._apply_imported_data(data) except ImportError: @@ -2203,7 +2203,7 @@ class DokoGenApp: def show_about(self): messagebox.showinfo("О программе", - "ДоКоГеНеРаТоР — 187-ФЗ\n" + "ДоКоГеНеРаТоР — KZI\n" "Версия 1.0\n" "Генератор документов из шаблонов") @@ -2251,7 +2251,7 @@ class DokoGenApp: def download_survey(self): from .help_docs import ensure_docs, survey_path ensure_docs() - self._save_resource(survey_path(), "Опросный_лист_187_ФЗ.xlsx", "Сохранить пустой опросник") + self._save_resource(survey_path(), "Опросный_лист_KZI.xlsx", "Сохранить пустой опросник") def main(): diff --git a/dokogen/variables.py b/dokogen/variables.py index 140199e..6660d28 100644 --- a/dokogen/variables.py +++ b/dokogen/variables.py @@ -19,7 +19,7 @@ def _norm_name(s): # ОПИСАНИЕ ПЕРЕМЕННЫХ # ============================================================ # Формат: (имя_переменной, группа, описание, ключ_резолвера) -# Группы: A — общие, B — 187-ФЗ +# Группы: A — общие, B — KZI VARIABLE_DEFS = [ # === Полное название организации (6 падежей) === @@ -68,7 +68,7 @@ VARIABLE_DEFS = [ ('{{document_date}}', 'A', 'Дата документа', 'doc_date'), ('{{document_number}}', 'A', 'Номер документа', 'doc_number'), - # === 187-ФЗ === + # === KZI === ('{{is_security_requirements}}', 'B', 'Требования уровня защищённости', 'security_reqs'), ('{{is_list}}', 'B', 'Список всех ИС (нумерованный)', 'is_list'), ('{{is_name}}', 'B', 'Наименование первой ИС', 'is:name'), @@ -138,7 +138,7 @@ def build_replacements( is_list: List = None, doc_number: str = "", doc_date: str = "", - direction: str = "187fz", + direction: str = "kzifz", ) -> Dict[str, str]: """Строит полный словарь замен {{переменная}} → значение.""" if is_list is None: @@ -159,7 +159,7 @@ def build_replacements( replacements = {} for var_name, group, desc, source in VARIABLE_DEFS: - if direction == '187fz' and group not in ('A', 'B'): + if direction == 'kzifz' and group not in ('A', 'B'): continue value = _resolve(source, ctx) replacements[var_name] = str(value) if value else '—' diff --git a/dokogen/verify.py b/dokogen/verify.py index 249bdc7..bbaeb3c 100644 --- a/dokogen/verify.py +++ b/dokogen/verify.py @@ -399,7 +399,7 @@ def check_company_ai(company_data, api_key, model='deepseek-chat', base_url=None if not api_key: return None, "Не задан API-ключ ИИ (Файл → Настройки → API)" system = ( - "Ты — юрист по защите персональных данных (187-ФЗ). Проверь реквизиты организации. " + "Ты — юрист по защите персональных данных (KZI). Проверь реквизиты организации. " "Верни ТОЛЬКО JSON: " '{"оценка": "ok|warning|error", ' '"замечания": ["..."], ' diff --git a/main.py b/main.py index 8e0999a..50ddf31 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"""DokoGen — Генератор документов 187-ФЗ +"""DokoGen — Генератор документов KZI Точка входа: python main.py """ import sys diff --git a/test_generator.py b/test_generator.py index a010332..ff8a80a 100644 --- a/test_generator.py +++ b/test_generator.py @@ -87,7 +87,7 @@ def test_zip_loop_expansion(): is_list=company.information_systems, doc_number='001', doc_date='31.07.2026', - direction='187fz' + direction='kzifz' ) loops = replacements.get('_loops', {}) @@ -135,7 +135,7 @@ def test_zip_loop_expansion(): is_list=company.information_systems, doc_number='001', doc_date='31.07.2026', - direction='187fz' + direction='kzifz' ) try: