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
![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.\
Developed by rubenwardy, license AGPLv3.0+.
@@ -82,7 +82,7 @@ Package "1" --> "*" Release
Package "1" --> "*" Dependency
Package "1" --> "*" Tag
Package "1" --> "*" MetaPackage : provides
Release --> MinetestVersion
Release --> LuantiVersion
Package --> License
Dependency --> Package
Dependency --> MetaPackage

View File

@@ -23,14 +23,14 @@ from wtforms.validators import InputRequired, Length
from app.utils import rank_required, add_audit_log
from . import bp
from app.models import UserRank, MinetestRelease, db, AuditSeverity
from app.models import UserRank, LuantiRelease, db, AuditSeverity
@bp.route("/versions/")
@rank_required(UserRank.MODERATOR)
def version_list():
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):
@@ -45,14 +45,14 @@ class VersionForm(FlaskForm):
def create_edit_version(name=None):
version = 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:
abort(404)
form = VersionForm(formdata=request.form, obj=version)
if form.validate_on_submit():
if version is None:
version = MinetestRelease(form.name.data)
version = LuantiRelease(form.name.data)
db.session.add(version)
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.markdown import render_markdown
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
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, \
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 .auth import is_api_authd
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")
engine_version = request.args.get("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:
version = None
@@ -116,7 +116,7 @@ def package_view_client(package: Package):
page_url = package.get_url("packages.view", absolute=True)
if data["long_description"] is not None:
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)
@@ -153,7 +153,7 @@ def package_hypertext(package):
include_images = is_yes(request.args.get("include_images", "true"))
html = render_markdown(package.desc if package.desc else "")
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"])
@@ -636,14 +636,14 @@ def versions():
protocol_version = request.args.get("protocol_version")
engine_version = request.args.get("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:
error(404, "No releases found")
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/")
@@ -835,7 +835,7 @@ def hypertext():
if request.content_type == "text/markdown":
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/")
@@ -886,9 +886,9 @@ def collection_view(token, author, name):
@cached(300)
def updates():
protocol_version = get_int_or_abort(request.args.get("protocol_version"))
minetest_version = request.args.get("engine_version")
if protocol_version or minetest_version:
version = MinetestRelease.get(minetest_version, protocol_version)
engine_version = request.args.get("engine_version")
if protocol_version or engine_version:
version = LuantiRelease.get(engine_version, protocol_version)
else:
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.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.models import APIToken, Package, MinetestRelease, PackageScreenshot
from app.models import APIToken, Package, LuantiRelease, PackageScreenshot
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,
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):
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,
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):
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
# GAMEJAM_BANNER = "https://jam.minetest.net/img/banner.png"
# GAMEJAM_BANNER = "https://jam.luanti.org/img/banner.png"
#
# class GameJam:
# cover_image = type("", (), dict(url=GAMEJAM_BANNER))()
@@ -40,7 +40,7 @@ PKGS_PER_ROW = 4
# def get_url(self, _name):
# return "/gamejam/"
#
# title = "Minetest Game Jam 2023: \"Unexpected\""
# title = "Luanti Game Jam 2023: \"Unexpected\""
# author = None
#
# 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/")
def gamejam():
return redirect("https://jam.minetest.net/")
return redirect("https://jam.luanti.org/")
@bp.route("/")

View File

@@ -23,7 +23,7 @@ from wtforms.validators import Optional
from wtforms_sqlalchemy.fields import QuerySelectMultipleField, QuerySelectField
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):
@@ -75,7 +75,7 @@ class AdvancedSearchForm(FlaskForm):
get_pk=lambda a: a.id, get_label=lambda a: a.title)
hide = SelectMultipleField(lazy_gettext("Hide Tags and Content Warnings"), [Optional()])
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="",
get_pk=lambda a: a.value, get_label=lambda a: a.name)
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 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
from app.rediscache import has_key, set_temp_key, make_download_key
from app.tasks.importtasks import check_update_config
@@ -42,11 +42,11 @@ def list_releases(package):
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:
query = query.limit(query.count() - 1)
else:
query = query.filter(MinetestRelease.name != "0.4.17")
query = query.filter(LuantiRelease.name != "0.4.17")
return query
@@ -128,9 +128,9 @@ def download_release(package, id):
ip = request.headers.get("X-Forwarded-For") or request.remote_addr
if ip is not None and not is_user_bot():
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")
PackageDailyStats.update(package, is_minetest, reason)
PackageDailyStats.update(package, is_luanti, reason)
key = make_download_key(ip, release.package)
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 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.utils import get_int_or_abort, is_yes, rank_required
from . import bp
@@ -170,7 +170,7 @@ def screenshots():
def mtver_support():
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) \
.filter(~Package.releases.any(or_(PackageRelease.max_rel==None, PackageRelease.max_rel == current_stable))) \

View File

@@ -16,7 +16,7 @@
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
from .utils import make_flask_login_password
@@ -35,12 +35,12 @@ def populate(session):
system_user.rank = UserRank.BOT
session.add(system_user)
session.add(MinetestRelease("None", 0))
session.add(MinetestRelease("0.4.16/17", 32))
session.add(MinetestRelease("5.0", 37))
session.add(MinetestRelease("5.1", 38))
session.add(MinetestRelease("5.2", 39))
session.add(MinetestRelease("5.3", 39))
session.add(LuantiRelease("None", 0))
session.add(LuantiRelease("0.4.16/17", 32))
session.add(LuantiRelease("5.0", 37))
session.add(LuantiRelease("5.1", 38))
session.add(LuantiRelease("5.2", 39))
session.add(LuantiRelease("5.3", 39))
tags = {}
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() }
tags = { x.name : x for x in Tag.query.all() }
admin_user = User.query.filter_by(rank=UserRank.ADMIN).first()
v4 = MinetestRelease.query.filter_by(protocol=32).first()
v51 = MinetestRelease.query.filter_by(protocol=38).first()
v4 = LuantiRelease.query.filter_by(protocol=32).first()
v51 = LuantiRelease.query.filter_by(protocol=38).first()
ez = User("Shara")
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.
<a href="https://github.com/minetest/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/" class="btn btn-primary me-1">Source code</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>
{% if monitoring_url -%}
<a href="{{ monitoring_url }}" class="btn btn-secondary">Stats / monitoring</a>

View File

@@ -3,7 +3,7 @@ title: API
## 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
@@ -131,7 +131,7 @@ curl -X DELETE https://content.luanti.org/api/delete-token/ \
* `<neutral>` with a thumbs up icon.
* `<thumbsdown>` with a thumbs up icon.
* 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.
* Query arguments:
* `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.
* See [JSON Schema Reference](https://json-schema.org/).
* 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.
* Post data: HTML or Markdown as plain text.
* 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">
{{ _("Translation - Luanti Modding Book") }}
</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") }}
</a>
</p>

View File

@@ -141,7 +141,7 @@ permanent bans.
## 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.
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
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
([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

View File

@@ -23,7 +23,7 @@ from flask_babel import lazy_gettext
from app.logic.LogicError import LogicError
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.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,
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)
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,
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):
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",
"minetest.net", "dropboxusercontent.com", "4shared.com",
"minetest.net", "luanti.org", "dropboxusercontent.com", "4shared.com",
"digitalaudioconcepts.com", "hg.intevation.org", "www.wtfpl.net",
"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)
name = db.Column(db.String(100), unique=True, nullable=False)
protocol = db.Column(db.Integer, nullable=False, default=0)
@@ -1067,11 +1067,11 @@ class MinetestRelease(db.Model):
}
@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:
parts = version.strip().split(".")
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:
query = query.filter_by(protocol=protocol_num)
@@ -1081,9 +1081,9 @@ class MinetestRelease(db.Model):
if protocol_num:
# Find the closest matching release
return MinetestRelease.query.order_by(db.desc(MinetestRelease.protocol),
db.desc(MinetestRelease.id)) \
.filter(MinetestRelease.protocol <= protocol_num).first()
return LuantiRelease.query.order_by(db.desc(LuantiRelease.protocol),
db.desc(LuantiRelease.id)) \
.filter(LuantiRelease.protocol <= protocol_num).first()
return None
@@ -1114,11 +1114,11 @@ class PackageRelease(db.Model):
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 = db.relationship("MinetestRelease", foreign_keys=[min_rel_id])
min_rel_id = db.Column(db.Integer, db.ForeignKey("luanti_release.id"), nullable=True, server_default=None)
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 = db.relationship("MinetestRelease", foreign_keys=[max_rel_id])
max_rel_id = db.Column(db.Integer, db.ForeignKey("luanti_release.id"), nullable=True, server_default=None)
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
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)
@staticmethod
def update(package: Package, is_minetest: bool, reason: str):
def update(package: Package, is_luanti: bool, reason: str):
date = datetime.datetime.utcnow().date()
to_update = dict()
@@ -1449,7 +1449,7 @@ class PackageDailyStats(db.Model):
"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
kwargs[field_platform] = 1

View File

@@ -86,7 +86,8 @@ window.addEventListener("load", () => {
"desc_page_topic": (val) => {
const topicId = document.getElementById("forums").value;
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) => {
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_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
from .utils import is_yes, get_int_or_abort
@@ -49,7 +49,7 @@ class QueryBuilder:
hide_wip: bool
hide_nonfree: bool
show_added: bool
version: Optional[MinetestRelease]
version: Optional[LuantiRelease]
has_lang: Optional[str]
@property
@@ -163,12 +163,12 @@ class QueryBuilder:
self.author = args.get("author")
protocol_version = get_int_or_abort(args.get("protocol_version"))
minetest_version = args.get("engine_version")
if minetest_version == "":
minetest_version = None
engine_version = args.get("engine_version")
if engine_version == "":
engine_version = None
if protocol_version or minetest_version:
self.version = MinetestRelease.get(minetest_version, protocol_version)
if protocol_version or engine_version:
self.version = LuantiRelease.get(engine_version, protocol_version)
else:
self.version = None

View File

@@ -31,13 +31,13 @@ from sqlalchemy import and_
from sqlalchemy.dialects.postgresql import insert
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
from app.tasks import celery, TaskError
from app.utils import random_string, post_bot_message, add_system_notification, add_system_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 .minetestcheck import build_tree, MinetestCheckError, ContentType, PackageTreeNode
from .luanticheck import build_tree, LuantiCheckError, ContentType, PackageTreeNode
from .webhooktasks import post_discord_webhook
from app import app
from app.logic.LogicError import LogicError
@@ -51,7 +51,7 @@ def get_meta(urlstr, author):
with clone_repo(urlstr, recursive=True) as repo:
try:
tree = build_tree(repo.working_tree_dir, author=author, repo=urlstr)
except MinetestCheckError as err:
except LuantiCheckError as err:
raise TaskError(str(err))
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)
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 = {}
def get_meta_packages(names):
@@ -165,10 +165,10 @@ def post_release_check_update(self, release: PackageRelease, path):
# Raise error on unresolved game dependencies
if package.type == PackageType.GAME and len(depends) > 0:
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:
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")
# Add dependencies
@@ -183,10 +183,10 @@ def post_release_check_update(self, release: PackageRelease, path):
# Update min/max
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"):
release.max_rel = MinetestRelease.get(tree.meta["max_minetest_version"], None)
release.max_rel = LuantiRelease.get(tree.meta["max_minetest_version"], None)
try:
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
except (MinetestCheckError, TaskError, LogicError) as err:
except (LuantiCheckError, TaskError, LogicError) as err:
db.session.rollback()
error_message = err.value if hasattr(err, "value") else str(err)
@@ -377,7 +377,7 @@ def import_languages(self, id, path):
strict=False)
update_translations(release.package, tree)
db.session.commit()
except (MinetestCheckError, TaskError, LogicError) as err:
except (LuantiCheckError, TaskError, LogicError) as err:
db.session.rollback()
task_url = url_for('tasks.check', id=self.request.id)

View File

@@ -17,7 +17,7 @@
from enum import Enum
class MinetestCheckError(Exception):
class LuantiCheckError(Exception):
def __init__(self, value):
self.value = value
@@ -43,14 +43,14 @@ class ContentType(Enum):
if self == ContentType.MOD:
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:
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:
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

View File

@@ -20,7 +20,7 @@ import re
import glob
from typing import Optional
from . import MinetestCheckError, ContentType
from . import LuantiCheckError, ContentType
from .config import parse_conf
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:
continue
elif " " in dep:
raise MinetestCheckError(
raise LuantiCheckError(
f"Invalid {key} name '{dep}' at {relative}, did you forget a comma?")
else:
raise MinetestCheckError(
raise LuantiCheckError(
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 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")
elif self.type == ContentType.MOD:
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:
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"])
elif self.type == ContentType.MODPACK:
@@ -139,7 +139,7 @@ class PackageTreeNode:
for dir in next(os.walk(self.baseDir))[1]:
lowercase = dir.lower()
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):
for filename in os.listdir(self.baseDir):
@@ -173,12 +173,12 @@ class PackageTreeNode:
for key, value in conf.items():
result[key] = value
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:
pass
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
if "description" not in result:
@@ -269,11 +269,11 @@ class PackageTreeNode:
if not entry.startswith('.') and os.path.isdir(path):
child = PackageTreeNode(path, relative + entry + "/", name=entry, strict=self.strict)
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))
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)
@@ -315,10 +315,10 @@ class PackageTreeNode:
def check_for_legacy_files(self):
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))
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()))
for child in self.children:
child.check_for_legacy_files()
@@ -348,6 +348,6 @@ class PackageTreeNode:
ret.append(parse_tr(name))
except SyntaxError as e:
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

View File

@@ -26,7 +26,7 @@ from . import app, utils
from app.markdown import get_headings
from .models import Permission, Package, PackageState, PackageRelease
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

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('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="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>
<form method="POST" action="{{ url_for('set_nonfree') }}" class="my-3">

View File

@@ -8,7 +8,7 @@
{% set translations = package.translations.all() %}
{% 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") }}
</a>
@@ -22,7 +22,7 @@
<a class="btn btn-primary me-2" href="https://rubenwardy.com/minetest_modding_book/en/quality/translations.html">
{{ _("Translation - Luanti Modding Book") }}
</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") }}
</a>
</p>

View File

@@ -61,7 +61,7 @@
{% 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") }}
</a>

View File

@@ -1,7 +1,7 @@
from typing import List, Tuple, Optional
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 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"
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
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
rel.approved = True

View File

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

View File

@@ -14,7 +14,7 @@
# 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 app.utils.minetest_hypertext import html_to_minetest
from app.utils.luanti_hypertext import html_to_luanti
conquer_html = """
@@ -74,7 +74,7 @@ page_url = "https://example.com/a/b/"
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():
@@ -83,7 +83,7 @@ def test_images():
"""
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 len(result["images"]) == 1
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>"
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 len(result["images"]) == 0
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_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["links"]["link_0"] == "https://example.com/a/b/relative"
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=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()
@@ -158,7 +158,7 @@ def test_table():
expected = "<action name=link_0><u>(view table in browser)</u></action>\n\n" \
"<b>Heading</b>\n" \
"<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["links"]["link_0"] == f"{page_url}#with-id"
assert result["links"]["link_1"] == f"{page_url}#heading"
@@ -170,7 +170,7 @@ def test_inline():
"""
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()
@@ -180,7 +180,7 @@ def test_escape():
"""
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()
@@ -190,5 +190,5 @@ def test_unknown_attr():
"""
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()

View File

@@ -32,8 +32,9 @@ def test_web_is_not_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("Luanti/5.12.0 (Linux/4.14.193+-ab49821 aarch64)").is_bot
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>"
class MinetestHTMLParser(HTMLParser):
class LuantiHTMLParser(HTMLParser):
def __init__(self, page_url: str, include_images: bool, link_prefix: str):
super().__init__()
self.page_url = page_url
@@ -224,8 +224,8 @@ class MinetestHTMLParser(HTMLParser):
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_"):
parser = MinetestHTMLParser(page_url, include_images, link_prefix)
def html_to_luanti(html, page_url: str, formspec_version: int = 7, include_images: bool = True, link_prefix: str = "link_"):
parser = LuantiHTMLParser(page_url, include_images, link_prefix)
parser.feed(html)
parser.finish_line()
@@ -329,7 +329,7 @@ def package_reviews_as_hypertext(package: Package, formspec_version: int = 7):
for review in reviews:
review: PackageReview
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}_")
links.update(content["links"])
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():
# 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 = {
"en": "English",
# "ar": "", blacklisted