refactor: modular structure, core and services directories
This commit is contained in:
@@ -6,16 +6,16 @@ import pandas as pd
|
|||||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
from config import DATE_TODAY, DATE_YESTERDAY, OUTPUT_DIR, DATA_DIR, normalize_fio
|
from config import DATE_TODAY, DATE_YESTERDAY, OUTPUT_DIR, DATA_DIR, normalize_fio
|
||||||
from modules.scud_export import run_export
|
from services.scud_export import run_export
|
||||||
from modules.share_copier import copy_1c_files_from_share
|
from services.share_copier import copy_1c_files_from_share
|
||||||
from modules.data_validator import check_file_freshness
|
from services.data_validator import check_file_freshness
|
||||||
from modules.data_loader import load_all_data
|
from services.data_loader import load_all_data
|
||||||
from modules.excel_exporter import generate_summary_excel, generate_detailed_excel
|
from services.excel_exporter import generate_summary_excel, generate_detailed_excel
|
||||||
from modules.ai_verifier import ai_verify_scud_against_staff
|
from services.ai_verifier import ai_verify_scud_against_staff
|
||||||
from modules.text_reporter import generate_markdown_report
|
from services.text_reporter import generate_markdown_report
|
||||||
from modules.feedback_loop import review_ai_decisions
|
from services.feedback_loop import review_ai_decisions
|
||||||
from modules.knowledge_base import load_knowledge_base
|
from services.knowledge_base import load_knowledge_base
|
||||||
from modules.database import (
|
from core.database import (
|
||||||
init_db,
|
init_db,
|
||||||
save_scud_to_db,
|
save_scud_to_db,
|
||||||
save_staff_to_db,
|
save_staff_to_db,
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def run_git_move():
|
||||||
|
print("=== Безопасная миграция файлов в структуру проекта ===")
|
||||||
|
|
||||||
|
# Словарь: имя файла -> целевая папка
|
||||||
|
file_mapping = {
|
||||||
|
"database.py": "core/database.py",
|
||||||
|
"scud_export.py": "services/scud_export.py",
|
||||||
|
"share_copier.py": "services/share_copier.py",
|
||||||
|
"data_loader.py": "services/data_loader.py",
|
||||||
|
"data_validator.py": "services/data_validator.py",
|
||||||
|
"zup_extractor.py": "services/zup_extractor.py",
|
||||||
|
"ai_verifier.py": "services/ai_verifier.py",
|
||||||
|
"excel_exporter.py": "services/excel_exporter.py",
|
||||||
|
"text_reporter.py": "services/text_reporter.py",
|
||||||
|
"feedback_loop.py": "services/feedback_loop.py",
|
||||||
|
"knowledge_base.py": "services/knowledge_base.py",
|
||||||
|
"db_cli.py": "scripts/db_cli.py"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Убедимся, что папки существуют и содержат __init__.py
|
||||||
|
for folder in ["core", "services", "api", "frontend", "scripts"]:
|
||||||
|
os.makedirs(folder, exist_ok=True)
|
||||||
|
init_file = os.path.join(folder, "__init__.py")
|
||||||
|
if not os.path.exists(init_file):
|
||||||
|
open(init_file, 'w').close()
|
||||||
|
|
||||||
|
for filename, dest in file_mapping.items():
|
||||||
|
# Проверим, где файл может находиться: в корне или уже в папке назначения
|
||||||
|
if os.path.exists(filename):
|
||||||
|
src = filename
|
||||||
|
elif os.path.exists(dest):
|
||||||
|
print(f"[ℹ️ Уже на месте] {dest}")
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
# Попробуем поискать файл рекурсивно
|
||||||
|
found = None
|
||||||
|
for root, dirs, files in os.walk("."):
|
||||||
|
if filename in files and "venv" not in root:
|
||||||
|
found = os.path.join(root, filename)
|
||||||
|
break
|
||||||
|
src = found
|
||||||
|
|
||||||
|
if src and os.path.exists(src):
|
||||||
|
if src == dest:
|
||||||
|
continue
|
||||||
|
dest_dir = os.path.dirname(dest)
|
||||||
|
os.makedirs(dest_dir, exist_ok=True)
|
||||||
|
try:
|
||||||
|
subprocess.run(["git", "mv", src, dest], check=True)
|
||||||
|
print(f"[git mv] Успешно перемещен: {src} -> {dest}")
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"[⚠️ Ошибка] Не удалось переместить через git mv {src}: {e}")
|
||||||
|
else:
|
||||||
|
print(f"[❌ Не найден] Файл {filename} не обнаружен в репозитории.")
|
||||||
|
|
||||||
|
print("\n=== Миграция завершена. Выполните 'git status' для проверки ===")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
run_git_move()
|
||||||
@@ -2,7 +2,7 @@ import json
|
|||||||
import re
|
import re
|
||||||
import requests
|
import requests
|
||||||
from config import OLLAMA_URL, OLLAMA_MODEL
|
from config import OLLAMA_URL, OLLAMA_MODEL
|
||||||
from modules.database import get_all_rules_from_db
|
from core.database import get_all_rules_from_db
|
||||||
|
|
||||||
|
|
||||||
def ask_ollama(prompt, system_prompt=None):
|
def ask_ollama(prompt, system_prompt=None):
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from config import (
|
|||||||
DATE_TODAY, DATE_YESTERDAY, find_dated_file, ZUP_1C_DIR, SCUD_DIR
|
DATE_TODAY, DATE_YESTERDAY, find_dated_file, ZUP_1C_DIR, SCUD_DIR
|
||||||
)
|
)
|
||||||
# Импортируем прямую SQL-выгрузку отсутствий из 1С
|
# Импортируем прямую SQL-выгрузку отсутствий из 1С
|
||||||
from modules.zup_extractor import fetch_zup_absences_from_sql
|
from services.zup_extractor import fetch_zup_absences_from_sql
|
||||||
|
|
||||||
warnings.filterwarnings('ignore', category=UserWarning, module='pandas')
|
warnings.filterwarnings('ignore', category=UserWarning, module='pandas')
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
from modules.database import add_rule_to_db
|
from core.database import add_rule_to_db
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from modules.knowledge_base import save_rule
|
from services.knowledge_base import save_rule
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
from modules.knowledge_base import add_rule as save_rule
|
from services.knowledge_base import add_rule as save_rule
|
||||||
except ImportError:
|
except ImportError:
|
||||||
save_rule = None
|
save_rule = None
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import pyodbc
|
|||||||
from openpyxl.utils import get_column_letter
|
from openpyxl.utils import get_column_letter
|
||||||
|
|
||||||
from config import SCUD_DIR, clean_scud_fio_light, load_exceptions
|
from config import SCUD_DIR, clean_scud_fio_light, load_exceptions
|
||||||
from modules.database import save_scud_to_db
|
from core.database import save_scud_to_db
|
||||||
|
|
||||||
warnings.filterwarnings("ignore", message="pandas only supports SQLAlchemy connectable")
|
warnings.filterwarnings("ignore", message="pandas only supports SQLAlchemy connectable")
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import json
|
import json
|
||||||
import difflib
|
import difflib
|
||||||
import re
|
import re
|
||||||
from modules.ai_verifier import ask_ollama
|
from services.ai_verifier import ask_ollama
|
||||||
from modules.knowledge_base import load_knowledge_base
|
from services.knowledge_base import load_knowledge_base
|
||||||
|
|
||||||
|
|
||||||
def find_python_fuzzy_matches(unexplained_df, raw_absent_df):
|
def find_python_fuzzy_matches(unexplained_df, raw_absent_df):
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
def update_file_imports(filepath):
|
||||||
|
with open(filepath, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# Заменяем старые пути на новые
|
||||||
|
new_content = content
|
||||||
|
new_content = new_content.replace("from modules.database", "from core.database")
|
||||||
|
new_content = new_content.replace("import modules.database", "import core.database")
|
||||||
|
|
||||||
|
# Все остальные модули уехали в services/
|
||||||
|
service_modules = [
|
||||||
|
"ai_verifier", "data_loader", "data_validator", "excel_exporter",
|
||||||
|
"feedback_loop", "knowledge_base", "scud_export", "share_copier",
|
||||||
|
"text_reporter", "zup_extractor"
|
||||||
|
]
|
||||||
|
|
||||||
|
for mod in service_modules:
|
||||||
|
new_content = new_content.replace(f"from modules.{mod}", f"from services.{mod}")
|
||||||
|
new_content = new_content.replace(f"import modules.{mod}", f"import services.{mod}")
|
||||||
|
# Также на случай относительных или прямых импортов внутри сервисов друг на друга
|
||||||
|
new_content = new_content.replace(f"from {mod}", f"from services.{mod}")
|
||||||
|
|
||||||
|
if content != new_content:
|
||||||
|
with open(filepath, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(new_content)
|
||||||
|
print(f"[Обновлено] Импорты в файле: {filepath}")
|
||||||
|
|
||||||
|
def run_update():
|
||||||
|
print("=== Автоматическое обновление импортов ===")
|
||||||
|
for root, dirs, files in os.walk("."):
|
||||||
|
if "venv" in root or ".git" in root:
|
||||||
|
continue
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(".py") and file != "migrate_structure.py" and file != "update_imports.py":
|
||||||
|
update_file_imports(os.path.join(root, file))
|
||||||
|
print("=== Обновление завершено ===")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
run_update()
|
||||||
Reference in New Issue
Block a user