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
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
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))
async def search(**kwargs): user = asyncio.ensure_future(getcurrentuser(request)) slug = kwargs.get('slug') is_json = kwargs.get('is_json', '') query = slug.replace('-', ' ') if slug else request.query.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.get_cookie('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))
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
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), )