def send_pdf_letter_notification(service_id, post_data): service = dao_fetch_service_by_id(service_id) check_service_has_permission(LETTER_TYPE, service.permissions) check_service_has_permission(UPLOAD_LETTERS, service.permissions) check_service_over_daily_message_limit(KEY_TYPE_NORMAL, service) validate_created_by(service, post_data["created_by"]) template = get_precompiled_letter_template(service.id) file_location = "service-{}/{}.pdf".format(service.id, post_data["file_id"]) try: letter = utils_s3download(current_app.config["TRANSIENT_UPLOADED_LETTERS"], file_location) except S3ObjectNotFound as e: current_app.logger.exception( "Letter {}.pdf not in transient {} bucket".format( post_data["file_id"], current_app.config["TRANSIENT_UPLOADED_LETTERS"] ) ) raise e # Getting the page count won't raise an error since admin has already checked the PDF is valid billable_units = get_page_count(letter.read()) personalisation = {"address_line_1": post_data["filename"]} # TODO: stop hard-coding postage as 'second' once we get postage from the admin notification = persist_notification( notification_id=post_data["file_id"], template_id=template.id, template_version=template.version, template_postage=template.postage, recipient=post_data["filename"], service=service, personalisation=personalisation, notification_type=LETTER_TYPE, api_key_id=None, key_type=KEY_TYPE_NORMAL, reference=create_one_off_reference(LETTER_TYPE), client_reference=post_data["filename"], created_by_id=post_data["created_by"], billable_units=billable_units, postage="second", ) upload_filename = get_letter_pdf_filename( notification.reference, notification.service.crown, is_scan_letter=False, postage=notification.postage, ) move_uploaded_pdf_to_letters_bucket(file_location, upload_filename) return {"id": str(notification.id)}
def send_pdf_letter_notification(service_id, post_data): service = dao_fetch_service_by_id(service_id) check_service_has_permission(LETTER_TYPE, [p.permission for p in service.permissions]) check_service_over_daily_message_limit(KEY_TYPE_NORMAL, service) validate_created_by(service, post_data['created_by']) validate_and_format_recipient( send_to=post_data['recipient_address'], key_type=KEY_TYPE_NORMAL, service=service, notification_type=LETTER_TYPE, allow_guest_list_recipients=False, ) template = get_precompiled_letter_template(service.id) file_location = 'service-{}/{}.pdf'.format(service.id, post_data['file_id']) try: letter = utils_s3download( current_app.config['TRANSIENT_UPLOADED_LETTERS'], file_location) except S3ObjectNotFound as e: current_app.logger.exception( 'Letter {}.pdf not in transient {} bucket'.format( post_data['file_id'], current_app.config['TRANSIENT_UPLOADED_LETTERS'])) raise e # Getting the page count won't raise an error since admin has already checked the PDF is valid page_count = get_page_count(letter.read()) billable_units = get_billable_units_for_letter_page_count(page_count) personalisation = {'address_line_1': post_data['filename']} notification = persist_notification( notification_id=post_data['file_id'], template_id=template.id, template_version=template.version, recipient=urllib.parse.unquote(post_data['recipient_address']), service=service, personalisation=personalisation, notification_type=LETTER_TYPE, api_key_id=None, key_type=KEY_TYPE_NORMAL, reference=create_one_off_reference(LETTER_TYPE), client_reference=post_data['filename'], created_by_id=post_data['created_by'], billable_units=billable_units, postage=post_data['postage'] or template.postage, ) upload_filename = get_letter_pdf_filename( reference=notification.reference, crown=notification.service.crown, created_at=notification.created_at, ignore_folder=False, postage=notification.postage) move_uploaded_pdf_to_letters_bucket(file_location, upload_filename) return {'id': str(notification.id)}
def process_virus_scan_passed(self, filename): reference = get_reference_from_filename(filename) notification = dao_get_notification_by_reference(reference) current_app.logger.info('notification id {} Virus scan passed: {}'.format(notification.id, filename)) is_test_key = notification.key_type == KEY_TYPE_TEST scan_pdf_object = s3.get_s3_object(current_app.config['LETTERS_SCAN_BUCKET_NAME'], filename) old_pdf = scan_pdf_object.get()['Body'].read() try: billable_units = get_page_count(old_pdf) except PdfReadError: current_app.logger.exception(msg='Invalid PDF received for notification_id: {}'.format(notification.id)) _move_invalid_letter_and_update_status(notification, filename, scan_pdf_object) return sanitise_response = _sanitise_precompiled_pdf(self, notification, old_pdf) if not sanitise_response: new_pdf = None else: sanitise_response = sanitise_response.json() try: new_pdf = base64.b64decode(sanitise_response["file"].encode()) except JSONDecodeError: new_pdf = sanitise_response.content redaction_failed_message = sanitise_response.get("redaction_failed_message") if redaction_failed_message and not is_test_key: current_app.logger.info('{} for notification id {} ({})'.format( redaction_failed_message, notification.id, filename) ) copy_redaction_failed_pdf(filename) # TODO: Remove this once CYSP update their template to not cross over the margins if notification.service_id == UUID('fe44178f-3b45-4625-9f85-2264a36dd9ec'): # CYSP # Check your state pension submit letters with good addresses and notify tags, so just use their supplied pdf new_pdf = old_pdf if not new_pdf: current_app.logger.info('Invalid precompiled pdf received {} ({})'.format(notification.id, filename)) _move_invalid_letter_and_update_status(notification, filename, scan_pdf_object) return else: current_app.logger.info( "Validation was successful for precompiled pdf {} ({})".format(notification.id, filename)) current_app.logger.info('notification id {} ({}) sanitised and ready to send'.format(notification.id, filename)) try: _upload_pdf_to_test_or_live_pdf_bucket( new_pdf, filename, is_test_letter=is_test_key) update_letter_pdf_status( reference=reference, status=NOTIFICATION_DELIVERED if is_test_key else NOTIFICATION_CREATED, billable_units=billable_units ) scan_pdf_object.delete() except BotoClientError: current_app.logger.exception( "Error uploading letter to live pdf bucket for notification: {}".format(notification.id) ) update_notification_status_by_id(notification.id, NOTIFICATION_TECHNICAL_FAILURE)