Skip to content

Commit

Permalink
Switch endpoint_like to endpoint groups for compatibility with tera
Browse files Browse the repository at this point in the history
  • Loading branch information
AMDmi3 committed Sep 17, 2024
1 parent bc5e43e commit 0b29846
Show file tree
Hide file tree
Showing 16 changed files with 105 additions and 79 deletions.
5 changes: 3 additions & 2 deletions repologyapp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
from repologyapp.config import config
from repologyapp.globals import repometadata
from repologyapp.template_filters import css_for_versionclass, extract_netloc, maintainer_to_links, maintainers_to_group_mailto
from repologyapp.template_functions import endpoint_like, needs_ipv6_notice, url_for, url_for_self, url_for_static
from repologyapp.template_functions import needs_ipv6_notice, url_for, url_for_self, url_for_static
from repologyapp.template_functions_extra import current_endpoint_group_in
from repologyapp.template_tests import for_page, has_flag, has_flag_at, is_fallback_maintainer
from repologyapp.views import registry as view_registry

Expand Down Expand Up @@ -60,6 +61,7 @@
app.jinja_env.tests['has_flag_at'] = has_flag_at

# templates: custom global functions
app.jinja_env.globals['current_endpoint_group_in'] = current_endpoint_group_in
app.jinja_env.globals['url_for'] = url_for
app.jinja_env.globals['url_for_self'] = url_for_self
app.jinja_env.globals['url_for_static'] = url_for_static
Expand All @@ -73,6 +75,5 @@
app.jinja_env.globals['utc'] = zoneinfo.ZoneInfo('UTC')
app.jinja_env.globals['now'] = lambda: datetime.datetime.now(zoneinfo.ZoneInfo('UTC'))
app.jinja_env.globals['randrange'] = random.randrange
app.jinja_env.globals['endpoint_like'] = endpoint_like

view_registry.register_in_flask(app)
15 changes: 0 additions & 15 deletions repologyapp/template_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,6 @@ def url_for_static(**args: Any) -> Any:
return url_for(endpoint='static', filename=args['file'])


def endpoint_like(*variants: str) -> bool:
python_endpoint = flask.request.endpoint
rust_endpoint = PYTHON_TO_RUST_ENDPOINT_NAMES.get(python_endpoint)

for variant in variants:
if python_endpoint == variant or rust_endpoint == variant:
return True
elif variant.endswith('*') and python_endpoint and python_endpoint.startswith(variant[:-1]):
return True
elif variant.endswith('*') and rust_endpoint and rust_endpoint.startswith(variant[:-1]):
return True

return False


def needs_ipv6_notice(*variants: str) -> bool:
now = datetime.datetime.now()
return now.month == 6 and now.day == 6 and ':' not in flask.request.environ.REMOTE_ADDR and flask.request.endpoint != 'index'
24 changes: 24 additions & 0 deletions repologyapp/template_functions_extra.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright (C) 2024 Dmitry Marakasov <amdmi3@amdmi3.ru>
#
# This file is part of repology
#
# repology is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# repology is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with repology. If not, see <http://www.gnu.org/licenses/>.

from typing import Any

from repologyapp.views import registry as view_registry


def current_endpoint_group_in(**args: Any) -> str | None:
return view_registry.get_current_endpoint_group() in args['groups']
18 changes: 9 additions & 9 deletions repologyapp/templates/_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,19 @@

<div class="collapse navbar-collapse" id="repology-navbar-collapse">
<ul class="nav navbar-nav">
<li{% if endpoint_like('projects', 'project_*') %} class="active"{% endif %}><a href="{{ url_for(endpoint='projects') }}">Projects</a></li>
<li{% if endpoint_like('maintainers', 'maintainer') %} class="active"{% endif %}><a href="{{ url_for(endpoint='maintainers') }}">Maintainers</a></li>
<li{% if endpoint_like('repositories_*', 'repository') %} class="active"{% endif %}><a href="{{ url_for(endpoint='repositories_statistics') }}">Repositories</a></li>
<li{% if endpoint_like('tools', 'tool_*', 'trending') %} class="active"{% endif %}><a href="{{ url_for(endpoint='tools') }}">Tools</a></li>
<li{% if endpoint_like('security_*') %} class="active"{% endif %}><a href="{{ url_for(endpoint='security_recent_cves') }}">Security</a></li>
{% if session.admin %}<li{% if endpoint_like('admin', 'admin_*') %} class="active"{% endif %}><a href="{{ url_for(endpoint='admin') }}">Admin</a></li>{% endif %}
<li{% if current_endpoint_group_in(groups=['Projects']) %} class="active"{% endif %}><a href="{{ url_for(endpoint='projects') }}">Projects</a></li>
<li{% if current_endpoint_group_in(groups=['Maintainers']) %} class="active"{% endif %}><a href="{{ url_for(endpoint='maintainers') }}">Maintainers</a></li>
<li{% if current_endpoint_group_in(groups=['Repositories']) %} class="active"{% endif %}><a href="{{ url_for(endpoint='repositories_statistics') }}">Repositories</a></li>
<li{% if current_endpoint_group_in(groups=['Tools']) %} class="active"{% endif %}><a href="{{ url_for(endpoint='tools') }}">Tools</a></li>
<li{% if current_endpoint_group_in(groups=['Security']) %} class="active"{% endif %}><a href="{{ url_for(endpoint='security_recent_cves') }}">Security</a></li>
{% if session.admin %}<li{% if current_endpoint_group_in(graoups=['Admin']) %} class="active"{% endif %}><a href="{{ url_for(endpoint='admin') }}">Admin</a></li>{% endif %}
</ul>
<ul class="nav navbar-nav navbar-right">
{% if session.experimental %}
<li{% if endpoint_like('experimental') %} class="active"{% endif %}><a href="{{ url_for(endpoint='experimental') }}">Experimental</a></li>
<li{% if current_endpoint_group_in(groups=['Experimental']) %} class="active"{% endif %}><a href="{{ url_for(endpoint='experimental') }}">Experimental</a></li>
{% endif %}
<li{% if endpoint_like('news') %} class="active"{% endif %}><a href="{{ url_for(endpoint='news') }}">News</a></li>
<li{% if endpoint_like('docs', 'docs_*', 'api_v1') %} class="active"{% endif %}><a href="{{ url_for(endpoint='docs') }}">Docs</a></li>
<li{% if current_endpoint_group_in(groups=['News']) %} class="active"{% endif %}><a href="{{ url_for(endpoint='news') }}">News</a></li>
<li{% if current_endpoint_group_in(groups=['Docs']) %} class="active"{% endif %}><a href="{{ url_for(endpoint='docs') }}">Docs</a></li>
</ul>
</div>
</div>
Expand Down
16 changes: 16 additions & 0 deletions repologyapp/view_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class ViewRegistrant():
_next: Union['ViewRegistrant', None]
_route: str
_options: dict[str, Any]
_group: str | None

def __init__(self, f: 'ViewRegistrant' | _ViewFunc, route: str, options: dict[str, Any]) -> None:
if isinstance(f, ViewRegistrant):
Expand All @@ -60,6 +61,9 @@ def __init__(self, f: 'ViewRegistrant' | _ViewFunc, route: str, options: dict[st

self._route = route
self._options = options
self._group = options.get('group')
if self._group:
del options['group']

def __call__(self, *args: Any, **kwargs: Any) -> Any:
return self._f(*args, **kwargs)
Expand All @@ -69,6 +73,9 @@ def register_in_flask(self, app: flask.Flask) -> None:
if self._next is not None:
self._next.register_in_flask(app)

def get_name_to_group(self) -> tuple[str, str | None]:
return (self._f.__name__, self._group)


class ViewRegistrar():
_route: str
Expand All @@ -84,6 +91,7 @@ def __call__(self, f: _ViewFunc) -> ViewRegistrant:

class ViewRegistry():
_registrants: list[ViewRegistrant]
_groups_by_endpoint: dict[str, str]

def __init__(self, pkgname: str, pkgfile: str) -> None:
self._registrants = []
Expand All @@ -93,6 +101,14 @@ def __init__(self, pkgname: str, pkgfile: str) -> None:
if isinstance(member, ViewRegistrant):
self._registrants.append(member)

self._group_by_endpoint = {}
for (name, group) in [registrant.get_name_to_group() for registrant in self._registrants]:
if group:
self._group_by_endpoint[name] = group

def register_in_flask(self, app: flask.Flask) -> None:
for registrant in self._registrants:
registrant.register_in_flask(app)

def get_current_endpoint_group(self) -> str | None:
return self._group_by_endpoint.get(flask.request.endpoint)
18 changes: 9 additions & 9 deletions repologyapp/views/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def unauthorized() -> Response:
return flask.redirect(flask.url_for('admin'))


@ViewRegistrar('/admin', methods=['GET', 'POST'])
@ViewRegistrar('/admin', methods=['GET', 'POST'], group='Admin')
def admin() -> Response:
if flask.request.method == 'GET' and flask.session.get('admin'):
return flask.redirect(flask.url_for('admin_reports_unprocessed'), 302)
Expand Down Expand Up @@ -82,17 +82,17 @@ def admin_reports_generic(report_getter: Callable[[], dict[str, Any]]) -> Respon
return flask.render_template('admin/reports.html', reports=report_getter())


@ViewRegistrar('/admin/reports/unprocessed/', methods=['GET', 'POST'])
@ViewRegistrar('/admin/reports/unprocessed/', methods=['GET', 'POST'], group='Admin')
def admin_reports_unprocessed() -> Response:
return admin_reports_generic(lambda: get_db().get_unprocessed_reports(limit=config['REPORTS_PER_PAGE']))


@ViewRegistrar('/admin/reports/recent/', methods=['GET', 'POST'])
@ViewRegistrar('/admin/reports/recent/', methods=['GET', 'POST'], group='Admin')
def admin_reports_recent() -> Response:
return admin_reports_generic(lambda: get_db().get_recently_updated_reports(limit=config['REPORTS_PER_PAGE']))


@ViewRegistrar('/admin/updates')
@ViewRegistrar('/admin/updates', group='Admin')
def admin_updates() -> Response:
if not flask.session.get('admin'):
return unauthorized()
Expand All @@ -103,7 +103,7 @@ def admin_updates() -> Response:
)


@ViewRegistrar('/admin/redirects', methods=['GET', 'POST'])
@ViewRegistrar('/admin/redirects', methods=['GET', 'POST'], group='Admin')
def admin_redirects() -> Response:
if not flask.session.get('admin'):
return unauthorized()
Expand Down Expand Up @@ -159,7 +159,7 @@ def admin_redirects() -> Response:
)


@ViewRegistrar('/admin/name_samples')
@ViewRegistrar('/admin/name_samples', group='Admin')
def admin_name_samples() -> Response:
if not flask.session.get('admin'):
return unauthorized()
Expand Down Expand Up @@ -284,7 +284,7 @@ def check_required_cpe_fields() -> bool:
return flask.redirect(url_for_self(), 302)


@ViewRegistrar('/admin/cpes', methods=['GET', 'POST'])
@ViewRegistrar('/admin/cpes', methods=['GET', 'POST'], group='Admin')
def admin_cpes() -> Response:
if not flask.session.get('admin'):
return unauthorized()
Expand All @@ -299,7 +299,7 @@ def admin_cpes() -> Response:
)


@ViewRegistrar('/admin/cve_misses', methods=['GET', 'POST'])
@ViewRegistrar('/admin/cve_misses', methods=['GET', 'POST'], group='Admin')
def admin_cve_misses() -> Response:
if not flask.session.get('admin'):
return unauthorized()
Expand All @@ -314,7 +314,7 @@ def admin_cve_misses() -> Response:
)


@ViewRegistrar('/admin/omni_cves')
@ViewRegistrar('/admin/omni_cves', group='Admin')
def admin_omni_cves() -> Response:
if not flask.session.get('admin'):
return unauthorized()
Expand Down
4 changes: 2 additions & 2 deletions repologyapp/views/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ def dump_json(data: Any) -> str:
return json.dumps(data, separators=(',', ':'))


@ViewRegistrar('/api')
@ViewRegistrar('/api/v1')
@ViewRegistrar('/api', group='Docs')
@ViewRegistrar('/api/v1', group='Docs')
def api_v1() -> Response:
return flask.render_template('api.html', per_page=config['METAPACKAGES_PER_PAGE'])

Expand Down
6 changes: 3 additions & 3 deletions repologyapp/views/experimental.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from repologyapp.view_registry import Response, ViewRegistrar


@ViewRegistrar('/experimental/', methods=['GET', 'POST'])
@ViewRegistrar('/experimental/', methods=['GET', 'POST'], group='Experimental')
def experimental() -> Response:
if flask.request.method == 'POST':
enabled = flask.request.form.get('experimental') == 'enable'
Expand All @@ -34,7 +34,7 @@ def experimental() -> Response:
return flask.render_template('experimental/index.html')


@ViewRegistrar('/experimental/turnover/maintainers')
@ViewRegistrar('/experimental/turnover/maintainers', group='Experimental')
def maintainers_turnover() -> Response:
return flask.render_template(
'experimental/maintainers-turnover.html',
Expand All @@ -43,6 +43,6 @@ def maintainers_turnover() -> Response:
)


@ViewRegistrar('/experimental/distromap')
@ViewRegistrar('/experimental/distromap', group='Experimental')
def distromap() -> Response:
return flask.render_template('experimental/distromap.html')
12 changes: 6 additions & 6 deletions repologyapp/views/maintainers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
from repologyapp.views.problems import problems_generic


@ViewRegistrar('/maintainers/')
@ViewRegistrar('/maintainers/<bound>/')
@ViewRegistrar('/maintainers/', group='Maintainers')
@ViewRegistrar('/maintainers/<bound>/', group='Maintainers')
def maintainers(bound: str | None = None) -> Response:
reverse = False
if bound and bound.startswith('..'):
Expand Down Expand Up @@ -81,7 +81,7 @@ def maintainers(bound: str | None = None) -> Response:
)


@ViewRegistrar('/maintainer/<maintainer>')
@ViewRegistrar('/maintainer/<maintainer>', group='Maintainers')
def maintainer(maintainer: str) -> Response:
maintainer = maintainer.lower()

Expand Down Expand Up @@ -137,7 +137,7 @@ class RepositoryInfo:
)


@ViewRegistrar('/maintainer/<maintainer>/problems-for-repo/<repo>')
@ViewRegistrar('/maintainer/<maintainer>/problems-for-repo/<repo>', group='Maintainers')
def maintainer_problems(maintainer: str, repo: str) -> Response:
return problems_generic(
repo=repo,
Expand All @@ -147,7 +147,7 @@ def maintainer_problems(maintainer: str, repo: str) -> Response:
)


@ViewRegistrar('/maintainer/<maintainer>/feed-for-repo/<repo>')
@ViewRegistrar('/maintainer/<maintainer>/feed-for-repo/<repo>', group='Maintainers')
def maintainer_repo_feed(maintainer: str, repo: str) -> Response:
autorefresh = flask.request.args.to_dict().get('autorefresh')

Expand All @@ -166,7 +166,7 @@ def maintainer_repo_feed(maintainer: str, repo: str) -> Response:
)


@ViewRegistrar('/maintainer/<maintainer>/feed-for-repo/<repo>/atom')
@ViewRegistrar('/maintainer/<maintainer>/feed-for-repo/<repo>/atom', group='Maintainers')
def maintainer_repo_feed_atom(maintainer: str, repo: str) -> Response:
return (
flask.render_template(
Expand Down
18 changes: 9 additions & 9 deletions repologyapp/views/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def handle_nonexisting_project(name: str, metapackage: dict[str, Any]) -> Respon
)


@ViewRegistrar('/project/<name>/versions')
@ViewRegistrar('/project/<name>/versions', group='Projects')
def project_versions(name: str) -> Response:
metapackage = get_db().get_metapackage(name)

Expand Down Expand Up @@ -112,7 +112,7 @@ def project_versions(name: str) -> Response:
)


@ViewRegistrar('/project/<name>/versions-compact')
@ViewRegistrar('/project/<name>/versions-compact', group='Projects')
def project_versions_compact(name: str) -> Response:
metapackage = get_db().get_metapackage(name)

Expand Down Expand Up @@ -142,7 +142,7 @@ def project_versions_compact(name: str) -> Response:
)


@ViewRegistrar('/project/<name>/packages')
@ViewRegistrar('/project/<name>/packages', group='Projects')
def project_packages(name: str) -> Response:
metapackage = get_db().get_metapackage(name)

Expand Down Expand Up @@ -209,7 +209,7 @@ def _link_type_is_raw(link_type: int) -> bool:
_LinkKey: TypeAlias = tuple[int] | tuple[int, str] # id, fragment


@ViewRegistrar('/project/<name>/information')
@ViewRegistrar('/project/<name>/information', group='Projects')
def project_information(name: str) -> Response:
metapackage = get_db().get_metapackage(name)

Expand Down Expand Up @@ -308,7 +308,7 @@ def project_information(name: str) -> Response:
)


@ViewRegistrar('/project/<name>/history')
@ViewRegistrar('/project/<name>/history', group='Projects')
def project_history(name: str) -> Response:
def prepare_repos(repos: Collection[str]) -> list[str]:
if not repos:
Expand Down Expand Up @@ -401,7 +401,7 @@ def postprocess_history(history: list[dict[str, Any]]) -> Iterable[dict[str, Any
)


@ViewRegistrar('/project/<name>/related')
@ViewRegistrar('/project/<name>/related', group='Projects')
def project_related(name: str) -> Response:
metapackage = get_db().get_metapackage(name)

Expand Down Expand Up @@ -432,7 +432,7 @@ def project_related(name: str) -> Response:
)


@ViewRegistrar('/project/<name>/badges')
@ViewRegistrar('/project/<name>/badges', group='Projects')
def project_badges(name: str) -> Response:
metapackage = get_db().get_metapackage(name)

Expand All @@ -453,7 +453,7 @@ def project_badges(name: str) -> Response:
)


@ViewRegistrar('/project/<name>/report', methods=['GET', 'POST'])
@ViewRegistrar('/project/<name>/report', methods=['GET', 'POST'], group='Projects')
def project_report(name: str) -> Response:
metapackage = get_db().get_metapackage(name)

Expand Down Expand Up @@ -573,7 +573,7 @@ class _CVEAggregation:
cpe_other: str


@ViewRegistrar('/project/<name>/cves')
@ViewRegistrar('/project/<name>/cves', group='Projects')
def project_cves(name: str) -> Response:
metapackage = get_db().get_metapackage(name)

Expand Down
Loading

0 comments on commit 0b29846

Please sign in to comment.