feat: ребрендинг под dokogen149FZ (основа из dokogen187)
This commit is contained in:
+1
-1
@@ -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-ФЗ (для «Справка → Пустой опросник»)
|
||||
# Пустой опросник 149-ФЗ (117 ПР ФСТЭК) (для «Справка → Пустой опросник»)
|
||||
('dokogen/data', 'dokogen/data'),
|
||||
# Иконка приложения (для окна программы в exe)
|
||||
('dokogen/icon.ico', 'dokogen'),
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""DokoGen — Пакет генератора документов 187-ФЗ"""
|
||||
"""DokoGen — Пакет генератора документов 149-ФЗ (117 ПР ФСТЭК)"""
|
||||
|
||||
from .models import Company, CommissionMember, InformationSystem, PaperDocument
|
||||
from .declension import inflect_name, decline, company_name_decline, get_short_fio, get_initials
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
рядом с программой (при сборке .exe — рядом с exe):
|
||||
- Инструкция_пользователя.docx
|
||||
- Инструкция_администратора.docx
|
||||
- Опросный_лист_187_ФЗ.xlsx (пустой шаблон)
|
||||
- Опросный_лист_149_FZ.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(), 'Опросный_лист_149_FZ.xlsx')
|
||||
|
||||
|
||||
def _h(doc, text, size=14):
|
||||
@@ -83,7 +83,7 @@ def _generate_variables_reference(path):
|
||||
_p(doc, 'Список переменных для шаблонов Word. Переменная подставляется в текст '
|
||||
'как есть: {{имя_переменной}}. Циклы: <!-- loop:имя --> ... <!-- loop_end -->.')
|
||||
|
||||
groups = {'A': 'Общие переменные', 'B': '187-ФЗ (персональные данные)'}
|
||||
groups = {'A': 'Общие переменные', 'B': '149-ФЗ (117 ПР ФСТЭК) (персональные данные)'}
|
||||
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, 'ДоКоГеНеРаТоР — 149-ФЗ (117 ПР ФСТЭК)')
|
||||
_h(doc, 'Инструкция пользователя', 13)
|
||||
|
||||
_h(doc, '1. Что это за программа', 12)
|
||||
_p(doc, 'Программа автоматически заполняет шаблоны документов по 187-ФЗ '
|
||||
_p(doc, 'Программа автоматически заполняет шаблоны документов по 149-ФЗ (117 ПР ФСТЭК) '
|
||||
'(акты обследования, политики, инструкции, приказы и т.д.) данными '
|
||||
'об организации, информационных системах, комиссии и сотрудниках. '
|
||||
'Данные можно ввести вручную на вкладках или импортировать из '
|
||||
@@ -173,7 +173,7 @@ def _generate_user_manual(path):
|
||||
def _generate_admin_manual(path):
|
||||
"""Инструкция администратора: словари, API-ключи, лимиты."""
|
||||
doc = docx.Document()
|
||||
_h(doc, 'ДоКоГеНеРаТоР — 187-ФЗ')
|
||||
_h(doc, 'ДоКоГеНеРаТоР — 149-ФЗ (117 ПР ФСТЭК)')
|
||||
_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', 'Опросный_лист_149_FZ.xlsx'),
|
||||
os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Опросный_лист_149_FZ.xlsx'),
|
||||
]
|
||||
for c in candidates:
|
||||
if os.path.exists(c):
|
||||
|
||||
+9
-9
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""DokoGen — Модуль импорта из Excel (опросный лист 187-ФЗ)"""
|
||||
"""DokoGen — Модуль импорта из Excel (опросный лист 149-ФЗ (117 ПР ФСТЭК))"""
|
||||
|
||||
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_149fz(filepath: str, log_fn: Optional[Callable] = None, settings_path: Optional[str] = None) -> dict:
|
||||
"""Импорт данных из опросного листа Excel (149-ФЗ (117 ПР ФСТЭК)).
|
||||
|
||||
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_149_common(wb, data, settings, log_fn)
|
||||
_import_149_is_list(wb, data, settings, log_fn)
|
||||
_import_149_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_149_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_149_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_149_employees(wb, data, settings, log_fn):
|
||||
"""Импорт комиссии и сотрудников из листа «Сотрудники»."""
|
||||
sheet_name = None
|
||||
sheet_kw = settings.get('employees_sheet_keyword', 'сотруд')
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""DokoGen — Модели данных (только 187-ФЗ, только нужные поля)"""
|
||||
"""DokoGen — Модели данных (только 149-ФЗ (117 ПР ФСТЭК), только нужные поля)"""
|
||||
|
||||
from dataclasses import dataclass, field, asdict
|
||||
from typing import List, Dict, Any
|
||||
@@ -49,7 +49,7 @@ class PaperDocument:
|
||||
|
||||
@dataclass
|
||||
class Company:
|
||||
"""Организация — основной объект (187-ФЗ)"""
|
||||
"""Организация — основной объект (149-ФЗ (117 ПР ФСТЭК))"""
|
||||
# Полное название
|
||||
full_name: str = ""
|
||||
company_name_1: str = "" # именительный
|
||||
|
||||
+8
-8
@@ -31,7 +31,7 @@ class DokoGenApp:
|
||||
|
||||
def __init__(self, root: tk.Tk):
|
||||
self.root = root
|
||||
root.title("ДоКоГеНеРаТоР — 187-ФЗ (КИИ)")
|
||||
root.title("ДоКоГеНеРаТоР — 149-ФЗ (117 ПР ФСТЭК)")
|
||||
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_149fz.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='149fz',
|
||||
)
|
||||
|
||||
results = []
|
||||
@@ -1846,7 +1846,7 @@ class DokoGenApp:
|
||||
|
||||
def import_from_survey(self):
|
||||
path = filedialog.askopenfilename(
|
||||
title="Выберите опросный лист (187-ФЗ)",
|
||||
title="Выберите опросный лист (149-ФЗ (117 ПР ФСТЭК))",
|
||||
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_149fz
|
||||
data = import_149fz(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"
|
||||
"ДоКоГеНеРаТоР — 149-ФЗ (117 ПР ФСТЭК)\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(), "Опросный_лист_149_FZ.xlsx", "Сохранить пустой опросник")
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -19,7 +19,7 @@ def _norm_name(s):
|
||||
# ОПИСАНИЕ ПЕРЕМЕННЫХ
|
||||
# ============================================================
|
||||
# Формат: (имя_переменной, группа, описание, ключ_резолвера)
|
||||
# Группы: A — общие, B — 187-ФЗ
|
||||
# Группы: A — общие, B — 149-ФЗ (117 ПР ФСТЭК)
|
||||
|
||||
VARIABLE_DEFS = [
|
||||
# === Полное название организации (6 падежей) ===
|
||||
@@ -68,7 +68,7 @@ VARIABLE_DEFS = [
|
||||
('{{document_date}}', 'A', 'Дата документа', 'doc_date'),
|
||||
('{{document_number}}', 'A', 'Номер документа', 'doc_number'),
|
||||
|
||||
# === 187-ФЗ ===
|
||||
# === 149-ФЗ (117 ПР ФСТЭК) ===
|
||||
('{{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 = "149fz",
|
||||
) -> 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 == '149fz' and group not in ('A', 'B'):
|
||||
continue
|
||||
value = _resolve(source, ctx)
|
||||
replacements[var_name] = str(value) if value else '—'
|
||||
|
||||
+1
-1
@@ -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-ФЗ). Проверь реквизиты организации. "
|
||||
"Ты — юрист по защите персональных данных (149-ФЗ (117 ПР ФСТЭК)). Проверь реквизиты организации. "
|
||||
"Верни ТОЛЬКО JSON: "
|
||||
'{"оценка": "ok|warning|error", '
|
||||
'"замечания": ["..."], '
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""DokoGen — Генератор документов 187-ФЗ
|
||||
"""DokoGen — Генератор документов 149-ФЗ (117 ПР ФСТЭК)
|
||||
Точка входа: python main.py
|
||||
"""
|
||||
import sys
|
||||
|
||||
+2
-2
@@ -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='149fz'
|
||||
)
|
||||
|
||||
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='149fz'
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user