def badge_tiny_repos(name): return (flask.render_template( 'badge-tiny-blue.svg', name=name, caption='in repositories', text=get_db().get_metapackage_families_count(name)), { 'Content-type': 'image/svg+xml' })
def repositories_updates(): autorefresh = flask.request.args.to_dict().get('autorefresh') return flask.render_template( 'repositories-updates.html', repos=get_db().get_repositories_update_statistics(), autorefresh=autorefresh )
def admin_updates() -> Response: if not flask.session.get('admin'): return unauthorized() return flask.render_template( 'admin-updates.html', repos=get_db().get_repositories_update_diagnostics() )
def admin_omni_cves() -> Response: if not flask.session.get('admin'): return unauthorized() return flask.render_template( 'admin-omni-cves.html', items=get_db().get_omni_cves() )
def badge_tiny_repos(name: str) -> Any: return (flask.render_template( 'badge-tiny-blue.svg', name=name, caption=flask.request.args.to_dict().get('header', 'in repositories'), text=get_db().get_metapackage_families_count(name)), { 'Content-type': 'image/svg+xml' })
def badge_tiny_repos(name: str) -> Response: return render_generic_badge([[ BadgeCell(flask.request.args.to_dict().get('header', 'in repositories'), collapsible=True), BadgeCell(str(get_db().get_metapackage_families_count(name)), '#007ec6'), ]])
def repository_problems(repo: str) -> Response: if repo not in repometadata.active_names(): flask.abort(404) return flask.render_template('repository-problems.html', repo=repo, problems=get_db().get_repository_problems( repo, config['PROBLEMS_PER_PAGE']))
def admin_redirects() -> Any: if not flask.session.get('admin'): return unauthorized() oldname = '' metapackages: List[Any] = [] metapackagedata: Dict[str, Any] = {} if flask.request.method == 'POST': oldname = flask.request.form.get('oldname', '') newname = flask.request.form.get('newname') if oldname and newname: if flask.request.form.get('action') == 'remove': get_db().remove_project_redirect(oldname, newname) flask.flash('Redirect removed succesfully', 'success') else: get_db().add_project_redirect(oldname, newname, True) flask.flash('Redirect added succesfully', 'success') if oldname: newnames = get_db().get_project_redirects(oldname) metapackages = get_db().get_metapackages(newnames) packages = get_db().get_metapackages_packages(newnames, fields=['family', 'effname', 'version', 'versionclass', 'flags']) metapackagedata = packages_to_summary_items(packages) return flask.render_template( 'admin-redirects.html', oldname=oldname, metapackages=metapackages, metapackagedata=metapackagedata, )
def handle_nonexisting_project(name: str, metapackage: Dict[str, Any]) -> Any: # we don't show anything to user when REDIRECTS_PER_PAGE is reached as # number of redirect targets is natually limited and we don't expect it to be reached redirects = get_db().get_project_redirects(name, limit=config['REDIRECTS_PER_PAGE']) if len(redirects) == 1: # single redirect - follow it right away flask.flash('You were redirected from project {}, which is not known by Repology'.format(name), 'info') return flask.redirect(flask.url_for(flask.request.endpoint, name=redirects[0]), 301) metapackages: List[Any] = [] metapackagedata: Dict[str, Any] = {} if redirects: # show redirects metapackages = get_db().get_metapackages(redirects) packages = get_db().get_metapackages_packages(redirects, fields=['family', 'effname', 'version', 'versionclass', 'flags']) metapackagedata = packages_to_summary_items(packages) if not metapackage: return ( flask.render_template( 'project-404.html', name=name, metapackages=metapackages, metapackagedata=metapackagedata ), 404 ) else: has_history, has_reports = get_db().project_has_history_or_reports(name) return ( flask.render_template( 'project-410.html', name=name, metapackage=metapackage, metapackages=metapackages, metapackagedata=metapackagedata, has_history=has_history, has_reports=has_reports ), 404 )
def metapackage_packages(name): packages_by_repo = defaultdict(list) for package in get_db().get_metapackage_packages(name): packages_by_repo[package.repo].append(package) packages = [] for repo in repometadata.active_names(): if repo in packages_by_repo: packages.extend(PackagesetSortByNameVersion( packages_by_repo[repo])) return flask.render_template( 'metapackage-packages.html', packages=packages, metapackage=get_db().get_metapackage(name), name=name, link_statuses=get_db().get_metapackage_link_statuses(name))
def repository(repo): autorefresh = flask.request.args.to_dict().get('autorefresh') if repo not in repometadata.all_names(): flask.abort(404) #return (flask.render_template('repository-404.html', repo=repo), 404) if repo not in repometadata.active_names(): # HTTP code is intentionally 404 return (flask.render_template( 'repository-410.html', repo=repo, repo_info=get_db().get_repository_information(repo)), 404) return flask.render_template( 'repository.html', repo=repo, repo_info=get_db().get_repository_information(repo), autorefresh=autorefresh)
def maintainer_repo_feed(maintainer, repo): return flask.render_template('maintainer-repo-feed.html', maintainer=maintainer, repo=repo, history=smear_timestamps( get_db().get_maintainer_feed( maintainer=maintainer, repo=repo, limit=config['HISTORY_PER_PAGE'])))
def metapackage_related(name): metapackages = get_db().get_metapackage_related_metapackages(name, limit=config['METAPACKAGES_PER_PAGE']) packages = get_db().get_metapackages_packages(list(metapackages.keys()), fields=['family', 'effname', 'version', 'versionclass', 'flags']) metapackagedata = metapackages_to_summary_items(packages_to_metapackages(packages)) too_many_warning = None if len(metapackagedata) == config['METAPACKAGES_PER_PAGE']: too_many_warning = config['METAPACKAGES_PER_PAGE'] return flask.render_template( 'metapackage-related.html', name=name, metapackages=metapackages, metapackagedata=metapackagedata, too_many_warning=too_many_warning )
def project_badges(name: str) -> Any: metapackage = get_db().get_metapackage(name) if not metapackage or metapackage['num_repos'] == 0: return handle_nonexisting_project(name, metapackage) repos_present_in = set(package['repo'] for package in get_db().get_metapackage_packages( name, fields=['repo'])) repos = [ repo for repo in repometadata.active_names() if repo in repos_present_in ] return flask.render_template('project-badges.html', name=name, metapackage=metapackage, repos=repos)
def project_packages(name: str) -> Any: packages_by_repo: Dict[str, List[Package]] = defaultdict(list) for package in get_db().get_metapackage_packages(name): packages_by_repo[package.repo].append(package) packages: List[Package] = [] for repo in repometadata.active_names(): if repo in packages_by_repo: packages.extend(packageset_sort_by_name_version(packages_by_repo[repo])) return flask.render_template( 'project-packages.html', packages=packages, metapackage=get_db().get_metapackage(name), name=name, link_statuses=get_db().get_metapackage_link_statuses(name) )
def tool_project_by() -> Any: repo = flask.request.args.get('repo') name_type = flask.request.args.get('name_type') name = flask.request.args.get('name') noautoresolve = bool(flask.request.args.get('noautoresolve')) target_page = None for allowed_target_page in _ALLOWED_TARGET_PAGES: if allowed_target_page.endpoint == flask.request.args.get( 'target_page'): target_page = allowed_target_page break template_url = None if repo and name_type and target_page: if not repometadata[repo]['family'] in _ALLOWED_FAMILIES: flask.abort(403) elif name: targets = [] for project in get_db().get_projects_by_name(repo=repo, name_type=name_type, name=name): possible_args = {'name': project, 'repo': repo} real_args = {k: possible_args[k] for k in target_page.args} targets.append( (project, flask.url_for(target_page.endpoint, **real_args))) if not targets: flask.abort(404) elif noautoresolve and len(targets) > 1: return flask.render_template( 'project-by-ambiguity.html', targets=targets, ) else: return flask.redirect(targets[0][1], 302) else: args = { k: v for k, v in flask.request.args.items() if k in _EXTRA_ALLOWED_ARGS | {'repo', 'name_type', 'noautoresolve', 'target_page'} } template_url = url_for_self(**args) return flask.render_template( 'project-by.html', allowed_target_pages=_ALLOWED_TARGET_PAGES, template_url=template_url, allowed_families=_ALLOWED_FAMILIES, )
def repository_feed_atom(repo: str) -> Response: return (flask.render_template( 'repository-feed-atom.xml', repo=repo, history=unicalize_feed_timestamps(get_db().get_repository_feed( repo=repo, timespan=datetime.timedelta(weeks=4), limit=config['HISTORY_PER_PAGE']))), { 'Content-type': 'application/atom+xml' })
def repository_feed(repo: str) -> Response: autorefresh = flask.request.args.to_dict().get('autorefresh') return flask.render_template('repository-feed.html', repo=repo, history=unicalize_feed_timestamps( get_db().get_repository_feed( repo=repo, limit=config['HISTORY_PER_PAGE'])), autorefresh=autorefresh)
def security_recent_cves() -> Response: return flask.render_template( 'security/recent-cves.html', cves=cache( 'recent-cves', lambda: get_db(). get_recent_cves( # type: ignore # https://github.com/python/mypy/issues/9590 max_age=datetime.timedelta(days=config[ 'RECENT_CVES_MAX_AGE_DAYS']), limit=config['RECENT_CVES_MAX_COUNT'])))
def project_versions(name: str) -> Any: packages_by_repo: Dict[str, List[Package]] = defaultdict(list) packages = get_db().get_metapackage_packages(name) for package in packages: packages_by_repo[package.repo].append(package) for repo, repo_packages in packages_by_repo.items(): packages_by_repo[repo] = packageset_sort_by_version(repo_packages) return flask.render_template( 'project-versions.html', reponames_absent=[reponame for reponame in repometadata.active_names() if reponame not in packages_by_repo], packages=packages, packages_by_repo=packages_by_repo, metapackage=get_db().get_metapackage(name), name=name )
def handle_cpe_request() -> Any: effname = flask.request.form.get('effname', '').strip() vendor = flask.request.form.get('cpe_vendor', '').strip() product = flask.request.form.get('cpe_product', '').strip() def have_all_attrs() -> bool: if not effname: flask.flash('Project name not specified', 'danger') elif not vendor: flask.flash('CPE vendor not specified', 'danger') elif not product: flask.flash('CPE product not specified', 'danger') else: return True return False if flask.request.form.get('action') == 'add': if have_all_attrs(): try: get_db().add_manual_cpe(effname, vendor, product) flask.flash(f'Manual CPE {vendor}:{product} added for {effname}', 'success') except psycopg2.errors.UniqueViolation: flask.flash(f'Manual CPE {vendor}:{product} already exists for {effname}', 'danger') elif flask.request.form.get('action') == 'remove': get_db().remove_manual_cpe(effname, vendor, product) flask.flash(f'Manual CPE {vendor}:{product} removed for {effname}', 'success') elif flask.request.form.get('action') == 'autoadd': if not effname: flask.flash('Project name not specified', 'danger') else: added = get_db().auto_add_manual_cpes(effname) if added: cpes = ', '.join(f'{vendor}:{product}' for vendor, product in added) flask.flash(f'{len(added)} manual CPE(s) {cpes} autoadded for {effname}', 'success') else: flask.flash(f'No manual CPE(s) for {effname} autoadded', 'warning') elif flask.request.form.get('action') == 'redirect': if have_all_attrs(): redirs = get_db().get_project_redirects(effname) if len(redirs) == 0: flask.flash(f'No redirects found for {effname}', 'danger') elif len(redirs) > 1: flask.flash(f'Redirect for {effname} leads to multiple projects {", ".join(redirs)}, cannot resolve', 'danger') else: try: get_db().modify_manual_cpe(effname, vendor, product, redirs[0]) flask.flash(f'Manual CPE {vendor}:{product} for {effname} moved to {redirs[0]}', 'success') except psycopg2.errors.UniqueViolation: flask.flash(f'Failed to move CPE {vendor}:{product} for {effname} to {redirs[0]} (target binding already exists?)', 'danger') return flask.redirect(url_for_self(), 302)
def get_graph(period: int) -> GraphProcessor: graph = GraphProcessor() for histentry in get_db().get_statistics_history_since(datetime.timedelta(seconds=period)): try: graph.add_point(histentry['timedelta'], getvalue(histentry['snapshot'])) except: pass # ignore missing keys, division errors etc. return graph
def api_v1_project(name: str) -> Response: return ( dump_json( list( api_v1_package_to_json(PackageDataDetailed(**item)) for item in get_db().get_metapackage_packages(name, detailed=True) ) ), {'Content-type': 'application/json'} )
def badge_vertical_allrepos(name: str) -> Response: args = flask.request.args.to_dict() best_pkg_by_repo = packageset_to_best_by_repo( (PackageDataMinimal(**item) for item in get_db().get_metapackage_packages(name, minimal=True)), allow_ignored=args.get('allow_ignored', False)) header = args.get('header') minversion = args.get('minversion') repo_filter = RepositoryFilter(args) cells = [] for reponame in repometadata.active_names(): if not repo_filter.check(reponame): continue if reponame in best_pkg_by_repo: version = best_pkg_by_repo[reponame].version versionclass = best_pkg_by_repo[reponame].versionclass unsatisfying = minversion and version_compare(version, minversion) < 0 color = badge_color(versionclass, unsatisfying) cells.append([ BadgeCell(repometadata[reponame]['desc'], align='r'), BadgeCell(version, color=color, truncate=13, minwidth=60) ]) try: columns = min(int(args.get('columns', '1')), len(cells)) except: columns = 1 if columns > 1: chunks = [] columnsize = (len(cells) + columns - 1) // columns for column in range(columns): chunks.append(cells[column * columnsize:column * columnsize + columnsize]) empty_filler = [BadgeCell(''), BadgeCell('')] cells = [ sum(cells, []) for cells in zip_longest(*chunks, fillvalue=empty_filler) ] if header is None: header = 'Packaging status' if cells else 'No known packages' return render_generic_badge(cells, header=header)
def handle_nonexisting_project(name: str, metapackage: Dict[str, Any]) -> Any: # we don't show anything to user when REDIRECTS_PER_PAGE is reached as # number of redirect targets is natually limited and we don't expect it to be reached redirects = get_db().get_project_redirects( name, limit=config['REDIRECTS_PER_PAGE']) if len(redirects) == 1: # single redirect - follow it right away flask.flash( f'You were redirected from {name}, which was moved or merged here', 'info') return flask.redirect( flask.url_for(flask.request.endpoint, name=redirects[0]), 301) metapackages: List[Any] = [] metapackagedata: Dict[str, Any] = {} if redirects: # show redirects metapackages = get_db().get_metapackages(redirects) metapackagedata = packages_to_summary_items( PackageDataSummarizable(**item) for item in get_db().get_metapackages_packages(redirects, summarizable=True)) if not metapackage: return (flask.render_template('project-404.html', name=name, metapackages=metapackages, metapackagedata=metapackagedata), 404) else: has_history, has_reports = get_db().project_has_history_or_reports( name) return (flask.render_template('project-410.html', name=name, metapackage=metapackage, metapackages=metapackages, metapackagedata=metapackagedata, has_history=has_history, has_reports=has_reports), 404)
def admin_name_samples() -> Response: if not flask.session.get('admin'): return unauthorized() samples_by_repo: Dict[str, List[Dict[Any, Any]]] = defaultdict(list) for sample in get_db().get_name_samples(10): samples_by_repo[sample['repo']].append(sample) return flask.render_template('admin-name-samples.html', samples_by_repo=samples_by_repo)
def admin_cve_misses() -> Any: if not flask.session.get('admin'): return unauthorized() if flask.request.method == 'POST': return handle_cpe_request() return flask.render_template( 'admin-cve-misses.html', cves=get_db().get_recent_cve_misses() )
def maintainer_problems(maintainer: str) -> Any: maintainer = maintainer.lower() return flask.render_template( 'maintainer-problems.html', maintainer=maintainer, problems=get_db().get_maintainer_problems( maintainer, config['PROBLEMS_PER_PAGE'] ) )
def maintainer_repo_feed(maintainer: str, repo: str) -> Any: autorefresh = flask.request.args.to_dict().get('autorefresh') return flask.render_template('maintainer-repo-feed.html', maintainer=maintainer, repo=repo, history=unicalize_feed_timestamps( get_db().get_maintainer_feed( maintainer=maintainer, repo=repo, limit=config['HISTORY_PER_PAGE'])), autorefresh=autorefresh)
def maintainer_repo_feed_atom(maintainer: str, repo: str) -> Any: return (flask.render_template( 'maintainer-repo-feed-atom.xml', maintainer=maintainer, repo=repo, history=unicalize_feed_timestamps(get_db().get_maintainer_feed( maintainer=maintainer, repo=repo, timespan=datetime.timedelta(weeks=4), limit=config['HISTORY_PER_PAGE']))), { 'Content-type': 'application/atom+xml' })