from flask import Blueprint, render_template, request, redirect, url_for from hubsrht.projects import ProjectAccess, get_project from hubsrht.services import git from hubsrht.types import Project, RepoType, SourceRepo, Visibility from srht.config import get_origin from srht.database import db from srht.oauth import current_user, loginrequired from srht.validation import Validation projects = Blueprint("projects", __name__) origin = get_origin("hub.sr.ht") @projects.route("/projects/create") @loginrequired def create_GET(): return render_template("project-create.html") @projects.route("/projects/create", methods=["POST"]) @loginrequired def create_POST(): valid = Validation(request) name = valid.require("name") description = valid.require("description") visibility = valid.require("visibility", cls=Visibility) valid.expect(not name or len(name) < 128, "Name must be fewer than 128 characters", field="name") valid.expect(not name or Project.query .filter(Project.name == name) .filter(Project.owner_id == current_user.id).count() == 0, "Name must be unique among your projects", field="name") valid.expect(not description or len(description) < 512, "Description must be fewer than 512 characters", field="description") if not valid.ok: return render_template("project-create.html", **valid.kwargs) project = Project() project.name = name project.description = description project.visibility = visibility project.owner_id = current_user.id db.session.add(project) db.session.commit() return redirect(url_for("projects.project_GET", owner=current_user.canonical_name, project_name=project.name)) @projects.route("//") def project_GET(owner, project_name): owner, project = get_project(owner, project_name, ProjectAccess.read) return render_template("project-summary.html", view="summary", owner=owner, project=project) @projects.route("///sources/new") @loginrequired def project_sources_new_GET(owner, project_name): # TODO: Redirect appropriately if this instance only has git or hg support owner, project = get_project(owner, project_name, ProjectAccess.write) return render_template("project-sources-new.html", view="new-resource", owner=owner, project=project) @projects.route("///sources/new", methods=["POST"]) @loginrequired def project_sources_new_POST(owner, project_name): owner, project = get_project(owner, project_name, ProjectAccess.write) valid = Validation(request) if "git" in valid: return redirect(url_for("projects.project_git_new_GET", owner=owner.canonical_name, project_name=project.name)) if "hg" in valid: # TODO: Hg repos return redirect(url_for("projects.project_hg_new_GET", owner=owner.canonical_name, project_name=project.name)) @projects.route("///git/new") @loginrequired def project_git_new_GET(owner, project_name): owner, project = get_project(owner, project_name, ProjectAccess.write) # TODO: Pagination repos = git.get_repos(owner) repos = sorted(repos, key=lambda r: r["updated"], reverse=True) return render_template("project-sources-select.html", view="new-resource", vcs="git", owner=owner, project=project, repos=repos, existing=[]) # TODO: Fetch existing repos for this project @projects.route("///git/new", methods=["POST"]) @loginrequired def project_git_new_POST(owner, project_name): owner, project = get_project(owner, project_name, ProjectAccess.write) valid = Validation(request) if "create" in valid: assert False # TODO: Create repo repo_name = None for field in valid.source: if field.startswith("existing-"): repo_name = field[len("existing-"):] break if not repo_name: search = valid.optional("search") repos = git.get_repos(owner) # TODO: Search properly repos = filter(lambda r: search.lower() in r["name"].lower(), repos) repos = sorted(repos, key=lambda r: r["updated"], reverse=True) # TODO: Fetch existing repos for this project return render_template("project-sources-select.html", view="new-resource", vcs="git", owner=owner, project=project, repos=repos, existing=[], search=search) git_repo = git.get_repo(owner, repo_name) repo = SourceRepo() repo.remote_id = git_repo["id"] repo.project_id = project.id repo.owner_id = owner.id repo.name = git_repo["name"] repo.description = git_repo["description"] repo.repo_type = RepoType.git db.session.add(repo) git.ensure_user_webhooks(owner, { url_for("webhooks.git_repo_update"): ["repo:update", "repo:delete"], }) db.session.commit() return redirect(url_for("projects.project_GET", owner=owner.canonical_name, project_name=project.name))