Exemplo n.º 1
0
def getclasstagtitle(classes, tags):
    """Return a title desciribing a class/tag search"""
    all_classes = list(tf2api.getallclasses().keys())
    classes_text = ', '.join(sorted(classes, key=all_classes.index))
    tags_text = ', '.join(sorted(tags)).title()

    if len(classes) == 1 and len(tags) == 1:
        title = f'{classes_text} {tags_text}'
    elif classes and tags:
        title = f'{classes_text} × {tags_text}'
    elif classes:
        title = classes_text
    elif tags:
        title = tags_text

    return title
Exemplo n.º 2
0
async def search(request, **kwargs):
    user = asyncio.ensure_future(getcurrentuser(request))

    slug = kwargs.get('slug')
    is_json = kwargs.get('is_json', '')

    query = slug.replace('-', ' ') if slug else request.args.get('q')

    if not query:
        if is_json:
            return {'error': 'No query provided.'}
        return redirect('/')

    elif query == 'random':
        index = await store.srandmember('items:indexes')
        return redirect('/{}{}'.format(index, is_json))

    itemnames = await store.hgetall('items:names')

    if query in itemnames:
        return redirect('/{}'.format(itemnames[query]))

    t0 = time.time()

    classes = set()
    tags = set()

    priceviz = False

    if query == 'all':
        items = store.Hashes(
            [getitemkey(k.decode()) for k in await store.sort('items')])
        results = [tf2search.getsearchresult(items=items)]
    else:
        sources = ('backpack.tf', 'trade.tf')
        pricesource = request.cookies.get('price_source')
        if pricesource not in sources:
            pricesource = sources[0]

        items = {
            item['index']: item async for item in store.Hashes([
                getitemkey(143),  # Earbuds
                getitemkey(5021),  # Key
                getitemkey(5002),  # Refined
                getitemkey(5001),  # Reclaimed
                getitemkey(5000),  # Scrap
                getitemkey(0)  # Weapon
            ])
        }
        results = tf2search.visualizeprice(query, items, pricesource)

        input_ = tf2search.parseinput(query)
        classes = input_['classes']
        tags = input_['tags']

        if results is not None:
            if len(results) != 0:
                priceviz = True
                if not is_json:
                    items = []
                    for item in results[0]['items']:
                        items.extend([item['item']] * item['count'])
                    results[0]['items'] = items

        elif classes or tags:
            results = await getresults(classes, tags)

        else:
            itemsdict = await store.SearchHashSet(
                'items', getitemkey,
                ('index', 'name', 'image', 'classes', 'tags', 'marketprice'),
                int)

            itemsets = await store.get('items:sets')
            bundles = await store.get('items:bundles')

            results = tf2search.search(query, itemsdict, itemnames,
                                       itemsets, bundles, pricesource)

            for result in results:
                result['items'] = store.Hashes(
                    [h.key for h in result['items']])

    t1 = time.time()

    count = sum(len(result['items']) for result in results)

    all_classes = list(tf2api.getallclasses().keys())
    classes_text = getlistastext(sorted(classes, key=all_classes.index))
    tags_text = getlistastext(sorted(tags))

    if query == 'all':
        description = f'A list of all {count:,} items in TF2.'
    elif classes and tags:
        description = (
            f'A list of the {count:,} {tags_text} items for {classes_text}'
            ' in TF2.'
        )
    elif classes:
        description = (
            f'A list of the {count:,} items for {classes_text} in TF2.'
        )
    elif tags:
        description = f'A list of the {count:,} {tags_text} items in TF2.'
    elif priceviz:
        from_, equals, to = results[0]['title'].partition(' = ')
        to = getlistastext(to.split(' + '))
        description = (f'{from_} is the same as {to} in TF2.' if equals else
                       f'A list of {from_} items in TF2.')
    elif results and ':' in results[0]['title']:
        title = results[0]['title'].replace(':', '')
        description = f'{count:,} {title} items in TF2.'
    else:
        description = f'Search results for "{query}" items in TF2.'

    qualities = defaultdict(set)

    user = await user
    if user:
        for item in user.get('backpack', {}).get('items', []):
            qualities[item['defindex']].add(item['quality'])

    if is_json:
        for result in results:
            result['items'] = [item async for item in result['items']]
        return tojson(results)
    else:
        return await render('search.html',
                            query=query,
                            description=description,
                            results=results,
                            qualities=qualities,
                            count=count,
                            time=round(t1 - t0, 3))
Exemplo n.º 3
0
def _parseblueprints(blueprints, itemsbyname):
    """Parse a dictionary of blueprint descriptions"""
    url = '/images/items/'
    localrepl = {'Any Class Token': 'class_token.png',
                 'Any Slot Token': 'slot_token.png',
                 'Any Token': 'token.png'}

    repl = {"Any Santa's Little Accomplice Weapon":
            "Santa's Little Accomplice Bundle",

            'Any Primary Weapon': 'Rocket Launcher',
            'Any Secondary Weapon': 'Pistol',
            'Any Melee Weapon': 'Fire Axe',
            'Any Spy Watch': 'Invis Watch',
            'Any Hat': 'Modest Pile of Hat',
            'Any Burned Item': 'Burned Banana Peel',
            'Any Cursed Object': 'Voodoo-Cursed Object'}

    polyweps = ("The Gas Jockey's Gear", "The Saharan Spy", "The Tank Buster",
                "The Croc-o-Style Kit", "The Special Delivery")

    for class_ in tf2api.getallclasses():
        repl['Any {} Weapon'.format(class_)] = '{} Starter Pack'.format(class_)

    for name in polyweps:
        repl['Any {} Weapon'.format(name)] = name

    for i in ('Victory', 'Moonman', 'Brainiac'):
        pack = "Dr. Grordbort's {} Pack".format(i)
        repl["Any {} Weapon".format(pack)] = pack

    blueprintsdict = defaultdict(list)
    for b in blueprints:
        required = blueprints[b][0]
        results = blueprints[b][1]

        for name in results:
            if name in itemsbyname:
                index = itemsbyname[name]['defindex']
                chance = int(round(100.0 / len(results)))

                blueprintlist = []

                for i in OrderedDict.fromkeys(required):
                    blueprintdict = {}

                    if i in localrepl:
                        image = url + localrepl[i]

                    elif i in repl:
                        image = itemsbyname[repl[i]]['image_url']

                    elif i in itemsbyname:
                        item = itemsbyname[i]
                        image = item['image_url']

                        blueprintdict['index'] = item['defindex']

                    else:
                        image = '/images/items/whatsthis.png'

                    blueprintdict['name'] = i
                    blueprintdict['image'] = image
                    blueprintdict['count'] = required.count(i)

                    blueprintlist.append(blueprintdict)

                blueprintsdict[index].append({'chance': chance,
                                              'required': blueprintlist})

    return blueprintsdict
Exemplo n.º 4
0
def _getclass(word):
    """Parse a word and return TF2 class or alias if it matches one"""
    word = word.capitalize()
    for name, aliases in tf2api.getallclasses().items():
        if word == name or word in aliases:
            return name
Exemplo n.º 5
0
async def main(flush):
    store = await create_redis(('localhost', 6379), commands_factory=Redis)

    tf2info = await tf2search.gettf2info(config.apikey,
                                         config.backpackkey, config.tradekey,
                                         config.blueprintsfile)

    if flush:
        await store.delete('items')
        await store.delete_all('items:*')
        await store.delete_all('item:*')

    suggestions = [[], [], []]

    sitemap = Sitemap()
    sitemap.add(config.homepage)

    all_classes = [class_.lower() for class_ in tf2api.getallclasses()]
    all_tags = list(tf2api.getalltags())
    all_qualities = [quality.replace("'", '').lower() for quality in
                     tf2api.getallqualities().values()]

    keywords = all_classes + all_tags + all_qualities
    for keyword in keywords:
        sitemap.add(f'{config.homepage}/search/{keyword}')

    for class_tag in all_classes + all_tags:
        for quality in all_qualities:
            sitemap.add(f'{config.homepage}/search/{quality}-{class_tag}')

    for class_ in all_classes:
        for tag in all_tags:
            sitemap.add(f'{config.homepage}/search/{class_}-{tag}')
            for quality in all_qualities:
                sitemap.add(
                    f'{config.homepage}/search/{quality}-{class_}-{tag}'
                )

    for index in tf2info.items:
        pipe = store.pipeline()

        itemdict = tf2search.createitemdict(index, tf2info)
        name = itemdict['name']

        pipe.hmset_dict(getitemkey(index), itemdict)
        pipe.sadd('items', index)

        classes = itemdict['classes']
        tags = itemdict['tags']

        if index == tf2info.itemsbyname[name]['defindex']:
            slug = slugify(name)

            pipe.hmset_dict('items:slugs', {slug: index})

            if tf2search.isvalidresult(itemdict, False):
                if not classes:
                    pipe.sadd(getclasskey(), index)
                if len(classes) > 1:
                    pipe.sadd(getclasskey(multi=True), index)
                if not tags:
                    pipe.sadd(gettagkey(), index)
                for class_ in classes:
                    pipe.sadd(getclasskey(class_), index)
                for tag in tags:
                    pipe.sadd(gettagkey(tag), index)

            if tf2search.isvalidresult(itemdict):
                pipe.sadd('items:indexes', index)
                pipe.hmset_dict('items:names', {name: index})

                path = f'{config.homepage}/{slug}'

                suggestions[0].append(name)
                suggestions[1].append('{} - {}'.format(
                    ', '.join(itemdict['classes']),
                    ', '.join(itemdict['tags'])))
                suggestions[2].append(path)

                sitemap.add(path)

        await pipe.execute()

    await store.delete('items:new')
    for index in tf2info.newstoreprices:
        await store.sadd('items:new', index)

    bundles = {str(k): v for k, v in tf2info.bundles.items()}

    data = {'items:sets': tf2info.itemsets,
            'items:bundles': bundles,
            'items:suggestions': suggestions,
            'items:lastupdated': time.time(),
            'sitemap': sitemap.toxml()}

    await store.mset_dict(data)