diff options
Diffstat (limited to 'git-gmi')
-rw-r--r-- | git-gmi/const.py | 1 | ||||
-rw-r--r-- | git-gmi/gateway.py | 24 | ||||
-rw-r--r-- | git-gmi/git.py | 41 |
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 |