""" Import asset model. This import asset model uses sqlalchemy. It's used to store imported asset in AR database """ from oto import response from sqlalchemy import Column from sqlalchemy import DateTime from sqlalchemy import Enum from sqlalchemy import Integer from sqlalchemy import String from sqlalchemy import Text from sqlalchemy.exc import SQLAlchemyError from assets.connectors import mysql from assets.connectors import sentry from assets.constants import asset_legacy from assets.constants import asset_types from assets.constants import error from assets.models.legacy import import_asset_detail _asset_types_map = { asset_types.TYPE_IMPORT_AUDIO: ( asset_types.TYPE_FILE_WAV, asset_types.TYPE_FILE_FLAC, asset_types.TYPE_FILE_M4A), asset_types.TYPE_IMPORT_IMAGE: ( asset_types.TYPE_FILE_TIF, asset_types.TYPE_FILE_JPG) } class ImportAsset(mysql.ArModel): """Table definition for import_asset table.""" __tablename__ = 'import_asset' import_asset_id = Column( 'id', Integer, primary_key=True, autoincrement=True) import_asset_batch_id = Column(Integer) foldername = Column(String(255)) filename = Column(String(255)) asset_type = Column(Enum(*asset_types.IMPORT_TYPES)) status = Column(Enum(*[ 'upload_complete', 'error', 'finished', 'new', 'deleted'])) upload_completed = Column(DateTime()) encoding_completed = Column(DateTime()) result = Column(Text()) def as_dict(self): """Return object as dict. Returns: dict: Dictionary representation of the object """ asset_dict = { 'id': self.import_asset_id, 'import_asset_batch_id': self.import_asset_batch_id, 'foldername': self.foldername, 'filename': self.filename, 'asset_type': self.asset_type, 'result': self.result, 'status': self.status } return asset_dict def convert_filetype(asset_type): """Convert asset file type to asset import type. Args: asset_type (str): Asset type for convertation Returns: str: Import asset type or None """ for import_type, file_types in _asset_types_map.items(): if asset_type in file_types: return import_type return None def create_import_asset( import_asset_batch_id, foldername, filename, asset_type, status='new', upload_completed=None, encoding_completed=None, result=''): """Create new import asset record. Args: import_asset_batch_id (int): Asset import batch Id foldername (str): Uploaded folder (or S3 bucket) name filename (str): Uploaded filename asset_type (str): Asset type status (str): Asset status upload_completed (datetime): Upload completed timestamp encoding_completed (datetime): Encoding completed timestamp result (str): Information about result of file upload Returns: response.Response: Inserted record info or error """ try: if asset_type in asset_types.FILE_TYPES: asset_type = convert_filetype(asset_type) if asset_type not in asset_types.IMPORT_TYPES: return response.create_error_response( code=error.ERROR_CODE_WRONG_VALUE, message=error.ERROR_WRONG_ASSET_TYPE) import_asset = ImportAsset( import_asset_batch_id=import_asset_batch_id, foldername=foldername, filename=filename, asset_type=asset_type, status=status, upload_completed=upload_completed, encoding_completed=encoding_completed, result=result) with mysql.ar_db_session() as session: session.add(import_asset) session.flush() import_asset_data = import_asset.as_dict() return response.Response(import_asset_data) except SQLAlchemyError as e: if sentry.sentry_client: sentry.sentry_client.captureException() return response.create_fatal_response(e.args) def get_import_asset_by_filename(filename): """Get import asset data from db by filename. Args: filename (str): filename of import asset in db without extension. Returns: response.Response: Data of import asset or error in Response object. """ try: with mysql.ar_db_session() as session: import_asset = session.query(ImportAsset).filter( ImportAsset.filename == filename).first() if not import_asset: return response.create_not_found_response( error.ERROR_MESSAGE_ASSET_NOT_FOUND) import_asset_dict = import_asset.as_dict() return response.Response(import_asset_dict) except SQLAlchemyError as ex: if sentry.sentry_client: sentry.sentry_client.captureException() return response.create_fatal_response(str(ex)) def _get_assets_by_filters(filters): """Get the list of assets by filters. Args: filters (list): The list of filters Returns: response.Response: List of import assets or error in Response object. """ try: with mysql.ar_db_session() as session: assets = session.query( ImportAsset, import_asset_detail.ImportAssetDetail).filter( *filters).order_by( ImportAsset.import_asset_id.desc()).all() assets_data = [{ 'import_asset': item[0].as_dict(), 'import_asset_detail': item[1].as_dict()} for item in assets] return response.Response(assets_data) except SQLAlchemyError as e: if sentry.sentry_client: sentry.sentry_client.captureException() return response.create_fatal_response(e.args) def get_assets_by_upc(upc): """Get the list of product assets by product upc (excluding deleted assets). Args: upc (int): Product UPC Returns: response.Response: List of import assets or error in Response object. """ filters = [ (import_asset_detail.ImportAssetDetail.upc == upc), (import_asset_detail.ImportAssetDetail.import_asset_id == ImportAsset.import_asset_id), (ImportAsset.status != asset_legacy.STATUS_DELETED)] return _get_assets_by_filters(filters) def get_assets_by_ids(ids): """Get the list of product assets by the list of import asset ids. Args: ids (list): The list of import asset ids Returns: response.Response: List of import assets or error in Response object. """ if not ids: ids = [0] filters = [ (ImportAsset.import_asset_id.in_(ids)), (import_asset_detail.ImportAssetDetail.import_asset_id == ImportAsset.import_asset_id)] return _get_assets_by_filters(filters)