1 | -- pages/log.lua |
2 | -- Log page builder |
3 |
|
4 | -- Copyright (c) 2020 Joshua 'joshuas3' Stockin |
5 | -- <https://joshstock.in> |
6 |
|
7 | local utils = require("utils/utils") |
8 | local git = require("git/git_commands") |
9 |
|
10 | local builder = require("utils/builder") |
11 | local tabulate = require("utils/tabulate") |
12 | local nav = require("utils/nav") |
13 |
|
14 | local _M = function(repo, repo_dir, branch, n, skip) |
15 | n = tonumber(n or 20) |
16 | skip = tonumber(skip or 0) |
17 |
|
18 | local build = builder:new() |
19 |
|
20 | -- Breadcrumb navigation and repository description |
21 | local breadcrumb_nav = { |
22 | {string.format("/%s", repo.name), repo.name}, |
23 | {string.format("/%s/tree/%s", repo.name, branch.name), branch.name}, |
24 | {string.format("/%s/log/%s", repo.name, branch.name), "log"} |
25 | } |
26 | build:add("<h2>"..nav(breadcrumb_nav, " / ").."</h2>") |
27 | build:add("<p>"..repo.description.."</p>") |
28 |
|
29 | -- Navigation links |
30 | local navlinks = { |
31 | {string.format("/%s/download", repo.name), "Download"}, |
32 | {string.format("/%s/refs", repo.name), "Refs"}, |
33 | {string.format("/%s/log/%s", repo.name, branch.name), "<b>Commit Log</b>"}, |
34 | {string.format("/%s/tree/%s", repo.name, branch.name), "Files"} |
35 | } |
36 |
|
37 | for _, special in pairs(repo.specialfiles) do -- create nav items for special files |
38 | local split = string.split(special, " ") |
39 | table.insert(navlinks, { |
40 | string.format("/%s/blob/%s/%s", repo.name, branch.name, split[2]), |
41 | split[1] |
42 | }) |
43 | end |
44 |
|
45 | build:add([[<div class="nav">]]) |
46 | build:add(nav(navlinks)) |
47 | build:add("</div>") |
48 |
|
49 | -- Commits table |
50 | build:add("<h3>Commits</h3>") |
51 |
|
52 | local commits_head = git.log(repo_dir, branch.name, path, n, skip, true) |
53 |
|
54 | local this_page = string.format("/%s/log/%s", repo.name, branch.name) |
55 |
|
56 | -- Build controls |
57 | local controls = [[<div class="controls">]] |
58 | local prev = false |
59 | if skip ~= 0 then -- previous page? |
60 | local params = "" |
61 | if skip - n > 0 then |
62 | params = params.."?skip="..tostring(tonumber(skip) - tonumber(n)) |
63 | end |
64 | if n ~= 20 then |
65 | if params ~= "" then |
66 | params = params.."&" |
67 | else |
68 | params = params.."?" |
69 | end |
70 | params = params.."n="..tostring(n) |
71 | end |
72 | controls = controls..[[<span><a href="]]..this_page..params..[["><< Previous Page</a></span>]] |
73 | prev = true |
74 | end |
75 | if git.count(repo_dir, commits_head[#commits_head].hash) ~= 1 then -- check if last commit in this list is actually the last |
76 | -- it's not the last, create a "next page" button |
77 | local params = "" |
78 | params = params.."?skip="..tostring(skip+n) |
79 | if n ~= 20 then |
80 | params = params.."&n="..tostring(n) |
81 | end |
82 | if prev then |
83 | controls = controls..[[<span style="margin:0 5px">|</span>]] |
84 | end |
85 | controls = controls..[[<span><a href="]]..this_page..params..[[">Next Page >></a></span>]] |
86 | end |
87 | controls = controls..[[<span float="right"> |
88 | <form class="control-form" method="GET" style="display:inline;margin:0;float:right"> |
89 | <input type="hidden" name="skip" value="]]..tostring(skip)..[["> |
90 | <label for="n">Results</label> |
91 | <select id="n" name="n" onchange="if (this.value != 0){this.form.submit();}"> |
92 | <option disabled selected value style="display:none">]]..tostring(n)..[[</option> |
93 | <option>10</option> |
94 | <option>20</option> |
95 | <option>50</option> |
96 | <option>100</option> |
97 | </select> |
98 | </form> |
99 | </span>]] |
100 | controls = controls.."</div>" |
101 |
|
102 | build:add(controls) |
103 |
|
104 | -- Build commit table |
105 | local commits_table_data = {} |
106 | commits_table_data.class = "log" |
107 | commits_table_data.headers = { |
108 | {"count", [[<span class="q" title="Commit number/count">{#}</span>]]}, |
109 | {"timestamp", "Time"}, |
110 | {"shorthash", "Hash"}, |
111 | {"subject", "Subject"}, |
112 | {"author", "Author"}, |
113 | {"changed_files", [[<span class="q" title="# of files changed">#</span>]]}, |
114 | {"changed_plus", [[<span class="q" title="Insertions">(+)</span>]]}, |
115 | {"changed_minus", [[<span class="q" title="Deletions">(-)</span>]]}, |
116 | {"gpggood", [[<span class="q" title="GPG signature status |
117 | |
118 | G: Good (valid) signature |
119 | B: Bad signature |
120 | U: Good signature with unknown validity |
121 | X: Good signature that has expired |
122 | Y: Good signature made by an expired key |
123 | R: Good signature made by a revoked key |
124 | E: Signature can't be checked (e.g. missing key) |
125 | N: No signature">GPG?</span>]]} |
126 | } |
127 | commits_table_data.rows = {} |
128 |
|
129 | for i, commit in pairs(commits_head) do |
130 | table.insert(commits_table_data.rows, { |
131 | git.count(repo_dir, commit.hash), |
132 | utils.iso8601(commit.timestamp), |
133 | string.format([[<a href="/%s/commit/%s">%s</a>]], repo.name, commit.hash, commit.shorthash), |
134 | utils.html_sanitize(commit.subject), |
135 | string.format([[<a href="mailto:%s">%s</a>]], commit.email, utils.html_sanitize(commit.author)), |
136 | commit.diff.num, |
137 | commit.diff.plus, |
138 | commit.diff.minus, |
139 | commit.gpggood |
140 | }) |
141 | end |
142 |
|
143 | -- Add |
144 | build:add(tabulate(commits_table_data)) |
145 | build:add(controls) |
146 |
|
147 | return build |
148 | end |
149 |
|
150 | return _M |
151 |
|