summaryrefslogtreecommitdiff
path: root/git-gmi/gateway.py
blob: b0c9b0a545536e0ae33f4b8ffd91b1c98a00ab7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
from git import *
from const import *
from config import *
from os import environ, listdir
import sys

# be careful when using print(); stdout is passed to the client.
# this cgi uses \n as newline.


def handle_cgi_request(path: str, query: str):
    # intended to work with Jetforce.
    # hypothetical example:
    # url: gemini://git.gemini.site/git/cgi/repo/src/static/css/[index.css]
    # path: /repo/src/static/css/[index.css]
    # path_trace = ['repo', 'src', 'static', 'css', 'index.css']
    path_trace = path[1:].split("/")
    if path_trace == [""]:  # empty path
        print(f"{STATUS_SUCCESS} {META_GEMINI}")  # welcome page
        print(f"# Welcome to {GIT_GMI_SITE_TITLE}")
        print("## Available repositories:")
        print("\n".join([f"=> {dir}/" for dir in listdir(GIT_CATALOG)]))
        return

    try:
        repo = GitGmiRepo(path_trace[0], f"{GIT_CATALOG}/{path_trace[0]}")
    except FileNotFoundError:
        print(STATUS_NOT_FOUND)
        return

    if len(path_trace) > 1:
        view = path_trace[1]  # e.g. summary, tree, log
    else:
        # gemini://git.gemini.site/git/cgi/<repo>/
        print("31 summary")
        return

    if view == "summary":
        try:
            print(repo.view_summary())
        except:
            print(STATUS_TEMPORARY_FAILURE)

    elif view == "tree":
        if len(path_trace) == 2:
            # gemini://git.gemini.site/git/cgi/<repo>/tree/
            print(f"31 {MAIN_BRANCH}/")

        elif len(path_trace) > 2:
            # gemini://git.gemini.site/git/cgi/<repo>/tree/<branch>/
            branch = path_trace[2]

        location = path_trace[3:]

        try:  # is dir
            print(repo.view_tree(branch, location))
        except FileNotFoundError:  # is file
            try:
                if query == "raw":
                    sys.stdout.buffer.write(repo.view_raw_blob(branch, location))
                else:
                    print(repo.view_blob(branch, location))
            except FileNotFoundError:
                print(STATUS_NOT_FOUND)

    elif view == "log":
        try:
            print(repo.view_log())
        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())
        except:
            print(STATUS_TEMPORARY_FAILURE)


handle_cgi_request(environ.get("PATH_INFO"), environ.get("QUERY_STRING"))