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 from boto3clients import dynamodb_client, s3_client from config import BUCKET_NAME, ENROLLMENT_TABLE, PAPERFORGE_API, SIGNATURE_URI logger = Logger(__name__) dyn = 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'] cert = dyn.collection.get_item( KeyPair( pk=new_image['id'], sk=SortKey('METADATA#COURSE', path_spec='cert', rename_key='cert'), ), raise_on_error=False, default=False, ) if not cert: logger.debug('Certificate not found') # There is no certificate to issue from metadata return False started_at: datetime = fromisoformat(new_image['started_at']) # type: ignore completed_at: datetime = fromisoformat(new_image['completed_at']) # type: ignore cert_expires_at = completed_at + timedelta(days=int(cert['exp_interval'])) try: # Send template URI and data to Paperforge API to generate a PDF r = requests.post( PAPERFORGE_API, data=json.dumps( { 'template_uri': cert['s3_uri'], 'sign_uri': SIGNATURE_URI, 'args': { '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'), }, }, ), ) r.raise_for_status() object_key = f'issuedcerts/{enrollment_id}.pdf' s3_uri = f's3://{BUCKET_NAME}/{object_key}' s3_client.put_object( Bucket=BUCKET_NAME, Key=object_key, Body=r.content, ContentType='application/pdf', ) logger.debug(f'PDF uploaded successfully to {s3_uri}') except KeyError: # PDF generation fails if template URI is missing s3_uri = None logger.debug('Template URI is missing') except requests.exceptions.RequestException as exc: logger.exception(exc) raise return dyn.update_item( key=KeyPair( pk=enrollment_id, sk='0', ), update_expr='SET issued_cert = :issued_cert, uploaded_at = :now', expr_attr_values={ ':now': now_, ':issued_cert': { 'issued_at': now_, 'expires_at': cert_expires_at, } | ({'s3_uri': s3_uri} if s3_uri else {}), }, 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}'