import json from datetime import datetime, timedelta import requests from aws_lambda_powertools import Logger from aws_lambda_powertools.utilities.data_classes import ( EventBridgeEvent, event_source, ) from aws_lambda_powertools.utilities.typing import LambdaContext from layercake.dateutils import fromisoformat, now from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey, TransactKey from boto3clients import dynamodb_client, s3_client from config import BUCKET_NAME, ENROLLMENT_TABLE, PAPERFORGE_API logger = Logger(__name__) enrollment_layer = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client) @event_source(data_class=EventBridgeEvent) @logger.inject_lambda_context def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: new_image = event.detail['new_image'] now_ = now() enrollment_id = new_image['id'] course = enrollment_layer.collection.get_items( TransactKey(new_image['id']) + SortKey('METADATA#COURSE', path_spec='cert', rename_key='cert') + SortKey('STARTED', path_spec='started_at', rename_key='started_at') + SortKey('COMPLETED', path_spec='completed_at', rename_key='completed_at'), flatten_top=False, ) if 'cert' not in course: logger.debug('Certificate not found') # There is no certificate to issue from metadata return False cert = course['cert'] started_at: datetime = fromisoformat(course['started_at']) # type: ignore completed_at: datetime = fromisoformat(course['completed_at']) # type: ignore cert_expires_at = now_ + timedelta(days=int(cert['exp_interval'])) data = json.dumps( { 'template_s3_uri': cert['s3_uri'], 'template_vars': { 'name': new_image['user']['name'], 'cpf': _cpffmt(new_image['user']['cpf']), 'score': new_image['score'], 'started_at': started_at.strftime('%d/%m/%Y'), 'completed_at': completed_at.strftime('%d/%m/%Y'), 'today': _datefmt(now_), 'year': now_.strftime('%Y'), }, }, ) # Send template URI and data to Paperforge API to generate a PDF r = requests.post(PAPERFORGE_API, data=data) r.raise_for_status() object_key = f'issuedcerts/{enrollment_id}.pdf' s3_uri = f's3://{BUCKET_NAME}/{object_key}' try: s3_client.put_object( Bucket=BUCKET_NAME, Key=object_key, Body=r.content, ContentType='application/pdf', ) except Exception as exc: logger.exception(exc) raise logger.debug(f'PDF uploaded successfully to {s3_uri}') return enrollment_layer.update_item( key=KeyPair( pk=enrollment_id, sk='0', ), update_expr='SET issued_cert = :issued_cert', expr_attr_values={ ':issued_cert': { 's3_uri': s3_uri, 'issued_at': now_, 'expires_at': cert_expires_at, }, }, cond_expr='attribute_exists(sk)', ) def _cpffmt(s: str) -> str: return '{}.{}.{}-{}'.format(s[:3], s[3:6], s[6:9], s[9:]) def _datefmt(dt: datetime) -> str: months = [ 'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro', ] return f'{dt.day:02d} de {months[dt.month - 1]} de {dt.year}'