"""Episode Replication Status Model.""" from sqlalchemy import Boolean from sqlalchemy import Column from sqlalchemy import DateTime from sqlalchemy import Enum from sqlalchemy import func from sqlalchemy import Integer from sqlalchemy import VARCHAR from podcast.connectors import mysql from podcast.constants import common as common_constants from podcast.constants.episode_replication_status import EPISODE_CREATION_FAILED from podcast.constants.episode_replication_status import EPISODE_REPLICATION_STATUSES from podcast.constants.episode_replication_status import INITIATED from podcast.constants.episode_replication_status import REPLICATION_TYPE_BULK from podcast.constants.episode_replication_status import REPLICATION_TYPE_SINGLE from podcast.constants.episode_replication_status import REPLICATION_TYPES class EpisodeReplicationStatus(mysql.BaseModel): """Table definition for episode_replication_status table.""" __tablename__ = 'episode_replication_status' id = Column(Integer, primary_key=True, autoincrement=True) # noqa original_podcast_id = Column(Integer, nullable=False) podcast_id = Column(Integer, nullable=False) original_episode_id = Column(Integer, nullable=False) episode_id = Column(Integer, nullable=True) status = Column(Enum(*EPISODE_REPLICATION_STATUSES), nullable=False, default=INITIATED) replication_type = Column(Enum(*REPLICATION_TYPES), nullable=False) error_message = Column(VARCHAR(4000), nullable=True) created_timestamp = Column(DateTime, default=func.now()) is_viewed = Column(Boolean, nullable=False, default=False) def to_dict(self): """Return object as dict. Returns: dict: Dictionary representation of object """ return { 'id': self.id, 'original_podcast_id': self.original_podcast_id, 'podcast_id': self.podcast_id, 'original_episode_id': self.original_episode_id, 'episode_id': self.episode_id, 'status': self.status, 'replication_type': self.replication_type, 'error_message': self.error_message, 'created_timestamp': self.created_timestamp, 'is_viewed': self.is_viewed } def create_status(data, session=None): """Create new episode replication status record. Args: payload (dict): EpisodeReplicationStatus fields values Returns: dict: Created EpisodeReplicationStatus dict. """ if session: episode_replication_status = EpisodeReplicationStatus(**data) session.add(episode_replication_status) session.flush() else: with mysql.pod_db_session() as session: episode_replication_status = EpisodeReplicationStatus(**data) session.add(episode_replication_status) return episode_replication_status.to_dict() def update_status(data, session=None): """Update episode replication status record. Args: data (dict): EpisodeReplicationStatus fields values Returns: dict: Updated EpisodeReplicationStatus dict. """ filters = [] if common_constants.ID in data.keys(): filters.append((EpisodeReplicationStatus.id == data['id'])) else: filters.extend([ (EpisodeReplicationStatus.original_episode_id == data['original_episode_id']), (EpisodeReplicationStatus.episode_id == data['episode_id']) ]) if session: return _update_status(data, filters, session) else: with mysql.pod_db_session() as session: return _update_status(data, filters, session) def _update_status(data, filters, session): query = session.query(EpisodeReplicationStatus).filter(*filters) query.update(data) session.flush() result = query.first() if result: return result.to_dict() def update_status_by_ids(status_ids): """Bulk update episode replication status row's is_viewed boolean to True by status ids. Args: status_ids (list of int): EpisodeReplicationStatus ids. Returns: dict: Updated list of EpisodeReplicationStatus dict. """ with mysql.pod_db_session() as session: query = session.query(EpisodeReplicationStatus).filter( EpisodeReplicationStatus.id.in_(status_ids) ) query.update({'is_viewed': True}) return {'items': [status.to_dict() for status in query.all()]} def get_failed_bulk_episodes_replication_status(podcast_id): """Return failed bulk episodes replication status for a podcast id. Args: podcast_id (int): podcast id Returns: dict: containing the episode status. """ with mysql.pod_db_session(read_only=True) as session: rows = session.query(EpisodeReplicationStatus).filter( EpisodeReplicationStatus.podcast_id == podcast_id, EpisodeReplicationStatus.replication_type == REPLICATION_TYPE_BULK, EpisodeReplicationStatus.status.in_((INITIATED, EPISODE_CREATION_FAILED)), EpisodeReplicationStatus.is_viewed.isnot(True) ).all() items = [row.to_dict() for row in rows] return {'items': items} def get_failed_single_episodes_replication_status(original_podcast_id): """Return failed episodes replication status for replication type single by original_podcast_id. Args: original_podcast_id (int): original_podcast_id Returns: dict: containing the failed episode status for replication type single. """ with mysql.pod_db_session(read_only=True) as session: rows = session.query(EpisodeReplicationStatus).filter( EpisodeReplicationStatus.original_podcast_id == original_podcast_id, EpisodeReplicationStatus.replication_type == REPLICATION_TYPE_SINGLE, EpisodeReplicationStatus.status.in_((INITIATED, EPISODE_CREATION_FAILED)), EpisodeReplicationStatus.is_viewed.isnot(True) ).all() items = [row.to_dict() for row in rows] return {'items': items}