"""AdActionComment Model. This model represents an Ad Action Comments """ import sqlalchemy from sqlalchemy import ForeignKey from sqlalchemy.dialects.mysql import INTEGER from sqlalchemy.sql import func from podcast.connectors import mysql from podcast.constants import error from podcast.utils.exc import OwsError class AdActionComment(mysql.BaseModel): """AdActionComment model.""" __tablename__ = 'ad_action_comment' id = sqlalchemy.Column(INTEGER(unsigned=True), primary_key=True, autoincrement=True) # noqa ad_action_id = sqlalchemy.Column( INTEGER, ForeignKey('ad_action.id'), nullable=False ) comment = sqlalchemy.Column(sqlalchemy.TEXT, nullable=False) created_by = sqlalchemy.Column(sqlalchemy.Integer) created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=func.now()) updated_by = sqlalchemy.Column(sqlalchemy.Integer) updated_date = sqlalchemy.Column( sqlalchemy.DateTime, default=func.now(), onupdate=func.now()) is_deleted = sqlalchemy.Column( sqlalchemy.Boolean, nullable=False, default=False) def to_dict(self): """Return the object as dictionary.""" return dict( id=self.id, ad_read_id=self.ad_action_id, comment=self.comment, created_by=self.created_by, created_date=self.created_date, updated_by=self.updated_by, updated_date=self.updated_date, is_deleted=self.is_deleted ) def get_ad_action_comments(ad_action_id, limit, offset): """Return all comments for an ad action (non-deleted). Args: ad_action_id (int): The id for the ad action for which we want to fetch comments. limit (int): Number of records to return per page. offset (int): The page numbner. Returns: dict: containing the ad action comments and total records count. """ with mysql.pod_db_session(read_only=True) as session: query = session.query(AdActionComment).filter( AdActionComment.ad_action_id == ad_action_id, AdActionComment.is_deleted.isnot(True) ) total_records = query.count() ad_action_comments = query.limit(limit).offset(offset).all() items = [ad_action_comment.to_dict() for ad_action_comment in ad_action_comments] return { 'items': items, 'pagination': { 'total_records': total_records } } def get_ad_action_comments_count(ad_action_ids): """Return count of comments for ad actions (non-deleted). Args: ad_action_ids (list of int): The ids for the ad action for which we want to fetch comments. Returns: dict: containing the ad action id and total records count. """ with mysql.pod_db_session(read_only=True) as session: rows = session.query( AdActionComment.ad_action_id, func.count(AdActionComment.id)) \ .filter( AdActionComment.ad_action_id.in_(ad_action_ids), AdActionComment.is_deleted.isnot(True)) \ .group_by(AdActionComment.ad_action_id) \ .all() ad_action_comments = [{'ad_read_id': row[0], 'total_records': row[1]} for row in rows] return {'items': ad_action_comments} def create_ad_action_comment(data, current_user_id): """Create a new Ad Action Comment. Args: data (dict): the data from which to create the ad action comment. Returns: dict: the created ad action comment dict. """ if not data: raise OwsError.bad_request(error.ERROR_MESSAGE_EMPTY_BODY) with mysql.pod_db_session() as session: data['created_by'] = current_user_id data['updated_by'] = current_user_id ad_action_comment = AdActionComment(**data) session.add(ad_action_comment) return ad_action_comment.to_dict() def delete_ad_action_comment(ad_action_comment_id, current_user_id): """Delete an Ad Action comment. Args: ad_action_comment_id (int): id to delete Returns: dict: soft deleted ad action comment """ with mysql.pod_db_session() as session: ad_action_comment = session.query(AdActionComment).filter( AdActionComment.id == ad_action_comment_id ).first() if not ad_action_comment: raise OwsError.not_found() if ad_action_comment.is_deleted: raise OwsError.not_found(error.ERROR_MESSAGE_AD_COMMENT_NOT_FOUND) if ad_action_comment.created_by != current_user_id: raise OwsError.forbidden(error.ERROR_MESSAGE_AD_COMMENT_DELETE_FORBIDDEN) ad_action_comment.updated_by = current_user_id ad_action_comment.is_deleted = True return ad_action_comment.to_dict()