"""Module that provides getting and processing job data.""" from botocore.exceptions import NoCredentialsError from oto import response from sentry_sdk import capture_exception from salessheets import config from salessheets.connectors import s3 from salessheets.connectors import sentry from salessheets.constants import error from salessheets.constants import field_const from salessheets.constants import salessheets from salessheets.models import history from salessheets.models import ows_product def get_download_url_by_job_id(job_id): """Function that process job data and creates download link. Args: job_id (int): Id of job for which link should be generated. Returns: response.Response: Object with error or with s3 link. """ job_data = history.get_job_by_id(job_id) if not job_data: return job_data job = job_data.message if job.status != salessheets.COMPLETED: error_msg = 'Job {id} is in {state} state'.format( id=job_id, state=job.status) return response.create_error_response( code=error.JOB_IS_NOT_COMPLETED_CODE, message=error_msg) filename = create_file_name_by_job_data(job) if config.BULK_SALESSHEETS_S3_DIRECTORY: filename = '{dir}/{name}'.format( dir=config.BULK_SALESSHEETS_S3_DIRECTORY, name=filename) try: connection = s3.connect_to_s3() return s3.get_s3_file_url( connection, config.SALESSHEETS_S3_BUCKET, filename) except NoCredentialsError as e: capture_exception(e) return response.create_fatal_response(e.args) def create_file_name_by_job_data(job_data): """Function that creates filename for job result. Filename in following format: YYYYMMDD_{JOB_ID}_bulk_sales_sheets.EXTENSION Args: job_data (Job): Job object with data. Returns: filename: created filename. """ date = job_data.timestamp.strftime('%Y%m%d') output_format = job_data.output_format job_id = job_data.job_id extension = salessheets.EXTENSIONS_BY_GENERATION_METHOD[output_format] filename = '{date}_{job_id}_bulk_sales_sheets.{extension}'.format( date=date, job_id=job_id, extension=extension) return filename def get_history_for_user( user_id, sort_field, sort_order, page_limit, page_offset): """Function that takes history from db for provided user. Args: user_id (str): id of user for which history will be taken sort_field (str): field for history sorting, e.g. date sort_order (str): order of sorting: asc or desc page_limit (int): count of pages that should be taken page_offset (int): count of pages to skip Returns: response.Response: history for provided user or error. """ total_records_data = history.get_jobs_count(user_id) if not total_records_data: return total_records_data total_records = total_records_data.message items = [] if total_records > 0: user_history = history.get_all_jobs_by_user_id( user_id, sort_field, sort_order, page_limit, page_offset) if not user_history: return user_history items = [item.as_dict() for item in user_history.message] items = [ item for item in items if item[salessheets.CONTEXT_TYPE] != salessheets.RELEASE_ID] pagination = { field_const.TYPE: field_const.STANDARD, field_const.OFFSET: page_offset, field_const.LIMIT: page_limit, field_const.TOTAL_RECORDS: total_records, field_const.SORT_BY: sort_field, field_const.SORT_ORDER: sort_order} result = { field_const.ITEMS: items, field_const.PAGINATION: pagination} return response.Response(result) def get_last_successful_job_for_release_id( release_id, grass_account_id=None, grass_account_type=None): """Function that returns last successful job for single release_id. Args: release_id (int): release_id for which job should be taken. grass_account_type (str): Type of user account from workstation. allowed values: "vendor", "subaccount"; not required for OA users. grass_account_id (str): Id of user account from workstation; not required for OA users. Returns: response.Response: Object with error or with job data. """ # Validate release ownership if both grass headers were provided. if grass_account_type and grass_account_id: validated_product = ( ows_product.get_product_ownership_by_account( account_type=grass_account_type, account_id=grass_account_id, product_id=str(release_id))) if not validated_product: return validated_product job_data = history.get_job_by_release_id(release_id) if not job_data: return job_data job = job_data.message if job.status is salessheets.STATUS_ERROR: return response.create_error_response( code=error.JOB_IS_NOT_COMPLETED_CODE, message=salessheets.ERROR_MESSAGE.format( id=release_id, state=job.status)) if job.status in salessheets.STATUS_IN_PROGRESS: return response.Response({ 'message': salessheets.ERROR_MESSAGE.format( id=release_id, state=job.status)}) filename = create_file_name_by_job_data(job) if config.BULK_SALESSHEETS_S3_DIRECTORY: filename = '{dir}/{name}'.format( dir=config.BULK_SALESSHEETS_S3_DIRECTORY, name=filename) try: connection = s3.connect_to_s3() url_data = s3.get_s3_file_url( connection, config.SALESSHEETS_S3_BUCKET, filename) except NoCredentialsError as e: capture_exception(e) return response.create_fatal_response(e.args) if not url_data: return url_data download_url = url_data.message result = { field_const.TIMESTAMP: job.as_dict()[field_const.TIMESTAMP], field_const.DOWNLOAD_URL: download_url} return response.Response(result)