mirror of
https://github.com/minetest/contentdb.git
synced 2025-01-03 11:47:28 +01:00
Add translators' page
This commit is contained in:
parent
7c59c1c5b1
commit
dd6f36bd2b
44
app/blueprints/translate/__init__.py
Normal file
44
app/blueprints/translate/__init__.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# ContentDB
|
||||||
|
# Copyright (C) 2024 rubenwardy
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
from flask import Blueprint, render_template, request
|
||||||
|
|
||||||
|
from app.models import Package, PackageState, db, PackageTranslation
|
||||||
|
|
||||||
|
bp = Blueprint("translate", __name__)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/translate/")
|
||||||
|
def translate():
|
||||||
|
query = Package.query.filter(
|
||||||
|
Package.state == PackageState.APPROVED,
|
||||||
|
Package.translations.any(PackageTranslation.language_id != "en"))
|
||||||
|
|
||||||
|
has_langs = request.args.getlist("has_lang")
|
||||||
|
for lang in has_langs:
|
||||||
|
query = query.filter(Package.translations.any(PackageTranslation.language_id == lang))
|
||||||
|
|
||||||
|
not_langs = request.args.getlist("not_lang")
|
||||||
|
for lang in not_langs:
|
||||||
|
query = query.filter(~Package.translations.any(PackageTranslation.language_id == lang))
|
||||||
|
|
||||||
|
supports_translation = (query
|
||||||
|
.order_by(Package.translation_url.is_(None), db.desc(Package.score))
|
||||||
|
.all())
|
||||||
|
|
||||||
|
return render_template("translate/index.html",
|
||||||
|
supports_translation=supports_translation, has_langs=has_langs, not_langs=not_langs)
|
@ -18,7 +18,7 @@ from datetime import datetime as dt
|
|||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
from flask import request, has_request_context
|
from flask import request, has_request_context
|
||||||
from flask_babel import format_timedelta, gettext
|
from flask_babel import format_timedelta, gettext, get_locale
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from markupsafe import Markup
|
from markupsafe import Markup
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ def inject_misc():
|
|||||||
hide_nonfree = False
|
hide_nonfree = False
|
||||||
if has_request_context():
|
if has_request_context():
|
||||||
hide_nonfree = request.cookies.get("hide_nonfree") == "1"
|
hide_nonfree = request.cookies.get("hide_nonfree") == "1"
|
||||||
return dict(debug=app.debug, hide_nonfree=hide_nonfree)
|
return dict(debug=app.debug, hide_nonfree=hide_nonfree, locale=get_locale())
|
||||||
|
|
||||||
|
|
||||||
@app.context_processor
|
@app.context_processor
|
||||||
|
@ -255,6 +255,7 @@
|
|||||||
<li class="list-inline-item"><a href="{{ url_for('threads.list_all') }}">{{ _("Threads") }}</a></li>
|
<li class="list-inline-item"><a href="{{ url_for('threads.list_all') }}">{{ _("Threads") }}</a></li>
|
||||||
<li class="list-inline-item"><a href="{{ url_for('collections.list_all') }}">{{ _("Collections") }}</a></li>
|
<li class="list-inline-item"><a href="{{ url_for('collections.list_all') }}">{{ _("Collections") }}</a></li>
|
||||||
<li class="list-inline-item"><a href="{{ url_for('donate.donate') }}">{{ _("Support Packages") }}</a></li>
|
<li class="list-inline-item"><a href="{{ url_for('donate.donate') }}">{{ _("Support Packages") }}</a></li>
|
||||||
|
<li class="list-inline-item"><a href="{{ url_for('translate.translate') }}">{{ _("Translate Packages") }}</a></li>
|
||||||
<li class="list-inline-item"><a href="https://github.com/minetest/contentdb">{{ _("Source Code") }}</a></li>
|
<li class="list-inline-item"><a href="https://github.com/minetest/contentdb">{{ _("Source Code") }}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
90
app/templates/translate/index.html
Normal file
90
app/templates/translate/index.html
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title -%}
|
||||||
|
{{ _("Find packages to translate") }}
|
||||||
|
{%- endblock %}
|
||||||
|
|
||||||
|
{% block description -%}
|
||||||
|
{{ _("Help make Minetest more accessible by translating packages into other languages.") }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% macro render_packages(packages) %}
|
||||||
|
<ul class="list-group">
|
||||||
|
{% for package in packages %}
|
||||||
|
<li class="list-group-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-auto text-muted" style="min-width: 250px;">
|
||||||
|
<a href="{{ package.get_url('packages.view') }}">
|
||||||
|
<img
|
||||||
|
class="img-fluid"
|
||||||
|
style="max-height: 22px; max-width: 22px;"
|
||||||
|
src="{{ package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
|
{% set title %}
|
||||||
|
<strong>{{ package.title }}</strong>
|
||||||
|
{% endset %}
|
||||||
|
|
||||||
|
<span class="ps-2">
|
||||||
|
{{ _("%(title)s by %(author)s", title=title, author=package.author.display_name) }}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-auto">
|
||||||
|
<a href="{{ package.get_url('packages.view') }}" class="btn btn-sm btn-secondary me-1">
|
||||||
|
{{ _("View package") }}
|
||||||
|
</a>
|
||||||
|
{% if package.translation_url %}
|
||||||
|
<a href="{{ package.translation_url }}" class="btn btn-sm btn-primary" rel="ugc">
|
||||||
|
<i class="fas fa-language me-1"></i>
|
||||||
|
{{ _("Translate") }}
|
||||||
|
</a>
|
||||||
|
{% elif package.repo %}
|
||||||
|
<a href="{{ package.repo }}" class="btn btn-sm btn-primary" rel="ugc">
|
||||||
|
<i class="fas fa-code me-1"></i>
|
||||||
|
{{ _("Source") }}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="list-group-item text-muted">
|
||||||
|
{{ _("No packages available") }}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ self.title() }}</h1>
|
||||||
|
<p class="lead">
|
||||||
|
{{ self.description() }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 id="contentdb">{{ _("ContentDB") }}</h2>
|
||||||
|
<p>
|
||||||
|
<a href="https://hosted.weblate.org/projects/minetest/contentdb/" class="btn btn-primary">
|
||||||
|
{{ _("Help translate ContentDB") }}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 id="packages-that-support-translation">{{ _("Packages that support translation") }}</h2>
|
||||||
|
{% if locale and locale.language != "en" %}
|
||||||
|
<p class="mb-4">
|
||||||
|
<a href="{{ url_set_query(_toggle={ 'has_lang': locale.language }) }}"
|
||||||
|
class="btn {% if locale.language in has_langs %}btn-primary{% else %}btn-secondary{% endif %} me-2">
|
||||||
|
{{ _("Only show packages with %(lang)s translation", lang=locale.get_language_name(locale)) }}
|
||||||
|
</a>
|
||||||
|
<a href="{{ url_set_query(_toggle={ 'not_lang': locale.language }) }}"
|
||||||
|
class="btn {% if locale.language in not_langs %}btn-primary{% else %}btn-secondary{% endif %}">
|
||||||
|
{{ _("Hide packages with %(lang)s translation", lang=locale.get_language_name(locale)) }}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{{ render_packages(supports_translation) }}
|
||||||
|
{% endblock %}
|
@ -87,7 +87,15 @@ def url_set_query(**kwargs):
|
|||||||
args = MultiDict(request.args)
|
args = MultiDict(request.args)
|
||||||
|
|
||||||
for key, value in kwargs.items():
|
for key, value in kwargs.items():
|
||||||
if key == "_add":
|
if key == "_toggle":
|
||||||
|
for key2, value_to_add in value.items():
|
||||||
|
values = set(args.getlist(key2))
|
||||||
|
if value_to_add in values:
|
||||||
|
values.discard(value_to_add)
|
||||||
|
else:
|
||||||
|
values.add(value_to_add)
|
||||||
|
args.setlist(key2, list(values))
|
||||||
|
elif key == "_add":
|
||||||
for key2, value_to_add in value.items():
|
for key2, value_to_add in value.items():
|
||||||
values = set(args.getlist(key2))
|
values = set(args.getlist(key2))
|
||||||
values.add(value_to_add)
|
values.add(value_to_add)
|
||||||
|
Loading…
Reference in New Issue
Block a user