def view_template(service_id, template_id): template = current_service.get_template(template_id) template_folder = current_service.get_template_folder(template['folder']) user_has_template_permission = current_user.has_template_folder_permission( template_folder) if should_skip_template_page(template['template_type']): return redirect( url_for('.send_one_off', service_id=service_id, template_id=template_id)) page_count = get_page_count_for_letter(template) return render_template( 'views/templates/template.html', template=get_template( template, current_service, letter_preview_url=url_for( 'no_cookie.view_letter_template_preview', service_id=service_id, template_id=template_id, filetype='png', ), show_recipient=True, page_count=get_page_count_for_letter(template), ), template_postage=template["postage"], user_has_template_permission=user_has_template_permission, letter_too_long=is_letter_too_long(page_count), letter_max_pages=LETTER_MAX_PAGE_COUNT, page_count=page_count)
def sanitise_file_contents(encoded_string, *, allow_international_letters, filename=None): """ Given a PDF, returns a new PDF that has been sanitised and dvla approved 👍 * makes sure letter meets DVLA's printable boundaries and page dimensions requirements * re-writes address block (to ensure it's in arial in the right location) * adds NOTIFY tag if not present """ try: file_data = BytesIO(encoded_string) page_count = pdf_page_count(file_data) if is_letter_too_long(page_count): message = "letter-too-long" raise ValidationFailed(message, page_count=page_count) message, invalid_pages = get_invalid_pages_with_message(file_data) if message: raise ValidationFailed(message, invalid_pages, page_count=page_count) file_data, recipient_address, redaction_failed_message = rewrite_pdf( file_data, page_count=page_count, allow_international_letters=allow_international_letters, filename=filename) return { "recipient_address": recipient_address, "page_count": page_count, "message": None, "invalid_pages": None, "redaction_failed_message": redaction_failed_message, "file": base64.b64encode(file_data.read()).decode('utf-8') } except Exception as error: if isinstance(error, ValidationFailed): current_app.logger.warning( 'Validation Failed for precompiled pdf: {} for file name: {}'. format(repr(error), filename)) else: current_app.logger.exception( 'Unhandled exception with precompiled pdf: {} for file name: {}' .format(repr(error), filename)) return { "page_count": getattr(error, 'page_count', None), "recipient_address": None, "message": getattr(error, 'message', 'unable-to-read-the-file'), "invalid_pages": getattr(error, 'invalid_pages', None), "file": None }
def _check_notification(service_id, template_id, exception=None): db_template = current_service.get_template_with_user_permission_or_403( template_id, current_user) email_reply_to = None sms_sender = None if db_template['template_type'] == 'email': email_reply_to = get_email_reply_to_address_from_session() elif db_template['template_type'] == 'sms': sms_sender = get_sms_sender_from_session() template = get_template( db_template, current_service, show_recipient=True, email_reply_to=email_reply_to, sms_sender=sms_sender, letter_preview_url=url_for( 'no_cookie.check_notification_preview', service_id=service_id, template_id=template_id, filetype='png', ), page_count=get_page_count_for_letter(db_template), ) placeholders = fields_to_fill_in(template) back_link = get_back_link(service_id, template, len(placeholders), placeholders) if ((not session.get('recipient') and db_template['template_type'] != 'letter') or not all_placeholders_in_session(template.placeholders)): raise PermanentRedirect(back_link) template.values = get_recipient_and_placeholders_from_session( template.template_type) page_count = get_page_count_for_letter(db_template, template.values) template.page_count = page_count return dict( template=template, back_link=back_link, help=get_help_argument(), letter_too_long=is_letter_too_long(page_count), letter_max_pages=LETTER_MAX_PAGE_COUNT, page_count=page_count, **(get_template_error_dict(exception) if exception else {}), )
def _check_messages(service_id, template_id, upload_id, preview_row, letters_as_pdf=False): try: # The happy path is that the job doesn’t already exist, so the # API will return a 404 and the client will raise HTTPError. job_api_client.get_job(service_id, upload_id) # the job exists already - so go back to the templates page # If we just return a `redirect` (302) object here, we'll get # errors when we try and unpack in the check_messages route. # Rasing a werkzeug.routing redirect means that doesn't happen. raise PermanentRedirect( url_for('main.send_messages', service_id=service_id, template_id=template_id)) except HTTPError as e: if e.status_code != 404: raise statistics = service_api_client.get_service_statistics(service_id, today_only=True) remaining_messages = (current_service.message_limit - sum(stat['requested'] for stat in statistics.values())) contents = s3download(service_id, upload_id) db_template = current_service.get_template_with_user_permission_or_403( template_id, current_user) email_reply_to = None sms_sender = None if db_template['template_type'] == 'email': email_reply_to = get_email_reply_to_address_from_session() elif db_template['template_type'] == 'sms': sms_sender = get_sms_sender_from_session() template = get_template( db_template, current_service, show_recipient=True, letter_preview_url=url_for( 'no_cookie.check_messages_preview', service_id=service_id, template_id=template_id, upload_id=upload_id, filetype='png', row_index=preview_row, ) if not letters_as_pdf else None, email_reply_to=email_reply_to, sms_sender=sms_sender, page_count=get_page_count_for_letter(db_template), ) recipients = RecipientCSV( contents, template=template, max_initial_rows_shown=50, max_errors_shown=50, whitelist=itertools.chain.from_iterable( [user.name, user.mobile_number, user.email_address] for user in Users(service_id)) if current_service.trial_mode else None, remaining_messages=remaining_messages, allow_international_sms=current_service.has_permission( 'international_sms'), allow_international_letters=current_service.has_permission( 'international_letters'), ) if request.args.get('from_test'): # only happens if generating a letter preview test back_link = url_for('main.send_one_off', service_id=service_id, template_id=template.id) choose_time_form = None else: back_link = url_for('main.send_messages', service_id=service_id, template_id=template.id) choose_time_form = ChooseTimeForm() if preview_row < 2: abort(404) if preview_row < len(recipients) + 2: template.values = recipients[preview_row - 2].recipient_and_personalisation elif preview_row > 2: abort(404) page_count = get_page_count_for_letter(db_template, template.values) original_file_name = get_csv_metadata(service_id, upload_id).get( 'original_file_name', '') return dict(recipients=recipients, template=template, errors=recipients.has_errors, row_errors=get_errors_for_csv(recipients, template.template_type), count_of_recipients=len(recipients), count_of_displayed_recipients=len( list(recipients.displayed_rows)), original_file_name=original_file_name, upload_id=upload_id, form=CsvUploadForm(), remaining_messages=remaining_messages, choose_time_form=choose_time_form, back_link=back_link, trying_to_send_letters_in_trial_mode=all(( current_service.trial_mode, template.template_type == 'letter', )), first_recipient_column=recipients.recipient_column_headers[0], preview_row=preview_row, sent_previously=job_api_client.has_sent_previously( service_id, template.id, db_template['version'], original_file_name), letter_too_long=is_letter_too_long(page_count), letter_max_pages=LETTER_MAX_PAGE_COUNT, letter_min_address_lines=PostalAddress.MIN_LINES, letter_max_address_lines=PostalAddress.MAX_LINES, page_count=page_count)
def test_is_letter_too_long(page_count, expected_result): assert is_letter_too_long(page_count) == expected_result