from app.rediscache import has_key, set_key, make_download_key
from app.models import *
-from app.tasks.importtasks import makeVCSRelease
+from app.tasks.importtasks import makeVCSRelease, checkZIPRelease
from app.utils import *
from celery import uuid
return redirect(url_for("tasks.check", id=rel.task_id, r=rel.getEditURL()))
else:
- uploadedPath = doFileUpload(form.fileUpload.data, "zip", "a zip file")
- if uploadedPath is not None:
+ uploadedUrl, uploadedPath = doFileUpload(form.fileUpload.data, "zip", "a zip file")
+ if uploadedUrl is not None:
rel = PackageRelease()
rel.package = package
rel.title = form["title"].data
- rel.url = uploadedPath
+ rel.url = uploadedUrl
+ rel.task_id = uuid()
rel.min_rel = form["min_rel"].data.getActual()
rel.max_rel = form["max_rel"].data.getActual()
- rel.approve(current_user)
db.session.add(rel)
db.session.commit()
+ checkZIPRelease.apply_async((rel.id, uploadedPath), task_id=rel.task_id)
+
msg = "{}: Release {} created".format(package.title, rel.title)
triggerNotif(package.author, current_user, msg, rel.getEditURL())
db.session.commit()
- return redirect(package.getDetailsURL())
+
+ return redirect(url_for("tasks.check", id=rel.task_id, r=rel.getEditURL()))
return render_template("packages/release_new.html", package=package, form=form)
# Initial form class from post data and default data
form = CreateScreenshotForm()
if request.method == "POST" and form.validate():
- uploadedPath = doFileUpload(form.fileUpload.data, "image",
+ uploadedUrl, uploadedPath = doFileUpload(form.fileUpload.data, "image",
"a PNG or JPG image file")
- if uploadedPath is not None:
+ if uploadedUrl is not None:
ss = PackageScreenshot()
ss.package = package
ss.title = form["title"].data or "Untitled"
- ss.url = uploadedPath
+ ss.url = uploadedUrl
ss.approved = package.checkPerm(current_user, Permission.APPROVE_SCREENSHOT)
db.session.add(ss)
from urllib.error import HTTPError
import urllib.request
from urllib.parse import urlparse, quote_plus, urlsplit
+from zipfile import ZipFile
+
from app import app
from app.models import *
from app.tasks import celery, TaskError
return "http://:@" + netloc + path + query
+
+def getTempDir():
+ return os.path.join(tempfile.gettempdir(), randomString(10))
+
+
# Clones a repo from an unvalidated URL.
# Returns a tuple of path and repo on sucess.
# Throws `TaskError` on failure.
# Caller is responsible for deleting returned directory.
def cloneRepo(urlstr, ref=None, recursive=False):
- gitDir = tempfile.gettempdir() + "/" + randomString(10)
+ gitDir = getTempDir()
err = None
try:
return release.url
+@celery.task()
+def checkZIPRelease(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")
+
+ temp = getTempDir()
+ try:
+ with ZipFile(path, 'r') as zip_ref:
+ zip_ref.extractall(temp)
+
+ try:
+ tree = build_tree(temp, expected_type=ContentType[release.package.type.name], \
+ author=release.package.author.username, name=release.package.name)
+ except MinetestCheckError as err:
+ raise TaskError(str(err))
+
+ release.task_id = None
+ release.approve(release.package.author)
+ db.session.commit()
+
+ finally:
+ shutil.rmtree(temp)
+
@celery.task()
def makeVCSRelease(id, branch):
def doFileUpload(file, fileType, fileTypeDesc):
if not file or file is None or file.filename == "":
flash("No selected file", "error")
- return None
+ return None, None
assert os.path.isdir(app.config["UPLOAD_DIR"]), "UPLOAD_DIR must exist"
ext = getExtension(file.filename)
if ext is None or not ext in allowedExtensions:
flash("Please upload load " + fileTypeDesc, "danger")
- return None
+ return None, None
if isImage and not isAllowedImage(file.stream.read()):
flash("Uploaded image isn't actually an image", "danger")
- return None
+ return None, None
file.stream.seek(0)
filename = randomString(10) + "." + ext
- file.save(os.path.join(app.config["UPLOAD_DIR"], filename))
- return "/uploads/" + filename
+ filepath = os.path.join(app.config["UPLOAD_DIR"], filename)
+ file.save(filepath)
+ return "/uploads/" + filename, filepath
def make_flask_user_password(plaintext_str):
# http://passlib.readthedocs.io/en/stable/modular_crypt_format.html