def handleCreateRelease(token, package, title, ref): if not token.canOperateOnPackage(package): return error(403, "API token does not have access to the package") if not package.checkPerm(token.owner, Permission.MAKE_RELEASE): return error(403, "Permission denied. Missing MAKE_RELEASE permission") five_minutes_ago = datetime.datetime.now() - datetime.timedelta(minutes=5) count = package.releases.filter( PackageRelease.releaseDate > five_minutes_ago).count() if count >= 2: return error(429, "Too many requests, please wait before trying again") rel = PackageRelease() rel.package = package rel.title = title rel.url = "" rel.task_id = uuid() rel.min_rel = None rel.max_rel = None db.session.add(rel) db.session.commit() makeVCSRelease.apply_async((rel.id, ref), task_id=rel.task_id) return jsonify({ "success": True, "task": url_for("tasks.check", id=rel.task_id), "release": rel.getAsDictionary() })
def do_create_vcs_release(user: User, package: Package, title: str, ref: str, min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason: str = None): check_can_create_release(user, package) rel = PackageRelease() rel.package = package rel.title = title rel.url = "" rel.task_id = uuid() rel.min_rel = min_v rel.max_rel = max_v db.session.add(rel) if reason is None: msg = "Created release {}".format(rel.title) else: msg = "Created release {} ({})".format(rel.title, reason) addAuditLog(AuditSeverity.NORMAL, user, msg, package.getURL("packages.view"), package) db.session.commit() makeVCSRelease.apply_async((rel.id, nonEmptyOrNone(ref)), task_id=rel.task_id) return rel
def create_release_page(package): if not package.checkPerm(current_user, Permission.MAKE_RELEASE): return redirect(package.getDetailsURL()) # Initial form class from post data and default data form = CreatePackageReleaseForm() if package.repo is not None: form["uploadOpt"].choices = [("vcs", "From Git Commit or Branch"), ("upload", "File Upload")] if request.method != "POST": form["uploadOpt"].data = "vcs" if request.method == "POST" and form.validate(): if form["uploadOpt"].data == "vcs": rel = PackageRelease() rel.package = package rel.title = form["title"].data rel.url = "" rel.task_id = uuid() rel.min_rel = form["min_rel"].data.getActual() rel.max_rel = form["max_rel"].data.getActual() db.session.add(rel) db.session.commit() makeVCSRelease.apply_async((rel.id, form["vcsLabel"].data), 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( url_for("check_task", id=rel.task_id, r=rel.getEditURL())) else: uploadedPath = doFileUpload(form.fileUpload.data, "zip", "a zip file") if uploadedPath is not None: rel = PackageRelease() rel.package = package rel.title = form["title"].data rel.url = uploadedPath 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() msg = "{}: Release {} created".format(package.title, rel.title) triggerNotif(package.author, current_user, msg, rel.getEditURL()) db.session.commit() return redirect(package.getDetailsURL()) return render_template("packages/release_new.html", package=package, form=form)
def apply_all_updates(username): user: User = User.query.filter_by(username=username).first() if not user: abort(404) if current_user != user and not current_user.rank.atLeast(UserRank.EDITOR): abort(403) outdated_packages = user.maintained_packages \ .filter(Package.state != PackageState.DELETED, Package.update_config.has(PackageUpdateConfig.outdated_at.isnot(None))) \ .order_by(db.asc(Package.title)).all() for package in outdated_packages: if not package.checkPerm(current_user, Permission.MAKE_RELEASE): continue if package.releases.filter( or_( PackageRelease.task_id.isnot(None), PackageRelease.commit_hash == package.update_config.last_commit)).count() > 0: continue title = package.update_config.get_title() ref = package.update_config.get_ref() rel = PackageRelease() rel.package = package rel.title = title rel.url = "" rel.task_id = uuid() db.session.add(rel) db.session.commit() makeVCSRelease.apply_async((rel.id, ref), task_id=rel.task_id) msg = "Created release {} (Applied all Git Update Detection)".format( rel.title) addNotification(package.maintainers, current_user, NotificationType.PACKAGE_EDIT, msg, rel.getEditURL(), package) addAuditLog(AuditSeverity.NORMAL, current_user, msg, package.getDetailsURL(), package) db.session.commit() return redirect(url_for("todo.view_user", username=username))
def admin_page(): if request.method == "POST": action = request.form["action"] if action == "delstuckreleases": PackageRelease.query.filter( PackageRelease.task_id != None).delete() db.session.commit() return redirect(url_for("admin.admin_page")) elif action == "checkreleases": releases = PackageRelease.query.filter( PackageRelease.url.like("/uploads/%")).all() tasks = [] for release in releases: zippath = release.url.replace("/uploads/", app.config["UPLOAD_DIR"]) tasks.append(checkZipRelease.s(release.id, zippath)) result = group(tasks).apply_async() while not result.ready(): import time time.sleep(0.1) return redirect(url_for("todo.view")) elif action == "importmodlist": task = importTopicList.delay() return redirect( url_for("tasks.check", id=task.id, r=url_for("todo.topics"))) elif action == "checkusers": task = checkAllForumAccounts.delay() return redirect( url_for("tasks.check", id=task.id, r=url_for("admin.admin_page"))) elif action == "importscreenshots": packages = Package.query \ .filter_by(soft_deleted=False) \ .outerjoin(PackageScreenshot, Package.id==PackageScreenshot.package_id) \ .filter(PackageScreenshot.id==None) \ .all() for package in packages: importRepoScreenshot.delay(package.id) return redirect(url_for("admin.admin_page")) elif action == "restore": package = Package.query.get(request.form["package"]) if package is None: flash("Unknown package", "danger") else: package.soft_deleted = False db.session.commit() 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": packages = Package.query.filter_by(type=PackageType.MOD).all() mpackage_cache = {} for p in packages: if len(p.provides) == 0: p.provides.append( MetaPackage.GetOrCreate(p.name, mpackage_cache)) db.session.commit() return redirect(url_for("admin.admin_page")) elif action == "recalcscores": for p in Package.query.all(): p.setStartScore() db.session.commit() return redirect(url_for("admin.admin_page")) elif action == "vcsrelease": for package in Package.query.filter( Package.repo.isnot(None)).all(): if package.releases.count() != 0: continue rel = PackageRelease() rel.package = package rel.title = datetime.date.today().isoformat() rel.url = "" rel.task_id = uuid() rel.approved = True db.session.add(rel) db.session.commit() makeVCSRelease.apply_async((rel.id, "master"), task_id=rel.task_id) msg = "{}: Release {} created".format(package.title, rel.title) triggerNotif(package.author, current_user, msg, rel.getEditURL()) db.session.commit() else: flash("Unknown action: " + action, "danger") deleted_packages = Package.query.filter_by(soft_deleted=True).all() return render_template("admin/list.html", deleted_packages=deleted_packages)
def admin_page(): if request.method == "POST": action = request.form["action"] if action == "delstuckreleases": PackageRelease.query.filter(PackageRelease.task_id != None).delete() db.session.commit() return redirect(url_for("admin.admin_page")) elif action == "checkreleases": releases = PackageRelease.query.filter(PackageRelease.url.like("/uploads/%")).all() tasks = [] for release in releases: zippath = release.url.replace("/uploads/", app.config["UPLOAD_DIR"]) tasks.append(checkZipRelease.s(release.id, zippath)) result = group(tasks).apply_async() while not result.ready(): import time time.sleep(0.1) return redirect(url_for("todo.view")) elif action == "importmodlist": task = importTopicList.delay() return redirect(url_for("tasks.check", id=task.id, r=url_for("todo.topics"))) elif action == "checkusers": task = checkAllForumAccounts.delay() return redirect(url_for("tasks.check", id=task.id, r=url_for("admin.admin_page"))) elif action == "importscreenshots": packages = Package.query \ .filter_by(soft_deleted=False) \ .outerjoin(PackageScreenshot, Package.id==PackageScreenshot.package_id) \ .filter(PackageScreenshot.id==None) \ .all() for package in packages: importRepoScreenshot.delay(package.id) return redirect(url_for("admin.admin_page")) elif action == "restore": package = Package.query.get(request.form["package"]) if package is None: flash("Unknown package", "danger") else: package.soft_deleted = False db.session.commit() return redirect(url_for("admin.admin_page")) elif action == "modprovides": packages = Package.query.filter_by(type=PackageType.MOD).all() mpackage_cache = {} for p in packages: if len(p.provides) == 0: p.provides.append(MetaPackage.GetOrCreate(p.name, mpackage_cache)) db.session.commit() return redirect(url_for("admin.admin_page")) elif action == "recalcscores": for p in Package.query.all(): p.setStartScore() db.session.commit() return redirect(url_for("admin.admin_page")) elif action == "vcsrelease": for package in Package.query.filter(Package.repo.isnot(None)).all(): if package.releases.count() != 0: continue rel = PackageRelease() rel.package = package rel.title = datetime.date.today().isoformat() rel.url = "" rel.task_id = uuid() rel.approved = True db.session.add(rel) db.session.commit() makeVCSRelease.apply_async((rel.id, "master"), task_id=rel.task_id) msg = "{}: Release {} created".format(package.title, rel.title) triggerNotif(package.author, current_user, msg, rel.getEditURL()) db.session.commit() elif action == "cleanuploads": upload_dir = app.config['UPLOAD_DIR'] (_, _, filenames) = next(os.walk(upload_dir)) existing_uploads = set(filenames) if len(existing_uploads) != 0: def getURLsFromDB(column): results = db.session.query(column).filter(column != None, column != "").all() return set([os.path.basename(x[0]) for x in results]) release_urls = getURLsFromDB(PackageRelease.url) screenshot_urls = getURLsFromDB(PackageScreenshot.url) db_urls = release_urls.union(screenshot_urls) unreachable = existing_uploads.difference(db_urls) import sys print("On Disk: ", existing_uploads, file=sys.stderr) print("In DB: ", db_urls, file=sys.stderr) print("Unreachable: ", unreachable, file=sys.stderr) for filename in unreachable: os.remove(os.path.join(upload_dir, filename)) flash("Deleted " + str(len(unreachable)) + " unreachable uploads", "success") else: flash("No downloads to create", "danger") else: flash("Unknown action: " + action, "danger") deleted_packages = Package.query.filter_by(soft_deleted=True).all() return render_template("admin/list.html", deleted_packages=deleted_packages)
def create_release(package): if not package.checkPerm(current_user, Permission.MAKE_RELEASE): return redirect(package.getDetailsURL()) # Initial form class from post data and default data form = CreatePackageReleaseForm() if package.repo is not None: form["uploadOpt"].choices = [("vcs", "Import from Git"), ("upload", "Upload .zip file")] if request.method != "POST": form["uploadOpt"].data = "vcs" if form.validate_on_submit(): if form["uploadOpt"].data == "vcs": rel = PackageRelease() rel.package = package rel.title = form["title"].data rel.url = "" rel.task_id = uuid() rel.min_rel = form["min_rel"].data.getActual() rel.max_rel = form["max_rel"].data.getActual() db.session.add(rel) db.session.commit() makeVCSRelease.apply_async( (rel.id, nonEmptyOrNone(form.vcsLabel.data)), task_id=rel.task_id) msg = "Release {} created".format(rel.title) addNotification(package.maintainers, current_user, NotificationType.PACKAGE_EDIT, msg, rel.getEditURL(), package) db.session.commit() return redirect( url_for("tasks.check", id=rel.task_id, r=rel.getEditURL())) else: 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 = uploadedUrl rel.task_id = uuid() rel.min_rel = form["min_rel"].data.getActual() rel.max_rel = form["max_rel"].data.getActual() db.session.add(rel) db.session.commit() checkZipRelease.apply_async((rel.id, uploadedPath), task_id=rel.task_id) msg = "Release {} created".format(rel.title) addNotification(package.maintainers, current_user, NotificationType.PACKAGE_EDIT, msg, rel.getEditURL(), package) db.session.commit() return redirect( url_for("tasks.check", id=rel.task_id, r=rel.getEditURL())) return render_template("packages/release_new.html", package=package, form=form)
def admin_page(): if request.method == "POST": action = request.form["action"] if action == "importmodlist": task = importTopicList.delay() return redirect( url_for("check_task", id=task.id, r=url_for("todo_topics_page"))) elif action == "importscreenshots": packages = Package.query \ .filter_by(soft_deleted=False) \ .outerjoin(PackageScreenshot, Package.id==PackageScreenshot.package_id) \ .filter(PackageScreenshot.id==None) \ .all() for package in packages: importRepoScreenshot.delay(package.id) return redirect(url_for("admin_page")) elif action == "restore": package = Package.query.get(request.form["package"]) if package is None: flash("Unknown package", "error") else: package.soft_deleted = False db.session.commit() return redirect(url_for("admin_page")) elif action == "importdepends": task = importAllDependencies.delay() return redirect( url_for("check_task", id=task.id, r=url_for("admin_page"))) elif action == "modprovides": packages = Package.query.filter_by(type=PackageType.MOD).all() mpackage_cache = {} for p in packages: if len(p.provides) == 0: p.provides.append( MetaPackage.GetOrCreate(p.name, mpackage_cache)) db.session.commit() return redirect(url_for("admin_page")) elif action == "recalcscores": for p in Package.query.all(): p.recalcScore() db.session.commit() return redirect(url_for("admin_page")) elif action == "vcsrelease": for package in Package.query.filter( Package.repo.isnot(None)).all(): if package.releases.count() != 0: continue rel = PackageRelease() rel.package = package rel.title = datetime.date.today().isoformat() rel.url = "" rel.task_id = uuid() rel.approved = True db.session.add(rel) db.session.commit() makeVCSRelease.apply_async((rel.id, "master"), task_id=rel.task_id) msg = "{}: Release {} created".format(package.title, rel.title) triggerNotif(package.author, current_user, msg, rel.getEditURL()) db.session.commit() else: flash("Unknown action: " + action, "error") deleted_packages = Package.query.filter_by(soft_deleted=True).all() return render_template("admin/list.html", deleted_packages=deleted_packages)