1 | -- resty-gitweb@pages/index.lua |
2 | -- Index (home) page builder |
3 |
|
4 | -- Copyright (c) 2020 Joshua 'joshuas3' Stockin |
5 | -- <https://git.joshstock.in/resty-gitweb> |
6 | -- This software is licensed under the MIT License. |
7 |
|
8 | local utils = require("utils/utils") |
9 | local git = require("git/git") |
10 |
|
11 | local builder = require("utils/builder") |
12 | local tabulate = require("utils/tabulate") |
13 | local nav = require("utils/nav") |
14 |
|
15 | local _M = function(repos) |
16 | local build = builder:new() |
17 |
|
18 | local center = build.center{ |
19 | class="index-banner", |
20 | build.h1{class="title", "Git Repositories"}, |
21 | build.p{class="description", "Index of the git repositories hosted on this server"} |
22 | } |
23 |
|
24 | local repolist = build.div{class="index-repolist"} |
25 |
|
26 | for _, repo in pairs(repos) do |
27 | local url = "/"..repo.name |
28 | local repo_dir = PRODUCTION and repo.location.prod or repo.location.dev |
29 |
|
30 | -- Latest Commit table |
31 | local repo_obj = git.repo.open(repo_dir) |
32 | local branch = git.find_rev(repo_obj, "HEAD") |
33 | git.repo.free(repo_obj) |
34 | local commit = git.commit(repo_dir, branch.name) |
35 |
|
36 | -- Title and description |
37 | local section = build.div{ |
38 | class="repo-section", |
39 | build.h2{ |
40 | class="name", |
41 | repo.name, " ", build.a{ |
42 | href="/"..repo.name, style="font-size:0.65em", "[more]" |
43 | } |
44 | }, |
45 | build.p{class="description", repo.description}, |
46 | build.h3{"Latest Commit (", branch.name, ")"} |
47 | } |
48 |
|
49 | local commits_table_data = {} |
50 | commits_table_data.class = "log" |
51 | commits_table_data.headers = { |
52 | {"count", [[<span class="q" title="Commit number/count">{#}</span>]]}, |
53 | {"timestamp", "Time"}, |
54 | {"shorthash", "Hash"}, |
55 | {"subject", "Subject"}, |
56 | {"author", "Author"}, |
57 | {"changed_files", [[<span class="q" title="# of files changed">#</span>]]}, |
58 | {"changed_plus", [[<span class="q" title="Insertions">(+)</span>]]}, |
59 | {"changed_minus", [[<span class="q" title="Deletions">(-)</span>]]}, |
60 | {"gpggood", [[<span class="q" title="GPG signature status |
61 | |
62 | G: Good (valid) signature |
63 | B: Bad signature |
64 | U: Good signature with unknown validity |
65 | X: Good signature that has expired |
66 | Y: Good signature made by an expired key |
67 | R: Good signature made by a revoked key |
68 | E: Signature can't be checked (e.g. missing key) |
69 | N: No signature">GPG?</span>]]} |
70 | } |
71 | commits_table_data.rows = {{ |
72 | commit.count, |
73 | utils.iso8601(commit.timestamp), |
74 | string.format([[<a href="/%s/commit/%s">%s</a>]], repo.name, commit.hash, commit.shorthash), |
75 | utils.html_sanitize(commit.subject), |
76 | string.format([[<a href="mailto:%s">%s</a>]], commit.email, utils.html_sanitize(commit.author)), |
77 | commit.diff.num, |
78 | commit.diff.plus, |
79 | commit.diff.minus, |
80 | commit.gpggood |
81 | }} |
82 |
|
83 | section{tabulate(commits_table_data)} |
84 |
|
85 | -- Navigation links |
86 | local navlinks = { |
87 | {string.format("/%s/download", repo.name), "Download"}, |
88 | {string.format("/%s/refs", repo.name), "Refs"}, |
89 | {string.format("/%s/log/%s", repo.name, branch.name), "Commit Log"}, |
90 | {string.format("/%s/tree/%s", repo.name, branch.name), "Files"} |
91 | } |
92 |
|
93 | for _, special in pairs(repo.specialfiles) do -- create nav items for special files |
94 | local split = string.split(special, " ") |
95 | table.insert(navlinks, { |
96 | string.format("/%s/blob/%s/%s", repo.name, branch.name, split[2]), |
97 | split[1] |
98 | }) |
99 | end |
100 |
|
101 | local navdiv = build.div{class="nav", nav(navlinks)} |
102 |
|
103 | for i = #repo.urls, 1, -1 do |
104 | local split = string.split(repo.urls[i], " ") |
105 | local name = split[1] |
106 | local url = split[2] |
107 | navdiv{ |
108 | build.span{ |
109 | style="float:right; margin-left:10px", |
110 | build.a{ |
111 | href=url, "[on ", name, "]" |
112 | } |
113 | } |
114 | } |
115 | end |
116 |
|
117 | section{navdiv} |
118 |
|
119 | repolist{section} |
120 | end |
121 |
|
122 | for i,v in pairs(repolist._objects) do |
123 | repolist._objects[i] = v:build() |
124 | end |
125 | build{center, table.concat(repolist._objects, "<hr>")} |
126 |
|
127 | return build |
128 | end |
129 |
|
130 | return _M |
131 |
|