mirror of
https://github.com/minetest/contentdb.git
synced 2025-03-30 14:52:30 +02:00
Use package translation in API
This commit is contained in:
@ -21,6 +21,7 @@ from typing import List
|
|||||||
|
|
||||||
import flask_sqlalchemy
|
import flask_sqlalchemy
|
||||||
from flask import request, jsonify, current_app, Response
|
from flask import request, jsonify, current_app, Response
|
||||||
|
from flask_babel import gettext
|
||||||
from flask_login import current_user, login_required
|
from flask_login import current_user, login_required
|
||||||
from sqlalchemy import and_, or_
|
from sqlalchemy import and_, or_
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
@ -31,7 +32,7 @@ from app.logic.graphs import get_package_stats, get_package_stats_for_user, get_
|
|||||||
from app.markdown import render_markdown
|
from app.markdown import render_markdown
|
||||||
from app.models import Tag, PackageState, PackageType, Package, db, PackageRelease, Permission, ForumTopic, \
|
from app.models import Tag, PackageState, PackageType, Package, db, PackageRelease, Permission, ForumTopic, \
|
||||||
MinetestRelease, APIToken, PackageScreenshot, License, ContentWarning, User, PackageReview, Thread, Collection, \
|
MinetestRelease, APIToken, PackageScreenshot, License, ContentWarning, User, PackageReview, Thread, Collection, \
|
||||||
PackageAlias
|
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
|
from app.utils import is_package_page, get_int_or_abort, url_set_query, abs_url, is_yes, get_request_date
|
||||||
from app.utils.minetest_hypertext import html_to_minetest
|
from app.utils.minetest_hypertext import html_to_minetest
|
||||||
@ -68,7 +69,10 @@ def cached(max_age: int):
|
|||||||
@cors_allowed
|
@cors_allowed
|
||||||
@cached(300)
|
@cached(300)
|
||||||
def packages():
|
def packages():
|
||||||
qb = QueryBuilder(request.args)
|
allowed_languages = set([x[0] for x in db.session.query(Language.id).all()])
|
||||||
|
lang = request.accept_languages.best_match(allowed_languages)
|
||||||
|
|
||||||
|
qb = QueryBuilder(request.args, lang=lang)
|
||||||
query = qb.build_package_query()
|
query = qb.build_package_query()
|
||||||
|
|
||||||
if request.args.get("fmt") == "keys":
|
if request.args.get("fmt") == "keys":
|
||||||
@ -88,7 +92,7 @@ def packages():
|
|||||||
Package.collections.any(and_(Collection.name == "featured", Collection.author.has(username="ContentDB")))).all())
|
Package.collections.any(and_(Collection.name == "featured", Collection.author.has(username="ContentDB")))).all())
|
||||||
for pkg in featured:
|
for pkg in featured:
|
||||||
featured_lut.add(f"{pkg['author']}/{pkg['name']}")
|
featured_lut.add(f"{pkg['author']}/{pkg['name']}")
|
||||||
pkg["short_description"] = "Featured. " + pkg["short_description"]
|
pkg["short_description"] = gettext("Featured") + ". " + pkg["short_description"]
|
||||||
|
|
||||||
not_featured = [pkg for pkg in pkgs if f"{pkg['author']}/{pkg['name']}" not in featured_lut]
|
not_featured = [pkg for pkg in pkgs if f"{pkg['author']}/{pkg['name']}" not in featured_lut]
|
||||||
pkgs = featured + not_featured
|
pkgs = featured + not_featured
|
||||||
@ -100,11 +104,14 @@ def packages():
|
|||||||
@is_package_page
|
@is_package_page
|
||||||
@cors_allowed
|
@cors_allowed
|
||||||
def package_view(package):
|
def package_view(package):
|
||||||
data = package.as_dict(current_app.config["BASE_URL"])
|
allowed_languages = set([x[0] for x in db.session.query(Language.id).all()])
|
||||||
|
lang = request.accept_languages.best_match(allowed_languages)
|
||||||
|
|
||||||
|
data = package.as_dict(current_app.config["BASE_URL"], lang=lang)
|
||||||
if "formspec_version" in request.args:
|
if "formspec_version" in request.args:
|
||||||
formspec_version = request.args["formspec_version"]
|
formspec_version = request.args["formspec_version"]
|
||||||
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)
|
html = render_markdown(data["long_description"])
|
||||||
data["long_description"] = html_to_minetest(html, formspec_version, include_images)
|
data["long_description"] = html_to_minetest(html, formspec_version, include_images)
|
||||||
|
|
||||||
return jsonify(data)
|
return jsonify(data)
|
||||||
|
@ -21,7 +21,7 @@ import os
|
|||||||
|
|
||||||
import typing
|
import typing
|
||||||
from flask import url_for
|
from flask import url_for
|
||||||
from flask_babel import lazy_gettext, get_locale
|
from flask_babel import lazy_gettext, get_locale, gettext
|
||||||
from flask_sqlalchemy import BaseQuery
|
from flask_sqlalchemy import BaseQuery
|
||||||
from sqlalchemy import or_, func
|
from sqlalchemy import or_, func
|
||||||
from sqlalchemy.dialects.postgresql import insert
|
from sqlalchemy.dialects.postgresql import insert
|
||||||
@ -502,7 +502,10 @@ class Package(db.Model):
|
|||||||
else:
|
else:
|
||||||
lang = "en"
|
lang = "en"
|
||||||
|
|
||||||
translation: typing.Optional[PackageTranslation] = self.translations.filter_by(language_id=lang).first()
|
translation: typing.Optional[PackageTranslation] = None
|
||||||
|
if lang != "en":
|
||||||
|
translation = self.translations.filter_by(language_id=lang).first()
|
||||||
|
|
||||||
if translation is None:
|
if translation is None:
|
||||||
return {
|
return {
|
||||||
"title": self.title,
|
"title": self.title,
|
||||||
@ -556,20 +559,21 @@ class Package(db.Model):
|
|||||||
"type": self.type.to_name(),
|
"type": self.type.to_name(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def as_short_dict(self, base_url, version=None, release_id=None, no_load=False):
|
def as_short_dict(self, base_url, version=None, release_id=None, no_load=False, lang="en"):
|
||||||
tnurl = self.get_thumb_url(1, format="png")
|
tnurl = self.get_thumb_url(1, format="png")
|
||||||
|
|
||||||
if release_id is None and no_load == False:
|
if release_id is None and no_load == False:
|
||||||
release = self.get_download_release(version=version)
|
release = self.get_download_release(version=version)
|
||||||
release_id = release and release.id
|
release_id = release and release.id
|
||||||
|
|
||||||
short_desc = self.short_desc
|
meta = self.get_translated(lang, load_desc=False)
|
||||||
|
short_desc = meta["short_desc"]
|
||||||
if self.dev_state == PackageDevState.WIP:
|
if self.dev_state == PackageDevState.WIP:
|
||||||
short_desc = "Work in Progress. " + self.short_desc
|
short_desc = gettext("Work in Progress") + ". " + self.short_desc
|
||||||
|
|
||||||
ret = {
|
ret = {
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"title": self.title,
|
"title": meta["title"],
|
||||||
"author": self.author.username,
|
"author": self.author.username,
|
||||||
"short_description": short_desc,
|
"short_description": short_desc,
|
||||||
"type": self.type.to_name(),
|
"type": self.type.to_name(),
|
||||||
@ -583,9 +587,11 @@ class Package(db.Model):
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def as_dict(self, base_url, version=None):
|
def as_dict(self, base_url, version=None, lang="en"):
|
||||||
tnurl = self.get_thumb_url(1, format="png")
|
tnurl = self.get_thumb_url(1, format="png")
|
||||||
release = self.get_download_release(version=version)
|
release = self.get_download_release(version=version)
|
||||||
|
meta = self.get_translated(lang)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"author": self.author.username,
|
"author": self.author.username,
|
||||||
"maintainers": [x.username for x in self.maintainers],
|
"maintainers": [x.username for x in self.maintainers],
|
||||||
@ -594,9 +600,9 @@ class Package(db.Model):
|
|||||||
"dev_state": self.dev_state.name if self.dev_state else None,
|
"dev_state": self.dev_state.name if self.dev_state else None,
|
||||||
|
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"title": self.title,
|
"title": meta["title"],
|
||||||
"short_description": self.short_desc,
|
"short_description": meta["short_desc"],
|
||||||
"long_description": self.desc,
|
"long_description": meta["desc"],
|
||||||
"type": self.type.to_name(),
|
"type": self.type.to_name(),
|
||||||
"created_at": self.created_at.isoformat(),
|
"created_at": self.created_at.isoformat(),
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ from .utils import is_yes, get_int_or_abort
|
|||||||
|
|
||||||
|
|
||||||
class QueryBuilder:
|
class QueryBuilder:
|
||||||
|
lang: str = "en"
|
||||||
types = None
|
types = None
|
||||||
search = None
|
search = None
|
||||||
only_approved = True
|
only_approved = True
|
||||||
@ -59,7 +60,8 @@ class QueryBuilder:
|
|||||||
return (self.search is not None or len(self.tags) > 1 or len(self.types) > 1 or len(self.hide_flags) > 0 or
|
return (self.search is not None or len(self.tags) > 1 or len(self.types) > 1 or len(self.hide_flags) > 0 or
|
||||||
self.random or self.lucky or self.author or self.version or self.game)
|
self.random or self.lucky or self.author or self.version or self.game)
|
||||||
|
|
||||||
def __init__(self, args, cookies=False):
|
def __init__(self, args, cookies=False, lang="en"):
|
||||||
|
self.lang = lang
|
||||||
|
|
||||||
# Get request types
|
# Get request types
|
||||||
types = args.getlist("type")
|
types = args.getlist("type")
|
||||||
@ -153,7 +155,7 @@ class QueryBuilder:
|
|||||||
|
|
||||||
def to_json(package: Package):
|
def to_json(package: Package):
|
||||||
release_id = releases.get(package.id)
|
release_id = releases.get(package.id)
|
||||||
return package.as_short_dict(current_app.config["BASE_URL"], release_id=release_id, no_load=True)
|
return package.as_short_dict(current_app.config["BASE_URL"], release_id=release_id, no_load=True, lang=self.lang)
|
||||||
|
|
||||||
return [to_json(pkg) for pkg in packages]
|
return [to_json(pkg) for pkg in packages]
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user