mirror of https://git.sr.ht/~sircmpwn/hub.sr.ht
Rig up Mercurial support
This commit is contained in:
parent
ab1cb8e381
commit
89a2e3ac9f
|
@ -1,6 +1,6 @@
|
|||
from flask import Blueprint, render_template, request, redirect, url_for
|
||||
from hubsrht.projects import ProjectAccess, get_project
|
||||
from hubsrht.services import git
|
||||
from hubsrht.services import git, hg
|
||||
from hubsrht.types import Event, EventType
|
||||
from hubsrht.types import Project, RepoType, Visibility
|
||||
from srht.database import db
|
||||
|
@ -18,9 +18,13 @@ def summary_GET(owner, project_name):
|
|||
summary_error = False
|
||||
if project.summary_repo_id is not None:
|
||||
repo = project.summary_repo
|
||||
assert repo.repo_type != RepoType.hg # TODO
|
||||
try:
|
||||
summary = git.get_readme(owner, repo.name)
|
||||
if repo.repo_type == RepoType.git:
|
||||
summary = git.get_readme(owner, repo.name)
|
||||
elif repo.repo_type == RepoType.hg:
|
||||
summary = hg.get_readme(owner, repo.name)
|
||||
else:
|
||||
assert False
|
||||
except:
|
||||
summary = None
|
||||
summary_error = True
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from flask import Blueprint, render_template, request, redirect, url_for
|
||||
from hubsrht.projects import ProjectAccess, get_project
|
||||
from hubsrht.services import git
|
||||
from hubsrht.services import git, hg
|
||||
from hubsrht.types import Event, EventType
|
||||
from hubsrht.types import RepoType, SourceRepo
|
||||
from srht.database import db
|
||||
|
@ -56,7 +56,14 @@ def git_new_GET(owner, project_name):
|
|||
@sources.route("/<owner>/<project_name>/hg/new")
|
||||
@loginrequired
|
||||
def hg_new_GET(owner, project_name):
|
||||
pass # TODO
|
||||
owner, project = get_project(owner, project_name, ProjectAccess.write)
|
||||
# TODO: Pagination
|
||||
repos = hg.get_repos(owner)
|
||||
repos = sorted(repos, key=lambda r: r["updated"], reverse=True)
|
||||
return render_template("sources-select.html",
|
||||
view="new-resource", vcs="hg",
|
||||
owner=owner, project=project, repos=repos,
|
||||
existing=[]) # TODO: Fetch existing repos for this project
|
||||
|
||||
@sources.route("/<owner>/<project_name>/git/new", methods=["POST"])
|
||||
@loginrequired
|
||||
|
@ -117,6 +124,65 @@ def git_new_POST(owner, project_name):
|
|||
return redirect(url_for("projects.summary_GET",
|
||||
owner=owner.canonical_name, project_name=project.name))
|
||||
|
||||
@sources.route("/<owner>/<project_name>/hg/new", methods=["POST"])
|
||||
@loginrequired
|
||||
def hg_new_POST(owner, project_name):
|
||||
owner, project = get_project(owner, project_name, ProjectAccess.write)
|
||||
valid = Validation(request)
|
||||
if "create" in valid:
|
||||
hg_repo = hg.create_repo(owner, valid)
|
||||
if not valid.ok:
|
||||
repos = hg.get_repos(owner)
|
||||
return render_template("sources-select.html",
|
||||
view="new-resource", vcs="hg",
|
||||
owner=owner, project=project, repos=repos,
|
||||
existing=[], **valid.kwargs)
|
||||
else:
|
||||
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 = hg.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("sources-select.html",
|
||||
view="new-resource", vcs="hg",
|
||||
owner=owner, project=project, repos=repos,
|
||||
existing=[], search=search)
|
||||
|
||||
hg_repo = hg.get_repo(owner, repo_name)
|
||||
|
||||
repo = SourceRepo()
|
||||
repo.remote_id = hg_repo["id"]
|
||||
repo.project_id = project.id
|
||||
repo.owner_id = owner.id
|
||||
repo.name = hg_repo["name"]
|
||||
repo.description = hg_repo["description"]
|
||||
repo.repo_type = RepoType.hg
|
||||
db.session.add(repo)
|
||||
db.session.flush()
|
||||
|
||||
event = Event()
|
||||
event.event_type = EventType.source_repo_added
|
||||
event.source_repo_id = repo.id
|
||||
event.project_id = project.id
|
||||
event.user_id = project.owner_id
|
||||
db.session.add(event)
|
||||
|
||||
hg.ensure_user_webhooks(owner)
|
||||
#hg.ensure_repo_webhooks(owner, repo.name) # TODO
|
||||
|
||||
db.session.commit()
|
||||
|
||||
return redirect(url_for("projects.summary_GET",
|
||||
owner=owner.canonical_name, project_name=project.name))
|
||||
|
||||
@sources.route("/<owner>/<project_name>/sources/manage")
|
||||
@loginrequired
|
||||
def manage_GET(owner, project_name):
|
||||
|
@ -187,7 +253,12 @@ def delete_POST(owner, project_name, repo_id):
|
|||
valid = Validation(request)
|
||||
delete_remote = valid.optional("delete-remote") == "on"
|
||||
if delete_remote:
|
||||
git.delete_repo(owner, repo.name)
|
||||
if repo.repo_type == RepoType.git:
|
||||
git.delete_repo(owner, repo.name)
|
||||
elif repo.repo_type == RepoType.hg:
|
||||
hg.delete_repo(owner, repo.name)
|
||||
else:
|
||||
assert False
|
||||
|
||||
db.session.commit()
|
||||
return redirect(url_for("projects.summary_GET",
|
||||
|
|
|
@ -27,6 +27,27 @@ def git_repo():
|
|||
elif event == "repo:post-update":
|
||||
raise NotImplementedError()
|
||||
|
||||
@csrf_bypass
|
||||
@webhooks.route("/webhooks/hg-repo", methods=["POST"])
|
||||
def hg_repo():
|
||||
event = request.headers.get("X-Webhook-Event")
|
||||
payload = json.loads(request.data.decode("utf-8"))
|
||||
if event == "repo:update":
|
||||
repo = (SourceRepo.query
|
||||
.filter(SourceRepo.remote_id == payload["id"])
|
||||
.filter(SourceRepo.repo_type == RepoType.hg)
|
||||
.one_or_none())
|
||||
if not repo:
|
||||
return "I don't recognize that repository.", 404
|
||||
repo.name = payload["name"]
|
||||
repo.description = payload["description"]
|
||||
db.session.commit()
|
||||
return f"Updated local:{repo.id}/remote:{repo.remote_id}. Thanks!", 200
|
||||
elif event == "repo:delete":
|
||||
raise NotImplementedError()
|
||||
elif event == "repo:post-update":
|
||||
raise NotImplementedError()
|
||||
|
||||
@csrf_bypass
|
||||
@webhooks.route("/webhooks/mailing-list", methods=["POST"])
|
||||
def mailing_list():
|
||||
|
|
|
@ -5,6 +5,7 @@ from srht.api import ensure_webhooks, get_authorization, get_results
|
|||
from srht.config import get_origin
|
||||
|
||||
_gitsrht = get_origin("git.sr.ht", external=True, default=None)
|
||||
_hgsrht = get_origin("hg.sr.ht", external=True, default=None)
|
||||
_listsrht = get_origin("lists.sr.ht", external=True, default=None)
|
||||
_todosrht = get_origin("todo.sr.ht", external=True, default=None)
|
||||
origin = get_origin("hub.sr.ht")
|
||||
|
@ -81,6 +82,61 @@ class GitService(SrhtService):
|
|||
url = f"{_gitsrht}/api/{user.canonical_name}/repos/{repo_name}/webhooks"
|
||||
ensure_webhooks(user, url, config)
|
||||
|
||||
class HgService(SrhtService):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def get_repos(self, user):
|
||||
return get_results(f"{_hgsrht}/api/repos", user)
|
||||
|
||||
def get_repo(self, user, repo_name):
|
||||
r = self.session.get(f"{_hgsrht}/api/repos/{repo_name}",
|
||||
headers=get_authorization(user))
|
||||
if r.status_code != 200:
|
||||
raise Exception(r.text)
|
||||
return r.json()
|
||||
|
||||
def get_readme(self, user, repo_name):
|
||||
# TODO: Cache?
|
||||
r = self.session.get(f"{_hgsrht}/api/repos/{repo_name}/raw/README.md",
|
||||
headers=get_authorization(user))
|
||||
if r.status_code == 404:
|
||||
return ""
|
||||
elif r.status_code != 200:
|
||||
raise Exception(r.text)
|
||||
return r.text
|
||||
|
||||
def create_repo(self, user, valid):
|
||||
name = valid.require("name")
|
||||
description = valid.optional("description")
|
||||
if not valid.ok:
|
||||
return None
|
||||
return self.post(user, valid, f"{_hgsrht}/api/repos", {
|
||||
"name": name,
|
||||
"description": description,
|
||||
"visibility": "public", # TODO: Should this be different?
|
||||
})
|
||||
|
||||
def delete_repo(self, user, repo_name):
|
||||
r = self.session.delete(f"{_hgsrht}/api/repos/{repo_name}",
|
||||
headers=get_authorization(user))
|
||||
if r.status_code != 204:
|
||||
raise Exception(r.text)
|
||||
|
||||
def ensure_user_webhooks(self, user):
|
||||
config = {
|
||||
origin + url_for("webhooks.hg_repo"):
|
||||
["repo:update", "repo:delete"],
|
||||
}
|
||||
ensure_webhooks(user, f"{_hgsrht}/api/user/webhooks", config)
|
||||
|
||||
def ensure_repo_webhooks(self, user, repo_name):
|
||||
config = {
|
||||
origin + url_for("webhooks.hg_repo"): ["repo:post-update"],
|
||||
}
|
||||
url = f"{_hgsrht}/api/{user.canonical_name}/repos/{repo_name}/webhooks"
|
||||
ensure_webhooks(user, url, config)
|
||||
|
||||
class ListService(SrhtService):
|
||||
def get_lists(self, user):
|
||||
return get_results(f"{_listsrht}/api/lists", user)
|
||||
|
@ -169,5 +225,6 @@ class TodoService(SrhtService):
|
|||
})
|
||||
|
||||
git = GitService()
|
||||
hg = HgService()
|
||||
lists = ListService()
|
||||
todo = TodoService()
|
||||
|
|
|
@ -5,7 +5,7 @@ from srht.config import get_origin
|
|||
from srht.database import Base
|
||||
|
||||
_gitsrht = get_origin("git.sr.ht", external=True, default=None)
|
||||
_hgsrht = get_origin("git.sr.ht", external=True, default=None)
|
||||
_hgsrht = get_origin("hg.sr.ht", external=True, default=None)
|
||||
|
||||
class RepoType(Enum):
|
||||
git = "git"
|
||||
|
|
Loading…
Reference in New Issue