Exemple #1
0
def translate_info_fields(sheet: SheetBinding, products: List[Product],
                          language_code: str, ws: Worksheet):
    """
    translating ProductInfo
    :param sheet: current sheet
    :param products: products to translate
    :param language_code:
    :param ws:
    """

    info_columns_to_translate = sheet.columns\
        .filter(is_info=True,
                **{f'column_name_{language_code}__isnull': False}) \
        .all()
    logger.info(
        f'info columns for translation'
        f'={list(map(lambda x: x.column_name, info_columns_to_translate))}')

    info_column_names_translation_map = {
        getattr(c, f'column_name_{language_code}'): c.column_name_ru
        for c in info_columns_to_translate
    }

    for product in products:
        row = parser.find_row(sheet.id_column.column_name, product.xlsx_alias,
                              ws)
        xlsx_product = parser.parse_row(row, ws)

        # activating  language_code required for parse_xlsx_product_info,
        # otherwise it will be looking for column names in wrong language
        translation.activate(language_code)

        # parsing products from xlsx
        all_parsed_product_info = parser.parse_xlsx_product_info(
            info_columns_to_translate, xlsx_product)
        translation.activate(DEFAULT_LANGUAGE_CODE)

        # iterating over column bindings
        for parsed_product_info in all_parsed_product_info:
            parsed_product_info_name = getattr(parsed_product_info,
                                               f'name_{language_code}')

            # looking for current product in db, searching by main language
            # we are searching by main language because language_code might not be set
            db_product_info = product.all_info\
                .filter(name=info_column_names_translation_map[parsed_product_info_name])\
                .first()

            translation.activate(language_code)

            db_product_info.name = parsed_product_info.name
            db_product_info.description = parsed_product_info.description

            db_product_info.save()

            translation.activate(DEFAULT_LANGUAGE_CODE)

            logger.info(
                f'translated ProductInfo id={db_product_info.id} name={db_product_info.name} '
                f'for Product alias={product.xlsx_alias}')
Exemple #2
0
def translate_colors_field(sheet: SheetBinding, products: List[Product],
                           language_code: str, ws: Worksheet):
    """
    translating ProductColors names
    :param sheet:
    :param products:
    :param language_code:
    :param ws:
    """

    for product in products:
        row = parser.find_row(sheet.id_column.column_name, product.xlsx_alias,
                              ws)
        xlsx_product = parser.parse_row(row, ws)

        all_colors = parser.parse_xlsx_colors(sheet, xlsx_product)
        for color in filter(lambda x: x.image_name != '', all_colors):
            db_color = product.all_colors.filter(
                image_name=color.image_name).first()

            translation.activate(language_code)
            db_color.color_name = color.color_name
            translation.activate(DEFAULT_LANGUAGE_CODE)

            db_color.save()
Exemple #3
0
def translate_base_fields(sheet: SheetBinding, products: List[Product],
                          language_code: str, ws: Worksheet):
    """
    translating base fields, which are not is_info and not is_options
    :param sheet: current sheet
    :param products: products to translate
    :param language_code:
    :param ws:
    """

    field_columns_to_translate = sheet.columns \
        .filter(is_options=False,
                is_info=False,
                field_name__in=ProductTranslationOptions.fields). \
        all()

    logger.info(
        f'basic columns(fields only) for translation'
        f'={list(map(lambda x: x.column_name, field_columns_to_translate))}')

    for product in products:
        row = parser.find_row(sheet.id_column.column_name, product.xlsx_alias,
                              ws)
        # parsing product from xlsx
        xlsx_product = parser.parse_row(row, ws)

        # iterating over basic columns and translating corresponding fields
        for column in field_columns_to_translate:
            logger.info(f'translating {column.field_name} for '
                        f'Product alias={product.xlsx_alias}')

            setattr(product, f'{column.field_name}_{language_code}',
                    xlsx_product[column.column_name])

        product.save()
Exemple #4
0
def create_new_product(sheet: SheetBinding, wb: Workbook, alias: str):
    """
    Create new product with product info, colors, product_options, thumbnail image,
     creating collection if not found in db.
    :param sheet: current sheet binding
    :param wb: current workbook
    :param alias: product alias
    """

    row = parser.find_row(sheet.id_column.column_name, alias, wb.active)
    # getting data from xlsx
    xlsx_product = parser.parse_row(row, wb.active)

    pr = Product()
    # setting all basic attributes
    parser.parse_xlsx_product(pr, sheet, xlsx_product)

    pr.xlsx_alias = alias
    pr.category = sheet.category

    if sheet.collection_column:
        pr.collection = get_or_create_collection(
            sheet.category, xlsx_product[sheet.collection_column.column_name])
    pr.save()

    info_columns_bindings = sheet.columns.filter(is_info=True).all()
    all_product_info = parser.parse_xlsx_product_info(info_columns_bindings,
                                                      xlsx_product)
    for product_info in all_product_info:
        product_info.product = pr
        product_info.save()

    all_colors = parser.parse_xlsx_colors(sheet, xlsx_product)
    for color in all_colors:
        color.product = pr
        color.save()

    options_columns = sheet.columns.filter(is_options=True).all()
    all_product_options = parser.parse_xlsx_product_options(
        sheet, wb, options_columns, xlsx_product)
    for (product_options, options) in all_product_options:
        product_options.product = pr
        product_options.save()
        for option in options:
            option.parent = product_options
            option.save()

    thumbnail_image = ProductThumbnailImage(
        color=pr.all_non_blank_colors.first())
    thumbnail_image.save()

    pr.thumbnail_image = thumbnail_image
    pr.save()

    logger.info(f'new product added with alias={alias}')
Exemple #5
0
def parse_xlsx(file: io.BytesIO, update_products: bool,
               is_update_product_compilations: bool,
               remove_old_products: bool):
    wb = load_workbook(filename=file, data_only=True)

    sheet_bindings = SheetBinding.objects.all()
    for sheet in sheet_bindings:
        if sheet.sheet_name in wb.sheetnames:
            wb.active = wb.get_sheet_by_name(sheet.sheet_name)
            columns_names = parser.get_columns_names(wb.active)
            logger.info(
                f'\nworking on sheet={sheet.sheet_name} collection_name={sheet.category.name}'
            )

            products = Product.objects.filter(category=sheet.category).all()
            db_aliases = set([product.xlsx_alias for product in products])
            sheet_aliases = set(
                parser.get_all_column_values(
                    columns_names.index(sheet.id_column.column_name) + 1,
                    wb.active))

            # deleting all products which weren't found
            deleted_aliases = db_aliases - sheet_aliases
            if remove_old_products:
                for alias in deleted_aliases:
                    Product.objects.filter(xlsx_alias=alias).delete()
                logger.info(f'deleted {len(deleted_aliases)} products')

            # creating and adding new products
            new_aliases = sheet_aliases - db_aliases
            for new_alias in new_aliases:
                logger.info(f'\ncreating new product with alias={new_alias}')
                create_new_product(sheet, wb, new_alias)

            # updating old products
            if update_products:
                old_aliases = sheet_aliases - new_aliases
                for alias in old_aliases:
                    logger.info(f'\nupdating product with alias={alias}')
                    row = parser.find_row(sheet.id_column.column_name, alias,
                                          wb.active)
                    xlsx_product = parser.parse_row(row, wb.active)

                    db_product = Product.objects.get(xlsx_alias=alias)
                    parser.parse_xlsx_product(db_product, sheet, xlsx_product)

                    logger.info('updating product info')
                    updating_helpers.update_product_info(
                        sheet, db_product, xlsx_product)

                    logger.info('updating product colors')
                    updating_helpers.update_product_colors(
                        sheet, db_product, xlsx_product)

                    logger.info('updating product thumbnail')
                    # should be called after updating product colors, ProductColor delete is overridden
                    updating_helpers.update_product_thumbnail(db_product)

                    logger.info('updating product options')
                    updating_helpers.update_product_options(
                        sheet, wb, db_product, xlsx_product)

                    if db_product.category != sheet.category:
                        db_product.category = sheet.category

                    if sheet.collection_column:
                        db_product.collection = \
                            get_or_create_collection(sheet.category,
                                                     xlsx_product[sheet.collection_column.column_name])

                    db_product.save()

            # updating product compilations for this category
            if is_update_product_compilations:
                updating_helpers.update_product_compilations(sheet, wb)
Exemple #6
0
def translate_options_field(sheet: SheetBinding, products: List[Product],
                            language_code: str, wb: Workbook):
    """
    translating ProductOptions and ProductOption
    :param sheet:
    :param products:
    :param language_code:
    :param wb:
    """

    ws = wb.active

    options_columns_to_translate = sheet.columns \
        .filter(is_options=True,
                **{f'column_name_{language_code}__isnull': False}) \
        .all()
    logger.info(
        f'options columns for translation'
        f'={list(map(lambda x: x.column_name, options_columns_to_translate))}')

    options_column_names_translation_map = {
        getattr(c, f'column_name_{language_code}'): c.column_name_ru
        for c in options_columns_to_translate
    }

    for product in products:
        row = parser.find_row(sheet.id_column.column_name, product.xlsx_alias,
                              ws)
        xlsx_product = parser.parse_row(row, ws)

        # activating language_code required for parse_xlsx_product_options,
        # otherwise it will be looking for column names in wrong language
        translation.activate(language_code)

        # parsing product options from xlsx
        all_product_options = parser\
            .parse_xlsx_product_options(sheet, wb, options_columns_to_translate, xlsx_product)

        translation.activate(DEFAULT_LANGUAGE_CODE)

        for (product_options_obj, options) in all_product_options:
            title_in_language_code = getattr(product_options_obj,
                                             f'title_{language_code}')

            db_product_options_obj = product.all_options\
                .filter(title=options_column_names_translation_map[title_in_language_code])\
                .first()

            logger.info(
                f'translating ProductOptions title={product_options_obj.title} for '
                f'Product alias={product.xlsx_alias}')

            translation.activate(language_code)

            db_product_options_obj.title = product_options_obj.title
            db_product_options_obj.description = product_options_obj.description

            translation.activate(DEFAULT_LANGUAGE_CODE)

            for option in options:
                # looking for the same option by its row
                db_option = db_product_options_obj.options\
                    .filter(xlsx_row=option.xlsx_row)\
                    .first()

                logger.info(
                    f'translating ProductOptions title={product_options_obj.title} '
                    f'ProductOption name={db_option.name} for '
                    f'Product alias={product.xlsx_alias}')

                translation.activate(language_code)
                db_option.name = option.name
                translation.activate(DEFAULT_LANGUAGE_CODE)

                db_option.save()

            db_product_options_obj.save()