Пример #1
0
    def start(self):
        while True:
            menu_items = [
                "Update stock prices", "Update price for a card",
                "List competition for a card",
                "Show top 20 expensive items in stock", "Show account info",
                "Clear entire stock (WARNING)", "Import stock from .\list.csv"
            ]
            self.print_menu(menu_items, f"PyMKM {__version__}")

            choice = input("Action number: ")

            try:
                if choice == "1":
                    self.update_stock_prices_to_trend(api=self.api)

                elif choice == "2":
                    search_string = PyMkmHelper.prompt_string(
                        'Search card name')
                    self.update_product_to_trend(search_string, api=self.api)

                elif choice == "3":
                    is_foil = False
                    search_string = PyMkmHelper.prompt_string(
                        'Search card name')
                    if PyMkmHelper.prompt_bool("Foil?") == True:
                        is_foil = True

                    self.list_competition_for_product(search_string,
                                                      is_foil,
                                                      api=self.api)

                elif choice == "4":
                    self.show_top_expensive_articles_in_stock(20, api=self.api)

                elif choice == "5":
                    self.show_account_info(api=self.api)

                elif choice == "6":
                    self.clear_entire_stock(api=self.api)

                elif choice == "7":
                    self.import_from_csv(api=self.api)

                elif choice == "0":
                    break
                else:
                    print("Not a valid choice, try again.")
            except ConnectionError as err:
                print(err)
Пример #2
0
    def list_competition_for_product(self, api):
        self.report("list competition for product")

        search_string = PyMkmHelper.prompt_string('Search card name')
        is_foil = PyMkmHelper.prompt_bool("Foil?")

        result = api.find_product(search_string, **{
            # 'exact ': 'true',
            'idGame': 1,
            'idLanguage': 1,
            # TODO: Add Partial Content support
            # TODO: Add language support
        })

        if (result):
            products = result['product']

            stock_list_products = [x['idProduct']
                                   for x in self.get_stock_as_array(api=self.api)]
            products = [x for x in products if x['idProduct']
                        in stock_list_products]

            if len(products) == 0:
                print('No matching cards in stock.')
            else:
                if len(products) > 1:
                    product = self.select_from_list_of_products(
                        [i for i in products if i['categoryName'] == 'Magic Single'])
                elif len(products) == 1:
                    product = products[0]

                self.show_competition_for_product(
                    product['idProduct'], product['enName'], is_foil, api=self.api)
        else:
            print('No results found.')
Пример #3
0
class TestPyMkmHelperFunctions(unittest.TestCase):
    def setUp(self):
        self.helper = PyMkmHelper()

    def test_calculate_average(self):
        table = [['Yxskaft', 'SE', 'NM', 1, 1.21],
                 ['Frazze11', 'SE', 'NM', 3, 1.3],
                 ['andli826', 'SE', 'NM', 2, 1.82]]
        self.assertEqual(self.helper.calculate_average(table, 3, 4), 1.46)

    def test_calculate_median(self):
        table = [['Yxskaft', 'SE', 'NM', 1, 1.21],
                 ['Frazze11', 'SE', 'NM', 3, 1.3],
                 ['andli826', 'SE', 'NM', 2, 1.82]]
        self.assertEqual(self.helper.calculate_median(table, 3, 4), 1.3)
        self.assertEqual(self.helper.calculate_average(table, 3, 4), 1.46)

    def test_calculate_lowest(self):
        table = [['Yxskaft', 'SE', 'NM', 1, 1.21],
                 ['Frazze11', 'SE', 'NM', 3, 1.3],
                 ['andli826', 'SE', 'NM', 2, 1.82]]
        self.assertEqual(self.helper.calculate_lowest(table, 4), 1.21)

    def test_round_up_to_limit(self):
        self.assertEqual(self.helper.round_up_to_limit(0.25, 0.99), 1)
        self.assertEqual(self.helper.round_up_to_limit(0.25, 0), 0)
        self.assertEqual(self.helper.round_up_to_limit(0.25, 0.1), 0.25)

        self.assertEqual(self.helper.round_up_to_limit(0.1, 0.99), 1)
        self.assertEqual(self.helper.round_up_to_limit(0.01, 0.011), 0.02)
        self.assertEqual(self.helper.round_up_to_limit(0.01, 1), 1)
        self.assertEqual(self.helper.round_up_to_limit(1, 0.1), 1)

    def test_round_down_to_limit(self):
        self.assertEqual(self.helper.round_down_to_limit(0.25, 0.99), 0.75)
        self.assertEqual(self.helper.round_down_to_limit(0.25, 1.01), 1)
        self.assertEqual(self.helper.round_down_to_limit(0.25, 0.1), 0)

        self.assertEqual(self.helper.round_down_to_limit(0.1, 0.99), 0.9)
        self.assertEqual(self.helper.round_down_to_limit(0.01, 0.011), 0.01)
        self.assertEqual(self.helper.round_down_to_limit(0.01, 1), 1)
        self.assertEqual(self.helper.round_down_to_limit(1, 0.1), 0)

    @patch('sys.stdout', new_callable=io.StringIO)
    @patch('builtins.input', side_effect=['y', 'n', 'p', 'n'])
    def test_prompt_bool(self, mock_input, mock_stdout):
        self.assertTrue(self.helper.prompt_bool('test_y'))
        self.assertFalse(self.helper.prompt_bool('test_n'))
        self.helper.prompt_bool('test_error')
        self.assertRegex(mock_stdout.getvalue(),
                         r'\nPlease answer with y\/n\n')

    @patch('builtins.input', side_effect=['y'])
    def test_prompt_string(self, mock_input):
        self.assertEqual(self.helper.prompt_string('test'), 'y')
Пример #4
0
    def update_product_to_trend(self, api):
        ''' This function updates one product in the user's stock to TREND. '''
        self.report("update product price to trend")

        search_string = PyMkmHelper.prompt_string('Search product name')

        try:
            articles = api.find_stock_article(search_string, 1)
        except Exception as err:
            print(err)

        if len(articles) > 1:
            article = self.select_from_list_of_articles(articles)
        else:
            article = articles[0]
            found_string = f"Found: {article['product']['enName']}"
            if article['product'].get('expansion'):
                found_string += f"[{article['product'].get('expansion')}]."
            else:
                found_string += '.'
            print(found_string)

        undercut_local_market = PyMkmHelper.prompt_bool(
            'Try to undercut local market? (slower, more requests)')

        r = self.get_article_with_updated_price(article,
                                                undercut_local_market,
                                                api=self.api)

        if r:
            self.draw_price_changes_table([r])

            print('\nTotal price difference: {}.'.format(
                str(
                    round(
                        sum(item['price_diff'] * item['count']
                            for item in [r]), 2))))

            if PyMkmHelper.prompt_bool(
                    "Do you want to update these prices?") == True:
                # Update articles on MKM
                print('Updating prices...')
                api.set_stock([r])
                print('Price updated.')
            else:
                print('Prices not updated.')
        else:
            print('No prices to update.')
Пример #5
0
    def find_deals_from_user(self, api):
        self.report("find deals from user")

        search_string = PyMkmHelper.prompt_string('Enter username')

        try:
            result = api.find_user_articles(search_string)
        except NoResultsError as err:
            print(err.mkm_msg())
        else:

            if (result):
                filtered_articles = [
                    x for x in result
                    if x.get('condition') in PyMkmApi.conditions[:3]
                ]  # EX+
                sorted_articles = sorted(result,
                                         key=lambda x: x['price'],
                                         reverse=True)
                print(
                    f"User '{search_string}' has {len(sorted_articles)} articles in stock."
                )
                num_searches = int(
                    PyMkmHelper.prompt_string(
                        f'Searching top X expensive cards (EX+) for deals, choose X (1-{len(sorted_articles)})'
                    ))
                if num_searches > 1 and num_searches <= len(sorted_articles):
                    table_data = []

                    index = 0
                    bar = progressbar.ProgressBar(max_value=num_searches)
                    for article in sorted_articles[:num_searches]:
                        p = api.get_product(article['idProduct'])
                        name = p['product']['enName']
                        expansion = p['product']['expansion']['enName']
                        condition = article.get('condition')
                        language = article['language']['languageName']
                        foil = article['isFoil']
                        price = float(article['price'])
                        if foil:
                            market_price = p['product']['priceGuide'][
                                'TRENDFOIL']
                        else:
                            market_price = p['product']['priceGuide']['TREND']
                        price_diff = price - market_price
                        if price_diff < 0:
                            table_data.append([
                                name, expansion, condition, language,
                                u'\u2713' if foil else '', price, market_price,
                                price_diff
                            ])
                        index += 1
                        bar.update(index)
                    bar.finish()

                    if table_data:
                        print('Found some interesting prices:')
                        print(
                            tb.tabulate(sorted(table_data,
                                               key=lambda x: x[5],
                                               reverse=True),
                                        headers=[
                                            'Name', 'Expansion', 'Condition',
                                            'Language', 'Foil?', 'Price',
                                            'Market price', 'Market diff'
                                        ],
                                        tablefmt="simple"))
                    else:
                        print('Found no deals. :(')
                else:
                    print("Invalid number.")
            else:
                print('No results found.')
Пример #6
0
    def find_deals_from_user(self, api):
        self.report("find deals from user")

        search_string = PyMkmHelper.prompt_string('Enter username')

        try:
            result = api.find_user_articles(search_string)
        except NoResultsError as err:
            print(err.mkm_msg())
        else:

            if (result):
                # [x for x in result if x.get('condition') in PyMkmApi.conditions[:3]]  # EX+
                filtered_articles = result
                # price > 1
                filtered_articles = [x for x in result if x.get('price') > 1]

                sorted_articles = sorted(filtered_articles,
                                         key=lambda x: x['price'],
                                         reverse=True)
                print(
                    f"User '{search_string}' has {len(sorted_articles)} articles that meet the criteria."
                )
                num_searches = int(
                    PyMkmHelper.prompt_string(
                        f'Searching top X expensive cards for deals, choose X (1-{len(sorted_articles)})'
                    ))
                if num_searches > 1 and num_searches <= len(sorted_articles):
                    table_data = []

                    index = 0
                    bar = progressbar.ProgressBar(max_value=num_searches)
                    for article in sorted_articles[:num_searches]:
                        condition = article.get('condition')
                        language = article.get('language').get('languageName')
                        foil = article.get('isFoil')
                        playset = article.get('isPlayset')
                        price = float(article['price'])

                        p = api.get_product(article['idProduct'])
                        name = p['product']['enName']
                        expansion = p['product'].get('expansion')
                        if expansion:
                            expansion_name = expansion.get('enName')
                        else:
                            expansion_name = 'N/A'
                        if foil:
                            market_price = p['product']['priceGuide'][
                                'TRENDFOIL']
                        else:
                            market_price = p['product']['priceGuide']['TREND']
                        price_diff = price - market_price
                        percent_deal = round(-100 *
                                             (price_diff / market_price))
                        if price_diff < -1 or percent_deal >= 10:
                            table_data.append([
                                name, expansion_name, condition, language,
                                u'\u2713' if foil else '',
                                u'\u2713' if playset else '', price,
                                market_price, price_diff, percent_deal
                            ])

                        index += 1
                        bar.update(index)
                    bar.finish()

                    if table_data:
                        print('Found some interesting prices:')
                        print(
                            tb.tabulate(sorted(table_data,
                                               key=lambda x: x[9],
                                               reverse=True),
                                        headers=[
                                            'Name', 'Expansion', 'Condition',
                                            'Language', 'Foil', 'Playset',
                                            'Price', 'Market price',
                                            'Market diff', 'Deal %'
                                        ],
                                        tablefmt="simple"))
                    else:
                        print('Found no deals. :(')
                else:
                    print("Invalid number.")
            else:
                print('No results found.')