summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederick Yin <fkfd@macaw.me>2020-06-14 18:03:01 +0800
committerFrederick Yin <fkfd@macaw.me>2020-06-14 18:03:01 +0800
commit59c2e948797d088e795cc2290fa8c3004ddb71c1 (patch)
tree472fdeb60b9431efb9b6f75cdee03efe3e69765a
parentee8f25fd963dec48b31ff4072afd2c95f24d518e (diff)
Massive improvements
- Python CGI server script renamed to gateway.py to avoid confusion - Repo not found error handling - Page header & navs - Fix faulty 20 response header - View (non-)raw blob
-rwxr-xr-xgit-gmi/cgi2
-rw-r--r--git-gmi/const.py6
-rw-r--r--git-gmi/gateway.py (renamed from git-gmi/cgi.py)20
-rw-r--r--git-gmi/git.py55
4 files changed, 56 insertions, 27 deletions
diff --git a/git-gmi/cgi b/git-gmi/cgi
index c0e0d25..7ef8259 100755
--- a/git-gmi/cgi
+++ b/git-gmi/cgi
@@ -1,3 +1,3 @@
#!/home/fakefred/p/git.gmi/venv/bin/python3.8
# gotta change the executable path before running
-import cgi.py \ No newline at end of file
+import gateway \ No newline at end of file
diff --git a/git-gmi/const.py b/git-gmi/const.py
index 9a1bddd..dcf97b1 100644
--- a/git-gmi/const.py
+++ b/git-gmi/const.py
@@ -1,5 +1,7 @@
-GIT_CATALOG = "/home/fakefred/p/gemini/git/"
-STATUS_SUCCESS = "20 SUCCESS"
+GIT_CATALOG = "/home/fakefred/p/gemini/repos/"
+CGI_PATH = "/git/cgi/"
+GIT_GMI_SITE_TITLE = "git.gmi demo instance"
+STATUS_SUCCESS = "20"
STATUS_NOT_FOUND = "51 NOT FOUND"
STATUS_TEMPORARY_FAILURE = "40 TEMPORARY FAILURE"
META_GEMINI = "text/gemini"
diff --git a/git-gmi/cgi.py b/git-gmi/gateway.py
index 76f1522..0ae963f 100644
--- a/git-gmi/cgi.py
+++ b/git-gmi/gateway.py
@@ -10,7 +10,7 @@ def generate_navigation(repo_name: str):
pass # TODO
-def handle_cgi_request(path: str):
+def handle_cgi_request(path: str, query: str):
# intended to work with Jetforce.
# url: gemini://git.gemini.site/cgi-bin/cgi.py/repo/src/static/css/[index.css]
# path: /repo/src/static/css/[index.css]
@@ -18,8 +18,8 @@ def handle_cgi_request(path: str):
path_trace = path[1:].split("/")
if path_trace == [""]: # empty path
print(f"{STATUS_SUCCESS} {META_GEMINI}") # welcome page
- print("Welcome to the git.gmi demo")
- print("Available repositories:")
+ print(f"# Welcome to {GIT_GMI_SITE_TITLE}")
+ print("## Available repositories:")
print("\n".join([f"=> {dir}/" for dir in listdir(GIT_CATALOG)]))
return
@@ -51,18 +51,18 @@ def handle_cgi_request(path: str):
if len(path_trace) > 2:
branch = path_trace[2]
- if len(path_trace) == 3:
- location = []
- else:
- location = path_trace[3:]
+ location = path_trace[3:]
try: # is dir
print(repo.view_tree(branch, location))
except FileNotFoundError: # is file
try:
- print(repo.view_blob(branch, location))
+ if query == "raw":
+ print(repo.view_raw_blob(branch, location))
+ else:
+ print(repo.view_blob(branch, location))
except FileNotFoundError:
- print("50 Error locating content")
+ print(STATUS_NOT_FOUND)
elif view == "log":
try:
@@ -73,4 +73,4 @@ def handle_cgi_request(path: str):
return
-handle_cgi_request(environ.get("PATH_INFO"))
+handle_cgi_request(environ.get("PATH_INFO"), environ.get("QUERY_STRING"))
diff --git a/git-gmi/git.py b/git-gmi/git.py
index 9a0ab0d..990ca0c 100644
--- a/git-gmi/git.py
+++ b/git-gmi/git.py
@@ -2,6 +2,9 @@ from pygit2 import *
import mimetypes
from const import *
+mimetypes.add_type("text/gemini", ".gmi")
+mimetypes.add_type("text/gemini", ".gemini")
+
class GitGmiRepo:
def __init__(self, name: str, path: str):
@@ -9,25 +12,37 @@ class GitGmiRepo:
self.path = path
try:
self.repo = Repository(path)
- except FileNotFoundError:
- print(f"Error: repository {path} not found")
+ except GitError:
+ raise FileNotFoundError(f"Error: no such repo: {name}")
+
+ def generate_header(self):
+ header = (
+ f"# {self.name}\n"
+ f"=> {CGI_PATH} {GIT_GMI_SITE_TITLE}\n"
+ f"=> {CGI_PATH}{self.name}/summary summary\n"
+ f"=> {CGI_PATH}{self.name}/tree/master/ tree\n"
+ f"=> {CGI_PATH}{self.name}/log log\n\n"
+ )
+ return header
def view_summary(self) -> str:
+ response = f"{STATUS_SUCCESS} {META_GEMINI}\n" + self.generate_header()
tree = self.get_tree("master")
trls = self.list_tree(tree)
+ found_readme = False
for item in trls:
- if item["type"] == "file" and item["name"].lower().split(".")[0] == (
- "readme"
+ if (
+ item["type"] == "file"
+ and item["name"].lower().split(".")[0] == ("readme")
+ and not found_readme
):
- # mimetypes.guess_type() returns tuple (type, encoding)
- # only the first one of which we care about
- response = (
- f"{STATUS_SUCCESS} {mimetypes.guess_type(item['name'])[0]}\n"
- "=> tree/master/ tree\n"
- "=> log/ log\n\n"
+ found_readme = True
+ response += (
+ f"## {item['name']} | {item['size']} bytes\n"
+ f"{item['blob'].data.decode('utf-8')}"
)
- response += item["blob"].data.decode("utf-8")
- break
+ if not found_readme:
+ response += "## No readme found."
return response
def get_commit_log(self) -> list:
@@ -48,7 +63,7 @@ class GitGmiRepo:
return log # reverse chronical order
def view_log(self) -> str:
- response = f"{STATUS_SUCCESS} {META_GEMINI}\n"
+ response = f"{STATUS_SUCCESS} {META_GEMINI}\n" + self.generate_header()
log = self.get_commit_log()
for cmt in log:
response += f"## {cmt['short_id']} - {cmt['author']}\n{cmt['msg']}\n\n"
@@ -123,7 +138,7 @@ class GitGmiRepo:
def view_tree(self, branch: str, location=[]) -> str:
# actual Gemini response
# consists of a header and a body
- response = f"{STATUS_SUCCESS} {META_GEMINI}\n"
+ response = f"{STATUS_SUCCESS} {META_GEMINI}\n" + self.generate_header()
tree = self.get_tree(branch)
contents = self.list_tree(tree, location)
for item in contents:
@@ -151,6 +166,18 @@ class GitGmiRepo:
def view_blob(self, branch: str, location=[]) -> str:
blob = self.get_blob(branch, location)
+ response = (
+ f"{STATUS_SUCCESS} {META_GEMINI}\n"
+ + self.generate_header()
+ + f"## {self.name}/{'/'.join(location)} | {blob.size} bytes\n\n"
+ f"=> {blob.name}?raw view raw\n\n"
+ f"```\n"
+ )
+ response += blob.data.decode("utf-8") + "\n```"
+ return response
+
+ def view_raw_blob(self, branch: str, location=[]) -> str:
+ blob = self.get_blob(branch, location)
guessed_mimetype = mimetypes.guess_type(blob.name)[0] or "text/plain"
response = f"{STATUS_SUCCESS} {guessed_mimetype}\n"
response += blob.data.decode("utf-8")