summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederick Yin <fkfd@macaw.me>2020-06-25 20:12:29 +0800
committerFrederick Yin <fkfd@macaw.me>2020-06-25 20:19:06 +0800
commit6a98cf09349272d1540a821ed048271bae94975a (patch)
tree217a1a79a6a6ab41e78d511fa2632876aef8895f
parent0d5ff48ee49971d7b4c21fc42c7cdb5cc829b8bd (diff)
View commit
-rw-r--r--git-gmi/const.py1
-rw-r--r--git-gmi/gateway.py24
-rw-r--r--git-gmi/git.py41
3 files changed, 57 insertions, 9 deletions
diff --git a/git-gmi/const.py b/git-gmi/const.py
index 11445c6..44818c6 100644
--- a/git-gmi/const.py
+++ b/git-gmi/const.py
@@ -2,3 +2,4 @@ STATUS_SUCCESS = "20"
STATUS_NOT_FOUND = "51 NOT FOUND"
STATUS_TEMPORARY_FAILURE = "40 TEMPORARY FAILURE"
META_GEMINI = "text/gemini"
+META_PLAINTEXT = "text/plain" \ No newline at end of file
diff --git a/git-gmi/gateway.py b/git-gmi/gateway.py
index 671d5cd..29f0268 100644
--- a/git-gmi/gateway.py
+++ b/git-gmi/gateway.py
@@ -37,18 +37,15 @@ def handle_cgi_request(path: str, query: str):
if view == "summary":
try:
print(repo.view_summary())
- return
except:
print(STATUS_TEMPORARY_FAILURE)
- return
elif view == "tree":
if len(path_trace) == 2:
# gemini://git.gemini.site/git/cgi/<repo>/tree/
print(f"31 {MAIN_BRANCH}/")
- return
- if len(path_trace) > 2:
+ elif len(path_trace) > 2:
# gemini://git.gemini.site/git/cgi/<repo>/tree/<branch>/
branch = path_trace[2]
@@ -68,18 +65,31 @@ def handle_cgi_request(path: str, query: str):
elif view == "log":
try:
print(repo.view_log())
- return
except:
print(STATUS_TEMPORARY_FAILURE)
+
+ elif view == "commit":
+ try:
+ commit_str = path_trace[2]
+ except IndexError:
+ print("50 No commit id given")
return
+ try:
+ if query == "raw":
+ print(repo.view_raw_commit(commit_str))
+ else:
+ print(repo.view_commit(commit_str))
+ except FileNotFoundError:
+ print("50 No such commit")
+ except:
+ print(STATUS_TEMPORARY_FAILURE)
+
elif view == "refs":
try:
print(repo.view_refs())
- return
except:
print(STATUS_TEMPORARY_FAILURE)
- return
handle_cgi_request(environ.get("PATH_INFO"), environ.get("QUERY_STRING"))
diff --git a/git-gmi/git.py b/git-gmi/git.py
index 71769cf..9e76b2d 100644
--- a/git-gmi/git.py
+++ b/git-gmi/git.py
@@ -89,11 +89,47 @@ class GitGmiRepo:
time = str(datetime.utcfromtimestamp(cmt["time"])) + " UTC"
response += (
f"## {cmt['short_id']} - {cmt['author']} - {time}\n"
- f"=> tree/{cmt['short_id']}/ view tree\n"
+ f"=> commit/{cmt['id']} view diff\n"
+ f"=> tree/{cmt['id']}/ view tree\n"
f"{cmt['msg']}\n\n"
)
return response
+ def get_commit(self, commit_str) -> dict:
+ try:
+ commit = self.repo.revparse_single(commit_str)
+ diff = self.repo.diff(commit.parents[0], commit)
+ return {
+ "id": commit.id,
+ "author": commit.author.name,
+ "time": commit.commit_time,
+ "msg": commit.message,
+ "patch": diff.patch,
+ }
+ except ValueError:
+ raise FileNotFoundError(f"Error: no such commit: {commit_str}")
+
+ def view_commit(self, commit_str) -> str:
+ commit = self.get_commit(commit_str)
+ response = (
+ f"{STATUS_SUCCESS} {META_GEMINI}\n"
+ + self.generate_header()
+ + f"{commit['id']} - {commit['author']} - {commit['time']}\n"
+ + commit["msg"]
+ + "\n"
+ + f"=> {CGI_PATH}{self.name}/tree/{commit['id']}/ view tree\n"
+ + f"=> {commit_str}?raw view raw\n"
+ + "\n```\n"
+ + commit["patch"]
+ + "\n```"
+ )
+ return response
+
+ def view_raw_commit(self, commit_str) -> str:
+ commit = self.get_commit(commit_str)
+ response = f"{STATUS_SUCCESS} {META_PLAINTEXT}\n" + commit["patch"]
+ return response
+
def get_refs(self) -> list:
refs = self.repo.listall_reference_objects()
return [
@@ -110,6 +146,7 @@ class GitGmiRepo:
response = f"{STATUS_SUCCESS} {META_GEMINI}\n" + self.generate_header()
refs = self.get_refs()
for ref in refs:
+ # HACK: filter out refs with slashes as remote branches
if ref["shorthand"].find("/") == -1:
response += (
f"## {ref['shorthand']}\n=> tree/{ref['shorthand']}/ view tree\n\n"
@@ -235,7 +272,7 @@ class GitGmiRepo:
def view_raw_blob(self, branch: str, location=[]) -> str:
blob = self.get_blob(branch, location)
# if mimetypes can't make out the type, set it to plaintext
- guessed_mimetype = mimetypes.guess_type(blob.name)[0] or "text/plain"
+ guessed_mimetype = mimetypes.guess_type(blob.name)[0] or META_PLAINTEXT
response = f"{STATUS_SUCCESS} {guessed_mimetype}\n"
response += blob.data.decode("utf-8")
return response