Beispiel #1
0
def _check_for_sheet_error(sheet, expected_headers, processed_sheets=Ellipsis):

    if sheet.worksheet.title in processed_sheets:
        raise BulkAppTranslationsException(
            _('Sheet "%s" was repeated. Only the first occurrence has been '
              'processed.') % sheet.worksheet.title)

    if not expected_headers:
        raise BulkAppTranslationsException(
            _('Skipping sheet "%s", could not recognize title') %
            sheet.worksheet.title)

    num_required_headers = 0
    if is_modules_and_forms_sheet(sheet.worksheet.title):
        num_required_headers = 1  # type
    elif is_module_sheet(sheet.worksheet.title):
        num_required_headers = 2  # case property, list or detail
    elif is_form_sheet(sheet.worksheet.title):
        num_required_headers = 1  # label
    elif is_single_sheet(sheet.worksheet.title):
        num_required_headers = 4  # menu or form, case property, list or detail, label

    expected_required_headers = tuple(expected_headers[:num_required_headers])
    actual_required_headers = tuple(sheet.headers[:num_required_headers])
    if expected_required_headers != actual_required_headers:
        raise BulkAppTranslationsException(
            _('Skipping sheet {title}: expected first columns to be '
              '{expected}').format(
                  title=sheet.worksheet.title,
                  expected=", ".join(expected_required_headers)))
Beispiel #2
0
def _check_for_sheet_error(app, sheet, headers, processed_sheets=Ellipsis):
    expected_sheets = {h[0]: h[1] for h in headers}

    if sheet.worksheet.title in processed_sheets:
        raise BulkAppTranslationsException(_('Sheet "%s" was repeated. Only the first occurrence has been '
                                             'processed.') % sheet.worksheet.title)

    expected_headers = _get_expected_headers(sheet, expected_sheets)
    if expected_headers is None:
        raise BulkAppTranslationsException(_('Skipping sheet "%s", could not recognize title') %
                                           sheet.worksheet.title)

    num_required_headers = 0
    if is_modules_and_forms_sheet(sheet.worksheet.title):
        num_required_headers = 1    # type
    elif is_module_sheet(sheet.worksheet.title):
        num_required_headers = 2    # case property, list or detail
    elif is_form_sheet(sheet.worksheet.title):
        num_required_headers = 1    # label
    elif is_single_sheet(sheet.worksheet.title):
        num_required_headers = 4    # menu or form, case property, list or detail, label

    expected_required_headers = tuple(expected_headers[:num_required_headers])
    actual_required_headers = tuple(sheet.headers[:num_required_headers])
    if expected_required_headers != actual_required_headers:
        raise BulkAppTranslationsException(_('Skipping sheet {title}: expected first columns to be '
                                             '{expected}').format(
                                                 title=sheet.worksheet.title,
                                                 expected=", ".join(expected_required_headers)))
Beispiel #3
0
def process_bulk_app_translation_upload(app, workbook, expected_headers, lang=None):
    """
    Process the bulk upload file for the given app.
    We return these message tuples instead of calling them now to allow this
    function to be used independently of request objects.

    :return: Returns a list of message tuples. The first item in each tuple is
    a function like django.contrib.messages.error, and the second is a string.
    """
    msgs = []
    error = _check_for_workbook_error(app, workbook, expected_headers)
    if error:
        msgs.append((messages.error, error))
        return msgs

    processed_sheets = set()
    sheet_name_to_unique_id = {}
    for sheet in workbook.worksheets:
        try:
            _check_for_sheet_error(app, sheet, expected_headers, processed_sheets=processed_sheets)
        except BulkAppTranslationsException as e:
            msgs.append((messages.error, six.text_type(e)))
            continue

        processed_sheets.add(sheet.worksheet.title)

        warnings = _check_for_sheet_warnings(app, sheet, expected_headers)
        for warning in warnings:
            msgs.append((messages.warning, warning))

        if is_single_sheet(sheet.worksheet.title):
            msgs.extend(_process_single_sheet(app, sheet, names_map=sheet_name_to_unique_id, lang=lang))
        else:
            msgs.extend(_process_rows(app, sheet.worksheet.title, sheet, names_map=sheet_name_to_unique_id))

    msgs.append(
        (messages.success, _("App Translations Updated!"))
    )
    return msgs
Beispiel #4
0
 def _is_single_sheet(self):
     sheets_count = len(self.uploaded_workbook.worksheets)
     first_sheet = self.uploaded_workbook.worksheets[0]
     if sheets_count == 1 and is_single_sheet(first_sheet.title):
         return True
     return False
Beispiel #5
0
def process_bulk_app_translation_upload(app,
                                        workbook,
                                        sheet_name_to_unique_id,
                                        lang=None):
    """
    Process the bulk upload file for the given app.
    We return these message tuples instead of calling them now to allow this
    function to be used independently of request objects.

    :return: Returns a list of message tuples. The first item in each tuple is
    a function like django.contrib.messages.error, and the second is a string.
    """
    def get_expected_headers(sheet_name):
        # This function does its best to return the headers we expect, based
        # on the current app, for an uploaded sheet. If the sheet is old, it
        # might not include the unique IDs of the modules/forms. In that case
        # `sheet_name_to_unique_id` will be empty and we fall back to using the
        # name of the sheet and hope that modules/forms have not been moved
        # since the sheet was originally downloaded.
        #
        # If a user created a new sheet, or renamed a sheet, or a form/module
        # has been deleted since this sheet was downloaded, then expected
        # headers will not be found. We return an empty list, and
        # `_check_for_sheet_error()` will handle it.
        if sheet_name in sheet_name_to_unique_id:
            unique_id = sheet_name_to_unique_id[sheet_name]
            if unique_id in expected_headers_by_id:
                return expected_headers_by_id[unique_id]
        return expected_headers_by_sheet_name.get(sheet_name, [])

    msgs = []
    error = _check_workbook_length(workbook, lang)
    if error:
        msgs.append((messages.error, error))
        return msgs

    expected_headers_by_sheet_name = {
        k: v
        for k, v in get_bulk_app_sheet_headers(app, lang=lang)
    }
    expected_headers_by_id = {
        k: v
        for k, v in get_bulk_app_sheet_headers(app, lang=lang, by_id=True)
    }
    processed_sheets = set()

    for sheet in workbook.worksheets:
        expected_headers = get_expected_headers(sheet.worksheet.title)
        try:
            _check_for_sheet_error(sheet, expected_headers, processed_sheets)
        except BulkAppTranslationsException as e:
            msgs.append((messages.error, six.text_type(e)))
            continue

        processed_sheets.add(sheet.worksheet.title)

        warnings = _check_for_sheet_warnings(sheet, expected_headers)
        for warning in warnings:
            msgs.append((messages.warning, warning))

        if is_single_sheet(sheet.worksheet.title):
            msgs.extend(
                _process_single_sheet(app,
                                      sheet,
                                      names_map=sheet_name_to_unique_id,
                                      lang=lang))
        else:
            msgs.extend(
                _process_rows(app,
                              sheet.worksheet.title,
                              sheet,
                              names_map=sheet_name_to_unique_id))

    msgs.append((messages.success, _("App Translations Updated!")))
    return msgs