def repositories_statistics(sorting: Optional[str] = None) -> Response: autorefresh = flask.request.args.to_dict().get('autorefresh') repostats_by_name = {repostat['name']: repostat for repostat in get_db().get_active_repositories()} repostats = [repostats_by_name[reponame] for reponame in repometadata.active_names() if reponame in repostats_by_name] if sorting == 'newest': repostats = sorted(repostats, key=lambda s: cast(int, s['num_metapackages_newest']), reverse=True) elif sorting == 'pnewest': repostats = sorted(repostats, key=lambda s: safe_percent(s['num_metapackages_newest'], s['num_metapackages_comparable']), reverse=True) elif sorting == 'outdated': repostats = sorted(repostats, key=lambda s: cast(int, s['num_metapackages_outdated']), reverse=True) elif sorting == 'poutdated': repostats = sorted(repostats, key=lambda s: safe_percent(s['num_metapackages_outdated'], s['num_metapackages_comparable']), reverse=True) elif sorting == 'total': repostats = sorted(repostats, key=lambda s: cast(int, s['num_metapackages']), reverse=True) elif sorting == 'nonunique': repostats = sorted(repostats, key=lambda s: cast(int, s['num_metapackages'] - s['num_metapackages_unique']), reverse=True) elif sorting == 'vulnerable': repostats = sorted(repostats, key=lambda s: cast(int, s['num_metapackages_vulnerable']), reverse=True) elif sorting == 'pvulnerable': repostats = sorted(repostats, key=lambda s: safe_percent(s['num_metapackages_vulnerable'], s['num_metapackages']), reverse=True) else: sorting = 'name' return flask.render_template( 'repositories-statistics.html', sorting=sorting, repostats=repostats, repostats_old={}, # {repo['name']: repo for repo in get_db().GetRepositoriesHistoryAgo(60 * 60 * 24 * 7)}, counts=get_db().get_counts(), autorefresh=autorefresh )
def badge_vertical_allrepos(name: str) -> Any: packages = get_db().get_metapackage_packages( name, fields=['repo', 'version', 'versionclass']) best_pkg_by_repo = packageset_to_best_by_repo(packages) header = flask.request.args.to_dict().get('header', 'Packaging status') minversion = flask.request.args.to_dict().get('minversion') entries = [{ 'repo': repometadata[reponame], 'package': best_pkg_by_repo[reponame], 'unsatisfying': version_compare(best_pkg_by_repo[reponame].version, minversion) < 0 if minversion else False, } for reponame in repometadata.active_names() if reponame in best_pkg_by_repo] if not entries: header = 'No known packages' return (flask.render_template('badge-vertical.svg', entries=entries, name=name, header=header), { 'Content-type': 'image/svg+xml' })
def project_versions(name: str) -> Any: metapackage = get_db().get_metapackage(name) if not metapackage or metapackage['num_repos'] == 0: return handle_nonexisting_project(name, metapackage) packages = [ PackageDataDetailed(**item) for item in get_db().get_metapackage_packages(name, detailed=True) ] packages_by_repo: Dict[str, List[PackageDataDetailed]] = defaultdict(list) 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', name=name, metapackage=metapackage, packages=packages, packages_by_repo=packages_by_repo, reponames_absent=[ reponame for reponame in repometadata.active_names() if reponame not in packages_by_repo ])
def badge_vertical_allrepos(name: str) -> Any: args = flask.request.args.to_dict() packages = get_db().get_metapackage_packages( name, fields=['repo', 'version', 'versionclass']) best_pkg_by_repo = packageset_to_best_by_repo(packages, allow_ignored=args.get( 'allow_ignored', False)) header = args.get('header') minversion = args.get('minversion') cells = [] for reponame in repometadata.active_names(): 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) ]) if header is None: header = 'Packaging status' if cells else 'No known packages' return render_generic_badge(cells, header=header)
def badge_vertical_allrepos(name): packages = get_db().get_metapackage_packages(name, fields=['repo', 'version', 'versionclass']) best_pkg_by_repo = PackagesetToBestByRepo(packages) header = flask.request.args.to_dict().get('header', 'Packaging status') entries = [ { 'repo': repometadata[reponame], 'package': best_pkg_by_repo[reponame] } for reponame in repometadata.active_names() if reponame in best_pkg_by_repo ] if not entries: header = 'No known packages' return ( flask.render_template( 'badge-vertical.svg', entries=entries, name=name, header=header ), {'Content-type': 'image/svg+xml'} )
def problems_generic(repo: str, maintainer: Optional[str] = None, start: Optional[str] = None, end: Optional[str] = None) -> Response: if repo not in repometadata.active_names(): flask.abort(404) problems = get_db().get_problems(repo=repo, maintainer=maintainer, start=start, end=end, limit=config['PROBLEMS_PER_PAGE']) first, last = get_db().get_problems_range(repo=repo, maintainer=maintainer) is_first_page, is_last_page = False, False for problem in problems: if problem['effname'] == first: is_first_page = True if problem['effname'] == last: is_last_page = True return flask.render_template('problems.html', repo=repo, maintainer=maintainer, start=start, end=end, first=first, last=last, is_first_page=is_first_page, is_last_page=is_last_page, problems=problems)
def repositories_statistics(sorting=None): autorefresh = flask.request.args.to_dict().get('autorefresh') repostats = {repostat['name']: repostat for repostat in get_db().get_active_repositories()} repostats = [repostats[reponame] for reponame in repometadata.active_names() if reponame in repostats] showmedals = True if sorting == 'newest': repostats = sorted(repostats, key=lambda s: s['num_metapackages_newest'], reverse=True) elif sorting == 'pnewest': repostats = sorted(repostats, key=lambda s: safe_percent(s['num_metapackages_newest'], s['num_metapackages_comparable']), reverse=True) elif sorting == 'outdated': repostats = sorted(repostats, key=lambda s: s['num_metapackages_outdated'], reverse=True) elif sorting == 'poutdated': repostats = sorted(repostats, key=lambda s: safe_percent(s['num_metapackages_outdated'], s['num_metapackages_comparable']), reverse=True) elif sorting == 'total': repostats = sorted(repostats, key=lambda s: s['num_metapackages'], reverse=True) else: sorting = 'name' showmedals = False return flask.render_template( 'repositories-statistics.html', sorting=sorting, repostats=repostats, showmedals=showmedals, repostats_old={}, # {repo['name']: repo for repo in get_db().GetRepositoriesHistoryAgo(60 * 60 * 24 * 7)}, counts=get_db().get_counts(), autorefresh=autorefresh )
def badge_version_for_repo(repo: str, name: str) -> Response: if repo not in repometadata.active_names(): flask.abort(404) args = flask.request.args.to_dict() best_package = packageset_to_best( (PackageDataMinimal(**item) for item in get_db().get_metapackage_packages(name, repo=repo, minimal=True)), allow_ignored=args.get('allow_ignored', False)) left_cell = BadgeCell(flask.request.args.to_dict().get( 'header', repometadata[repo]['singular']), collapsible=True) if best_package is None: # Note: it would be more correct to return 404 with content here, # but some browsers (e.g. Firefox) won't display the image in that case right_cell = BadgeCell('-') else: minversion = flask.request.args.to_dict().get('minversion') unsatisfying = minversion and version_compare(best_package.version, minversion) < 0 right_cell = BadgeCell(best_package.version, badge_color(best_package.versionclass, unsatisfying), truncate=20) return render_generic_badge([[left_cell, right_cell]])
def repository_problems(repo): 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 project_information(name: str) -> Any: metapackage = get_db().get_metapackage(name) if not metapackage or metapackage['num_repos'] == 0: return handle_nonexisting_project(name, metapackage) packages = sorted( (PackageDataDetailed(**item) for item in get_db().get_metapackage_packages(name, detailed=True)), key=lambda package: package.repo + package.visiblename + package. version) information: Dict[str, Any] = {} def append_info(infokey: str, infoval: str, package: PackageDataDetailed) -> None: if infokey not in information: information[infokey] = {} if infoval not in information[infokey]: information[infokey][infoval] = set() information[infokey][infoval].add(package.family) for package in packages: append_info('names', package.visiblename, package) append_info('versions', package.version, package) append_info('repos', package.repo, package) if package.comment: append_info('summaries', package.comment, package) for maintainer in package.maintainers: append_info('maintainers', maintainer, package) if package.category: append_info('categories', package.category, package) if package.homepage: append_info('homepages', package.homepage, package) for download in package.downloads: append_info('downloads', download, package) for license_ in package.licenses: append_info('licenses', license_, package) if 'repos' in information: # preserve repos order information['repos'] = [(reponame, information['repos'][reponame]) for reponame in repometadata.active_names() if reponame in information['repos']] versions = packageset_aggregate_by_version( packages, {PackageStatus.LEGACY: PackageStatus.OUTDATED}) return flask.render_template( 'project-information.html', name=name, metapackage=metapackage, information=information, versions=versions, link_statuses=get_db().get_metapackage_link_statuses(name))
def metapackages_not_in_repo(repo, bound=None): if repo not in repometadata.active_names(): flask.abort(404) return flask.redirect( flask.url_for('metapackages', bound=bound, notinrepo=repo, search=flask.request.args.to_dict().get('search')), 301)
def metapackages_in_repo(repo: str, bound: Optional[str] = None) -> Any: if repo not in repometadata.active_names(): flask.abort(404) return flask.redirect( flask.url_for('projects', bound=bound, inrepo=repo, search=flask.request.args.to_dict().get('search')), 301)
def project_badges(name: str) -> Any: repos_present_in = set([package.repo for package in get_db().get_metapackage_packages(name)]) repos = [repo for repo in repometadata.active_names() if repo in repos_present_in] return flask.render_template( 'project-badges.html', metapackage=get_db().get_metapackage(name), name=name, repos=repos )
def metapackages_candidates_for_repo(repo, bound=None): if repo not in repometadata.active_names(): flask.abort(404) return flask.redirect( flask.url_for('projects', bound=bound, inrepo=repo, families='5-', search=flask.request.args.to_dict().get('search')), 301)
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 repositories_packages() -> Response: autorefresh = flask.request.args.to_dict().get('autorefresh') repostats_by_name = {repostat['name']: repostat for repostat in get_db().get_active_repositories()} repostats = [repostats_by_name[reponame] for reponame in repometadata.active_names() if reponame in repostats_by_name] return flask.render_template( 'repositories-packages.html', repostats=repostats, counts=get_db().get_counts(), autorefresh=autorefresh )
def metapackage_information(name): packages = get_db().get_metapackage_packages(name) packages = sorted( packages, key=lambda package: package.repo + package.name + package.version) information = {} def append_info(infokey, infoval, package): if infokey not in information: information[infokey] = {} if infoval not in information[infokey]: information[infokey][infoval] = set() information[infokey][infoval].add(package.family) for package in packages: append_info('names', package.name, package) append_info('versions', package.version, package) append_info('repos', package.repo, package) if package.comment: append_info('summaries', package.comment, package) for maintainer in package.maintainers: append_info('maintainers', maintainer, package) if package.category: append_info('categories', package.category, package) if package.homepage: append_info('homepages', package.homepage, package) for download in package.downloads: append_info('downloads', download, package) for license_ in package.licenses: append_info('licenses', license_, package) if 'repos' in information: # preserve repos order information['repos'] = [(reponame, information['repos'][reponame]) for reponame in repometadata.active_names() if reponame in information['repos']] versions = PackagesetAggregateByVersion( packages, {VersionClass.legacy: VersionClass.outdated}) return flask.render_template( 'metapackage-information.html', information=information, versions=versions, metapackage=get_db().get_metapackage(name), name=name, link_statuses=get_db().get_metapackage_link_statuses(name))
def metapackage_versions(name): packages_by_repo = defaultdict(list) for package in get_db().get_metapackage_packages(name): packages_by_repo[package.repo].append(package) for repo, packages in packages_by_repo.items(): packages_by_repo[repo] = PackagesetSortByVersion(packages) return flask.render_template( 'metapackage-versions.html', reponames_absent=[reponame for reponame in repometadata.active_names() if reponame not in packages_by_repo], packages_by_repo=packages_by_repo, name=name )
def repository(repo): 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))
def tool_project_by() -> Response: 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 repo not in repometadata.active_names(): return (flask.render_template('project-by-failed.html', reason='no_repo'), 404) elif not repometadata[repo]['family'] in _ALLOWED_FAMILIES: return (flask.render_template('project-by-failed.html', reason='disallowed_repo'), 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: return (flask.render_template('project-by-failed.html', reason='no_package'), 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 graph_repo_generic(repo: str, getvalue: Callable[[Any], float], color: str, suffix: str = '') -> Response: if repo not in repometadata.active_names(): flask.abort(404) def get_graph(period: int) -> GraphProcessor: graph = GraphProcessor() for histentry in get_db().get_repository_history_since(repo, datetime.timedelta(seconds=period)): try: graph.add_point(histentry['timedelta'], getvalue(histentry['snapshot'])) except: pass # ignore missing keys, division errors etc. return graph return graph_generic(get_graph, color, suffix)
def repository(repo: str) -> Response: 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 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, name=name, link_statuses=get_db().get_metapackage_link_statuses(name) )
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) packages = get_db().get_metapackage_packages(name) repos_present_in = set([package.repo for package in packages]) 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): 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( 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 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 project_packages(name: str) -> Any: metapackage = get_db().get_metapackage(name) if not metapackage or metapackage['num_repos'] == 0: return handle_nonexisting_project(name, metapackage) 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', name=name, metapackage=metapackage, packages=packages, link_statuses=get_db().get_metapackage_link_statuses(name) )
def metapackage_badges(name): repos_present_in = set([package.repo for package in get_db().get_metapackage_packages(name)]) repos = [repo for repo in repometadata.active_names() if repo in repos_present_in] return flask.render_template('metapackage-badges.html', name=name, repos=repos)
def project_information(name: str) -> Response: metapackage = get_db().get_metapackage(name) if not metapackage or metapackage['num_repos'] == 0: return handle_nonexisting_project(name, metapackage) packages = sorted( (PackageDataDetailed(**item) for item in get_db().get_metapackage_packages(name, detailed=True)), key=lambda package: (package.repo, package.visiblename, package.version)) information: Dict[str, Any] = {} def append_info(infokey: str, infoval: Any, package: PackageDataDetailed) -> None: if infokey not in information: information[infokey] = {} if infoval not in information[infokey]: information[infokey][infoval] = set() information[infokey][infoval].add(package.family) for package in packages: append_info('names', package.projectname_seed, package) append_info('versions', package.version, package) append_info('repos', package.repo, package) if package.comment: append_info('summaries', package.comment, package) if package.maintainers is not None: for maintainer in package.maintainers: append_info('maintainers', maintainer, package) if package.category: append_info('categories', package.category, package) if package.licenses is not None: for license_ in package.licenses: append_info('licenses', license_, package) if package.links is not None: maybe_raw_links = defaultdict(list) for link_type, link_id in package.links: if link_type in [ LinkType.UPSTREAM_HOMEPAGE, LinkType.PROJECT_HOMEPAGE ]: append_info('homepages', link_id, package) elif link_type in [ LinkType.UPSTREAM_DOWNLOAD, LinkType.PROJECT_DOWNLOAD ]: append_info('downloads', link_id, package) elif link_type == LinkType.UPSTREAM_ISSUE_TRACKER: append_info('issues', link_id, package) elif link_type == LinkType.UPSTREAM_REPOSITORY: append_info('repositories', link_id, package) elif link_type == LinkType.UPSTREAM_DOCUMENTATION: append_info('documentation', link_id, package) elif link_type == LinkType.PACKAGE_HOMEPAGE: append_info('packages', link_id, package) elif link_type == LinkType.PACKAGE_RECIPE: maybe_raw_links['recipes'].append(link_id) elif link_type == LinkType.PACKAGE_RECIPE_RAW: maybe_raw_links['recipes_raw'].append(link_id) elif link_type == LinkType.PACKAGE_PATCH: maybe_raw_links['patches'].append(link_id) elif link_type == LinkType.PACKAGE_PATCH_RAW: maybe_raw_links['patches_raw'].append(link_id) elif link_type == LinkType.PACKAGE_BUILD_LOG: maybe_raw_links['buildlogs'].append(link_id) elif link_type == LinkType.PACKAGE_BUILD_LOG_RAW: maybe_raw_links['buildlogs_raw'].append(link_id) # for links which may have both human-readlabe and raw flavors, we # prefer human-readable ones here for key in ['recipes', 'patches', 'buildlogs']: if key in maybe_raw_links: for link_id in maybe_raw_links[key]: append_info(key, link_id, package) elif key + '_raw' in maybe_raw_links: for link_id in maybe_raw_links[key + '_raw']: append_info(key, link_id, package) if 'repos' in information: # preserve repos order information['repos'] = [(reponame, information['repos'][reponame]) for reponame in repometadata.active_names() if reponame in information['repos']] versions = packageset_aggregate_by_version( packages, {PackageStatus.LEGACY: PackageStatus.OUTDATED}) links = get_db().get_project_links(name) for key in [ 'homepages', 'downloads', 'issues', 'repositories', 'patches', 'buildlogs', 'documentation', 'recipes' ]: if key in information: information[key] = sorted( information[key].items(), key=lambda l: links[l[0]]['url'].lower() # type: ignore ) return flask.render_template('project-information.html', name=name, metapackage=metapackage, information=information, versions=versions, links=links)