Beispiel #1
0
    def __init__(self, **data):
        self._id = build_game_id(data['_id'], data['system'])
        self.system = data['system']

        self.nsuids = data.get('nsuids', {region: None for region in REGIONS})
        self.titles = data.get('titles', {region: None for region in REGIONS})
        self.release_dates = data.get('release_dates',
                                      {region: None
                                       for region in REGIONS})

        self.wishlisted = data.get('wishlisted', 0)
        self.wishlisted_history = data.get('wishlisted_history', {})

        self.hidden_gem = data.get('hidden_gem', False)

        self.number_of_players = data.get('number_of_players', 0)
        self.published_by_nintendo = data.get('published_by_nintendo', False)
        self.categories = sorted(list(set(data.get('categories', []))))

        self.websites = data.get(
            'websites', {
                country: None
                for country, dets in COUNTRIES.items() if WEBSITE in dets
            })
        self.scores = Score(**data.get('scores', {}))

        self.free_to_play = data.get('free_to_play', False)

        self._title = None
Beispiel #2
0
def index():
    if MAINTENANCE:
        return render_template('maintenance.html')

    return render_template('index.html',
                           systems=sorted(
                               [system[ID] for system in SYSTEMS.values()]),
                           countries=COUNTRIES.values(),
                           delete_url=DELETE_URL,
                           show_url=SHOW_URL,
                           emoji_star=STAR,
                           emoji_warning=WARNING)
Beispiel #3
0
def make_table(games, prices, system):
    games = sorted(games.values(), key=lambda x: x.wishlisted, reverse=True)

    content = [
        f'Title | Countries/Regions | % | MS | US | {STAR} ',
        '--- | --- | :---: | :---: | :---: | :---:'
    ]

    for game in games[:30]:
        if game.system != system:
            continue

        if not game.wishlisted:
            continue

        countries = {}

        discounts = set()

        for country, details in COUNTRIES.items():
            nsuid = game.nsuids.get(details[REGION])

            if not nsuid:
                continue

            price = prices.get(nsuid)

            if not price:
                continue

            country_price = price.prices[country]

            if not country_price:
                continue

            latest_sale = country_price.active

            if not latest_sale:
                continue

            countries[country] = details[FLAG]

            discounts.add(latest_sale.discount)

        if len(countries):
            row = make_row(game, countries, sum(discounts) / len(discounts))
            content.append(row)

    if len(content) < 3:
        return None

    return '\n'.join(content)
Beispiel #4
0
def extract_game_data(system, data):
    title = data.get('title')
    fs_id = data.get('fs_id')

    if fs_id in FSID_FIXER:
        data['product_code_txt'], data['nsuid_txt'] = FSID_FIXER.get(fs_id)

    try:
        # Getting nsuids for switch (7) or 3ds (5)
        nsuid = [
            nsuid_txt for nsuid_txt in data.get('nsuid_txt', [])
            if nsuid_txt[0] in ['5', '7']
        ][0]

        product_id = [
            product_code_txt
            for product_code_txt in data.get('product_code_txt', [])
            if product_code_txt[:3] in ['HAC', 'CTR', 'KTR']
        ][0]
    except:
        return None

    game_code = get_game_id(nsuid=nsuid, game_id=product_id)

    if len(nsuid) < 10 or len(game_code) < 7:
        return None

    game = Game(_id=game_code, system=system)

    game.titles[EU] = title
    game.nsuids[EU] = nsuid

    game.categories = get_categories(data.get('game_categories_txt', []))

    game.free_to_play = data.get('price_sorting_f', 1) == 0

    game.published_by_nintendo = data.get('publisher', '') == 'Nintendo'
    game.number_of_players = data.get('players_to', 0)

    for country, details in COUNTRIES.items():
        if details[REGION] == EU and WEBSITE in details:
            game.websites[country] = details[WEBSITE].format(nsuid=nsuid)

    try:
        game.release_dates[EU] = datetime.strptime(
            data.get('dates_released_dts')[0][:10], '%Y-%m-%d')
    except:
        return None

    return game
Beispiel #5
0
def validate(system, country=None):
    system = SYSTEMS.get(system.title(), SYSTEMS.get(system.upper()))

    if not system:
        raise Exception(f'Invalid system {system}')

    if not country:
        return system, None

    country = COUNTRIES.get(country.upper())

    if not country:
        raise Exception(f'Invalid country {country}')

    return system, country
Beispiel #6
0
def extract_game_data(system, slug):
    url = AMERICA[DATA].format(slug=slug)

    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')

    scripts = [tag.text for tag in soup.find_all('script') if 'window.game' in tag.text]

    if not len(scripts):
        return None

    data = {x[0]: x[1] for x in [line.strip().replace('",', '').split(': "') for line in scripts[0].split('\n') if ':' in line]}

    nsuid = data.get('nsuid')
    game_code = data.get('productCode')

    if len(nsuid) < 10 or len(game_code) < 7:
        return None

    title = data.get('title')

    game_id = get_game_id(nsuid=nsuid, game_id=game_code)

    game = Game(_id=game_id, system=system)
    game.titles[NA] = FIXES.get(title, title)
    game.nsuids[NA] = FIXES.get(nsuid, nsuid)
    game.categories = get_categories(data.get('genre', '').split(','))
    game.free_to_play = data.get('msrp') == '0.00'
    game.published_by_nintendo = data.get('publisher') == 'Nintendo'

    for country, details in COUNTRIES.items():
        if details[REGION] == NA and WEBSITE in details:
            game.websites[country] = details[WEBSITE].format(nsuid=nsuid)

    try:
        game.release_dates[NA] = datetime.strptime(data.get('releaseDate'), '%b %d, %Y')
    except:
        return None

    try:
        number_of_players = soup.find('dd', {'class': 'num-of-players'}).text.strip()
        game.number_of_players = int(re.sub('[^0-9]*', '', number_of_players))
    except:
        game.number_of_players = 0

    return game
Beispiel #7
0
def generate(games, prices, submissions, system):
    title = f'Current Nintendo {system} eShop deals'

    table = make_table(games, prices, system)

    content = []

    content.extend(header())

    content.append(
        '> 💸 👉 PRICES AND SCORES IN THE LINKS AT THE BOTTOM 👈 💸')
    content.append('')

    if table:
        content.append('###Most wanted games on sale')
        content.append('')
        content.append(table)
        content.append(SEPARATOR)

    content.append('###For prices and more check your country/region post')
    content.append(
        f'> *{WARNING} There\'s a known bug on reddit mobile where links won\'t open correctly*'
    )
    content.append('')

    content.append('-|new sales this week|total sales')
    content.append('---|:---:|:---:')

    for country, details in COUNTRIES.items():
        key = f'{system}/{country}'

        submission = submissions.get(key)

        if not submission:
            continue

        content.append(
            f'[{details[FLAG]} {details[NAME]}]({submission.url})|{submission.new_sales}|{submission.total_sales}'
        )

    content.extend(footer())

    return title, '\n'.join(content)
Beispiel #8
0
def wishlist(system, country):
    if MAINTENANCE:
        return render_template('maintenance.html')

    try:
        system, country = validate(system, country)
    except:
        return None

    region = country[REGION]
    games = list(GamesDatabase().load_all(filter={
        SYSTEM: system[ID],
        f'nsuids.{region}': {
            '$ne': None
        },
        'free_to_play': False
    },
                                          sort=[(f'release_dates.{region}', -1)
                                                ]))

    for game in games:
        game.countries = []

        for c, d in COUNTRIES.items():
            if d[REGION] in game.nsuids:
                game.countries.append(c)

        game.countries = ' '.join(game.countries)

    return render_template('wishlist.html',
                           system=system[NAME],
                           country=country[ID],
                           flag=country[FLAG],
                           region=region,
                           games=games,
                           add_url=ADD_URL,
                           delete_url=DELETE_URL,
                           show_url=SHOW_URL,
                           now=datetime.utcnow(),
                           emoji_nintendo=NINTENDO,
                           emoji_plus=PLUS,
                           emoji_star=STAR,
                           emoji_warning=WARNING)
Beispiel #9
0
def generate(games, prices, submissions, system):
    title = f'Current Nintendo {system} eShop deals'

    table = make_table(games, prices, system)

    content = []
    content.extend(header())

    content.append('')
    content.append('⬇ Regional posts with prices, dates, scores, and more.')
    content.append('')
    content.append('-|new sales this week|total sales')
    content.append('---|:---:|:---:')

    for country, details in COUNTRIES.items():
        key = f'{system}/{country}'

        submission = submissions.get(key)

        if not submission:
            continue

        full_url = f'https://www.reddit.com/r/{USER_SUBREDDIT}/comments/{submission.submission_id}'

        content.append(
            f'[{details[FLAG]} {details[NAME]}]({full_url})|{submission.new_sales}|{submission.total_sales}'
        )

    content.append('')

    if table:
        content.append(f'###Most [wishlisted]({WEBSITE_URL}) games on sale')
        content.append('')
        content.append(table)
        content.append(SEPARATOR)

    content.extend(footer())

    return title, '\n'.join(content)
Beispiel #10
0
def update_games(system, wishlist_counts):
    now = datetime.utcnow()
    games_db = GamesDatabase()
    prices_db = PricesDatabase()

    games = {
        game.id: game
        for game in games_db.load_all(filter={SYSTEM: system})
    }

    new_games_found = {}

    for region in REGIONS:
        saved_games = [
            game.nsuids[region] for game in games.values()
            if game.nsuids.get(region)
        ]

        for nsuid, new_game in new_game_finders[region](system, saved_games):
            new_games_found[region] = new_games_found.get(region, 0) + 1

            game = games.get(new_game.id, Game(_id=new_game.id, system=system))
            game.nsuids[region] = new_game.nsuids.get(region)

            title = new_game.titles.get(region)

            for lookup, replacement in TITLE_FIXES.items():
                if lookup in title:
                    title = title.replace(lookup, replacement)

            game.titles[region] = title

            game.release_dates[region] = new_game.release_dates.get(region)
            game.categories += new_game.categories
            game.categories = list(set(game.categories))

            game.number_of_players = max(
                [game.number_of_players, new_game.number_of_players])
            game.published_by_nintendo = any(
                [game.published_by_nintendo, new_game.published_by_nintendo])

            game.free_to_play = any([game.free_to_play, new_game.free_to_play])

            for country, website in new_game.websites.items():
                if website:
                    game.websites[country] = website

            games[game.id] = game

    prices = {price.id: price for price in prices_db.load_all()}

    for game_id, game in games.items():
        week = str(int(now.strftime("%V")))
        game.wishlisted_history[week] = wishlist_counts.get(game_id, 0)
        game.wishlisted = game.wishlisted_average

        if game.scores.next_update < now:
            game.scores = metacritic.get_scores(system, game.titles.values())

        try:
            GamesDatabase().save(game)
        except Exception as e:
            LOG.error(f'Error saving {game}: {str(e)}')
            continue

        for region, nsuid in game.nsuids.items():
            if not nsuid:
                continue

            save = False

            price = prices.get(nsuid)

            if not price:
                save = True
                price = Price(_id=nsuid,
                              game_id=game.id,
                              system=system,
                              region=region)

            for country, details in COUNTRIES.items():
                if details[REGION] == region and country not in price.prices:
                    price.prices[country] = None
                    save = True

            if save:
                LOG.info(f'Saving {game.title} ({nsuid}) into prices')
                prices_db.save(price)

    return f'{system} games found: {new_games_found}'