mirror of
https://github.com/minetest/contentdb.git
synced 2025-01-03 19:57:29 +01:00
Add import translation action
This commit is contained in:
parent
028452c2ca
commit
8f9f554749
@ -26,7 +26,8 @@ from app.models import PackageRelease, db, Package, PackageState, PackageScreens
|
|||||||
NotificationType, PackageUpdateConfig, License, UserRank, PackageType, Thread
|
NotificationType, PackageUpdateConfig, License, UserRank, PackageType, Thread
|
||||||
from app.tasks.emails import send_pending_digests
|
from app.tasks.emails import send_pending_digests
|
||||||
from app.tasks.forumtasks import import_topic_list, check_all_forum_accounts
|
from app.tasks.forumtasks import import_topic_list, check_all_forum_accounts
|
||||||
from app.tasks.importtasks import import_repo_screenshot, check_zip_release, check_for_updates, update_all_game_support
|
from app.tasks.importtasks import import_repo_screenshot, check_zip_release, check_for_updates, update_all_game_support, \
|
||||||
|
import_languages
|
||||||
from app.utils import add_notification, get_system_user
|
from app.utils import add_notification, get_system_user
|
||||||
|
|
||||||
actions = {}
|
actions = {}
|
||||||
@ -321,7 +322,7 @@ def check_releases():
|
|||||||
@action("DANGER: Check latest release of all packages (postReleaseCheckUpdate)")
|
@action("DANGER: Check latest release of all packages (postReleaseCheckUpdate)")
|
||||||
def reimport_packages():
|
def reimport_packages():
|
||||||
tasks = []
|
tasks = []
|
||||||
for package in Package.query.filter(Package.state != PackageState.DELETED).all():
|
for package in Package.query.filter(Package.state == PackageState.APPROVED).all():
|
||||||
release = package.releases.first()
|
release = package.releases.first()
|
||||||
if release:
|
if release:
|
||||||
tasks.append(check_zip_release.s(release.id, release.file_path))
|
tasks.append(check_zip_release.s(release.id, release.file_path))
|
||||||
@ -335,6 +336,22 @@ def reimport_packages():
|
|||||||
return redirect(url_for("todo.view_editor"))
|
return redirect(url_for("todo.view_editor"))
|
||||||
|
|
||||||
|
|
||||||
|
@action("DANGER: Import translations")
|
||||||
|
def reimport_translations():
|
||||||
|
tasks = []
|
||||||
|
for package in Package.query.filter(Package.state == PackageState.APPROVED).all():
|
||||||
|
release = package.releases.first()
|
||||||
|
if release:
|
||||||
|
tasks.append(import_languages.s(release.id, release.file_path))
|
||||||
|
|
||||||
|
result = group(tasks).apply_async()
|
||||||
|
while not result.ready():
|
||||||
|
import time
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
return redirect(url_for("todo.view_editor"))
|
||||||
|
|
||||||
|
|
||||||
@action("DANGER: Import screenshots from Git")
|
@action("DANGER: Import screenshots from Git")
|
||||||
def import_screenshots():
|
def import_screenshots():
|
||||||
packages = Package.query \
|
packages = Package.query \
|
||||||
|
@ -164,37 +164,7 @@ def post_release_check_update(self, release: PackageRelease, path):
|
|||||||
db.session.add(Dependency(package, meta=meta, optional=True))
|
db.session.add(Dependency(package, meta=meta, optional=True))
|
||||||
|
|
||||||
# Read translations
|
# Read translations
|
||||||
allowed_languages = set([x[0] for x in db.session.query(Language.id).all()])
|
update_translations(package, tree)
|
||||||
allowed_languages.discard("en")
|
|
||||||
conn = db.session.connection()
|
|
||||||
|
|
||||||
for language in tree.get_supported_languages():
|
|
||||||
if language not in allowed_languages:
|
|
||||||
continue
|
|
||||||
|
|
||||||
values = {
|
|
||||||
"package_id": package.id,
|
|
||||||
"language_id": language,
|
|
||||||
}
|
|
||||||
stmt = insert(PackageTranslation).values(**values)
|
|
||||||
stmt = stmt.on_conflict_do_nothing(
|
|
||||||
index_elements=[PackageTranslation.package_id, PackageTranslation.language_id],
|
|
||||||
)
|
|
||||||
conn.execute(stmt)
|
|
||||||
|
|
||||||
raw_translations = tree.get_translations(tree.get("textdomain", tree.name))
|
|
||||||
for raw_translation in raw_translations:
|
|
||||||
if raw_translation.language not in allowed_languages:
|
|
||||||
continue
|
|
||||||
|
|
||||||
to_update = {
|
|
||||||
"title": raw_translation.entries.get(tree.get("title", package.title)),
|
|
||||||
"short_desc": raw_translation.entries.get(tree.get("description", package.short_desc)),
|
|
||||||
}
|
|
||||||
|
|
||||||
PackageTranslation.query \
|
|
||||||
.filter_by(package_id=package.id, language_id=raw_translation.language) \
|
|
||||||
.update(to_update)
|
|
||||||
|
|
||||||
# Update min/max
|
# Update min/max
|
||||||
if tree.meta.get("min_minetest_version"):
|
if tree.meta.get("min_minetest_version"):
|
||||||
@ -258,6 +228,39 @@ def post_release_check_update(self, release: PackageRelease, path):
|
|||||||
raise TaskError(str(err))
|
raise TaskError(str(err))
|
||||||
|
|
||||||
|
|
||||||
|
def update_translations(package: Package, tree: PackageTreeNode):
|
||||||
|
allowed_languages = set([x[0] for x in db.session.query(Language.id).all()])
|
||||||
|
allowed_languages.discard("en")
|
||||||
|
conn = db.session.connection()
|
||||||
|
for language in tree.get_supported_languages():
|
||||||
|
if language not in allowed_languages:
|
||||||
|
continue
|
||||||
|
|
||||||
|
values = {
|
||||||
|
"package_id": package.id,
|
||||||
|
"language_id": language,
|
||||||
|
}
|
||||||
|
stmt = insert(PackageTranslation).values(**values)
|
||||||
|
stmt = stmt.on_conflict_do_nothing(
|
||||||
|
index_elements=[PackageTranslation.package_id, PackageTranslation.language_id],
|
||||||
|
)
|
||||||
|
conn.execute(stmt)
|
||||||
|
|
||||||
|
raw_translations = tree.get_translations(tree.get("textdomain", tree.name))
|
||||||
|
for raw_translation in raw_translations:
|
||||||
|
if raw_translation.language not in allowed_languages:
|
||||||
|
continue
|
||||||
|
|
||||||
|
to_update = {
|
||||||
|
"title": raw_translation.entries.get(tree.get("title", package.title)),
|
||||||
|
"short_desc": raw_translation.entries.get(tree.get("description", package.short_desc)),
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageTranslation.query \
|
||||||
|
.filter_by(package_id=package.id, language_id=raw_translation.language) \
|
||||||
|
.update(to_update)
|
||||||
|
|
||||||
|
|
||||||
@celery.task(bind=True)
|
@celery.task(bind=True)
|
||||||
def check_zip_release(self, id, path):
|
def check_zip_release(self, id, path):
|
||||||
release = PackageRelease.query.get(id)
|
release = PackageRelease.query.get(id)
|
||||||
@ -277,6 +280,37 @@ def check_zip_release(self, id, path):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
@celery.task(bind=True)
|
||||||
|
def import_languages(self, id, path):
|
||||||
|
release = PackageRelease.query.get(id)
|
||||||
|
if release is None:
|
||||||
|
raise TaskError("No such release!")
|
||||||
|
elif release.package is None:
|
||||||
|
raise TaskError("No package attached to release")
|
||||||
|
|
||||||
|
with get_temp_dir() as temp:
|
||||||
|
with ZipFile(path, 'r') as zip_ref:
|
||||||
|
zip_ref.extractall(temp)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tree: PackageTreeNode = build_tree(temp,
|
||||||
|
expected_type=ContentType[release.package.type.name],
|
||||||
|
author=release.package.author.username,
|
||||||
|
name=release.package.name,
|
||||||
|
strict=False)
|
||||||
|
update_translations(release.package, tree)
|
||||||
|
db.session.commit()
|
||||||
|
except (MinetestCheckError, TaskError, LogicError) as err:
|
||||||
|
db.session.rollback()
|
||||||
|
|
||||||
|
task_url = url_for('tasks.check', id=self.request.id)
|
||||||
|
msg = f"{err}\n\n[View Release]({release.get_edit_url()}) | [View Task]({task_url})"
|
||||||
|
post_bot_message(release.package, f"Release {release.title} validation failed", msg)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
raise TaskError(str(err))
|
||||||
|
|
||||||
|
|
||||||
@celery.task(bind=True)
|
@celery.task(bind=True)
|
||||||
def make_vcs_release(self, id, branch):
|
def make_vcs_release(self, id, branch):
|
||||||
release = PackageRelease.query.get(id)
|
release = PackageRelease.query.get(id)
|
||||||
|
@ -56,10 +56,10 @@ class ContentType(Enum):
|
|||||||
from .tree import PackageTreeNode, get_base_dir
|
from .tree import PackageTreeNode, get_base_dir
|
||||||
|
|
||||||
|
|
||||||
def build_tree(path, expected_type=None, author=None, repo=None, name=None):
|
def build_tree(path, expected_type=None, author=None, repo=None, name=None, strict: bool = True):
|
||||||
path = get_base_dir(path)
|
path = get_base_dir(path)
|
||||||
|
|
||||||
root = PackageTreeNode(path, "/", author=author, repo=repo, name=name)
|
root = PackageTreeNode(path, "/", author=author, repo=repo, name=name, strict=strict)
|
||||||
assert root
|
assert root
|
||||||
|
|
||||||
if expected_type:
|
if expected_type:
|
||||||
|
@ -89,9 +89,12 @@ class PackageTreeNode:
|
|||||||
meta: dict
|
meta: dict
|
||||||
children: list
|
children: list
|
||||||
type: ContentType
|
type: ContentType
|
||||||
|
strict: bool
|
||||||
|
|
||||||
def __init__(self, base_dir: str, relative: str,
|
def __init__(self, base_dir: str, relative: str,
|
||||||
author: Optional[str] = None, repo: Optional[str] = None, name: Optional[str] = None):
|
author: Optional[str] = None,
|
||||||
|
repo: Optional[str] = None, name: Optional[str] = None,
|
||||||
|
strict: bool = True):
|
||||||
self.baseDir = base_dir
|
self.baseDir = base_dir
|
||||||
self.relative = relative
|
self.relative = relative
|
||||||
self.author = author
|
self.author = author
|
||||||
@ -99,6 +102,7 @@ class PackageTreeNode:
|
|||||||
self.repo = repo
|
self.repo = repo
|
||||||
self.meta = {}
|
self.meta = {}
|
||||||
self.children = []
|
self.children = []
|
||||||
|
self.strict = strict
|
||||||
|
|
||||||
# Detect type
|
# Detect type
|
||||||
self.type = detect_type(base_dir)
|
self.type = detect_type(base_dir)
|
||||||
@ -169,7 +173,7 @@ class PackageTreeNode:
|
|||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if "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 MinetestCheckError("{} should not contain 'release' key, as this is for use by ContentDB only.".format(meta_file_rel))
|
||||||
|
|
||||||
# description.txt
|
# description.txt
|
||||||
@ -251,7 +255,7 @@ class PackageTreeNode:
|
|||||||
for entry in next(os.walk(dir))[1]:
|
for entry in next(os.walk(dir))[1]:
|
||||||
path = os.path.join(dir, entry)
|
path = os.path.join(dir, entry)
|
||||||
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)
|
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 MinetestCheckError("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))
|
||||||
|
Loading…
Reference in New Issue
Block a user