Replace 'Minetest' with 'Luanti' in remaining places

This commit is contained in:
rubenwardy
2025-08-25 14:21:43 +01:00
committed by GitHub
parent 1c2a56e784
commit 6265c0665b
36 changed files with 146 additions and 127 deletions

View File

@@ -1,5 +1,5 @@
# ContentDB # ContentDB
![Build Status](https://github.com/minetest/contentdb/actions/workflows/test.yml/badge.svg) ![Build Status](https://github.com/luanti-org/contentdb/actions/workflows/test.yml/badge.svg)
A content database for Luanti mods, games, and more.\ A content database for Luanti mods, games, and more.\
Developed by rubenwardy, license AGPLv3.0+. Developed by rubenwardy, license AGPLv3.0+.
@@ -82,7 +82,7 @@ Package "1" --> "*" Release
Package "1" --> "*" Dependency Package "1" --> "*" Dependency
Package "1" --> "*" Tag Package "1" --> "*" Tag
Package "1" --> "*" MetaPackage : provides Package "1" --> "*" MetaPackage : provides
Release --> MinetestVersion Release --> LuantiVersion
Package --> License Package --> License
Dependency --> Package Dependency --> Package
Dependency --> MetaPackage Dependency --> MetaPackage

View File

@@ -23,14 +23,14 @@ from wtforms.validators import InputRequired, Length
from app.utils import rank_required, add_audit_log from app.utils import rank_required, add_audit_log
from . import bp from . import bp
from app.models import UserRank, MinetestRelease, db, AuditSeverity from app.models import UserRank, LuantiRelease, db, AuditSeverity
@bp.route("/versions/") @bp.route("/versions/")
@rank_required(UserRank.MODERATOR) @rank_required(UserRank.MODERATOR)
def version_list(): def version_list():
return render_template("admin/versions/list.html", return render_template("admin/versions/list.html",
versions=MinetestRelease.query.order_by(db.asc(MinetestRelease.id)).all()) versions=LuantiRelease.query.order_by(db.asc(LuantiRelease.id)).all())
class VersionForm(FlaskForm): class VersionForm(FlaskForm):
@@ -45,14 +45,14 @@ class VersionForm(FlaskForm):
def create_edit_version(name=None): def create_edit_version(name=None):
version = None version = None
if name is not None: if name is not None:
version = MinetestRelease.query.filter_by(name=name).first() version = LuantiRelease.query.filter_by(name=name).first()
if version is None: if version is None:
abort(404) abort(404)
form = VersionForm(formdata=request.form, obj=version) form = VersionForm(formdata=request.form, obj=version)
if form.validate_on_submit(): if form.validate_on_submit():
if version is None: if version is None:
version = MinetestRelease(form.name.data) version = LuantiRelease(form.name.data)
db.session.add(version) db.session.add(version)
flash("Created version " + form.name.data, "success") flash("Created version " + form.name.data, "success")

View File

@@ -29,12 +29,12 @@ from app import csrf
from app.logic.graphs import get_package_stats, get_package_stats_for_user, get_all_package_stats from app.logic.graphs import get_package_stats, get_package_stats_for_user, get_all_package_stats
from app.markdown import render_markdown from app.markdown import render_markdown
from app.models import Tag, PackageState, PackageType, Package, db, PackageRelease, Permission, \ from app.models import Tag, PackageState, PackageType, Package, db, PackageRelease, Permission, \
MinetestRelease, APIToken, PackageScreenshot, License, ContentWarning, User, PackageReview, Thread, Collection, \ LuantiRelease, APIToken, PackageScreenshot, License, ContentWarning, User, PackageReview, Thread, Collection, \
PackageAlias, Language PackageAlias, Language
from app.querybuilder import QueryBuilder from app.querybuilder import QueryBuilder
from app.utils import is_package_page, get_int_or_abort, url_set_query, abs_url, is_yes, get_request_date, cached, \ from app.utils import is_package_page, get_int_or_abort, url_set_query, abs_url, is_yes, get_request_date, cached, \
cors_allowed cors_allowed
from app.utils.minetest_hypertext import html_to_minetest, package_info_as_hypertext, package_reviews_as_hypertext from app.utils.luanti_hypertext import html_to_luanti, package_info_as_hypertext, package_reviews_as_hypertext
from . import bp from . import bp
from .auth import is_api_authd from .auth import is_api_authd
from .support import error, api_create_vcs_release, api_create_zip_release, api_create_screenshot, \ from .support import error, api_create_vcs_release, api_create_zip_release, api_create_screenshot, \
@@ -102,7 +102,7 @@ def package_view_client(package: Package):
protocol_version = request.args.get("protocol_version") protocol_version = request.args.get("protocol_version")
engine_version = request.args.get("engine_version") engine_version = request.args.get("engine_version")
if protocol_version or engine_version: if protocol_version or engine_version:
version = MinetestRelease.get(engine_version, get_int_or_abort(protocol_version)) version = LuantiRelease.get(engine_version, get_int_or_abort(protocol_version))
else: else:
version = None version = None
@@ -116,7 +116,7 @@ def package_view_client(package: Package):
page_url = package.get_url("packages.view", absolute=True) page_url = package.get_url("packages.view", absolute=True)
if data["long_description"] is not None: if data["long_description"] is not None:
html = render_markdown(data["long_description"]) html = render_markdown(data["long_description"])
data["long_description"] = html_to_minetest(html, page_url, formspec_version, include_images) data["long_description"] = html_to_luanti(html, page_url, formspec_version, include_images)
data["info_hypertext"] = package_info_as_hypertext(package, formspec_version) data["info_hypertext"] = package_info_as_hypertext(package, formspec_version)
@@ -153,7 +153,7 @@ def package_hypertext(package):
include_images = is_yes(request.args.get("include_images", "true")) include_images = is_yes(request.args.get("include_images", "true"))
html = render_markdown(package.desc if package.desc else "") html = render_markdown(package.desc if package.desc else "")
page_url = package.get_url("packages.view", absolute=True) page_url = package.get_url("packages.view", absolute=True)
return jsonify(html_to_minetest(html, page_url, formspec_version, include_images)) return jsonify(html_to_luanti(html, page_url, formspec_version, include_images))
@bp.route("/api/packages/<author>/<name>/", methods=["PUT"]) @bp.route("/api/packages/<author>/<name>/", methods=["PUT"])
@@ -636,14 +636,14 @@ def versions():
protocol_version = request.args.get("protocol_version") protocol_version = request.args.get("protocol_version")
engine_version = request.args.get("engine_version") engine_version = request.args.get("engine_version")
if protocol_version or engine_version: if protocol_version or engine_version:
rel = MinetestRelease.get(engine_version, get_int_or_abort(protocol_version)) rel = LuantiRelease.get(engine_version, get_int_or_abort(protocol_version))
if rel is None: if rel is None:
error(404, "No releases found") error(404, "No releases found")
return jsonify(rel.as_dict()) return jsonify(rel.as_dict())
return jsonify([rel.as_dict() \ return jsonify([rel.as_dict() \
for rel in MinetestRelease.query.all() if rel.get_actual() is not None]) for rel in LuantiRelease.query.all() if rel.get_actual() is not None])
@bp.route("/api/languages/") @bp.route("/api/languages/")
@@ -835,7 +835,7 @@ def hypertext():
if request.content_type == "text/markdown": if request.content_type == "text/markdown":
html = render_markdown(html) html = render_markdown(html)
return jsonify(html_to_minetest(html, "", formspec_version, include_images)) return jsonify(html_to_luanti(html, "", formspec_version, include_images))
@bp.route("/api/collections/") @bp.route("/api/collections/")
@@ -886,9 +886,9 @@ def collection_view(token, author, name):
@cached(300) @cached(300)
def updates(): def updates():
protocol_version = get_int_or_abort(request.args.get("protocol_version")) protocol_version = get_int_or_abort(request.args.get("protocol_version"))
minetest_version = request.args.get("engine_version") engine_version = request.args.get("engine_version")
if protocol_version or minetest_version: if protocol_version or engine_version:
version = MinetestRelease.get(minetest_version, protocol_version) version = LuantiRelease.get(engine_version, protocol_version)
else: else:
version = None version = None

View File

@@ -20,7 +20,7 @@ from flask import jsonify, abort, make_response, url_for, current_app
from app.logic.packages import do_edit_package from app.logic.packages import do_edit_package
from app.logic.releases import LogicError, do_create_vcs_release, do_create_zip_release from app.logic.releases import LogicError, do_create_vcs_release, do_create_zip_release
from app.logic.screenshots import do_create_screenshot, do_order_screenshots, do_set_cover_image from app.logic.screenshots import do_create_screenshot, do_order_screenshots, do_set_cover_image
from app.models import APIToken, Package, MinetestRelease, PackageScreenshot from app.models import APIToken, Package, LuantiRelease, PackageScreenshot
def error(code: int, msg: str): def error(code: int, msg: str):
@@ -39,7 +39,7 @@ def guard(f):
def api_create_vcs_release(token: APIToken, package: Package, name: str, title: Optional[str], release_notes: Optional[str], ref: str, def api_create_vcs_release(token: APIToken, package: Package, name: str, title: Optional[str], release_notes: Optional[str], ref: str,
min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason="API"): min_v: LuantiRelease = None, max_v: LuantiRelease = None, reason="API"):
if not token.can_operate_on_package(package): if not token.can_operate_on_package(package):
error(403, "API token does not have access to the package") error(403, "API token does not have access to the package")
@@ -55,7 +55,7 @@ def api_create_vcs_release(token: APIToken, package: Package, name: str, title:
def api_create_zip_release(token: APIToken, package: Package, name: str, title: Optional[str], release_notes: Optional[str], file, def api_create_zip_release(token: APIToken, package: Package, name: str, title: Optional[str], release_notes: Optional[str], file,
min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason="API", commit_hash: str = None): min_v: LuantiRelease = None, max_v: LuantiRelease = None, reason="API", commit_hash: str = None):
if not token.can_operate_on_package(package): if not token.can_operate_on_package(package):
error(403, "API token does not have access to the package") error(403, "API token does not have access to the package")

View File

@@ -28,7 +28,7 @@ from sqlalchemy.sql.expression import func
PKGS_PER_ROW = 4 PKGS_PER_ROW = 4
# GAMEJAM_BANNER = "https://jam.minetest.net/img/banner.png" # GAMEJAM_BANNER = "https://jam.luanti.org/img/banner.png"
# #
# class GameJam: # class GameJam:
# cover_image = type("", (), dict(url=GAMEJAM_BANNER))() # cover_image = type("", (), dict(url=GAMEJAM_BANNER))()
@@ -40,7 +40,7 @@ PKGS_PER_ROW = 4
# def get_url(self, _name): # def get_url(self, _name):
# return "/gamejam/" # return "/gamejam/"
# #
# title = "Minetest Game Jam 2023: \"Unexpected\"" # title = "Luanti Game Jam 2023: \"Unexpected\""
# author = None # author = None
# #
# short_desc = "The game jam has finished! It's now up to the community to play and rate the games." # short_desc = "The game jam has finished! It's now up to the community to play and rate the games."
@@ -51,7 +51,7 @@ PKGS_PER_ROW = 4
@bp.route("/gamejam/") @bp.route("/gamejam/")
def gamejam(): def gamejam():
return redirect("https://jam.minetest.net/") return redirect("https://jam.luanti.org/")
@bp.route("/") @bp.route("/")

View File

@@ -23,7 +23,7 @@ from wtforms.validators import Optional
from wtforms_sqlalchemy.fields import QuerySelectMultipleField, QuerySelectField from wtforms_sqlalchemy.fields import QuerySelectMultipleField, QuerySelectField
from . import bp from . import bp
from ...models import PackageType, Tag, db, ContentWarning, License, Language, MinetestRelease, Package, PackageState from ...models import PackageType, Tag, db, ContentWarning, License, Language, LuantiRelease, Package, PackageState
def make_label(obj: Tag | ContentWarning): def make_label(obj: Tag | ContentWarning):
@@ -75,7 +75,7 @@ class AdvancedSearchForm(FlaskForm):
get_pk=lambda a: a.id, get_label=lambda a: a.title) get_pk=lambda a: a.id, get_label=lambda a: a.title)
hide = SelectMultipleField(lazy_gettext("Hide Tags and Content Warnings"), [Optional()]) hide = SelectMultipleField(lazy_gettext("Hide Tags and Content Warnings"), [Optional()])
engine_version = QuerySelectField(lazy_gettext("Luanti Version"), engine_version = QuerySelectField(lazy_gettext("Luanti Version"),
query_factory=lambda: MinetestRelease.query.order_by(db.asc(MinetestRelease.id)), query_factory=lambda: LuantiRelease.query.order_by(db.asc(LuantiRelease.id)),
allow_blank=True, blank_value="", allow_blank=True, blank_value="",
get_pk=lambda a: a.value, get_label=lambda a: a.name) get_pk=lambda a: a.value, get_label=lambda a: a.name)
sort = SelectField(lazy_gettext("Sort by"), [Optional()], choices=[ sort = SelectField(lazy_gettext("Sort by"), [Optional()], choices=[

View File

@@ -25,7 +25,7 @@ from wtforms.validators import InputRequired, Length, Optional
from wtforms_sqlalchemy.fields import QuerySelectField from wtforms_sqlalchemy.fields import QuerySelectField
from app.logic.releases import do_create_vcs_release, LogicError, do_create_zip_release from app.logic.releases import do_create_vcs_release, LogicError, do_create_zip_release
from app.models import Package, db, User, PackageState, Permission, UserRank, PackageDailyStats, MinetestRelease, \ from app.models import Package, db, User, PackageState, Permission, UserRank, PackageDailyStats, LuantiRelease, \
PackageRelease, PackageUpdateTrigger, PackageUpdateConfig PackageRelease, PackageUpdateTrigger, PackageUpdateConfig
from app.rediscache import has_key, set_temp_key, make_download_key from app.rediscache import has_key, set_temp_key, make_download_key
from app.tasks.importtasks import check_update_config from app.tasks.importtasks import check_update_config
@@ -42,11 +42,11 @@ def list_releases(package):
def get_mt_releases(is_max): def get_mt_releases(is_max):
query = MinetestRelease.query.order_by(db.asc(MinetestRelease.id)) query = LuantiRelease.query.order_by(db.asc(LuantiRelease.id))
if is_max: if is_max:
query = query.limit(query.count() - 1) query = query.limit(query.count() - 1)
else: else:
query = query.filter(MinetestRelease.name != "0.4.17") query = query.filter(LuantiRelease.name != "0.4.17")
return query return query
@@ -128,9 +128,9 @@ def download_release(package, id):
ip = request.headers.get("X-Forwarded-For") or request.remote_addr ip = request.headers.get("X-Forwarded-For") or request.remote_addr
if ip is not None and not is_user_bot(): if ip is not None and not is_user_bot():
user_agent = request.headers.get("User-Agent") or "" user_agent = request.headers.get("User-Agent") or ""
is_minetest = user_agent.startswith("Luanti") or user_agent.startswith("Minetest") is_luanti = user_agent.startswith("Luanti") or user_agent.startswith("Minetest")
reason = request.args.get("reason") reason = request.args.get("reason")
PackageDailyStats.update(package, is_minetest, reason) PackageDailyStats.update(package, is_luanti, reason)
key = make_download_key(ip, release.package) key = make_download_key(ip, release.package)
if not has_key(key): if not has_key(key):

View File

@@ -20,7 +20,7 @@ from flask_login import current_user, login_required
from sqlalchemy import or_, and_ from sqlalchemy import or_, and_
from app.models import Package, PackageState, PackageScreenshot, PackageUpdateConfig, ForumTopic, db, \ from app.models import Package, PackageState, PackageScreenshot, PackageUpdateConfig, ForumTopic, db, \
PackageRelease, Permission, UserRank, License, MetaPackage, Dependency, AuditLogEntry, Tag, MinetestRelease PackageRelease, Permission, UserRank, License, MetaPackage, Dependency, AuditLogEntry, Tag, LuantiRelease
from app.querybuilder import QueryBuilder from app.querybuilder import QueryBuilder
from app.utils import get_int_or_abort, is_yes, rank_required from app.utils import get_int_or_abort, is_yes, rank_required
from . import bp from . import bp
@@ -170,7 +170,7 @@ def screenshots():
def mtver_support(): def mtver_support():
is_mtm_only = is_yes(request.args.get("mtm")) is_mtm_only = is_yes(request.args.get("mtm"))
current_stable = MinetestRelease.query.filter(~MinetestRelease.name.like("%-dev")).order_by(db.desc(MinetestRelease.id)).first() current_stable = LuantiRelease.query.filter(~LuantiRelease.name.like("%-dev")).order_by(db.desc(LuantiRelease.id)).first()
query = db.session.query(Package) \ query = db.session.query(Package) \
.filter(~Package.releases.any(or_(PackageRelease.max_rel==None, PackageRelease.max_rel == current_stable))) \ .filter(~Package.releases.any(or_(PackageRelease.max_rel==None, PackageRelease.max_rel == current_stable))) \

View File

@@ -16,7 +16,7 @@
import datetime import datetime
from .models import User, UserRank, MinetestRelease, Tag, License, Notification, NotificationType, Package, \ from .models import User, UserRank, LuantiRelease, Tag, License, Notification, NotificationType, Package, \
PackageState, PackageType, PackageRelease, MetaPackage, Dependency PackageState, PackageType, PackageRelease, MetaPackage, Dependency
from .utils import make_flask_login_password from .utils import make_flask_login_password
@@ -35,12 +35,12 @@ def populate(session):
system_user.rank = UserRank.BOT system_user.rank = UserRank.BOT
session.add(system_user) session.add(system_user)
session.add(MinetestRelease("None", 0)) session.add(LuantiRelease("None", 0))
session.add(MinetestRelease("0.4.16/17", 32)) session.add(LuantiRelease("0.4.16/17", 32))
session.add(MinetestRelease("5.0", 37)) session.add(LuantiRelease("5.0", 37))
session.add(MinetestRelease("5.1", 38)) session.add(LuantiRelease("5.1", 38))
session.add(MinetestRelease("5.2", 39)) session.add(LuantiRelease("5.2", 39))
session.add(MinetestRelease("5.3", 39)) session.add(LuantiRelease("5.3", 39))
tags = {} tags = {}
for tag in ["Inventory", "Mapgen", "Building", for tag in ["Inventory", "Mapgen", "Building",
@@ -69,8 +69,8 @@ def populate_test_data(session):
licenses = { x.name : x for x in License.query.all() } licenses = { x.name : x for x in License.query.all() }
tags = { x.name : x for x in Tag.query.all() } tags = { x.name : x for x in Tag.query.all() }
admin_user = User.query.filter_by(rank=UserRank.ADMIN).first() admin_user = User.query.filter_by(rank=UserRank.ADMIN).first()
v4 = MinetestRelease.query.filter_by(protocol=32).first() v4 = LuantiRelease.query.filter_by(protocol=32).first()
v51 = MinetestRelease.query.filter_by(protocol=38).first() v51 = LuantiRelease.query.filter_by(protocol=38).first()
ez = User("Shara") ez = User("Shara")
ez.github_username = "Ezhh" ez.github_username = "Ezhh"

View File

@@ -10,8 +10,8 @@ as it was submitted as university coursework. To learn about the history and dev
ContentDB is open source software, licensed under AGPLv3.0. ContentDB is open source software, licensed under AGPLv3.0.
<a href="https://github.com/minetest/contentdb/" class="btn btn-primary me-1">Source code</a> <a href="https://github.com/luanti-org/contentdb/" class="btn btn-primary me-1">Source code</a>
<a href="https://github.com/minetest/contentdb/issues/" class="btn btn-secondary me-1">Issue tracker</a> <a href="https://github.com/luanti-org/contentdb/issues/" class="btn btn-secondary me-1">Issue tracker</a>
<a href="{{ admin_contact_url }}" class="btn btn-secondary me-1">Contact admin</a> <a href="{{ admin_contact_url }}" class="btn btn-secondary me-1">Contact admin</a>
{% if monitoring_url -%} {% if monitoring_url -%}
<a href="{{ monitoring_url }}" class="btn btn-secondary">Stats / monitoring</a> <a href="{{ monitoring_url }}" class="btn btn-secondary">Stats / monitoring</a>

View File

@@ -3,7 +3,7 @@ title: API
## Resources ## Resources
* [How the Luanti client uses the API](https://github.com/minetest/contentdb/blob/master/docs/minetest_client.md) * [How the Luanti client uses the API](https://github.com/luanti-org/contentdb/blob/master/docs/luanti_client.md)
## Responses and Error Handling ## Responses and Error Handling
@@ -131,7 +131,7 @@ curl -X DELETE https://content.luanti.org/api/delete-token/ \
* `<neutral>` with a thumbs up icon. * `<neutral>` with a thumbs up icon.
* `<thumbsdown>` with a thumbs up icon. * `<thumbsdown>` with a thumbs up icon.
* GET `/api/packages/<author>/<name>/hypertext/` * GET `/api/packages/<author>/<name>/hypertext/`
* Converts the long description to [Luanti Markup Language](https://github.com/minetest/minetest/blob/master/doc/lua_api.md#markup-language) * Converts the long description to [Luanti Markup Language](https://github.com/luanti-org/luanti/blob/master/doc/lua_api.md#markup-language)
to be used in a `hypertext` formspec element. to be used in a `hypertext` formspec element.
* Query arguments: * Query arguments:
* `formspec_version`: Required, maximum supported formspec version. * `formspec_version`: Required, maximum supported formspec version.
@@ -577,7 +577,7 @@ Supported query parameters:
* Get JSON Schema of `.cdb.json`, including licenses, tags and content warnings. * Get JSON Schema of `.cdb.json`, including licenses, tags and content warnings.
* See [JSON Schema Reference](https://json-schema.org/). * See [JSON Schema Reference](https://json-schema.org/).
* POST `/api/hypertext/` * POST `/api/hypertext/`
* Converts HTML or Markdown to [Luanti Markup Language](https://github.com/minetest/minetest/blob/master/doc/lua_api.md#markup-language) * Converts HTML or Markdown to [Luanti Markup Language](https://github.com/luanti-org/luanti/blob/master/doc/lua_api.md#markup-language)
to be used in a `hypertext` formspec element. to be used in a `hypertext` formspec element.
* Post data: HTML or Markdown as plain text. * Post data: HTML or Markdown as plain text.
* Content-Type: `text/html` or `text/markdown`. * Content-Type: `text/html` or `text/markdown`.

View File

@@ -68,7 +68,7 @@ can also translate your ContentDB page. See Edit Package > Translation for more
<a class="btn btn-primary me-2" href="https://rubenwardy.com/minetest_modding_book/en/quality/translations.html"> <a class="btn btn-primary me-2" href="https://rubenwardy.com/minetest_modding_book/en/quality/translations.html">
{{ _("Translation - Luanti Modding Book") }} {{ _("Translation - Luanti Modding Book") }}
</a> </a>
<a class="btn btn-primary" href="https://api.minetest.net/translations/#translating-content-meta"> <a class="btn btn-primary" href="https://api.luanti.org/translations/#translating-content-meta">
{{ _("Translating content meta - lua_api.md") }} {{ _("Translating content meta - lua_api.md") }}
</a> </a>
</p> </p>

View File

@@ -141,7 +141,7 @@ permanent bans.
## Where can I get help? ## Where can I get help?
[Join](https://www.minetest.net/get-involved/) IRC, Matrix, or Discord to ask for help. [Join](https://www.luanti.org/get-involved/) IRC, Matrix, or Discord to ask for help.
In Discord, there are the #assets or #contentdb channels. In IRC or Matrix, you can just ask in the main channels. In Discord, there are the #assets or #contentdb channels. In IRC or Matrix, you can just ask in the main channels.
If your package is already on ContentDB, you can open a thread. If your package is already on ContentDB, you can open a thread.

View File

@@ -33,4 +33,4 @@ downloaded from that IP.
You can see all scores using the [scores REST API](/api/scores/), or by You can see all scores using the [scores REST API](/api/scores/), or by
using the [Prometheus metrics](/help/metrics/) endpoint. using the [Prometheus metrics](/help/metrics/) endpoint.
Consider [suggesting improvements](https://github.com/minetest/contentdb/issues/new?assignees=&labels=Policy&template=policy.md&title=). Consider [suggesting improvements](https://github.com/luanti-org/contentdb/issues/new?assignees=&labels=Policy&template=policy.md&title=).

View File

@@ -2,7 +2,7 @@ title: Privacy Policy
--- ---
Last Updated: 2024-04-30 Last Updated: 2024-04-30
([View updates](https://github.com/minetest/contentdb/commits/master/app/flatpages/privacy_policy.md)) ([View updates](https://github.com/luanti-org/contentdb/commits/master/app/flatpages/privacy_policy.md))
## What Information is Collected ## What Information is Collected

View File

@@ -23,7 +23,7 @@ from flask_babel import lazy_gettext
from app.logic.LogicError import LogicError from app.logic.LogicError import LogicError
from app.logic.uploads import upload_file from app.logic.uploads import upload_file
from app.models import PackageRelease, db, Permission, User, Package, MinetestRelease from app.models import PackageRelease, db, Permission, User, Package, LuantiRelease
from app.tasks.importtasks import make_vcs_release, check_zip_release from app.tasks.importtasks import make_vcs_release, check_zip_release
from app.utils import AuditSeverity, add_audit_log, nonempty_or_none, normalize_line_endings from app.utils import AuditSeverity, add_audit_log, nonempty_or_none, normalize_line_endings
@@ -42,7 +42,7 @@ def check_can_create_release(user: User, package: Package, name: str):
def do_create_vcs_release(user: User, package: Package, name: str, title: Optional[str], release_notes: Optional[str], ref: str, def do_create_vcs_release(user: User, package: Package, name: str, title: Optional[str], release_notes: Optional[str], ref: str,
min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason: str = None): min_v: LuantiRelease = None, max_v: LuantiRelease = None, reason: str = None):
check_can_create_release(user, package, name) check_can_create_release(user, package, name)
rel = PackageRelease() rel = PackageRelease()
@@ -70,7 +70,7 @@ def do_create_vcs_release(user: User, package: Package, name: str, title: Option
def do_create_zip_release(user: User, package: Package, name: str, title: Optional[str], release_notes: Optional[str], file, def do_create_zip_release(user: User, package: Package, name: str, title: Optional[str], release_notes: Optional[str], file,
min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason: str = None, min_v: LuantiRelease = None, max_v: LuantiRelease = None, reason: str = None,
commit_hash: str = None): commit_hash: str = None):
check_can_create_release(user, package, name) check_can_create_release(user, package, name)

View File

@@ -131,7 +131,7 @@ class AuditLogEntry(db.Model):
REPO_BLACKLIST = [".zip", "mediafire.com", "dropbox.com", "weebly.com", REPO_BLACKLIST = [".zip", "mediafire.com", "dropbox.com", "weebly.com",
"minetest.net", "dropboxusercontent.com", "4shared.com", "minetest.net", "luanti.org", "dropboxusercontent.com", "4shared.com",
"digitalaudioconcepts.com", "hg.intevation.org", "www.wtfpl.net", "digitalaudioconcepts.com", "hg.intevation.org", "www.wtfpl.net",
"imageshack.com", "imgur.com"] "imageshack.com", "imgur.com"]

View File

@@ -1043,7 +1043,7 @@ class Tag(db.Model):
} }
class MinetestRelease(db.Model): class LuantiRelease(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), unique=True, nullable=False) name = db.Column(db.String(100), unique=True, nullable=False)
protocol = db.Column(db.Integer, nullable=False, default=0) protocol = db.Column(db.Integer, nullable=False, default=0)
@@ -1067,11 +1067,11 @@ class MinetestRelease(db.Model):
} }
@classmethod @classmethod
def get(cls, version: typing.Optional[str], protocol_num: typing.Optional[str]) -> typing.Optional["MinetestRelease"]: def get(cls, version: typing.Optional[str], protocol_num: typing.Optional[str]) -> typing.Optional["LuantiRelease"]:
if version: if version:
parts = version.strip().split(".") parts = version.strip().split(".")
if len(parts) >= 2: if len(parts) >= 2:
query = MinetestRelease.query.filter(func.replace(MinetestRelease.name, "-dev", "") == "{}.{}".format(parts[0], parts[1])) query = LuantiRelease.query.filter(func.replace(LuantiRelease.name, "-dev", "") == "{}.{}".format(parts[0], parts[1]))
if protocol_num: if protocol_num:
query = query.filter_by(protocol=protocol_num) query = query.filter_by(protocol=protocol_num)
@@ -1081,9 +1081,9 @@ class MinetestRelease(db.Model):
if protocol_num: if protocol_num:
# Find the closest matching release # Find the closest matching release
return MinetestRelease.query.order_by(db.desc(MinetestRelease.protocol), return LuantiRelease.query.order_by(db.desc(LuantiRelease.protocol),
db.desc(MinetestRelease.id)) \ db.desc(LuantiRelease.id)) \
.filter(MinetestRelease.protocol <= protocol_num).first() .filter(LuantiRelease.protocol <= protocol_num).first()
return None return None
@@ -1114,11 +1114,11 @@ class PackageRelease(db.Model):
return self.release_notes.split("\n")[0] return self.release_notes.split("\n")[0]
min_rel_id = db.Column(db.Integer, db.ForeignKey("minetest_release.id"), nullable=True, server_default=None) min_rel_id = db.Column(db.Integer, db.ForeignKey("luanti_release.id"), nullable=True, server_default=None)
min_rel = db.relationship("MinetestRelease", foreign_keys=[min_rel_id]) min_rel = db.relationship("LuantiRelease", foreign_keys=[min_rel_id])
max_rel_id = db.Column(db.Integer, db.ForeignKey("minetest_release.id"), nullable=True, server_default=None) max_rel_id = db.Column(db.Integer, db.ForeignKey("luanti_release.id"), nullable=True, server_default=None)
max_rel = db.relationship("MinetestRelease", foreign_keys=[max_rel_id]) max_rel = db.relationship("LuantiRelease", foreign_keys=[max_rel_id])
# If the release is approved, then the task_id must be null and the url must be present # If the release is approved, then the task_id must be null and the url must be present
CK_approval_valid = db.CheckConstraint("not approved OR (task_id IS NULL AND (url = '') IS NOT FALSE)") CK_approval_valid = db.CheckConstraint("not approved OR (task_id IS NULL AND (url = '') IS NOT FALSE)")
@@ -1441,7 +1441,7 @@ class PackageDailyStats(db.Model):
reason_update = db.Column(db.Integer, nullable=False, default=0) reason_update = db.Column(db.Integer, nullable=False, default=0)
@staticmethod @staticmethod
def update(package: Package, is_minetest: bool, reason: str): def update(package: Package, is_luanti: bool, reason: str):
date = datetime.datetime.utcnow().date() date = datetime.datetime.utcnow().date()
to_update = dict() to_update = dict()
@@ -1449,7 +1449,7 @@ class PackageDailyStats(db.Model):
"package_id": package.id, "date": date "package_id": package.id, "date": date
} }
field_platform = "platform_minetest" if is_minetest else "platform_other" field_platform = "platform_minetest" if is_luanti else "platform_other"
to_update[field_platform] = getattr(PackageDailyStats, field_platform) + 1 to_update[field_platform] = getattr(PackageDailyStats, field_platform) + 1
kwargs[field_platform] = 1 kwargs[field_platform] = 1

View File

@@ -86,7 +86,8 @@ window.addEventListener("load", () => {
"desc_page_topic": (val) => { "desc_page_topic": (val) => {
const topicId = document.getElementById("forums").value; const topicId = document.getElementById("forums").value;
const r = new RegExp(`forum\\.minetest\\.net\\/viewtopic\\.php\\?[a-z0-9=&]*t=${topicId}`); const r = new RegExp(`forum\\.minetest\\.net\\/viewtopic\\.php\\?[a-z0-9=&]*t=${topicId}`);
return topicId && r.test(val); const r2 = new RegExp(`forum\\.luanti\\.org\\/viewtopic\\.php\\?[a-z0-9=&]*t=${topicId}`);
return topicId && (r.test(val) || r2.test(val));
}, },
"desc_page_repo": (val) => { "desc_page_repo": (val) => {
const repoUrl = document.getElementById("repo").value.replace(".git", ""); const repoUrl = document.getElementById("repo").value.replace(".git", "");

View File

@@ -22,7 +22,7 @@ from sqlalchemy.orm import subqueryload
from sqlalchemy.sql.expression import func from sqlalchemy.sql.expression import func
from sqlalchemy_searchable import search from sqlalchemy_searchable import search
from .models import db, PackageType, Package, ForumTopic, License, MinetestRelease, PackageRelease, User, Tag, \ from .models import db, PackageType, Package, ForumTopic, License, LuantiRelease, PackageRelease, User, Tag, \
ContentWarning, PackageState, PackageDevState ContentWarning, PackageState, PackageDevState
from .utils import is_yes, get_int_or_abort from .utils import is_yes, get_int_or_abort
@@ -49,7 +49,7 @@ class QueryBuilder:
hide_wip: bool hide_wip: bool
hide_nonfree: bool hide_nonfree: bool
show_added: bool show_added: bool
version: Optional[MinetestRelease] version: Optional[LuantiRelease]
has_lang: Optional[str] has_lang: Optional[str]
@property @property
@@ -163,12 +163,12 @@ class QueryBuilder:
self.author = args.get("author") self.author = args.get("author")
protocol_version = get_int_or_abort(args.get("protocol_version")) protocol_version = get_int_or_abort(args.get("protocol_version"))
minetest_version = args.get("engine_version") engine_version = args.get("engine_version")
if minetest_version == "": if engine_version == "":
minetest_version = None engine_version = None
if protocol_version or minetest_version: if protocol_version or engine_version:
self.version = MinetestRelease.get(minetest_version, protocol_version) self.version = LuantiRelease.get(engine_version, protocol_version)
else: else:
self.version = None self.version = None

View File

@@ -31,13 +31,13 @@ from sqlalchemy import and_
from sqlalchemy.dialects.postgresql import insert from sqlalchemy.dialects.postgresql import insert
from app.models import AuditSeverity, db, NotificationType, PackageRelease, MetaPackage, Dependency, PackageType, \ from app.models import AuditSeverity, db, NotificationType, PackageRelease, MetaPackage, Dependency, PackageType, \
MinetestRelease, Package, PackageState, PackageScreenshot, PackageUpdateTrigger, PackageUpdateConfig, \ LuantiRelease, Package, PackageState, PackageScreenshot, PackageUpdateTrigger, PackageUpdateConfig, \
PackageGameSupport, PackageTranslation, Language PackageGameSupport, PackageTranslation, Language
from app.tasks import celery, TaskError from app.tasks import celery, TaskError
from app.utils import random_string, post_bot_message, add_system_notification, add_system_audit_log, \ from app.utils import random_string, post_bot_message, add_system_notification, add_system_audit_log, \
get_games_from_list, add_audit_log get_games_from_list, add_audit_log
from app.utils.git import clone_repo, get_latest_tag, get_latest_commit, get_temp_dir, get_release_notes from app.utils.git import clone_repo, get_latest_tag, get_latest_commit, get_temp_dir, get_release_notes
from .minetestcheck import build_tree, MinetestCheckError, ContentType, PackageTreeNode from .luanticheck import build_tree, LuantiCheckError, ContentType, PackageTreeNode
from .webhooktasks import post_discord_webhook from .webhooktasks import post_discord_webhook
from app import app from app import app
from app.logic.LogicError import LogicError from app.logic.LogicError import LogicError
@@ -51,7 +51,7 @@ def get_meta(urlstr, author):
with clone_repo(urlstr, recursive=True) as repo: with clone_repo(urlstr, recursive=True) as repo:
try: try:
tree = build_tree(repo.working_tree_dir, author=author, repo=urlstr) tree = build_tree(repo.working_tree_dir, author=author, repo=urlstr)
except MinetestCheckError as err: except LuantiCheckError as err:
raise TaskError(str(err)) raise TaskError(str(err))
result = {"name": tree.name, "type": tree.type.name} result = {"name": tree.name, "type": tree.type.name}
@@ -113,7 +113,7 @@ def post_release_check_update(self, release: PackageRelease, path):
author=release.package.author.username, name=release.package.name) author=release.package.author.username, name=release.package.name)
if tree.name is not None and release.package.name != tree.name and tree.type == ContentType.MOD: if tree.name is not None and release.package.name != tree.name and tree.type == ContentType.MOD:
raise MinetestCheckError(f"Expected {tree.relative} to have technical name {release.package.name}, instead has name {tree.name}") raise LuantiCheckError(f"Expected {tree.relative} to have technical name {release.package.name}, instead has name {tree.name}")
cache = {} cache = {}
def get_meta_packages(names): def get_meta_packages(names):
@@ -165,10 +165,10 @@ def post_release_check_update(self, release: PackageRelease, path):
# Raise error on unresolved game dependencies # Raise error on unresolved game dependencies
if package.type == PackageType.GAME and len(depends) > 0: if package.type == PackageType.GAME and len(depends) > 0:
deps = ", ".join(depends) deps = ", ".join(depends)
raise MinetestCheckError("Game has unresolved hard dependencies: " + deps) raise LuantiCheckError("Game has unresolved hard dependencies: " + deps)
if package.state != PackageState.APPROVED and tree.find_license_file() is None: if package.state != PackageState.APPROVED and tree.find_license_file() is None:
raise MinetestCheckError( raise LuantiCheckError(
"You need to add a LICENSE.txt/.md or COPYING file to your package. See the 'Copyright Guide' for more info") "You need to add a LICENSE.txt/.md or COPYING file to your package. See the 'Copyright Guide' for more info")
# Add dependencies # Add dependencies
@@ -183,10 +183,10 @@ def post_release_check_update(self, release: PackageRelease, path):
# Update min/max # Update min/max
if tree.meta.get("min_minetest_version"): if tree.meta.get("min_minetest_version"):
release.min_rel = MinetestRelease.get(tree.meta["min_minetest_version"], None) release.min_rel = LuantiRelease.get(tree.meta["min_minetest_version"], None)
if tree.meta.get("max_minetest_version"): if tree.meta.get("max_minetest_version"):
release.max_rel = MinetestRelease.get(tree.meta["max_minetest_version"], None) release.max_rel = LuantiRelease.get(tree.meta["max_minetest_version"], None)
try: try:
with open(os.path.join(tree.baseDir, ".cdb.json"), "r") as f: with open(os.path.join(tree.baseDir, ".cdb.json"), "r") as f:
@@ -232,7 +232,7 @@ def post_release_check_update(self, release: PackageRelease, path):
return tree return tree
except (MinetestCheckError, TaskError, LogicError) as err: except (LuantiCheckError, TaskError, LogicError) as err:
db.session.rollback() db.session.rollback()
error_message = err.value if hasattr(err, "value") else str(err) error_message = err.value if hasattr(err, "value") else str(err)
@@ -377,7 +377,7 @@ def import_languages(self, id, path):
strict=False) strict=False)
update_translations(release.package, tree) update_translations(release.package, tree)
db.session.commit() db.session.commit()
except (MinetestCheckError, TaskError, LogicError) as err: except (LuantiCheckError, TaskError, LogicError) as err:
db.session.rollback() db.session.rollback()
task_url = url_for('tasks.check', id=self.request.id) task_url = url_for('tasks.check', id=self.request.id)

View File

@@ -17,7 +17,7 @@
from enum import Enum from enum import Enum
class MinetestCheckError(Exception): class LuantiCheckError(Exception):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
@@ -43,14 +43,14 @@ class ContentType(Enum):
if self == ContentType.MOD: if self == ContentType.MOD:
if not other.is_mod_like(): if not other.is_mod_like():
raise MinetestCheckError("Expected a mod or modpack, found " + other.value) raise LuantiCheckError("Expected a mod or modpack, found " + other.value)
elif self == ContentType.TXP: elif self == ContentType.TXP:
if other != ContentType.UNKNOWN and other != ContentType.TXP: if other != ContentType.UNKNOWN and other != ContentType.TXP:
raise MinetestCheckError("expected a " + self.value + ", found a " + other.value) raise LuantiCheckError("expected a " + self.value + ", found a " + other.value)
elif other != self: elif other != self:
raise MinetestCheckError("Expected a " + self.value + ", found a " + other.value) raise LuantiCheckError("Expected a " + self.value + ", found a " + other.value)
from .tree import PackageTreeNode, get_base_dir from .tree import PackageTreeNode, get_base_dir

View File

@@ -20,7 +20,7 @@ import re
import glob import glob
from typing import Optional from typing import Optional
from . import MinetestCheckError, ContentType from . import LuantiCheckError, ContentType
from .config import parse_conf from .config import parse_conf
from .translation import Translation, parse_tr from .translation import Translation, parse_tr
@@ -73,10 +73,10 @@ def check_name_list(key: str, value: list[str], relative: str, allow_star: bool
if dep == "*" and allow_star: if dep == "*" and allow_star:
continue continue
elif " " in dep: elif " " in dep:
raise MinetestCheckError( raise LuantiCheckError(
f"Invalid {key} name '{dep}' at {relative}, did you forget a comma?") f"Invalid {key} name '{dep}' at {relative}, did you forget a comma?")
else: else:
raise MinetestCheckError( raise LuantiCheckError(
f"Invalid {key} name '{dep}' at {relative}, names must only contain a-z0-9_.") f"Invalid {key} name '{dep}' at {relative}, names must only contain a-z0-9_.")
@@ -114,14 +114,14 @@ class PackageTreeNode:
if self.type == ContentType.GAME: if self.type == ContentType.GAME:
if not os.path.isdir(os.path.join(base_dir, "mods")): if not os.path.isdir(os.path.join(base_dir, "mods")):
raise MinetestCheckError("Game at {} does not have a mods/ folder".format(self.relative)) raise LuantiCheckError("Game at {} does not have a mods/ folder".format(self.relative))
self._add_children_from_mod_dir("mods") self._add_children_from_mod_dir("mods")
elif self.type == ContentType.MOD: elif self.type == ContentType.MOD:
if self.name and not basenamePattern.match(self.name): if self.name and not basenamePattern.match(self.name):
raise MinetestCheckError(f"Invalid base name for mod {self.name} at {self.relative}, names must only contain a-z0-9_.") raise LuantiCheckError(f"Invalid base name for mod {self.name} at {self.relative}, names must only contain a-z0-9_.")
if self.name and self.name in DISALLOWED_NAMES: if self.name and self.name in DISALLOWED_NAMES:
raise MinetestCheckError(f"Forbidden mod name '{self.name}' used at {self.relative}") raise LuantiCheckError(f"Forbidden mod name '{self.name}' used at {self.relative}")
self._check_dir_casing(["textures", "media", "sounds", "models", "locale"]) self._check_dir_casing(["textures", "media", "sounds", "models", "locale"])
elif self.type == ContentType.MODPACK: elif self.type == ContentType.MODPACK:
@@ -139,7 +139,7 @@ class PackageTreeNode:
for dir in next(os.walk(self.baseDir))[1]: for dir in next(os.walk(self.baseDir))[1]:
lowercase = dir.lower() lowercase = dir.lower()
if lowercase != dir and lowercase in dirs: if lowercase != dir and lowercase in dirs:
raise MinetestCheckError(f"Incorrect case, {dir} should be {lowercase} at {self.relative}{dir}") raise LuantiCheckError(f"Incorrect case, {dir} should be {lowercase} at {self.relative}{dir}")
def get_readme_path(self): def get_readme_path(self):
for filename in os.listdir(self.baseDir): for filename in os.listdir(self.baseDir):
@@ -173,12 +173,12 @@ class PackageTreeNode:
for key, value in conf.items(): for key, value in conf.items():
result[key] = value result[key] = value
except SyntaxError as e: except SyntaxError as e:
raise MinetestCheckError("Error while reading {}: {}".format(meta_file_rel , e.msg)) raise LuantiCheckError("Error while reading {}: {}".format(meta_file_rel , e.msg))
except IOError: except IOError:
pass pass
if self.strict and "release" in result: if self.strict and "release" in result:
raise MinetestCheckError("{} should not contain 'release' key, as this is for use by ContentDB only.".format(meta_file_rel)) raise LuantiCheckError("{} should not contain 'release' key, as this is for use by ContentDB only.".format(meta_file_rel))
# description.txt # description.txt
if "description" not in result: if "description" not in result:
@@ -269,11 +269,11 @@ class PackageTreeNode:
if not entry.startswith('.') and os.path.isdir(path): if not entry.startswith('.') and os.path.isdir(path):
child = PackageTreeNode(path, relative + entry + "/", name=entry, strict=self.strict) child = PackageTreeNode(path, relative + entry + "/", name=entry, strict=self.strict)
if not child.type.is_mod_like(): if not child.type.is_mod_like():
raise MinetestCheckError("Expecting mod or modpack, found {} at {} inside {}" \ raise LuantiCheckError("Expecting mod or modpack, found {} at {} inside {}" \
.format(child.type.value, child.relative, self.type.value)) .format(child.type.value, child.relative, self.type.value))
if child.name is None: if child.name is None:
raise MinetestCheckError("Missing base name for mod at {}".format(self.relative)) raise LuantiCheckError("Missing base name for mod at {}".format(self.relative))
self.children.append(child) self.children.append(child)
@@ -315,10 +315,10 @@ class PackageTreeNode:
def check_for_legacy_files(self): def check_for_legacy_files(self):
if self.has_legacy_depends: if self.has_legacy_depends:
raise MinetestCheckError("Found depends.txt at {}. Delete this file and use depends in mod.conf instead" \ raise LuantiCheckError("Found depends.txt at {}. Delete this file and use depends in mod.conf instead" \
.format(self.relative)) .format(self.relative))
if self.has_legacy_description: if self.has_legacy_description:
raise MinetestCheckError("Found description.txt at {}. Delete this file and use description in {} instead" \ raise LuantiCheckError("Found description.txt at {}. Delete this file and use description in {} instead" \
.format(self.relative, self.get_meta_file_name())) .format(self.relative, self.get_meta_file_name()))
for child in self.children: for child in self.children:
child.check_for_legacy_files() child.check_for_legacy_files()
@@ -348,6 +348,6 @@ class PackageTreeNode:
ret.append(parse_tr(name)) ret.append(parse_tr(name))
except SyntaxError as e: except SyntaxError as e:
relative_path = os.path.join(self.relative, os.path.relpath(name, self.baseDir)) relative_path = os.path.join(self.relative, os.path.relpath(name, self.baseDir))
raise MinetestCheckError(f"Syntax error whilst reading {relative_path}: {e}") raise LuantiCheckError(f"Syntax error whilst reading {relative_path}: {e}")
return ret return ret

View File

@@ -26,7 +26,7 @@ from . import app, utils
from app.markdown import get_headings from app.markdown import get_headings
from .models import Permission, Package, PackageState, PackageRelease from .models import Permission, Package, PackageState, PackageRelease
from .utils import abs_url_for, url_set_query, url_set_anchor, url_current from .utils import abs_url_for, url_set_query, url_set_anchor, url_current
from .utils.minetest_hypertext import normalize_whitespace as do_normalize_whitespace from .utils.luanti_hypertext import normalize_whitespace as do_normalize_whitespace
@app.context_processor @app.context_processor

View File

@@ -274,7 +274,7 @@
<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 Creators") }}</a></li> <li class="list-inline-item"><a href="{{ url_for('donate.donate') }}">{{ _("Support Creators") }}</a></li>
<li class="list-inline-item"><a href="{{ url_for('translate.translate') }}">{{ _("Translate 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/luanti-org/contentdb">{{ _("Source Code") }}</a></li>
</ul> </ul>
<form method="POST" action="{{ url_for('set_nonfree') }}" class="my-3"> <form method="POST" action="{{ url_for('set_nonfree') }}" class="my-3">

View File

@@ -8,7 +8,7 @@
{% set translations = package.translations.all() %} {% set translations = package.translations.all() %}
{% set num = translations | length + 1 %} {% set num = translations | length + 1 %}
<a class="btn btn-secondary float-end" href="https://api.minetest.net/translations/#translating-content-meta"> <a class="btn btn-secondary float-end" href="https://api.luanti.org/translations/#translating-content-meta">
{{ _("Help") }} {{ _("Help") }}
</a> </a>
@@ -22,7 +22,7 @@
<a class="btn btn-primary me-2" href="https://rubenwardy.com/minetest_modding_book/en/quality/translations.html"> <a class="btn btn-primary me-2" href="https://rubenwardy.com/minetest_modding_book/en/quality/translations.html">
{{ _("Translation - Luanti Modding Book") }} {{ _("Translation - Luanti Modding Book") }}
</a> </a>
<a class="btn btn-primary" href="https://api.minetest.net/translations/#translating-content-meta"> <a class="btn btn-primary" href="https://api.luanti.org/translations/#translating-content-meta">
{{ _("Translating content meta - lua_api.md") }} {{ _("Translating content meta - lua_api.md") }}
</a> </a>
</p> </p>

View File

@@ -61,7 +61,7 @@
{% block content %} {% block content %}
<a class="btn btn-secondary float-end" href="https://dev.minetest.net/Translation#Translating_mods_and_games"> <a class="btn btn-secondary float-end" href="https://dev.luanti.org/Translation#Translating_mods_and_games">
{{ _("How to translate a mod / game") }} {{ _("How to translate a mod / game") }}
</a> </a>

View File

@@ -1,7 +1,7 @@
from typing import List, Tuple, Optional from typing import List, Tuple, Optional
from app.default_data import populate_test_data from app.default_data import populate_test_data
from app.models import db, License, PackageType, User, Package, PackageState, PackageRelease, MinetestRelease from app.models import db, License, PackageType, User, Package, PackageState, PackageRelease, LuantiRelease
from .utils import parse_json, validate_package_list from .utils import parse_json, validate_package_list
from .utils import client # noqa from .utils import client # noqa
@@ -32,10 +32,10 @@ def make_package(name: str, versions: List[Tuple[Optional[str], Optional[str]]])
rel.url = "https://github.com/ezhh/handholds/archive/master.zip" rel.url = "https://github.com/ezhh/handholds/archive/master.zip"
if minv: if minv:
rel.min_rel = MinetestRelease.query.filter_by(name=minv).first() rel.min_rel = LuantiRelease.query.filter_by(name=minv).first()
assert rel.min_rel assert rel.min_rel
if maxv: if maxv:
rel.max_rel = MinetestRelease.query.filter_by(name=maxv).first() rel.max_rel = LuantiRelease.query.filter_by(name=maxv).first()
assert rel.max_rel assert rel.max_rel
rel.approved = True rel.approved = True

View File

@@ -2,7 +2,7 @@ import os
import pytest import pytest
from app.tasks.minetestcheck.translation import parse_tr from app.tasks.luanticheck.translation import parse_tr
def test_parses_tr(): def test_parses_tr():

View File

@@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
from app.utils.minetest_hypertext import html_to_minetest from app.utils.luanti_hypertext import html_to_luanti
conquer_html = """ conquer_html = """
@@ -74,7 +74,7 @@ page_url = "https://example.com/a/b/"
def test_conquer(): def test_conquer():
assert html_to_minetest(conquer_html, page_url)["body"].strip() == conquer_expected.strip() assert html_to_luanti(conquer_html, page_url)["body"].strip() == conquer_expected.strip()
def test_images(): def test_images():
@@ -83,7 +83,7 @@ def test_images():
""" """
expected = "<img name=image_0 width=128 height=128>" expected = "<img name=image_0 width=128 height=128>"
result = html_to_minetest(html, page_url) result = html_to_luanti(html, page_url)
assert result["body"].strip() == expected.strip() assert result["body"].strip() == expected.strip()
assert len(result["images"]) == 1 assert len(result["images"]) == 1
assert result["images"]["image_0"] == "https://example.com/path/to/img.png" assert result["images"]["image_0"] == "https://example.com/path/to/img.png"
@@ -95,7 +95,7 @@ def test_images_removed():
""" """
expected = "<action name=image_0><u>Image: alt</u></action>" expected = "<action name=image_0><u>Image: alt</u></action>"
result = html_to_minetest(html, page_url, 7, False) result = html_to_luanti(html, page_url, 7, False)
assert result["body"].strip() == expected.strip() assert result["body"].strip() == expected.strip()
assert len(result["images"]) == 0 assert len(result["images"]) == 0
assert result["links"]["image_0"] == "https://example.com/path/to/img.png" assert result["links"]["image_0"] == "https://example.com/path/to/img.png"
@@ -112,7 +112,7 @@ def test_links_relative_absolute():
"<action name=link_1><u>Absolute</u></action> " \ "<action name=link_1><u>Absolute</u></action> " \
"<action name=link_2><u>Other domain</u></action>" "<action name=link_2><u>Other domain</u></action>"
result = html_to_minetest(html, page_url, 7, False) result = html_to_luanti(html, page_url, 7, False)
assert result["body"].strip() == expected.strip() assert result["body"].strip() == expected.strip()
assert result["links"]["link_0"] == "https://example.com/a/b/relative" assert result["links"]["link_0"] == "https://example.com/a/b/relative"
assert result["links"]["link_1"] == "https://example.com/absolute" assert result["links"]["link_1"] == "https://example.com/absolute"
@@ -134,7 +134,7 @@ def test_bullets():
"<img name=blank.png width=32 height=1>• sub two\n\n" \ "<img name=blank.png width=32 height=1>• sub two\n\n" \
"<img name=blank.png width=16 height=1>• four\n" "<img name=blank.png width=16 height=1>• four\n"
result = html_to_minetest(html, page_url) result = html_to_luanti(html, page_url)
assert result["body"].strip() == expected.strip() assert result["body"].strip() == expected.strip()
@@ -158,7 +158,7 @@ def test_table():
expected = "<action name=link_0><u>(view table in browser)</u></action>\n\n" \ expected = "<action name=link_0><u>(view table in browser)</u></action>\n\n" \
"<b>Heading</b>\n" \ "<b>Heading</b>\n" \
"<action name=link_1><u>(view table in browser)</u></action>" "<action name=link_1><u>(view table in browser)</u></action>"
result = html_to_minetest(html, page_url) result = html_to_luanti(html, page_url)
assert result["body"].strip() == expected.strip() assert result["body"].strip() == expected.strip()
assert result["links"]["link_0"] == f"{page_url}#with-id" assert result["links"]["link_0"] == f"{page_url}#with-id"
assert result["links"]["link_1"] == f"{page_url}#heading" assert result["links"]["link_1"] == f"{page_url}#heading"
@@ -170,7 +170,7 @@ def test_inline():
""" """
expected = "<b>One <i>two</i> three</b>" expected = "<b>One <i>two</i> three</b>"
result = html_to_minetest(html, page_url) result = html_to_luanti(html, page_url)
assert result["body"].strip() == expected.strip() assert result["body"].strip() == expected.strip()
@@ -180,7 +180,7 @@ def test_escape():
""" """
expected = r"<b>One <i>t\\w\<o\></i> three</b>" expected = r"<b>One <i>t\\w\<o\></i> three</b>"
result = html_to_minetest(html, page_url) result = html_to_luanti(html, page_url)
assert result["body"].strip() == expected.strip() assert result["body"].strip() == expected.strip()
@@ -190,5 +190,5 @@ def test_unknown_attr():
""" """
expected = r"<action name=link_0><u>link</u></action>" expected = r"<action name=link_0><u>link</u></action>"
result = html_to_minetest(html, page_url) result = html_to_luanti(html, page_url)
assert result["body"].strip() == expected.strip() assert result["body"].strip() == expected.strip()

View File

@@ -32,8 +32,9 @@ def test_web_is_not_bot():
"Chrome/125.0.0.0 Safari/537.36").is_bot "Chrome/125.0.0.0 Safari/537.36").is_bot
def test_minetest_is_not_bot(): def test_luanti_is_not_bot():
assert not user_agents.parse("Minetest/5.5.1 (Linux/4.14.193+-ab49821 aarch64)").is_bot assert not user_agents.parse("Minetest/5.5.1 (Linux/4.14.193+-ab49821 aarch64)").is_bot
assert not user_agents.parse("Luanti/5.12.0 (Linux/4.14.193+-ab49821 aarch64)").is_bot
def test_crawlers_are_bots(): def test_crawlers_are_bots():

View File

@@ -55,7 +55,7 @@ def make_indent(w):
return f"<img name=blank.png width={16*w} height=1>" return f"<img name=blank.png width={16*w} height=1>"
class MinetestHTMLParser(HTMLParser): class LuantiHTMLParser(HTMLParser):
def __init__(self, page_url: str, include_images: bool, link_prefix: str): def __init__(self, page_url: str, include_images: bool, link_prefix: str):
super().__init__() super().__init__()
self.page_url = page_url self.page_url = page_url
@@ -224,8 +224,8 @@ class MinetestHTMLParser(HTMLParser):
self.current_line += f"&{name};" self.current_line += f"&{name};"
def html_to_minetest(html, page_url: str, formspec_version: int = 7, include_images: bool = True, link_prefix: str = "link_"): def html_to_luanti(html, page_url: str, formspec_version: int = 7, include_images: bool = True, link_prefix: str = "link_"):
parser = MinetestHTMLParser(page_url, include_images, link_prefix) parser = LuantiHTMLParser(page_url, include_images, link_prefix)
parser.feed(html) parser.feed(html)
parser.finish_line() parser.finish_line()
@@ -329,7 +329,7 @@ def package_reviews_as_hypertext(package: Package, formspec_version: int = 7):
for review in reviews: for review in reviews:
review: PackageReview review: PackageReview
html = render_markdown(review.thread.first_reply.comment) html = render_markdown(review.thread.first_reply.comment)
content = html_to_minetest(html, package.get_url("packages.view", absolute=True), content = html_to_luanti(html, package.get_url("packages.view", absolute=True),
formspec_version, False, f"review_{review.id}_") formspec_version, False, f"review_{review.id}_")
links.update(content["links"]) links.update(content["links"])
comment_body = content["body"].rstrip() comment_body = content["body"].rstrip()

View File

@@ -0,0 +1,17 @@
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '663521dfe86d'
down_revision = 'c181c6c88bae'
branch_labels = None
depends_on = None
def upgrade():
op.rename_table("minetest_release", "luanti_release")
def downgrade():
op.rename_table("luanti_release", "minetest_release")

View File

@@ -18,7 +18,7 @@ depends_on = None
def upgrade(): def upgrade():
# Source: https://github.com/minetest/minetest/blob/master/builtin/mainmenu/settings/dlg_settings.lua#L156 # Source: https://github.com/luanti-org/luanti/blob/master/builtin/mainmenu/settings/dlg_settings.lua#L156
languages = { languages = {
"en": "English", "en": "English",
# "ar": "", blacklisted # "ar": "", blacklisted