"""Common functions for all stores.""" from availability import exceptions from availability.connectors import loggly from availability.constants import models as models_constants from availability.constants import stores as stores_constants from availability.logic.polling.stores import deezer from availability.logic.polling.stores import itunes from availability.logic.polling.stores import spotify from availability.models import product_in_store from availability.models import task_log logger = loggly.get_current_logger() def update_product_status( *, store_id, product_in_store_id, orchard_product_id, upc, task_id, countries): """Update product availability status information. Performs store-specific query, parsing and updates the DB. Is expected to be called from a daemon loop. Args: store_id (int): ID of the store. orchard_product_id (int): unique product ID. Exact semantics depends on the store: we expect UPC for Spotify and either IODA release ID or UPC for iTunes (depends on the release provider). product_in_store_id (int): PK of the product_in_store DB record. It is used to update DB record after polling the store. upc (str): The Universal Product Code. task_id (int): PK of task record that corresponds to this product_in_store. countries (list): ISO 3166-1 alpha-2 country codes. Raises: NotImplementedError: if passed store_id has no corresponding module with polling implementation. """ store_modules = dict(( (stores_constants.STORE_ID_ITUNES, itunes), (stores_constants.STORE_ID_SPOTIFY, spotify), (stores_constants.STORE_ID_DEEZER, deezer))) log_msg_args = ( 'store_id={:d}, product_in_store_id={:d}, orchard_product_id={:d}, ' 'upc={}'.format( store_id, product_in_store_id, orchard_product_id, upc)) try: store_module = store_modules[store_id] except KeyError: msg = ('An attempt to call update_product_status() ' 'for unknown store: {}'.format(log_msg_args)) logger.error(msg) task_log.create_task_log( task_id, models_constants.TASK_LOG_TYPE_FAILED, msg) raise exceptions.UpdateProductStatusError try: release_status = store_module.get_status_from_store( product_id=orchard_product_id, upc=upc, countries=countries) logger.info('Release status received {}'.format( release_status.as_dict())) except (exceptions.StoreRequestError, exceptions.StoreResponseParseError) as e: msg = 'Error while calling get_status_from_store(): "{}", {}'.format( e, log_msg_args) logger.error(msg) task_log.create_task_log( task_id, models_constants.TASK_LOG_TYPE_FAILED, msg) raise else: product_in_store_response = product_in_store.update_release_status( product_in_store_id, store_id, release_status=release_status) assert product_in_store_response, product_in_store_response.errors logger.info( 'Release status updated for product_in_store {}'.format( product_in_store_id))