Пример #1
0
async def getresults(classes, tags):
    key = getsearchkey(classes, tags)
    multikey = getsearchkey(classes, tags, 'Multi')
    allkey = getsearchkey(classes, tags, 'All')

    title = tf2search.getclasstagtitle(classes, tags)

    keys = (key, multikey, allkey)
    titles = (title, 'Multi-Class Items', 'All-Class Items')

    if not await store.exists(key) and not await store.exists(allkey):
        classeskey = 'temp:classes'
        tagskey = 'temp:tags'
        remove = []

        pipe = store.multi_exec()

        classkeys = [getclasskey(class_) for class_ in classes] or ['items']
        pipe.sunionstore(classeskey, *classkeys)

        # Get only the specified weapon types
        if 'weapon' in tags and not tags.isdisjoint(tf2api.getweapontags()):
            tags.remove('weapon')
            remove.append(gettagkey('token'))

        tagkeys = [gettagkey(tag) for tag in tags] or ['items']
        pipe.sunionstore(tagskey, *tagkeys)

        # Hide medals if not explicitly searching for them
        if 'tournament' not in tags:
            remove.append(gettagkey('tournament'))

        if remove:
            pipe.sdiffstore(tagskey, *([tagskey] + remove))

        pipe.sinterstore(key, classeskey, tagskey)
        pipe.sinterstore(multikey, key, getclasskey(multi=True))
        pipe.sinterstore(allkey, tagskey, getclasskey())
        pipe.sdiffstore(key, key, multikey, allkey)

        pipe.delete(classeskey)
        pipe.delete(tagskey)

        for k in keys:
            pipe.sort(k, store=k)
            pipe.expire(k, 3600)

        await pipe.execute()

    async def getkeys(key):
        return [getitemkey(k) for k in await store.lrange(key, 0, -1)]

    results = []
    for title, key in zip(titles, keys):
        itemkeys = await getkeys(key)
        if itemkeys:
            results.append(tf2search.getsearchresult(
                title=title, items=store.Hashes(itemkeys)))

    return results
Пример #2
0
def getresults(classes, tags):
    key = getsearchkey(classes, tags)
    multikey = getsearchkey(classes, tags, "Multi")
    allkey = getsearchkey(classes, tags, "All")

    keys = (key, multikey, allkey)
    titles = ("", "Multi-Class Items", "All-Class Items")

    if not store.exists(key) and not store.exists(allkey):
        classeskey = "temp:classes"
        tagskey = "temp:tags"
        remove = []

        pipe = store.pipeline()

        classkeys = [getclasskey(class_) for class_ in classes] or "items"
        pipe.sunionstore(classeskey, classkeys)

        # Get only the specified weapon types
        if "weapon" in tags and not tags.isdisjoint(tf2api.getweapontags()):
            tags.remove("weapon")
            remove.append(gettagkey("token"))

        tagkeys = [gettagkey(tag) for tag in tags] or "items"
        pipe.sunionstore(tagskey, tagkeys)

        # Hide medals if not explicitly searching for them
        if "tournament" not in tags:
            remove.append(gettagkey("tournament"))

        if remove:
            pipe.sdiffstore(tagskey, [tagskey] + remove)

        pipe.sinterstore(key, [classeskey, tagskey])
        pipe.sinterstore(multikey, [key, getclasskey(multi=True)])
        pipe.sinterstore(allkey, [tagskey, getclasskey()])
        pipe.sdiffstore(key, [key, multikey, allkey])

        pipe.delete(classeskey)
        pipe.delete(tagskey)

        for k in keys:
            pipe.sort(k, store=k)
            pipe.expire(k, 3600)

        pipe.execute()

    getkeys = lambda key: [getitemkey(k) for k in store.lrange(key, 0, -1)]

    results = []
    for title, key in zip(titles, keys):
        itemkeys = getkeys(key)
        if itemkeys:
            results.append(tf2search.getsearchresult(title=title, items=store.Hashes(itemkeys)))

    return results
Пример #3
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))
Пример #4
0
def search(is_json):
    query = request.query.q

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

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

    itemnames = store.Hash("items:names")

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

    t0 = time.time()

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

        items = store.HashSet("items", getitemkey)
        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:
                for item in results[0]["items"]:
                    item["item"] = item["item"].todict()

                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 = getresults(classes, tags)

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

            itemsets = store.get("items:sets")
            bundles = 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()

    if is_json:
        return tojson(results)
    else:
        return render(
            "search.html",
            query=query,
            results=results,
            count=sum(len(result["items"]) for result in results),
            time=round(t1 - t0, 3),
        )