Загрузка данных
# -*- coding: utf-8 -*-
# project_manager.py
import datetime as dt
import os
import sqlite3
from pathlib import Path
from gui.models import Project
from modules.project_database import ProjectDatabase
class ProjectManager:
"""
Класс для управления проектами.
Автоматически загружает список проектов из файлов .db в папке 'project_dbs'.
"""
DB_DIRECTORY = "project_dbs"
DB_EXTENSION = ".db"
def __init__(self):
"""Инициализирует менеджер и загружает существующие проекты."""
self.projects = []
self.projects_dir = self._initialize_projects_directory()
if self.projects_dir: # Проверка, что папка создана успешно
self._load_existing_projects()
def _initialize_projects_directory(self):
"""Создаёт директорию для проектов, если она не существует. Возвращает путь или None при ошибке."""
projects_dir = os.path.join(os.getcwd(), self.DB_DIRECTORY)
try:
os.makedirs(projects_dir, exist_ok=True)
print(f"[INFO] Папка для проектов готова: {projects_dir}")
return projects_dir
except Exception as e:
print(f"[ERROR] Не удалось создать/проверить папку 'project_dbs': {e}")
return None
def _load_existing_projects(self):
"""Загружает список проектов из файлов .db в рабочей директории."""
# --- Читаем имя из БД, а не берем имя файла ---
for filename in os.listdir(self.projects_dir):
file_path = os.path.join(self.projects_dir, filename)
if os.path.isfile(file_path) and filename.lower().endswith(
self.DB_EXTENSION
):
try:
# Имя файла без расширения - это наш "Имя файла"
# (project_code)
file_code = os.path.splitext(filename)[0]
# --- 1. Открываем базу данных этого проекта ---
conn = sqlite3.connect(file_path)
cursor = conn.cursor()
# --- 2. Читаем ИМЯ из колонки 'name' ---
cursor.execute("SELECT name FROM project_data LIMIT 1")
row = cursor.fetchone()
# Если имя в базе есть, используем его. Если нет -
# используем код файла.
human_name = row[0] if row and row[0] else file_code
# --- 3. Создаем объект Project с ПРАВИЛЬНЫМИ данными ---
project = Project(name=human_name)
# --- 4. Принудительно задаем ID объекта, чтобы он совпадал с кодом ---
# Это критически важно для связки с базой данных.
project.id = file_code
self.projects.append(project)
print(
f"[INFO] Проект '{human_name}' (Код: {file_code}) найден и загружен."
)
except Exception as e:
print(f"[ERROR] Ошибка при загрузке проекта {filename}: {e}")
finally:
if "conn" in locals():
conn.close()
def list_projects(self):
"""Возвращает список загруженных объектов Project."""
return self.projects
def add_project(self, project_object):
"""
ГЛАВНЫЙ МЕТОД ДЛЯ СОЗДАНИЯ ПРОЕКТА.
Принимает объект проекта из окна создания.
"""
try:
# --- ИСПРАВЛЕНИЕ: Используем project.id для имени файла БД ---
# В объекте project, который пришел из окна создания,
# поле 'id' должно содержать КОД (для имени файла),
# а поле 'name' - человеческое имя.
project_code = project_object.id
# Проверка на дубликат (файл уже существует)
# Конструктор ProjectDatabase теперь получит правильный код
project_db = ProjectDatabase(project_code)
if os.path.exists(project_db.db_path):
error_msg = f"База данных для кода '{project_code}' уже существует!"
print(f"[ERROR] {error_msg}")
return False
# Создаем структуру (файл и таблицы)
project_db.connect()
project_db.create_tables()
# Записываем данные в таблицу 'project_data'
conn = sqlite3.connect(project_db.db_path)
cursor = conn.cursor()
current_time = dt.datetime.now().isoformat()
cursor.execute(
"""
INSERT INTO project_data (
project_code, created_at, name, description, date_opened, responsible
) VALUES (?, ?, ?, ?, ?, ?)
""",
(
project_code, # Код для БД и имени файла
current_time,
project_object.name, # Человеческое имя
getattr(project_object, "description", ""),
getattr(project_object, "date_opened", ""),
getattr(project_object, "responsible", ""),
),
)
conn.commit()
conn.close()
print(f"[SUCCESS] УСПЕХ: Проект '{
project_object.name}' (Код: {project_code}) успешно создан.")
self.projects.append(project_object)
return True
except Exception as e:
print(f"[CRITICAL ERROR] Не удалось создать проект: {e}")
return False