/
fenixcyc
/
Bot_Tasks_Manager
Обзор
Документация
Войти
/
fenixcyc
/
Bot_Tasks_Manager
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
models.py
252 строки
12 KB
Wasa
first commit
15 фев 2025, 07:49
15 фев 2025, 07:49
9e1271d
Код
Авторство
О чём код?
from datetime import datetime from dataclasses import dataclass from typing import Dict, List, Optional, Tuple import re import json from pathlib import Path @dataclass class Task: date: datetime description: str completed: bool = False category: str = "общее" user_id: int = 0 # Добавляем user_id def to_dict(self): """Преобразует задачу в словарь для сохранения""" return { "date": self.date.strftime('%d.%m.%Y'), "description": self.description, "completed": self.completed, "category": self.category, "user_id": self.user_id } @classmethod def from_dict(cls, data): """Создает задачу из словаря""" return cls( date=datetime.strptime(data["date"], '%d.%m.%Y'), description=data["description"], completed=data["completed"], category=data.get("category", "общее"), user_id=data.get("user_id", 0) ) def __str__(self): status = "✓" if self.completed else " " return f"[{status}] {self.description} ({self.category})" class TaskManager: def __init__(self): self.tasks_by_date: Dict[str, List[Task]] = {} self.load_tasks() def save_tasks(self): """Сохраняет задачи в файл""" data = {} for date, tasks in self.tasks_by_date.items(): data[date] = [task.to_dict() for task in tasks] with open('tasks.json', 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) def load_tasks(self): """Загружает задачи из файла""" try: with open('tasks.json', 'r', encoding='utf-8') as f: data = json.load(f) for date, tasks_data in data.items(): self.tasks_by_date[date] = [Task.from_dict(task_data) for task_data in tasks_data] except FileNotFoundError: self.tasks_by_date = {} def is_appropriate_content(self, text: str) -> Tuple[bool, str]: """Проверяет описание задачи на корректность содержания""" inappropriate_words = ["отъебать", "нахуй", "блять", "сука"] text_lower = text.lower() for word in inappropriate_words: if word in text_lower: return False, "Описание содержит недопустимые выражения" return True, "Содержание корректно" def add_task(self, date_str: str, description: str, category: str = "общее", user_id: int = 0) -> tuple[bool, str]: """Добавляет новую задачу""" try: if not re.match(r'^\d{2}\.\d{2}\.\d{4}$', date_str): return False, "Неверный формат даты. Используйте ДД.ММ.ГГГГ" date = datetime.strptime(date_str, '%d.%m.%Y') if date.date() < datetime.now().date(): return False, "Дата не может быть в прошлом" description = description.strip() if not description: return False, "Описание задачи не может быть пустым" if len(description) < 3: return False, "Описание задачи должно содержать минимум 3 символа" if len(description) > 100: return False, "Описание задачи не должно превышать 100 символов" is_appropriate, error_message = self.is_appropriate_content(description) if not is_appropriate: return False, error_message task = Task(date=date, description=description, category=category, user_id=user_id) if date_str not in self.tasks_by_date: self.tasks_by_date[date_str] = [] self.tasks_by_date[date_str].append(task) self.tasks_by_date[date_str].sort(key=lambda x: x.description) self.save_tasks() return True, "Задача успешно добавлена" except ValueError: return False, "Некорректная дата" def get_tasks_by_date(self, date_str: str, user_id: int = 0) -> List[Task]: """Возвращает задачи на конкретную дату для конкретного пользователя""" tasks = self.tasks_by_date.get(date_str, []) return [task for task in tasks if task.user_id == user_id] def get_tasks_by_category(self, category: str, user_id: int = 0) -> List[Task]: """Возвращает задачи определенной категории для конкретного пользователя""" tasks = [] for date_tasks in self.tasks_by_date.values(): tasks.extend([task for task in date_tasks if task.category == category and task.user_id == user_id]) return tasks def get_completed_tasks(self, user_id: int = 0) -> List[Task]: """Возвращает выполненные задачи для конкретного пользователя""" tasks = [] for date_tasks in self.tasks_by_date.values(): tasks.extend([task for task in date_tasks if task.completed and task.user_id == user_id]) return tasks def remove_task(self, date_str: str, task_index: int, user_id: int = 0) -> tuple[bool, str]: """Удаляет задачу по дате и индексу""" if date_str in self.tasks_by_date and 0 <= task_index < len(self.tasks_by_date[date_str]): task_to_remove = self.tasks_by_date[date_str][task_index] if task_to_remove.user_id == user_id: self.tasks_by_date[date_str].pop(task_index) if not self.tasks_by_date[date_str]: del self.tasks_by_date[date_str] self.save_tasks() return True, "Задача удалена" else: return False, "Нет прав на удаление этой задачи" return False, "Неверный номер задачи" def toggle_task(self, date_str: str, task_index: int, user_id: int = 0) -> tuple[bool, str]: """Отмечает задачу как выполненную/невыполненную""" if date_str in self.tasks_by_date and 0 <= task_index < len(self.tasks_by_date[date_str]): task = self.tasks_by_date[date_str][task_index] if task.user_id == user_id: task.completed = not task.completed self.save_tasks() status = "выполнена" if task.completed else "не выполнена" return True, f"Задача отмечена как {status}" else: return False, "Нет прав на изменение этой задачи" return False, "Неверный номер задачи" def get_all_tasks(self, user_id: int = 0) -> Dict[str, List[Task]]: """Возвращает словарь всех задач пользователя, сгруппированных по датам""" filtered_tasks = {} for date, tasks in self.tasks_by_date.items(): user_tasks = [task for task in tasks if task.user_id == user_id] if user_tasks: filtered_tasks[date] = user_tasks return filtered_tasks def get_statistics(self, user_id: int = 0) -> List[str]: """Возвращает статистику по задачам для конкретного пользователя""" user_tasks = [task for date_tasks in self.tasks_by_date.values() for task in date_tasks if task.user_id == user_id] total_tasks = len(user_tasks) completed_tasks = len([task for task in user_tasks if task.completed]) tasks_by_category = {} for task in user_tasks: if task.category not in tasks_by_category: tasks_by_category[task.category] = 0 tasks_by_category[task.category] += 1 stats = [ f"📊 Всего задач: {total_tasks}", f"✅ Выполнено задач: {completed_tasks}", f"📈 Процент выполнения: {(completed_tasks/total_tasks*100):.1f}%" if total_tasks > 0 else "📈 Процент выполнения: 0%", "\n📑 Задачи по категориям:" ] for category, count in sorted(tasks_by_category.items()): stats.append(f"- {category}: {count}") return stats def edit_task(self, old_date_str: str, task_index: int, new_date_str: str, new_description: str, new_category: str = None, user_id: int = 0) -> tuple[bool, str]: """Редактирует существующую задачу""" try: # Проверяем существование задачи if old_date_str not in self.tasks_by_date or task_index >= len(self.tasks_by_date[old_date_str]): return False, "Задача не найдена" # Проверяем права доступа old_task = self.tasks_by_date[old_date_str][task_index] if old_task.user_id != user_id: return False, "Нет прав на редактирование этой задачи" # Проверяем новую дату if not re.match(r'^\d{2}\.\d{2}\.\d{4}$', new_date_str): return False, "Неверный формат даты. Используйте ДД.ММ.ГГГГ" new_date = datetime.strptime(new_date_str, '%d.%m.%Y') if new_date.date() < datetime.now().date(): return False, "Дата не может быть в прошлом" # Проверяем новое описание new_description = new_description.strip() if not new_description: return False, "Описание задачи не может быть пустым" if len(new_description) < 3: return False, "Описание задачи должно содержать минимум 3 символа" if len(new_description) > 100: return False, "Описание задачи не должно превышать 100 символов" is_appropriate, error_message = self.is_appropriate_content(new_description) if not is_appropriate: return False, error_message # Создаем новую задачу new_task = Task( date=new_date, description=new_description, completed=old_task.completed, category=new_category if new_category else old_task.category, user_id=user_id ) # Удаляем старую задачу self.tasks_by_date[old_date_str].pop(task_index) if not self.tasks_by_date[old_date_str]: del self.tasks_by_date[old_date_str] # Добавляем новую задачу if new_date_str not in self.tasks_by_date: self.tasks_by_date[new_date_str] = [] self.tasks_by_date[new_date_str].append(new_task) # Сортируем задачи и сохраняем self.tasks_by_date[new_date_str].sort(key=lambda x: x.description) self.save_tasks() return True, "Задача успешно отредактирована" except ValueError: return False, "Некорректная дата" except Exception as e: return False, f"Ошибка при редактировании задачи: {str(e)}"