""" AssetUpload Model. This AssetUpload model uses sqlalchemy. It's used to store about newly uploaded assets. """ from oto import response from sqlalchemy import Column from sqlalchemy import Integer from sqlalchemy import LargeBinary from sqlalchemy import String from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import SQLAlchemyError from assets.connectors import mysql from assets.connectors import sentry class AssetUpload(mysql.AuModel): """Table definition for asset_upload table.""" __tablename__ = 'asset_upload' asset_upload_id = Column( 'id', Integer, primary_key=True, autoincrement=True) user_id = Column(String(127), nullable=False) asset_type = Column(String(16)) token = Column(LargeBinary, nullable=False) filename = Column(String(64), unique=True, nullable=False) product_id = Column(Integer, default=0) upc = Column(String(50), default=None, nullable=True) track_unique_id = Column(Integer, default=0) def as_dict(self): """Return object as dict. Returns: dict: Dictionary representation of object """ asset_upload_dict = { 'id': self.asset_upload_id, 'user_id': self.user_id, 'asset_type': self.asset_type, 'token': self.token.decode(), 'filename': self.filename, 'product_id': self.product_id, 'upc': self.upc, 'track_unique_id': self.track_unique_id } return asset_upload_dict def create_asset_upload(user_id, filename, token): """Put new raw asset item into asset_upload table. Args: user_id (str): user id filename (str): unique filename token (str): sts token Returns: response.Response: AssetUpload.as_dict() in message attribute or error response. """ try: asset_upload = AssetUpload( user_id=user_id, filename=filename, token=token.encode()) with mysql.au_db_session() as session: session.add(asset_upload) asset_upload_dict = asset_upload.as_dict() return response.Response(asset_upload_dict) except IntegrityError as e: if sentry.sentry_client: sentry.sentry_client.captureException() return response.create_error_response( code='token_generation_integrity_error', message=str(e), status=500) except SQLAlchemyError as e: if sentry.sentry_client: sentry.sentry_client.captureException() return response.create_fatal_response(e.args) def get_asset_upload(filename, token=None, user_id=None): """Check if asset_upload exists in database. Args: filename (str): unique filename token (str): sts token user_id (str): user id Returns: response.Response: AssetUpload.as_dict() in message attribute or error response. """ try: with mysql.au_db_session() as session: filters = [ (AssetUpload.filename == filename) ] if user_id and token: filters.extend([ (AssetUpload.user_id == user_id), (AssetUpload.token == token.encode()) ]) asset_upload = session.query(AssetUpload).filter(*filters).first() if asset_upload is None: return response.create_not_found_response('asset_not_found') asset_upload_dict = asset_upload.as_dict() return response.Response(asset_upload_dict) except SQLAlchemyError as e: if sentry.sentry_client: sentry.sentry_client.captureException() return response.create_fatal_response(e.args) def update_asset_upload( filename, asset_type, upc, track_unique_id, product_id, token=None, user_id=None): """Check if asset_upload exists in database and update with asset_type. Args: filename (str): Unique filename token (str): STS token. asset_type (str): Asset type. upc (int): Product UPC. track_unique_id (int): Track unique id. product_id (int): Product id. user_id (str): User id. Returns: response.Response: AssetUpload.as_dict() in message attribute or error response. """ try: with mysql.au_db_session() as session: filters = [ (AssetUpload.filename == filename) ] if user_id and token: filters.extend([ (AssetUpload.user_id == user_id), (AssetUpload.token == token.encode()) ]) updated_items = session.query(AssetUpload).filter( *filters).update( { 'asset_type': asset_type, 'upc': upc, 'track_unique_id': track_unique_id, 'product_id': product_id, } ) if updated_items != 1: return response.create_fatal_response( 'No asset_upload record was updated') session.commit() asset_upload_dict = session.query(AssetUpload).filter( AssetUpload.filename == filename, ).first().as_dict() return response.Response(asset_upload_dict) except SQLAlchemyError as e: if sentry.sentry_client: sentry.sentry_client.captureException() return response.create_fatal_response(e.args)