def test_category_remove_product(self): self.category.add_product(self.product) transaction.commit() self.keeper.close() keeper = open_storage() milk = ProductCategory.fetch('milk', keeper) stored_product = Product.fetch(self.product.key, keeper) milk.remove_product(stored_product) transaction.commit() keeper.close() keeper = open_storage() stored_product = Product.fetch(self.product.key, keeper) milk = ProductCategory.fetch('milk', keeper) self.assertNotIn(stored_product, milk.products)
def test_250g_comma_preceding(self): sour_cream025 = Product(u'Сметана Углече Поле органическая 15%, 250г') key = sour_cream025.get_category_key() sour_cream = ProductCategory(key) self.assertEqual('0.25 kg', sour_cream025.get_package_key()) self.assertEqual(0.625, sour_cream025.get_package().get_ratio(sour_cream))
def test_price_report_lifetime(self): milk = ProductCategory.fetch("milk", self.keeper) # add an outdated report PriceReport.assemble( price_value=15.40, product_title=u"Молоко Минувших дней 1л", reporter_name="John", merchant_title="Howie's grocery", url="http://someshop.com/item/345", date_time=MONTH_AGO, storage_manager=self.keeper, ) transaction.commit() self.assertEqual(50.75, milk.get_price()) # add a valid report PriceReport.assemble( price_value=10.22, product_title=u"Молоко Минувших дней 1л", reporter_name="John", merchant_title="Howie's grocery", url="http://someshop.com/item/349", date_time=HOUR_AGO, storage_manager=self.keeper, ) transaction.commit() self.assertEqual(45.9, milk.get_price()) self.assertEqual(15.40, milk.get_price(datetime.datetime.now() - datetime.timedelta(days=25))) self.assertIsNone(milk.get_price(datetime.datetime.now() - datetime.timedelta(days=45)))
def test_report_assembly_new_product(self): from uuid import uuid4 product_title = u"Молоко Great Milk TWO 1L" reporter_name = "Jill" merchant_title = "Scotty's grocery" raw_data1 = { "product_title": product_title, "price_value": 42.6, "url": "http://scottys.com/products/milk/1", "merchant_title": merchant_title, "date_time": None, "reporter_name": reporter_name, } uuid_ = uuid4() report, stats = PriceReport.assemble(storage_manager=self.keeper, uuid=uuid_, **raw_data1) transaction.commit() self.keeper.close() self.keeper = open_storage() stored_report = PriceReport.fetch(report.key, self.keeper) self.assertEqual(report.key, stored_report.key) self.assertEqual(report.key, str(uuid_)) product = Product.fetch(product_title, self.keeper) self.assertEqual(product_title, product.title) self.assertIn(report, product.reports) category = ProductCategory.fetch("milk", self.keeper) self.assertIn(product, category.products) merchant = Merchant.fetch(merchant_title, self.keeper) self.assertEqual(merchant_title, merchant.title) self.assertIn(product, merchant)
def test_report_assembly_new_product(self): from uuid import uuid4 product_title = u'Молоко Great Milk TWO 1L' reporter_name = 'Jill' merchant_title = "Scotty's grocery" raw_data1 = { 'product_title': product_title, 'price_value': 42.6, 'url': 'http://scottys.com/products/milk/1', 'merchant_title': merchant_title, 'date_time': None, 'reporter_name': reporter_name } uuid_ = uuid4() report, stats = PriceReport.assemble(storage_manager=self.keeper, uuid=uuid_, **raw_data1) transaction.commit() self.keeper.close() self.keeper = open_storage() stored_report = PriceReport.fetch(report.key, self.keeper) self.assertEqual(report.key, stored_report.key) self.assertEqual(report.key, str(uuid_)) product = Product.fetch(product_title, self.keeper) self.assertEqual(product_title, product.title) self.assertIn(report, product.reports) category = ProductCategory.fetch('milk', self.keeper) self.assertIn(product, category.products) merchant = Merchant.fetch(merchant_title, self.keeper) self.assertEqual(merchant_title, merchant.title) self.assertIn(product, merchant)
def test_price_report_lifetime(self): milk = ProductCategory.fetch('milk', self.keeper) # add an outdated report PriceReport.assemble(price_value=15.40, product_title=u'Молоко Минувших дней 1л', reporter_name='John', merchant_title="Howie's grocery", url='http://someshop.com/item/345', date_time=MONTH_AGO, storage_manager=self.keeper) transaction.commit() self.assertEqual(50.75, milk.get_price()) # add a valid report PriceReport.assemble(price_value=10.22, product_title=u'Молоко Минувших дней 1л', reporter_name='John', merchant_title="Howie's grocery", url='http://someshop.com/item/349', date_time=HOUR_AGO, storage_manager=self.keeper) transaction.commit() self.assertEqual(45.9, milk.get_price()) self.assertEqual(15.40, milk.get_price(datetime.datetime.now() - datetime.timedelta(days=25))) self.assertIsNone(milk.get_price(datetime.datetime.now() - datetime.timedelta(days=45)))
def test_category_remove_product(self): self.category.add_product(self.product) transaction.commit() self.keeper.close() keeper = open_storage() milk = ProductCategory.fetch("milk", keeper) stored_product = Product.fetch(self.product.key, keeper) milk.remove_product(stored_product) transaction.commit() keeper.close() keeper = open_storage() stored_product = Product.fetch(self.product.key, keeper) milk = ProductCategory.fetch("milk", keeper) self.assertNotIn(stored_product, milk.products)
def setUp(self): try: shutil.rmtree(STORAGE_DIR) except OSError: pass os.mkdir(STORAGE_DIR) self.keeper = open_storage() category = ProductCategory('milk') product = Product(u'Молоко Great Milk 1L') merchant = Merchant('test merchant') self.keeper.register(category, product, merchant) transaction.commit() self.keeper.close() self.keeper = open_storage() self.category = ProductCategory.fetch('milk', self.keeper) self.product = Product.fetch(u'Молоко Great Milk 1L', self.keeper) self.merchant = Merchant.fetch('test merchant', self.keeper)
def test_remove_from_category(self): product = Product.fetch(u"Молоко Farmers Milk 1L", self.keeper) product.category.remove_product(product) transaction.commit() product = Product.fetch(u"Молоко Farmers Milk 1L", self.keeper) milk = ProductCategory.fetch("milk", self.keeper) self.assertIsNone(product.category) self.assertEqual(55.6, milk.get_price()) self.assertEqual(45.9, milk.get_price(cheap=True))
def test_remove_from_category(self): product = Product.fetch(u'Молоко Farmers Milk 1L', self.keeper) product.category.remove_product(product) transaction.commit() product = Product.fetch(u'Молоко Farmers Milk 1L', self.keeper) milk = ProductCategory.fetch('milk', self.keeper) self.assertIsNone(product.category) self.assertEqual(55.6, milk.get_price()) self.assertEqual(45.9, milk.get_price(cheap=True))
def test_product_category_median_ignore_irrelevant(self): raw_data1 = { 'product_title': u'Молоко Great Milk 0,5л', 'price_value': 32.6, 'url': 'http://scottys.com/products/milk/10', 'merchant_title': "Scotty's grocery", 'date_time': None, 'reporter_name': 'Jill' } PriceReport.assemble(storage_manager=self.keeper, **raw_data1) transaction.commit() milk = ProductCategory.fetch('milk', self.keeper) self.assertEqual(50.75, milk.get_price())
def test_product_category_median_ignore_irrelevant(self): raw_data1 = { "product_title": u"Молоко Great Milk 0,5л", "price_value": 32.6, "url": "http://scottys.com/products/milk/10", "merchant_title": "Scotty's grocery", "date_time": None, "reporter_name": "Jill", } PriceReport.assemble(storage_manager=self.keeper, **raw_data1) transaction.commit() milk = ProductCategory.fetch("milk", self.keeper) self.assertEqual(50.75, milk.get_price())
def test_presense_in_references(self): milk = ProductCategory.fetch("milk", self.keeper) diary = Category.fetch("diary", self.keeper) self.assertEqual("diary", diary.title) self.assertEqual(4, len(milk.products)) self.assertIn(64.3, milk.get_prices()) report1 = PriceReport.fetch(self.report1_key, self.keeper) self.assertEqual(55.6, report1.normalized_price_value) self.assertIs(milk, report1.product.category) self.assertEqual(u"Московский магазин", report1.merchant.title) self.assertEqual("Jack", report1.reporter.name) self.assertIs(diary, milk.category) self.assertIn(milk, diary.categories)
def test_presense_in_references(self): milk = ProductCategory.fetch('milk', self.keeper) diary = Category.fetch('diary', self.keeper) self.assertEqual('diary', diary.title) self.assertEqual(4, len(milk.products)) self.assertIn(64.3, milk.get_prices()) report1 = PriceReport.fetch(self.report1_key, self.keeper) self.assertEqual(55.6, report1.normalized_price_value) self.assertIs(milk, report1.product.category) self.assertEqual(u'Московский магазин', report1.merchant.title) self.assertEqual('Jack', report1.reporter.name) self.assertIs(diary, milk.category) self.assertIn(milk, diary.categories)
def test_category_add_product(self): milk = self.category product1 = Product(u"Молоко Great Milk 1L") product2 = Product(u"Молоко Greatest Milk 1L") milk.add_product(product1, product2) self.keeper.register(product1, product2) transaction.commit() self.keeper.close() self.keeper = open_storage() milk = ProductCategory.fetch("milk", self.keeper) stored_product1 = Product.fetch(u"Молоко Great Milk 1L", self.keeper) stored_product2 = Product.fetch(u"Молоко Greatest Milk 1L", self.keeper) self.assertIn(stored_product1, milk.products) self.assertIn(stored_product2, milk.products)
def test_qualified_products(self): milk = ProductCategory.fetch('milk', self.keeper) fancy_milk_title = u'Молоко The Luxury Milk!!! 0,5л' PriceReport.assemble(price_value=40, product_title=fancy_milk_title, url='http"//blah', merchant_title="Howie's grocery", reporter_name='John', storage_manager=self.keeper) transaction.commit() fancy_milk = Product.fetch(fancy_milk_title, self.keeper) qual_products = [p for p, pr in milk.get_qualified_products()] self.assertNotIn(fancy_milk, qual_products) self.assertEqual(4, len(qual_products))
def test_category_add_product(self): milk = self.category product1 = Product(u'Молоко Great Milk 1L') product2 = Product(u'Молоко Greatest Milk 1L') milk.add_product(product1, product2) self.keeper.register(product1, product2) transaction.commit() self.keeper.close() self.keeper = open_storage() milk = ProductCategory.fetch('milk', self.keeper) stored_product1 = Product.fetch(u'Молоко Great Milk 1L', self.keeper) stored_product2 = Product.fetch(u'Молоко Greatest Milk 1L', self.keeper) self.assertIn(stored_product1, milk.products) self.assertIn(stored_product2, milk.products)
def stats(category_key, days=2): """Show daily statistics for a category""" from prettytable import PrettyTable table = PrettyTable(['date/time', 'report #', 'product #', 'median', 'min', 'max']) table.align = 'l' dates = get_datetimes(days) keeper = StorageManager(FileStorage('storage.fs')) category = ProductCategory.fetch(category_key, keeper) print(table) for date in dates: table.add_row([str(date), len(category.get_reports(date)), len(category.products), category.get_price(date), category.get_price(cheap=True), max(category.get_prices(date))])
def test_qualified_products(self): milk = ProductCategory.fetch("milk", self.keeper) fancy_milk_title = u"Молоко The Luxury Milk!!! 0,5л" PriceReport.assemble( price_value=40, product_title=fancy_milk_title, url='http"//blah', merchant_title="Howie's grocery", reporter_name="John", storage_manager=self.keeper, ) transaction.commit() fancy_milk = Product.fetch(fancy_milk_title, self.keeper) qual_products = [p for p, pr in milk.get_qualified_products()] self.assertNotIn(fancy_milk, qual_products) self.assertEqual(4, len(qual_products))
def setUp(self): try: shutil.rmtree(STORAGE_DIR) except OSError: pass os.mkdir(STORAGE_DIR) self.keeper = open_storage() category = ProductCategory("milk") product = Product(u"Молоко Great Milk 1L") merchant = Merchant("test merchant") self.keeper.register(category, product, merchant) transaction.commit() self.keeper.close() self.keeper = open_storage() self.category = ProductCategory.fetch("milk", self.keeper) self.product = Product.fetch(u"Молоко Great Milk 1L", self.keeper) self.merchant = Merchant.fetch("test merchant", self.keeper)
def display_category(category_key): """Display category data in table""" from prettytable import PrettyTable table = PrettyTable(['product', 'N', 'O', 'pack.']) table.align = 'l' keeper = get_storage() category = ProductCategory.fetch(category_key, keeper) min_package_ratio = category.get_data('min_package_ratio') products = category.products.values() if min_package_ratio: try: products = [product for product in products if product.get_package().get_ratio(category) >= float(min_package_ratio)] except PackageLookupError, e: print(e.message)
def stats(category_key, days=2): """Show daily statistics for a category""" from prettytable import PrettyTable table = PrettyTable( ['date/time', 'report #', 'product #', 'median', 'min', 'max']) table.align = 'l' dates = get_datetimes(days) keeper = StorageManager(FileStorage('storage.fs')) category = ProductCategory.fetch(category_key, keeper) print(table) for date in dates: table.add_row([ str(date), len(category.get_reports(date)), len(category.products), category.get_price(date), category.get_price(cheap=True), max(category.get_prices(date)) ])
def display_category(category_key): """Display category data in table""" from prettytable import PrettyTable table = PrettyTable(['product', 'N', 'O', 'pack.']) table.align = 'l' keeper = get_storage() category = ProductCategory.fetch(category_key, keeper) min_package_ratio = category.get_data('min_package_ratio') products = category.products.values() if min_package_ratio: try: products = [ product for product in products if product.get_package().get_ratio(category) >= float( min_package_ratio) ] except PackageLookupError, e: print(e.message)
def test_price_from_past_date(self): milk = ProductCategory.fetch("milk", self.keeper) cheapest_milk_title = u"Молоко The Cheapest Milk!!! 1л" PriceReport.assemble( price_value=30.10, product_title=cheapest_milk_title, reporter_name="John", merchant_title="Howie's grocery", url="http://someshop.com/item/344", date_time=HOUR_AGO, storage_manager=self.keeper, ) PriceReport.assemble( price_value=29.10, product_title=cheapest_milk_title, reporter_name="John", merchant_title="Howie's grocery", url="http://someshop.com/item/344", date_time=WEEK_AGO, storage_manager=self.keeper, ) PriceReport.assemble( price_value=25.22, product_title=cheapest_milk_title, reporter_name="John", merchant_title="Howie's grocery", url="http://someshop.com/item/344", date_time=MONTH_AGO, storage_manager=self.keeper, ) transaction.commit() cheapest_milk = Product.fetch(cheapest_milk_title, self.keeper) self.assertEqual(30.10, cheapest_milk.get_price()) self.assertEqual(1, cheapest_milk.get_price_delta(DAY_AGO, relative=False)) self.assertEqual(0.034364261168384876, cheapest_milk.get_price_delta(DAY_AGO)) self.assertEqual(30.10, min(milk.get_prices())) self.assertEqual(45.9, milk.get_price()) self.assertEqual(0.5773195876288658, milk.get_price_delta(DAY_AGO))
def test_report_assembly_stored_product(self): product_title = u'Молоко Great Milk three 1L' product = Product(product_title, self.category) self.keeper.register(product) transaction.commit() self.keeper.close() self.keeper = open_storage() reporter_name = 'Jill' merchant_title = "Scotty's grocery 2" raw_data1 = { 'product_title': product_title, 'price_value': 42.6, 'url': 'http://scottys2.com/products/milk/1', 'merchant_title': merchant_title, 'date_time': None, 'reporter_name': reporter_name } report, stats = PriceReport.assemble(self.keeper, **raw_data1) transaction.commit() self.keeper.close() self.keeper = open_storage() stored_report = PriceReport.fetch(report.key, self.keeper) self.assertEqual(report.key, stored_report.key) product = Product.fetch(product_title, self.keeper) self.assertEqual(product_title, product.title) self.assertIn(report, product) category = ProductCategory.fetch('milk', self.keeper) self.assertIn(product, category) merchant = Merchant.fetch(merchant_title, self.keeper) self.assertEqual(merchant_title, merchant.title) self.assertIn(product, merchant) self.assertIn(merchant, product.merchants)
def test_report_assembly_stored_product(self): product_title = u"Молоко Great Milk three 1L" product = Product(product_title, self.category) self.keeper.register(product) transaction.commit() self.keeper.close() self.keeper = open_storage() reporter_name = "Jill" merchant_title = "Scotty's grocery 2" raw_data1 = { "product_title": product_title, "price_value": 42.6, "url": "http://scottys2.com/products/milk/1", "merchant_title": merchant_title, "date_time": None, "reporter_name": reporter_name, } report, stats = PriceReport.assemble(self.keeper, **raw_data1) transaction.commit() self.keeper.close() self.keeper = open_storage() stored_report = PriceReport.fetch(report.key, self.keeper) self.assertEqual(report.key, stored_report.key) product = Product.fetch(product_title, self.keeper) self.assertEqual(product_title, product.title) self.assertIn(report, product) category = ProductCategory.fetch("milk", self.keeper) self.assertIn(product, category) merchant = Merchant.fetch(merchant_title, self.keeper) self.assertEqual(merchant_title, merchant.title) self.assertIn(product, merchant) self.assertIn(merchant, product.merchants)
def test_price_from_past_date(self): milk = ProductCategory.fetch('milk', self.keeper) cheapest_milk_title = u'Молоко The Cheapest Milk!!! 1л' PriceReport.assemble(price_value=30.10, product_title=cheapest_milk_title, reporter_name='John', merchant_title="Howie's grocery", url='http://someshop.com/item/344', date_time=HOUR_AGO, storage_manager=self.keeper) PriceReport.assemble(price_value=29.10, product_title=cheapest_milk_title, reporter_name='John', merchant_title="Howie's grocery", url='http://someshop.com/item/344', date_time=WEEK_AGO, storage_manager=self.keeper) PriceReport.assemble(price_value=25.22, product_title=cheapest_milk_title, reporter_name='John', merchant_title="Howie's grocery", url='http://someshop.com/item/344', date_time=MONTH_AGO, storage_manager=self.keeper) transaction.commit() cheapest_milk = Product.fetch(cheapest_milk_title, self.keeper) self.assertEqual(30.10, cheapest_milk.get_price()) self.assertEqual(1, cheapest_milk.get_price_delta(DAY_AGO, relative=False)) self.assertEqual(0.034364261168384876, cheapest_milk.get_price_delta(DAY_AGO)) self.assertEqual(30.10, min(milk.get_prices())) self.assertEqual(45.9, milk.get_price()) self.assertEqual(0.5773195876288658, milk.get_price_delta(DAY_AGO))
def test_representation(self): milk = ProductCategory.fetch('milk', self.keeper) self.assertIn(u"55.6-Молоко Красная Цена у/паст. 3.2% 1л" u"-Московский магазин-" u"Москва-Jack", [unicode(r) for r in milk.get_reports()])
def test_report_assembly(self): raw_data1 = { 'product_title': u'Молоко Great Milk 1L', 'sku': 'ART97665', 'price_value': 42.6, 'url': 'http://scottys.com/products/milk/1', 'merchant_title': "Scotty's grocery", 'date_time': None, 'reporter_name': 'Jill' } raw_data2 = { 'product_title': u'Молоко Great Milk 0.93 L', 'price_value': 50, 'url': 'http://scottys.com/products/milk/5', 'merchant_title': "Scotty's grocery", 'date_time': None, 'reporter_name': 'Jill' } raw_data3 = { 'product_title': u'Сметана Great Sour Cream 450g', 'price_value': 60.4, 'url': 'http://scottys.com/products/sc/6', 'merchant_title': "Scotty's grocery", 'date_time': datetime.datetime(2014, 10, 5), 'reporter_name': 'Jill' } raw_data4 = { 'product_title': u'Сметана Great Sour Cream 987987g', 'price_value': 60.4, 'url': 'http://scottys.com/products/sc/8978', 'merchant_title': "Scotty's grocery", 'date_time': datetime.datetime(2014, 10, 5), 'reporter_name': 'Jill' } raw_data5 = { 'product_title': u'Картофель Вегетория для варки 3кг', 'price_value': 80.5, 'url': 'http://scottys.com/products/pot/324', 'merchant_title': "Scotty's grocery", 'reporter_name': 'Jill' } report1, stats1 = PriceReport.assemble(storage_manager=self.keeper, **raw_data1) report2, stats2 = PriceReport.assemble(storage_manager=self.keeper, **raw_data2) report3, stats3 = PriceReport.assemble(storage_manager=self.keeper, **raw_data3) report5, stats5 = PriceReport.assemble(storage_manager=self.keeper, **raw_data5) try: PriceReport.assemble(storage_manager=self.keeper, **raw_data4) except PackageLookupError: pass transaction.commit() # check category and products milk = ProductCategory.fetch('milk', self.keeper) sc = ProductCategory.fetch('sour cream', self.keeper) self.assertEqual(6, len(milk.products)) self.assertIn(42.6, milk.get_prices()) product1 = Product.fetch(u'Молоко Great Milk 1L', self.keeper) product2 = Product.fetch(u'Молоко Great Milk 0.93 L', self.keeper) self.assertIs(milk, product1.category) self.assertEqual('1 l', product1.package.title) self.assertEqual('ART97665', report1.sku) self.assertEqual('0.93 l', product2.package.title) self.assertEqual(1, product1.package_ratio) self.assertEqual(0.93, product2.package_ratio) self.assertFalse(hasattr(report2, 'sku')) self.assertIn(product1, milk.products) self.assertEqual('sour cream', report3.product.category.title) self.assertIn(u'Сметана Great Sour Cream 450g', [p.title for p in sc.products]) self.assertNotIn(u'Сметана Great Sour Cream 987987g', [p.title for p in sc.products]) # check references potato = ProductCategory.fetch('potato', self.keeper) self.assertIn(report5, PriceReport.fetch_all(self.keeper)) self.assertIn(report5, potato.products[0].reports) self.assertIn(report5, Product.fetch(u'Картофель Вегетория для варки 3кг', self.keeper).reports) # check reporter jill = Reporter.fetch('Jill', self.keeper) self.assertIs(jill, report1.reporter) self.assertIs(jill, report2.reporter) self.assertIs(jill, report3.reporter) # check price calculations self.assertEqual(42.60, round(report1.normalized_price_value, 2)) self.assertEqual(53.76, round(report2.normalized_price_value, 2)) self.assertEqual(53.69, round(report3.normalized_price_value, 2)) # check merchant merchant = Merchant.fetch("Scotty's grocery", self.keeper) self.assertIs(merchant, report1.merchant) self.assertIn(merchant, product1.merchants) self.assertIn(product1, merchant) # check datetime that is not now date_in_past = datetime.datetime(2014, 10, 5) self.assertEqual(date_in_past, report3.date_time) # check if no false product is registered false_product = Product.fetch(u'Сметана Great Sour Cream 987987g', self.keeper) self.assertIsNone(false_product)
def test_product_category_get_locations(self): milk = ProductCategory.fetch('milk', self.keeper) self.assertIn(u'Москва', milk.get_locations()) self.assertIn(u'Санкт-Петербург', milk.get_locations())
def cycle(entity_class_name_, keeper): """Perform all needed routines on an `entity_class`""" print(cyan('{} check...'.format(entity_class_name_))) entity_class = globals()[entity_class_name_] instances = entity_class.fetch_all(keeper, objects_only=False) for key in instances.keys(): instance = instances[key] if entity_class is ProductCategory: if not hasattr(instance, 'category') or not instance.category: category_key = instance.get_category_key() category = Category.acquire(category_key, keeper) instance.category = category category.add(instance) print(green(u'Added {} to {}'.format(instance, category))) for product in instance.products: if product.category is not instance: instance.remove_product(product) print( yellow(u'Removed ' u'`{}` from `{}`...'.format( product, instance))) if len(product.reports) == 0: instance.remove_product(product) print( yellow(u'Removed stale ' u'`{}` from `{}`...'.format( product, instance))) if product.key not in keeper[product.namespace]: try: instance.remove_product(product) print( yellow(u'Removed `{}` from `{}` ' u'as its not ' u'registered...'.format( product, instance))) except ValueError: pass if entity_class is Product: if type(instance.reports) is not list: print( yellow(u'Fixing product report ' u'list for `{}`...'.format(instance))) instance.reports = list(instance.reports.values()) if type(instance.merchants) is not list: print( yellow(u'Fixing product merchant ' u'list for `{}`...'.format(instance))) instance.merchants = list(instance.merchants.values()) if len(instance.reports) == 0: print(yellow(u'Removing stale `{}`...'.format(instance))) instance.delete_from(keeper) # check category try: cat_key = instance.get_category_key() category = ProductCategory.fetch(cat_key, keeper) if instance.category is not category: print( yellow(u'Adding `{}` to ' u'`{}`...'.format(instance, category))) category.add_product(instance) instance.category = category except CategoryLookupError: print( yellow(u'Removing `{}` as no ' u'category found...'.format(instance))) instance.delete_from(keeper) # check key if key != instance.key: print(yellow(u'Fixing key for `{}`...'.format(key))) keeper.register(instance) keeper.delete_key(instance.namespace, key) if entity_class is Merchant: if type(instance.products) is not list: instance.products = list(instance.products.values()) for product in instance.products: if len(product.reports) == 0: print( yellow(u'Deleting `{}` ' u'from `{}`...'.format(product, instance))) instance.remove_product(product) for report in product.reports: if type(report) is str: print( yellow('Removing product with str report ...')) product.delete_from(keeper) if entity_class is PriceReport: if instance.product.category is None: print( yellow(u'Removing report ' u'for {}'.format(instance.product))) instance.delete_from(keeper) break try: correct_package_key = instance.product.get_package_key() except PackageLookupError, e: print(e.message) else: if instance.product.package.key != correct_package_key: correct_package = ProductPackage.acquire( correct_package_key, keeper) product = Product.fetch(instance.product.key, keeper) print( yellow(u'Fixing package for {}: {}-->{}'.format( instance.product, product.package, correct_package))) product.package = correct_package instance.product = product old_norm_price = instance.normalized_price_value correct_norm_price = instance._get_normalized_price( instance.price_value) if old_norm_price != correct_norm_price: print( yellow(u'Fixing normal price ' u'for {} report ({}-->{})'.format( instance.product, old_norm_price, correct_norm_price))) instance.normalized_price_value = correct_norm_price
def test_product_category_median_location(self): milk = ProductCategory.fetch('milk', self.keeper) self.assertEqual(45.9, milk.get_price(location=u'Санкт-Петербург')) self.assertEqual(55.6, milk.get_price(location=u'Москва'))
def test_20pieces(self): egg = ProductCategory('chicken egg') product4_title = u'Яйцо динозавриное столовое, 20шт' self.assertEqual(2, Product(product4_title).get_package().get_ratio(egg))
def test_representation(self): milk = ProductCategory.fetch("milk", self.keeper) self.assertIn( u"55.6-Молоко Красная Цена у/паст. 3.2% 1л" u"-Московский магазин-" u"Москва-Jack", [unicode(r) for r in milk.get_reports()], )
def test_product_category_get_data(self): milk = ProductCategory("milk") self.assertEqual(1, milk.get_data("priority")) asp = ProductCategory("asparagus") self.assertEqual(0, asp.get_data("priority", default=0))
def test_traverse_yaml(self): milk = ProductCategory('milk') self.assertEqual(u'молоко', milk.get_data('keyword').split(', ')[0]) self.assertEqual('diary', milk.get_category_key()) tuna = ProductCategory('tuna') self.assertEqual('fish', tuna.get_category_key()) chair = ProductCategory('chair') self.assertEqual('furniture', chair.get_category_key()) food = ProductCategory('food') self.assertEqual('product_categories', food.get_category_key()) root = ProductCategory('product_categories') self.assertIsNone(root.get_category_key())
def test_report_assembly(self): raw_data1 = { "product_title": u"Молоко Great Milk 1L", "sku": "ART97665", "price_value": 42.6, "url": "http://scottys.com/products/milk/1", "merchant_title": "Scotty's grocery", "date_time": None, "reporter_name": "Jill", } raw_data2 = { "product_title": u"Молоко Great Milk 0.93 L", "price_value": 50, "url": "http://scottys.com/products/milk/5", "merchant_title": "Scotty's grocery", "date_time": None, "reporter_name": "Jill", } raw_data3 = { "product_title": u"Сметана Great Sour Cream 450g", "price_value": 60.4, "url": "http://scottys.com/products/sc/6", "merchant_title": "Scotty's grocery", "date_time": datetime.datetime(2014, 10, 5), "reporter_name": "Jill", } raw_data4 = { "product_title": u"Сметана Great Sour Cream 987987g", "price_value": 60.4, "url": "http://scottys.com/products/sc/8978", "merchant_title": "Scotty's grocery", "date_time": datetime.datetime(2014, 10, 5), "reporter_name": "Jill", } raw_data5 = { "product_title": u"Картофель Вегетория для варки 3кг", "price_value": 80.5, "url": "http://scottys.com/products/pot/324", "merchant_title": "Scotty's grocery", "reporter_name": "Jill", } report1, stats1 = PriceReport.assemble(storage_manager=self.keeper, **raw_data1) report2, stats2 = PriceReport.assemble(storage_manager=self.keeper, **raw_data2) report3, stats3 = PriceReport.assemble(storage_manager=self.keeper, **raw_data3) report5, stats5 = PriceReport.assemble(storage_manager=self.keeper, **raw_data5) try: PriceReport.assemble(storage_manager=self.keeper, **raw_data4) except PackageLookupError: pass transaction.commit() # check category and products milk = ProductCategory.fetch("milk", self.keeper) sc = ProductCategory.fetch("sour cream", self.keeper) self.assertEqual(6, len(milk.products)) self.assertIn(42.6, milk.get_prices()) product1 = Product.fetch(u"Молоко Great Milk 1L", self.keeper) product2 = Product.fetch(u"Молоко Great Milk 0.93 L", self.keeper) self.assertIs(milk, product1.category) self.assertEqual("1 l", product1.package.title) self.assertEqual("ART97665", report1.sku) self.assertEqual("0.93 l", product2.package.title) self.assertEqual(1, product1.package_ratio) self.assertEqual(0.93, product2.package_ratio) self.assertFalse(hasattr(report2, "sku")) self.assertIn(product1, milk.products) self.assertEqual("sour cream", report3.product.category.title) self.assertIn(u"Сметана Great Sour Cream 450g", [p.title for p in sc.products]) self.assertNotIn(u"Сметана Great Sour Cream 987987g", [p.title for p in sc.products]) # check references potato = ProductCategory.fetch("potato", self.keeper) self.assertIn(report5, PriceReport.fetch_all(self.keeper)) self.assertIn(report5, potato.products[0].reports) self.assertIn(report5, Product.fetch(u"Картофель Вегетория для варки 3кг", self.keeper).reports) # check reporter jill = Reporter.fetch("Jill", self.keeper) self.assertIs(jill, report1.reporter) self.assertIs(jill, report2.reporter) self.assertIs(jill, report3.reporter) # check price calculations self.assertEqual(42.60, round(report1.normalized_price_value, 2)) self.assertEqual(53.76, round(report2.normalized_price_value, 2)) self.assertEqual(53.69, round(report3.normalized_price_value, 2)) # check merchant merchant = Merchant.fetch("Scotty's grocery", self.keeper) self.assertIs(merchant, report1.merchant) self.assertIn(merchant, product1.merchants) self.assertIn(product1, merchant) # check datetime that is not now date_in_past = datetime.datetime(2014, 10, 5) self.assertEqual(date_in_past, report3.date_time) # check if no false product is registered false_product = Product.fetch(u"Сметана Great Sour Cream 987987g", self.keeper) self.assertIsNone(false_product)
def test_product_category_median(self): milk = ProductCategory.fetch("milk", self.keeper) self.assertEqual(50.75, milk.get_price())
def test_traverse_yaml(self): milk = ProductCategory("milk") self.assertEqual(u"молоко", milk.get_data("keyword").split(", ")[0]) self.assertEqual("diary", milk.get_category_key()) tuna = ProductCategory("tuna") self.assertEqual("fish", tuna.get_category_key()) chair = ProductCategory("chair") self.assertEqual("furniture", chair.get_category_key()) food = ProductCategory("food") self.assertEqual("product_categories", food.get_category_key()) root = ProductCategory("product_categories") self.assertIsNone(root.get_category_key())
def cycle(entity_class_name_, keeper): """Perform all needed routines on an `entity_class`""" print(cyan('{} check...'.format(entity_class_name_))) entity_class = globals()[entity_class_name_] instances = entity_class.fetch_all(keeper, objects_only=False) for key in instances.keys(): instance = instances[key] if entity_class is ProductCategory: if not hasattr(instance, 'category') or not instance.category: category_key = instance.get_category_key() category = Category.acquire(category_key, keeper) instance.category = category category.add(instance) print(green(u'Added {} to {}'.format(instance, category))) for product in instance.products: if product.category is not instance: instance.remove_product(product) print(yellow(u'Removed ' u'`{}` from `{}`...'.format(product, instance))) if len(product.reports) == 0: instance.remove_product(product) print(yellow(u'Removed stale ' u'`{}` from `{}`...'.format(product, instance))) if product.key not in keeper[product.namespace]: try: instance.remove_product(product) print(yellow(u'Removed `{}` from `{}` ' u'as its not ' u'registered...'.format(product, instance))) except ValueError: pass if entity_class is Product: if type(instance.reports) is not list: print(yellow(u'Fixing product report ' u'list for `{}`...'.format(instance))) instance.reports = list(instance.reports.values()) if type(instance.merchants) is not list: print(yellow(u'Fixing product merchant ' u'list for `{}`...'.format(instance))) instance.merchants = list(instance.merchants.values()) if len(instance.reports) == 0: print(yellow(u'Removing stale `{}`...'.format(instance))) instance.delete_from(keeper) # check category try: cat_key = instance.get_category_key() category = ProductCategory.fetch(cat_key, keeper) if instance.category is not category: print(yellow(u'Adding `{}` to ' u'`{}`...'.format(instance, category))) category.add_product(instance) instance.category = category except CategoryLookupError: print(yellow(u'Removing `{}` as no ' u'category found...'.format(instance))) instance.delete_from(keeper) # check key if key != instance.key: print(yellow(u'Fixing key for `{}`...'.format(key))) keeper.register(instance) keeper.delete_key(instance.namespace, key) if entity_class is Merchant: if type(instance.products) is not list: instance.products = list(instance.products.values()) for product in instance.products: if len(product.reports) == 0: print(yellow(u'Deleting `{}` ' u'from `{}`...'.format(product, instance))) instance.remove_product(product) for report in product.reports: if type(report) is str: print(yellow('Removing product with str report ...')) product.delete_from(keeper) if entity_class is PriceReport: if instance.product.category is None: print(yellow(u'Removing report ' u'for {}'.format(instance.product))) instance.delete_from(keeper) break try: correct_package_key = instance.product.get_package_key() except PackageLookupError, e: print(e.message) else: if instance.product.package.key != correct_package_key: correct_package = ProductPackage.acquire( correct_package_key, keeper) product = Product.fetch(instance.product.key, keeper) print(yellow(u'Fixing package for {}: {}-->{}'.format( instance.product, product.package, correct_package))) product.package = correct_package instance.product = product old_norm_price = instance.normalized_price_value correct_norm_price = instance._get_normalized_price( instance.price_value) if old_norm_price != correct_norm_price: print(yellow( u'Fixing normal price ' u'for {} report ({}-->{})'.format( instance.product, old_norm_price, correct_norm_price))) instance.normalized_price_value = correct_norm_price
def test_product_category_median_location(self): milk = ProductCategory.fetch("milk", self.keeper) self.assertEqual(45.9, milk.get_price(location=u"Санкт-Петербург")) self.assertEqual(55.6, milk.get_price(location=u"Москва"))
def test_product_category_median(self): milk = ProductCategory.fetch('milk', self.keeper) self.assertEqual(50.75, milk.get_price())
def test_product_category_get_data(self): milk = ProductCategory('milk') self.assertEqual(1, milk.get_data('priority')) asp = ProductCategory('asparagus') self.assertEqual(0, asp.get_data('priority', default=0))
def setUp(self): self.milk = ProductCategory('milk')
def test_1_5kg(self): category = ProductCategory('rice') product = Product(u'Рис АГРОАЛЬЯНС краснодарский 1,5кг', category=category) self.assertEqual('1.5 kg', product.get_package_key())
def test_product_category_get_locations(self): milk = ProductCategory.fetch("milk", self.keeper) self.assertIn(u"Москва", milk.get_locations()) self.assertIn(u"Санкт-Петербург", milk.get_locations())