"""Lambda shared module.""" import os from contextlib import contextmanager from dateutil.parser import parse import json from tempfile import NamedTemporaryFile import urllib import boto3 from botocore.exceptions import ClientError from xlsx2csv import Xlsx2csv from common_config import logger from common_config import SLACK_WEBHOOK_URL from constants import errors from connectors import sentry def say_hello(): """Generate high SLA Orchard greeting and logs it.""" logger.info('Hello, world!') def convert_xsl_to_csv(bucket_name, xls_key, csv_key): """Download an xsl from S3, convert it to csv and upload it to S3. Args: bucket_name (str): s3 bucket name xls_key (str): the name of the xls file key to convert csv_key (str): the name of the destination csv file key Returns: bool: True if file was converted and uploaded successfully False if xls file does not exist """ s3_bucket = boto3.resource('s3').Bucket(bucket_name) with tmp_file_path() as xls_path, tmp_file_path() as csv_path: if download_file(s3_bucket, xls_key, xls_path): Xlsx2csv(xls_path, outputencoding='utf8').convert(csv_path) s3_bucket.upload_file(csv_path, csv_key) return True else: return False @contextmanager def tmp_file_path(): """Temporary file context manager. Returns: str: temp file path """ f = NamedTemporaryFile(delete=False) f.close() path = f.name try: yield path finally: os.unlink(path) def download_file(s3_bucket, s3_key, destination_path): """Download an S3 object to a file. Args: s3_bucket: boto3.resource('s3').Bucket s3_key (str): the name of the xls file key to download from destination_path (str): the path to the file to download to Returns: bool: True if file was downloaded successfully False if file does not exist """ try: s3_bucket.download_file(s3_key, destination_path) except ClientError as e: try: err_code = e.response['Error']['Code'] if err_code == '404': # file does not exist return False else: raise e except (KeyError, AttributeError): raise e return True def notify_slack(message): """Send message to Slack. Args: message (str): message to send """ data = json.dumps({'text': message}).encode('ascii') try: urllib.request.urlopen(SLACK_WEBHOOK_URL, data) except Exception: logger.error(errors.NOTIFY_SLACK_ERROR.format(message)) sentry.capture_exception() def get_date_from_report_key(xls_key): """Extract date from the xls report S3 key. Args: xls_key (str): the name of the xls file key Returns: date: date extracted from the S3 key """ try: return parse(xls_key.split('/')[-2]).date() except (IndexError, ValueError): raise ValueError(errors.INVALID_XLS_KEY.format(xls_key))