Add support for setting min/max minetest versions in conf

This commit is contained in:
rubenwardy 2020-06-03 17:46:59 +01:00
parent 14cf3912f0
commit 183b769ee2
5 changed files with 33 additions and 180 deletions

View File

@ -21,7 +21,7 @@ import flask_menu as menu
from . import bp from . import bp
from app.models import * from app.models import *
from celery import uuid, group from celery import uuid, group
from app.tasks.importtasks import importRepoScreenshot, importAllDependencies, makeVCSRelease, checkZipRelease from app.tasks.importtasks import importRepoScreenshot, makeVCSRelease, checkZipRelease
from app.tasks.forumtasks import importTopicList, checkAllForumAccounts from app.tasks.forumtasks import importTopicList, checkAllForumAccounts
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import * from wtforms import *
@ -76,9 +76,6 @@ def admin_page():
package.soft_deleted = False package.soft_deleted = False
db.session.commit() db.session.commit()
return redirect(url_for("admin.admin_page")) return redirect(url_for("admin.admin_page"))
elif action == "importdepends":
task = importAllDependencies.delay()
return redirect(url_for("tasks.check", id=task.id, r=url_for("admin.admin_page")))
elif action == "modprovides": elif action == "modprovides":
packages = Package.query.filter_by(type=PackageType.MOD).all() packages = Package.query.filter_by(type=PackageType.MOD).all()
mpackage_cache = {} mpackage_cache = {}

View File

@ -65,15 +65,11 @@ The process is as follows:
### Setting minimum and maximum Minetest versions ### Setting minimum and maximum Minetest versions
<p class="alert alert-info">
This feature is unimplemented.
</p>
1. Open up the conf file for the package. 1. Open up the conf file for the package.
This will be `game.conf`, `mod.conf`, `modpack.conf`, or `texture_pack.conf` This will be `game.conf`, `mod.conf`, `modpack.conf`, or `texture_pack.conf`
depending on the content type. depending on the content type.
2. Set `min_protocol` and `max_protocol` to the respective protocol numbers 2. Set `min_minetest_version` and `max_minetest_version` to the respective Minetest versions.
of the Minetest versions.
* 0.4 = 32 Eg:
* 5.0 = 37
* 5.1 = 38 min_minetest_version = 5.0

View File

@ -789,10 +789,8 @@ class MinetestRelease(db.Model):
@classmethod @classmethod
def get(cls, version, protocol_num): def get(cls, version, protocol_num):
import sys
if version: if version:
parts = version.split(".") parts = version.strip().split(".")
if len(parts) >= 2: if len(parts) >= 2:
major_minor = parts[0] + "." + parts[1] major_minor = parts[0] + "." + parts[1]
query = MinetestRelease.query.filter(MinetestRelease.name.like("%{}%".format(major_minor))) query = MinetestRelease.query.filter(MinetestRelease.name.like("%{}%".format(major_minor)))

View File

@ -31,45 +31,6 @@ from app.utils import randomString
from .minetestcheck import build_tree, MinetestCheckError, ContentType from .minetestcheck import build_tree, MinetestCheckError, ContentType
from .minetestcheck.config import parse_conf from .minetestcheck.config import parse_conf
class GithubURLMaker:
def __init__(self, url):
self.baseUrl = None
self.user = None
self.repo = None
# Rewrite path
import re
m = re.search("^\/([^\/]+)\/([^\/]+)\/?$", url.path)
if m is None:
return
user = m.group(1)
repo = m.group(2).replace(".git", "")
self.baseUrl = "https://raw.githubusercontent.com/{}/{}/master" \
.format(user, repo)
self.user = user
self.repo = repo
def isValid(self):
return self.baseUrl is not None
def getRepoURL(self):
return "https://github.com/{}/{}".format(self.user, self.repo)
def getScreenshotURL(self):
return self.baseUrl + "/screenshot.png"
def getModConfURL(self):
return self.baseUrl + "/mod.conf"
def getCommitsURL(self, branch):
return "https://api.github.com/repos/{}/{}/commits?sha={}" \
.format(self.user, self.repo, urllib.parse.quote_plus(branch))
def getCommitDownload(self, commit):
return "https://github.com/{}/{}/archive/{}.zip" \
.format(self.user, self.repo, commit)
krock_list_cache = None krock_list_cache = None
krock_list_cache_by_name = None krock_list_cache_by_name = None
def getKrockList(): def getKrockList():
@ -211,30 +172,6 @@ def getMeta(urlstr, author):
return result return result
def makeVCSReleaseFromGithub(id, branch, release, url):
urlmaker = GithubURLMaker(url)
if not urlmaker.isValid():
raise TaskError("Invalid github repo URL")
commitsURL = urlmaker.getCommitsURL(branch)
try:
contents = urllib.request.urlopen(commitsURL).read().decode("utf-8")
commits = json.loads(contents)
except HTTPError:
raise TaskError("Unable to get commits for Github repository. Either the repository or reference doesn't exist.")
if len(commits) == 0 or not "sha" in commits[0]:
raise TaskError("No commits found")
release.url = urlmaker.getCommitDownload(commits[0]["sha"])
release.task_id = None
release.commit_hash = commits[0]["sha"]
release.approve(release.package.author)
db.session.commit()
return release.url
@celery.task(bind=True) @celery.task(bind=True)
def checkZipRelease(self, id, path): def checkZipRelease(self, id, path):
release = PackageRelease.query.get(id) release = PackageRelease.query.get(id)
@ -277,12 +214,9 @@ def makeVCSRelease(id, branch):
elif release.package is None: elif release.package is None:
raise TaskError("No package attached to release") raise TaskError("No package attached to release")
# url = urlparse(release.package.repo)
# if url.netloc == "github.com":
# return makeVCSReleaseFromGithub(id, branch, release, url)
gitDir, repo = cloneRepo(release.package.repo, ref=branch, recursive=True) gitDir, repo = cloneRepo(release.package.repo, ref=branch, recursive=True)
tree = None
try: try:
tree = build_tree(gitDir, expected_type=ContentType[release.package.type.name], \ tree = build_tree(gitDir, expected_type=ContentType[release.package.type.name], \
author=release.package.author.username, name=release.package.name) author=release.package.author.username, name=release.package.name)
@ -301,8 +235,14 @@ def makeVCSRelease(id, branch):
release.url = "/uploads/" + filename release.url = "/uploads/" + filename
release.task_id = None release.task_id = None
release.commit_hash = repo.head.object.hexsha release.commit_hash = repo.head.object.hexsha
if tree.meta["min_minetest_version"]:
release.min_rel = MinetestRelease.get(tree.meta["min_minetest_version"], None)
if tree.meta["max_minetest_version"]:
release.max_rel = MinetestRelease.get(tree.meta["max_minetest_version"], None)
release.approve(release.package.author) release.approve(release.package.author)
print(release.url)
db.session.commit() db.session.commit()
return release.url return release.url
@ -346,92 +286,3 @@ def importRepoScreenshot(id):
print("screenshot.png does not exist") print("screenshot.png does not exist")
return None return None
def getDepends(package):
url = urlparse(package.repo)
urlmaker = None
if url.netloc == "github.com":
urlmaker = GithubURLMaker(url)
else:
return {}
result = {}
if not urlmaker.isValid():
return {}
#
# Try getting depends on mod.conf
#
try:
contents = urllib.request.urlopen(urlmaker.getModConfURL()).read().decode("utf-8")
conf = parse_conf(contents)
for key in ["depends", "optional_depends"]:
try:
result[key] = conf[key]
except KeyError:
pass
except HTTPError:
print("mod.conf does not exist")
if "depends" in result or "optional_depends" in result:
return result
#
# Try depends.txt
#
import re
pattern = re.compile("^([a-z0-9_]+)\??$")
try:
contents = urllib.request.urlopen(urlmaker.getDependsURL()).read().decode("utf-8")
soft = []
hard = []
for line in contents.split("\n"):
line = line.strip()
if pattern.match(line):
if line[len(line) - 1] == "?":
soft.append( line[:-1])
else:
hard.append(line)
result["depends"] = ",".join(hard)
result["optional_depends"] = ",".join(soft)
except HTTPError:
print("depends.txt does not exist")
return result
def importDependencies(package, mpackage_cache):
if Dependency.query.filter_by(depender=package).count() != 0:
return
result = getDepends(package)
if "depends" in result:
deps = Dependency.SpecToList(package, result["depends"], mpackage_cache)
print("{} hard: {}".format(len(deps), result["depends"]))
for dep in deps:
dep.optional = False
db.session.add(dep)
if "optional_depends" in result:
deps = Dependency.SpecToList(package, result["optional_depends"], mpackage_cache)
print("{} soft: {}".format(len(deps), result["optional_depends"]))
for dep in deps:
dep.optional = True
db.session.add(dep)
@celery.task()
def importAllDependencies():
Dependency.query.delete()
mpackage_cache = {}
packages = Package.query.filter_by(type=PackageType.MOD).all()
for i, p in enumerate(packages):
print("============= {} ({}/{}) =============".format(p.name, i, len(packages)))
importDependencies(p, mpackage_cache)
db.session.commit()

View File

@ -51,19 +51,31 @@ class PackageTreeNode:
elif self.type == ContentType.MODPACK: elif self.type == ContentType.MODPACK:
self.add_children_from_mod_dir(baseDir) self.add_children_from_mod_dir(baseDir)
def getMetaFilePath(self):
filename = None
if self.type == ContentType.GAME:
filename = "game.conf"
elif self.type == ContentType.MOD:
filename = "mod.conf"
elif self.type == ContentType.MODPACK:
filename = "modpack.conf"
elif self.type == ContentType.TXP:
filename = "texture_pack.conf"
else:
return None
return self.baseDir + "/" + filename
def read_meta(self): def read_meta(self):
result = {} result = {}
# .conf file # .conf file
try: try:
with open(self.baseDir + "/mod.conf", "r") as myfile: with open(self.getMetaFilePath(), "r") as myfile:
conf = parse_conf(myfile.read()) conf = parse_conf(myfile.read())
for key in ["name", "description", "title", "depends", "optional_depends"]: for key, value in conf.items():
try: result[key] = value
result[key] = conf[key]
except KeyError:
pass
except IOError: except IOError:
pass pass
@ -104,7 +116,6 @@ class PackageTreeNode:
if "optional_depends" in result: if "optional_depends" in result:
result["optional_depends"] = [x.strip() for x in result["optional_depends"].split(",")] result["optional_depends"] = [x.strip() for x in result["optional_depends"].split(",")]
# Calculate Title # Calculate Title
if "name" in result and not "title" in result: if "name" in result and not "title" in result:
result["title"] = result["name"].replace("_", " ").title() result["title"] = result["name"].replace("_", " ").title()