def upload_file(file, fileType, fileTypeDesc): if not file or file is None or file.filename == "": raise LogicError(400, "Expected file") assert os.path.isdir(app.config["UPLOAD_DIR"]), "UPLOAD_DIR must exist" isImage = False if fileType == "image": allowedExtensions = ["jpg", "jpeg", "png"] isImage = True elif fileType == "zip": allowedExtensions = ["zip"] else: raise Exception("Invalid fileType") ext = get_extension(file.filename) if ext is None or not ext in allowedExtensions: raise LogicError(400, "Please upload " + fileTypeDesc) if isImage and not isAllowedImage(file.stream.read()): raise LogicError(400, "Uploaded image isn't actually an image") file.stream.seek(0) filename = randomString(10) + "." + ext filepath = os.path.join(app.config["UPLOAD_DIR"], filename) file.save(filepath) return "/uploads/" + filename, filepath
def check_can_create_release(user: User, package: Package): if not package.checkPerm(user, Permission.MAKE_RELEASE): raise LogicError(403, "You do not have permission to make releases") five_minutes_ago = datetime.datetime.now() - datetime.timedelta(minutes=5) count = package.releases.filter( PackageRelease.releaseDate > five_minutes_ago).count() if count >= 5: raise LogicError( 429, "You've created too many releases for this package in the last 5 minutes, please wait before trying again" )
def do_create_screenshot(user: User, package: Package, title: str, file, reason: str = None): thirty_minutes_ago = datetime.datetime.now() - datetime.timedelta(minutes=30) count = package.screenshots.filter(PackageScreenshot.created_at > thirty_minutes_ago).count() if count >= 20: raise LogicError(429, "Too many requests, please wait before trying again") uploaded_url, uploaded_path = upload_file(file, "image", "a PNG or JPG image file") counter = 1 for screenshot in package.screenshots.all(): screenshot.order = counter counter += 1 ss = PackageScreenshot() ss.package = package ss.title = title or "Untitled" ss.url = uploaded_url ss.approved = package.checkPerm(user, Permission.APPROVE_SCREENSHOT) ss.order = counter db.session.add(ss) if reason is None: msg = "Created screenshot {}".format(ss.title) else: msg = "Created screenshot {} ({})".format(ss.title, reason) addNotification(package.maintainers, user, NotificationType.PACKAGE_EDIT, msg, package.getURL("packages.view"), package) addAuditLog(AuditSeverity.NORMAL, user, msg, package.getURL("packages.view"), package) db.session.commit() return ss
def do_order_screenshots(_user: User, package: Package, order: [any]): lookup = {} for screenshot in package.screenshots.all(): lookup[screenshot.id] = screenshot counter = 1 for ss_id in order: try: lookup[int(ss_id)].order = counter counter += 1 except KeyError as e: raise LogicError(400, "Unable to find screenshot with id={}".format(ss_id)) except (ValueError, TypeError) as e: raise LogicError(400, "Invalid id, not a number: {}".format(json.dumps(ss_id))) db.session.commit()
def get_license(name): if type(name) == License: return name license = License.query.filter(License.name.ilike(name)).first() if license is None: raise LogicError(400, "Unknown license: " + name) return license
def do_create_zip_release(user: User, package: Package, title: str, file, min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason: str = None, commit_hash: str = None): check_can_create_release(user, package) if commit_hash: commit_hash = commit_hash.lower() if not (len(commit_hash) == 40 and re.match(r"^[0-9a-f]+$", commit_hash)): raise LogicError( 400, "Invalid commit hash; it must be a 40 character long base16 string" ) uploaded_url, uploaded_path = upload_file(file, "zip", "a zip file") rel = PackageRelease() rel.package = package rel.title = title rel.url = uploaded_url rel.task_id = uuid() rel.commit_hash = commit_hash 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() checkZipRelease.apply_async((rel.id, uploaded_path), task_id=rel.task_id) return rel
def check(cond: bool, msg: str): if not cond: raise LogicError(400, msg)
def do_edit_package(user: User, package: Package, was_new: bool, data: dict, reason: str = None): if not package.checkPerm(user, Permission.EDIT_PACKAGE): raise LogicError(403, "You do not have permission to edit this package") if "name" in data and package.name != data["name"] and \ not package.checkPerm(user, Permission.CHANGE_NAME): raise LogicError( 403, "You do not have permission to change the package name") for alias, to in ALIASES.items(): if alias in data: data[to] = data[alias] validate(data) if "type" in data: data["type"] = PackageType.coerce(data["type"]) if "license" in data: data["license"] = get_license(data["license"]) if "media_license" in data: data["media_license"] = get_license(data["media_license"]) for key in [ "name", "title", "short_desc", "desc", "type", "license", "media_license", "repo", "website", "issueTracker", "forums" ]: if key in data: setattr(package, key, data[key]) if package.type == PackageType.TXP: package.license = package.media_license if was_new and package.type == PackageType.MOD: m = MetaPackage.GetOrCreate(package.name, {}) package.provides.append(m) if "tags" in data: package.tags.clear() for tag_id in data["tags"]: if is_int(tag_id): package.tags.append(Tag.query.get(tag_id)) else: tag = Tag.query.filter_by(name=tag_id).first() if tag is None: raise LogicError(400, "Unknown tag: " + tag_id) package.tags.append(tag) if "content_warnings" in data: package.content_warnings.clear() for warning_id in data["content_warnings"]: if is_int(warning_id): package.content_warnings.append( ContentWarning.query.get(warning_id)) else: warning = ContentWarning.query.filter_by( name=warning_id).first() if warning is None: raise LogicError(400, "Unknown warning: " + warning_id) package.content_warnings.append(warning) if not was_new: if reason is None: msg = "Edited {}".format(package.title) else: msg = "Edited {} ({})".format(package.title, reason) severity = AuditSeverity.NORMAL if user in package.maintainers else AuditSeverity.EDITOR addAuditLog(severity, user, msg, package.getDetailsURL(), package) db.session.commit() return package