from typing import List, Optional from sqlalchemy.orm import Session from sqlalchemy import and_, or_ from ..models.post import Post from ..schemas.post import PostCreate, PostUpdate from datetime import datetime class PostService: def __init__(self, db_session: Session): self.db = db_session def get_post(self, post_id: int, owner_id: int) -> Optional[Post]: """Получить пост по ID и владельцу""" return self.db.query(Post).filter( and_(Post.id == post_id, Post.owner_id == owner_id) ).first() def get_posts(self, owner_id: int, skip: int = 0, limit: int = 100) -> List[Post]: """Получить список постов пользователя""" return self.db.query(Post).filter(Post.owner_id == owner_id)\ .order_by(Post.created_at.desc())\ .offset(skip)\ .limit(limit)\ .all() def create_post(self, post_data: PostCreate, owner_id: int) -> Post: """Создать новый пост""" db_post = Post( title=post_data.title, content=post_data.content, scheduled_time=post_data.scheduled_time, status=post_data.status, owner_id=owner_id ) self.db.add(db_post) self.db.commit() self.db.refresh(db_post) return db_post def update_post(self, post_id: int, post_data: PostUpdate, owner_id: int) -> Optional[Post]: """Обновить пост""" db_post = self.get_post(post_id, owner_id) if not db_post: return None # Обновляем только те поля, которые предоставлены update_data = post_data.dict(exclude_unset=True) for field, value in update_data.items(): setattr(db_post, field, value) # Обновляем время последнего изменения db_post.updated_at = datetime.utcnow() # Если статус меняется на published и published_at еще не установлен, устанавливаем его if post_data.status == "published" and not db_post.published_at: db_post.published_at = datetime.utcnow() self.db.commit() self.db.refresh(db_post) return db_post def delete_post(self, post_id: int, owner_id: int) -> bool: """Удалить пост""" db_post = self.get_post(post_id, owner_id) if not db_post: return False self.db.delete(db_post) self.db.commit() return True def get_scheduled_posts(self) -> List[Post]: """Получить посты, готовые к публикации (статус scheduled и время наступило)""" current_time = datetime.utcnow() return self.db.query(Post).filter( and_( Post.status == "scheduled", Post.scheduled_time <= current_time ) ).all() def get_posts_by_status(self, owner_id: int, status: str) -> List[Post]: """Получить посты по статусу""" return self.db.query(Post).filter( and_(Post.owner_id == owner_id, Post.status == status) ).all()