def route_search_stats(limit=20): search_events = db.session.query(SearchEvent).\ order_by(SearchEvent.timestamp.desc()).\ limit(99999).all() keywords = {} for ev in search_events: for tok in _split_search_string(ev.value): if tok in keywords: keywords[tok] += 1 continue keywords[tok] = 1 results = [] for keyword in keywords: results.append((keyword, keywords[keyword])) results.sort(key=lambda k: k[1], reverse=True) # generate the graph data labels = [] data = [] for res in results[0:limit]: labels.append(str(res[0])) data.append(res[1]) return render_template('analytics-search-stats.html', category='analytics', labels=labels, data=data)
def route_fw(max_results=100): if 'value' not in request.args: flash('No search value!', 'danger') return redirect(url_for('search.route_search')) keywords_unsafe = _split_search_string(request.args['value']) if not keywords_unsafe: keywords_unsafe = request.args['value'].split(' ') # never allow empty keywords keywords = [] for keyword in keywords_unsafe: if keyword: keywords.append(keyword) if not keywords: flash('No valid search value!', 'danger') return redirect(url_for('search.route_search')) # use keywords first fws = db.session.query(Firmware).join(Component).\ join(Keyword).\ filter(Keyword.value.in_(keywords)).\ distinct(Keyword.component_id).\ order_by(Keyword.component_id.desc(), Firmware.timestamp.desc()).\ limit(max_results).all() # try GUIDs if not fws: fws = db.session.query(Firmware).join(Component).\ join(Guid).\ filter(Guid.value.in_(keywords)).\ distinct(Keyword.component_id).\ order_by(Keyword.component_id.desc(), Firmware.timestamp.desc()).\ limit(max_results).all() # try version numbers if not fws: fws = db.session.query(Firmware).join(Component).\ filter(Component.version.in_(keywords)).\ distinct(Keyword.component_id).\ order_by(Keyword.component_id.desc(), Firmware.timestamp.desc()).\ limit(max_results).all() # try appstream ID if not fws: fws = db.session.query(Firmware).join(Component).\ filter(Component.appstream_id.startswith(keywords[0])).\ distinct(Keyword.component_id).\ order_by(Keyword.component_id.desc(), Firmware.timestamp.desc()).\ limit(max_results).all() # try CVE, e.g. CVE-2018-3646 if not fws: fws = db.session.query(Firmware).join(Component).join(ComponentIssue).\ filter(ComponentIssue.value.in_(keywords)).\ distinct(Keyword.component_id).\ order_by(Keyword.component_id.desc(), Firmware.timestamp.desc()).\ limit(max_results).all() # filter by ACL fws_safe = [] for fw in fws: if fw.check_acl('@view'): fws_safe.append(fw) return render_template('firmware-search.html', category='firmware', state='search', remote=None, fws=fws_safe)
def route_search(max_results=150): # no search results if 'value' not in request.args: return render_template('search.html', mds=None, search_size=-1, keywords_good=[], keywords_bad=[]) # components that match keywords = _split_search_string(request.args['value']) ids = db.session.query(Keyword.component_id).\ filter(Keyword.value.in_(keywords)).\ group_by(Keyword.component_id).\ having(func.count() == len(keywords)).\ subquery() mds = [] appstream_ids = [] vendors = [] for md in db.session.query(Component).join(ids).\ join(Firmware).join(Remote).filter(Remote.is_public).\ order_by(Component.version.desc()).\ limit(max_results*4): if md.appstream_id in appstream_ids: continue mds.append(md) appstream_ids.append(md.appstream_id) if md.fw.vendor not in vendors: vendors.append(md.fw.vendor) # get any vendor information as a fallback keywords_good = [] keywords_bad = [] if mds: keywords_good.extend(keywords) search_method = 'FW' else: search_method = 'AND' # always add vendor results for vendor in db.session.query(Vendor).\ filter(Vendor.visible_for_search): for kw in keywords: if vendor.keywords: if kw in vendor.keywords: if vendor not in vendors: vendors.append(vendor) if kw not in keywords_good: keywords_good.append(kw) break if vendor.display_name: if kw in _split_search_string(vendor.display_name): if vendor not in vendors: vendors.append(vendor) if kw not in keywords_good: keywords_good.append(kw) break for kw in keywords: if not kw in keywords_good: keywords_bad.append(kw) # this seems like we're over-logging but I'd like to see how people are # searching so we can tweak the algorithm used _add_search_event( SearchEvent(value=request.args['value'], addr=_addr_hash(_get_client_address()), count=len(mds) + len(vendors), method=search_method)) return render_template('search.html', mds=mds[:max_results], search_size=len(mds), vendors=vendors, keywords_good=keywords_good, keywords_bad=keywords_bad)