Esempio n. 1
0
def get_placeholder_form_instance(
    placeholder_name,
    dict_to_populate_from,
    template_type,
    optional_placeholder=False,
    allow_international_phone_numbers=False,
):

    if (
        Columns.make_key(placeholder_name) == 'emailaddress'
        and template_type == 'email'
    ):
        field = email_address(label=placeholder_name, gov_user=False)
    elif (
        Columns.make_key(placeholder_name) == 'phonenumber'
        and template_type == 'sms'
    ):
        if allow_international_phone_numbers:
            field = international_phone_number(label=placeholder_name)
        else:
            field = uk_mobile_number(label=placeholder_name)
    elif optional_placeholder:
        field = StringField(placeholder_name)
    else:
        field = StringField(placeholder_name, validators=[
            DataRequired(message='Can’t be empty')
        ])

    PlaceholderForm.placeholder_value = field

    return PlaceholderForm(
        placeholder_value=dict_to_populate_from.get(placeholder_name, '')
    )
    def _get_error_for_field(self, key, value):  # noqa: C901

        if self.is_address_column(key):
            return

        if Columns.make_key(
                key) in self.recipient_column_headers_as_column_keys:
            if value in [None, ''] or isinstance(value, list):
                if self.duplicate_recipient_column_headers:
                    return None
                else:
                    return Cell.missing_field_error
            try:
                validate_recipient(
                    value,
                    self.template_type,
                    allow_international_sms=self.allow_international_sms)
            except (InvalidEmailError, InvalidPhoneError) as error:
                return str(error)

        if Columns.make_key(key) not in self.placeholders_as_column_keys:
            return

        if value in [None, '']:
            return Cell.missing_field_error
def validate_address(address_line, column):
    if Columns.make_key(column) in Columns.from_keys(optional_address_columns).keys():
        return address_line
    if Columns.make_key(column) not in Columns.from_keys(first_column_headings['letter']).keys():
        raise TypeError
    if not address_line or not strip_whitespace(address_line):
        raise InvalidAddressError('Missing')
    return address_line
Esempio n. 4
0
 def placeholders(self, value):
     try:
         self._placeholders = list(value) + self.recipient_column_headers
     except TypeError:
         self._placeholders = self.recipient_column_headers
     self.placeholders_as_column_keys = [
         Columns.make_key(placeholder) for placeholder in self._placeholders
     ]
     self.recipient_column_headers_as_column_keys = [
         Columns.make_key(placeholder)
         for placeholder in self.recipient_column_headers
     ]
Esempio n. 5
0
    def duplicate_recipient_column_headers(self):

        raw_recipient_column_headers = [
            Columns.make_key(column_header)
            for column_header in self._raw_column_headers if Columns.make_key(
                column_header) in self.recipient_column_headers_as_column_keys
        ]

        return OrderedSet((column_header
                           for column_header in self._raw_column_headers
                           if raw_recipient_column_headers.count(
                               Columns.make_key(column_header)) > 1))
Esempio n. 6
0
 def missing_column_headers(self):
     required = {
         Columns.make_key(key): key
         for key in set([self.recipient_column_header] + self.placeholders)
     }
     return set(
         required[key] for key in set(
             [Columns.make_key(self.recipient_column_header)] + self.placeholders_as_column_keys
         ) - set(
             Columns.make_key(column_header) for column_header in self.column_headers
         )
     )
Esempio n. 7
0
 def rows_with_missing_data(self):
     return set(
         row['index'] for row in self.annotated_rows if any(
             str(key) not in Columns.make_key(self.recipient_column_header) and value.get('error')
             for key, value in row['columns'].items()
         )
     )
Esempio n. 8
0
 def placeholders(self, value):
     try:
         self._placeholders = list(value)
         self.placeholders_as_column_keys = [
             Columns.make_key(placeholder) for placeholder in value
         ]
     except TypeError:
         self._placeholders, self.placeholders_as_column_keys = [], []
 def missing_column_headers(self):
     return set(
         key for key in self.placeholders
         if (
             Columns.make_key(key) not in self.column_headers_as_column_keys and
             not self.is_optional_address_column(key)
         )
     )
 def values(self, value):
     if not value:
         self._values = {}
     else:
         placeholders = Columns.from_keys(self.placeholders)
         self._values = Columns(value).as_dict_with_keys(
             self.placeholders
             | set(key for key in value.keys()
                   if Columns.make_key(key) not in placeholders.keys()))
Esempio n. 11
0
    def _get_error_for_field(self, key, value):

        if key == Columns.make_key(self.recipient_column_header):
            try:
                validate_recipient(value, self.template_type)
            except (InvalidEmailError, InvalidPhoneError) as error:
                return str(error)

        if key not in self.placeholders_as_column_keys:
            return

        if value in [None, '']:
            return 'Missing'
Esempio n. 12
0
    def _get_error_for_field(self, key, value):

        if self.is_optional_address_column(key):
            return

        if Columns.make_key(
                key) in self.recipient_column_headers_as_column_keys:
            if value in [None, '']:
                return Cell.missing_field_error
            try:
                validate_recipient(value,
                                   self.template_type,
                                   column=key,
                                   international_sms=self.international_sms)
            except (InvalidEmailError, InvalidPhoneError,
                    InvalidAddressError) as error:
                return str(error)

        if Columns.make_key(key) not in self.placeholders_as_column_keys:
            return

        if value in [None, '']:
            return Cell.missing_field_error
    def get_rows(self):

        column_headers = self._raw_column_headers  # this is for caching
        length_of_column_headers = len(column_headers)

        rows_as_lists_of_columns = self._rows

        next(rows_as_lists_of_columns, None)  # skip the header row

        for index, row in enumerate(rows_as_lists_of_columns):

            output_dict = OrderedDict()

            for column_name, column_value in zip(column_headers, row):

                column_value = strip_and_remove_obscure_whitespace(
                    column_value)

                if Columns.make_key(
                        column_name
                ) in self.recipient_column_headers_as_column_keys:
                    output_dict[column_name] = column_value or None
                else:
                    insert_or_append_to_dict(output_dict, column_name,
                                             column_value or None)

            length_of_row = len(row)

            if length_of_column_headers < length_of_row:
                output_dict[None] = row[length_of_column_headers:]
            elif length_of_column_headers > length_of_row:
                for key in column_headers[length_of_row:]:
                    insert_or_append_to_dict(output_dict, key, None)

            if index < self.max_rows:
                yield Row(
                    output_dict,
                    index=index,
                    error_fn=self._get_error_for_field,
                    recipient_column_headers=self.recipient_column_headers,
                    placeholders=self.placeholders_as_column_keys,
                    template=self.template,
                    allow_international_letters=self.
                    allow_international_letters,
                )
            else:
                yield None
Esempio n. 14
0
 def get_annotated_rows(self):
     if self.too_many_rows:
         return []
     for row_index, row in enumerate(self.rows):
         if self.template:
             self.template.values = dict(row.items())
         yield dict(
             columns=Columns({key: {
                 'data': value,
                 'error': self._get_error_for_field(key, value),
                 'ignore': (
                     key != Columns.make_key(self.recipient_column_header) and
                     key not in self.placeholders_as_column_keys
                 )
             } for key, value in row.items()}),
             index=row_index,
             message_too_long=bool(self.template and self.template.content_too_long)
         )
Esempio n. 15
0
 def has_recipient_columns(self):
     return set(
         Columns.make_key(recipient_column)
         for recipient_column in self.recipient_column_headers
         if not self.is_optional_address_column(recipient_column)
     ) <= self.column_headers_as_column_keys
Esempio n. 16
0
 def is_optional_address_column(self, key):
     return (self.template_type == 'letter' and Columns.make_key(key)
             in Columns.from_keys(optional_address_columns).keys())
Esempio n. 17
0
 def has_recipient_column(self):
     return Columns.make_key(self.recipient_column_header) in set(
         Columns.make_key(column_header) for column_header in self.column_headers
     )
Esempio n. 18
0
def check_contact_list(service_id, upload_id):

    form = CsvUploadForm()

    contents = ContactList.download(service_id, upload_id)
    first_row = contents.splitlines()[0].strip().rstrip(
        ',') if contents else ''
    original_file_name = ContactList.get_metadata(service_id, upload_id).get(
        'original_file_name', '')

    template_type = {
        'emailaddress': 'email',
        'phonenumber': 'sms',
    }.get(Columns.make_key(first_row))

    recipients = RecipientCSV(
        contents,
        template=get_sample_template(template_type or 'sms'),
        whitelist=itertools.chain.from_iterable(
            [user.name, user.mobile_number, user.email_address]
            for user in current_service.active_users)
        if current_service.trial_mode else None,
        allow_international_sms=current_service.has_permission(
            'international_sms'),
        max_initial_rows_shown=50,
        max_errors_shown=50,
    )

    non_empty_column_headers = list(filter(None, recipients.column_headers))

    if len(non_empty_column_headers
           ) > 1 or not template_type or not recipients:
        return render_template(
            'views/uploads/contact-list/too-many-columns.html',
            recipients=recipients,
            original_file_name=original_file_name,
            template_type=template_type,
            form=form,
            allowed_file_extensions=Spreadsheet.ALLOWED_FILE_EXTENSIONS)

    if recipients.too_many_rows or not len(recipients):
        return render_template(
            'views/uploads/contact-list/column-errors.html',
            recipients=recipients,
            original_file_name=original_file_name,
            form=form,
            allowed_file_extensions=Spreadsheet.ALLOWED_FILE_EXTENSIONS)

    row_errors = get_errors_for_csv(recipients, template_type)
    if row_errors:
        return render_template(
            'views/uploads/contact-list/row-errors.html',
            recipients=recipients,
            original_file_name=original_file_name,
            row_errors=row_errors,
            form=form,
            allowed_file_extensions=Spreadsheet.ALLOWED_FILE_EXTENSIONS)

    if recipients.has_errors:
        return render_template(
            'views/uploads/contact-list/column-errors.html',
            recipients=recipients,
            original_file_name=original_file_name,
            form=form,
            allowed_file_extensions=Spreadsheet.ALLOWED_FILE_EXTENSIONS)

    metadata_kwargs = {
        'row_count': len(recipients),
        'valid': True,
        'original_file_name': original_file_name,
        'template_type': template_type
    }

    ContactList.set_metadata(service_id, upload_id, **metadata_kwargs)

    return render_template(
        'views/uploads/contact-list/ok.html',
        recipients=recipients,
        original_file_name=original_file_name,
        upload_id=upload_id,
    )