Index

joshstock.in / 5814dba

Source for serving and static templating/compiling of https://joshstock.in.

Latest Commit

{#}TimeHashSubjectAuthor#(+)(-)GPG?
10113 Dec 2020 11:455814dbaFix README renderingJosh Stockin143G

Blob @ joshstock.in / lua-gitweb / pages / tree.lua

text/plain7498 bytesdownload raw
1-- pages/tree.lua
2-- Tree page builder
3
4-- Copyright (c) 2020 Joshua 'joshuas3' Stockin
5-- <https://joshstock.in>
6
7local utils = require("utils/utils")
8local git = require("git/git_commands")
9
10local builder = require("utils/builder")
11local tabulate = require("utils/tabulate")
12local nav = require("utils/nav")
13
14local _M = function(repo, repo_dir, branch, path)
15
16 -- Pre checks
17 if path ~= "" then -- make sure path exists
18 local path_tree = git.list_tree(repo_dir, branch.name, string.sub(path, 1, path:len() - 1))
19 if #path_tree.dirs == 0 then -- no path found
20 return nil
21 end
22 end
23
24 if branch.name == "" then
25 branch.name = branch.hash
26 end
27
28
29 local build = builder:new()
30
31 -- Breadcrumb navigation and repository description
32 local breadcrumb_nav = {
33 {string.format("/%s", repo.name), repo.name},
34 {string.format("/%s/tree/%s", repo.name, branch.name), branch.name},
35 }
36 build:add("<h2>"..nav(breadcrumb_nav, " / ").."</h2>")
37 build:add("<p>"..repo.description.."</p>")
38
39 -- Navigation links
40 local navlinks = {
41 {string.format("/%s/download", repo.name), "Download"},
42 {string.format("/%s/refs", repo.name), "Refs"},
43 {string.format("/%s/log/%s", repo.name, branch.name), "Commit Log"},
44 {string.format("/%s/tree/%s", repo.name, branch.name), "<b>Files</b>"}
45 }
46
47 for _, special in pairs(repo.specialfiles) do -- create nav items for special files
48 local split = string.split(special, " ")
49 table.insert(navlinks, {
50 string.format("/%s/blob/%s/%s", repo.name, branch.name, split[2]),
51 split[1]
52 })
53 end
54
55 build:add([[<div class="nav">]])
56 build:add(nav(navlinks))
57 build:add("</div>")
58
59 -- Latest Commit table
60 build:add("<h3>Latest Commit</h3>")
61
62 local commit = git.log(repo_dir, branch.name, path.."/", 1, 0, true)[1]
63
64 local commits_table_data = {}
65 commits_table_data.class = "log"
66 commits_table_data.headers = {
67 {"count", [[<span class="q" title="Commit number/count">{#}</span>]]},
68 {"timestamp", "Time"},
69 {"shorthash", "Hash"},
70 {"subject", "Subject"},
71 {"author", "Author"},
72 {"changed_files", [[<span class="q" title="# of files changed">#</span>]]},
73 {"changed_plus", [[<span class="q" title="Insertions">(+)</span>]]},
74 {"changed_minus", [[<span class="q" title="Deletions">(-)</span>]]},
75 {"gpggood", [[<span class="q" title="GPG signature status
76
77G: Good (valid) signature
78B: Bad signature
79U: Good signature with unknown validity
80X: Good signature that has expired
81Y: Good signature made by an expired key
82R: Good signature made by a revoked key
83E: Signature can't be checked (e.g. missing key)
84N: No signature">GPG?</span>]]}
85 }
86 commits_table_data.rows = {}
87
88 table.insert(commits_table_data.rows, {
89 git.count(repo_dir, commit.hash),
90 utils.iso8601(commit.timestamp),
91 string.format([[<a href="/%s/commit/%s">%s</a>]], repo.name, commit.hash, commit.shorthash),
92 utils.html_sanitize(commit.subject),
93 string.format([[<a href="mailto:%s">%s</a>]], commit.email, utils.html_sanitize(commit.author)),
94 commit.diff.num,
95 commit.diff.plus,
96 commit.diff.minus,
97 commit.gpggood
98 })
99
100 build:add(tabulate(commits_table_data))
101
102 -- Tree/files table
103 local title = builder:new()
104
105 if path == "" then
106 title:add("<h3>Tree</h3>")
107 else -- build path with hyperlinks for section header
108 title:add("<h3>Tree")
109 local split = string.split(path, "/")
110 table.remove(split, #split)
111 local base = "/"..repo.name.."/tree/"..branch.name
112 title:add(string.format([[ @ <a href="%s">%s</a>]], base, repo.name))
113 local build = ""
114 for _, part in pairs(split) do
115 build = build.."/"..part
116 title:add(string.format([[ / <a href="%s%s">%s</a>]], base, build, part))
117 end
118 title:add("</h3>")
119 end
120
121 build:add(title.body)
122
123 local files = git.list_tree(repo_dir, branch.name, path)
124
125 local files_table_data = {}
126 files_table_data.class = "files"
127 files_table_data.headers = {
128 {"object", "Object"},
129 {"subject", "Latest Commit Subject"},
130 {"timestamp", "Time"},
131 {"shorthash", "Hash"}}
132 files_table_data.rows = {}
133
134 local file_icon = [[<img style="width:1em;height:1em;vertical-align:middle;margin-right:0.5em;" src="https://joshuas3.s3.amazonaws.com/svg/file.svg"/>]]
135 local folder_icon = [[<img style="width:1em;height:1em;vertical-align:middle;margin-right:0.5em;fill:#ffe9a2;" src="https://joshuas3.s3.amazonaws.com/svg/folder.svg"/>]]
136
137 -- .. directory
138 if path ~= "" then
139 local split = string.split(string.sub(path, 1, path:len() - 1), "/")
140 table.remove(split, #split)
141 if #split > 0 then -- deeper than 1 directory
142 table.insert(files_table_data.rows, {
143 string.format([[%s<a href="/%s/tree/%s/%s">..</a>]], folder_icon, repo.name, branch.name, table.concat(split, "/")),
144 "","",""
145 })
146 else -- only one directory deep
147 table.insert(files_table_data.rows, {
148 string.format([[%s<a href="/%s/tree/%s">..</a>]], folder_icon, repo.name, branch.name),
149 "","",""
150 })
151 end
152 end
153
154 -- Regular directories
155 for _, dir in pairs(files.dirs) do
156 local lastedit = git.log(repo_dir, branch.name.." -1", dir, 1, 0, false)[1]
157 local split = string.split(dir, "/")
158 local name = split[#split]
159 table.insert(files_table_data.rows, {
160 string.format([[%s<a href="/%s/tree/%s/%s">%s</a>]], folder_icon, repo.name, branch.name, dir, name),
161 utils.html_sanitize(lastedit.subject),
162 utils.iso8601(lastedit.timestamp),
163 string.format([[<a href="/%s/commit/%s">%s</a>]], repo.name, lastedit.hash, lastedit.shorthash)
164 })
165 end
166
167 -- Regular files
168 for _, file in pairs(files.files) do
169 local lastedit = git.log(repo_dir, branch.name.." -1", file, 1, 0, false)[1]
170 local split = string.split(file, "/")
171 local name = split[#split]
172 table.insert(files_table_data.rows, {
173 string.format([[%s<a href="/%s/blob/%s/%s">%s</a>]], file_icon, repo.name, branch.name, file, name),
174 utils.html_sanitize(lastedit.subject),
175 utils.iso8601(lastedit.timestamp),
176 string.format([[<a href="/%s/commit/%s">%s</a>]], repo.name, lastedit.hash, lastedit.shorthash)
177 })
178 end
179
180 build:add(tabulate(files_table_data))
181
182 -- Look for and render README if it exists
183 for _, file in pairs(files.files) do
184 local split = string.split(file, "/")
185 local l = split[#split]:lower()
186 if l:match("^readme") then
187 build:add("<h3>README</h3>")
188 local text = git.show_file(repo_dir, branch.name, file)
189 local s = l:len()
190 local body = builder:new()
191 if string.sub(l, s-2, s) == ".md" then
192 body:add([[<div class="markdown">]]..utils.markdown(text).."</div>")
193 else
194 body:add("<pre><code>"..text.."</code></pre>")
195 end
196 build:add(body.body)
197 break
198 end
199 end
200
201 return build
202end
203
204return _M
205