def packageReleaseDeletePost(packageId, packageReleaseId):
		if g.currentUser is None: return api.jsonMissingActionPermissionFailure("delete package releases")
		
		packageRelease = PackageRelease.getById(g.databaseSession, packageReleaseId)
		package        = packageRelease.package
		
		if packageRelease is None: return api.jsonFailure("The package release does not exist or has been deleted.")
		if not g.currentUser.canEditPackage(package): return api.jsonMissingActionPermissionFailure("delete package releases")
		
		packageRelease.remove(g.databaseSession)
		g.databaseSession.commit()
		
		return { "success": True }
	def packageReleases(type):
		packages = []
		packageDictionaries = {}
		for package in Package.getAll(g.databaseSession):
			packageDictionary = package.toDictionary()
			packageDictionary["releases"] = packageDictionary.get("releases", [])
			packageDictionaries[package.id] = packageDictionary
			packages.append(packageDictionary)
		
		packageReleases = PackageRelease.getLatestPackageReleases(g.databaseSession)
		for packageRelease in packageReleases:
			packageDictionary = packageDictionaries[packageRelease.packageId]
			if packageDictionary is None: continue
			
			packageDictionary["releases"].append(packageRelease.toDictionary())
		
		return packages
	def packageReleaseDownload(packageId, packageReleaseId):
		packageRelease = PackageRelease.getById(g.databaseSession, packageReleaseId)
		if packageRelease is None: flask.abort(404)
		
		response = flask.send_file(packageRelease.generatePackage(g.databaseSession), as_attachment = True, attachment_filename = packageRelease.getFullFileName(), conditional = True)
		return response
	def packageReleaseJson(packageId, packageReleaseId, type):
		packageRelease = PackageRelease.getById(g.databaseSession, packageReleaseId)
		if packageRelease is None: return None
		
		return packageRelease.toDictionaryRecursive(g.currentUser == packageRelease.package.creatorUser)