2023-08-16 00:07:13 (UTC-03:00)
Marcel Rodrigues <marcelgmr@gmail.com>
add tar.gz archive downloads
diff --git a/cogit/cogit.lua b/cogit/cogit.lua index 1fc3da7..56a1afd 100644 --- a/cogit/cogit.lua +++ b/cogit/cogit.lua @@ -104,6 +104,26 @@ function Cogit:is_admin(cookies) return self.sessions[session_id] end +function Cogit:archive(rname, rev, fmt) + local arc_path = "/tmp/cogit-archive/" + os.execute("mkdir -p "..arc_path) + local aname = rname.."-"..rev + local fname = aname.."."..fmt + -- check if file already exists + local fp = io.open(arc_path..fname) + if fp == nil then + local cmd = "GIT_DIR='"..self.path.."/"..rname..".git' " + cmd = cmd.."git archive --prefix="..aname.."/" + cmd = cmd.." -o "..arc_path..fname.." "..rev + os.execute(cmd) + self:log(LOG_INFO, "generated archive "..fname) + else + self:log(LOG_INFO, "using cached archive "..fname) + fp:close() + end + return arc_path, fname +end + function Cogit:routes() return { {"GET", "/?", @@ -170,7 +190,7 @@ function Cogit:routes() local tnames = repo:tags() local env = { title=self.title, is_admin=is_admin, repo=repo, - rname=rname, bnames=bnames, tnames=tnames, + rname=rname, bnames=bnames, tnames=tnames, fmt=self.archive_fmt, } return {fname="view/repo.html", env=env} end}, @@ -219,6 +239,27 @@ function Cogit:routes() } return {fname="view/commit.html", env=env} end}, + {"GET", "/repo/([%w_-]+)/archive/(%S+)", + function (req, rname, cid) + local repo = self.repos[rname] + if repo == nil then + return "Page not found", 404, "Not found" + end + local is_admin = self:is_admin(req.cookies) + if not is_admin and is_private(self.descs[rname]) then + return "/login", 303 + end + local commit = repo:commit(cid) + if commit == nil then + return "Page not found", 404, "Not found" + end + local path, fname = self:archive(rname, cid, self.archive_fmt) + local headers = { + ["Content-Type"] = 'application/gzip', + ["Content-Disposition"] = 'attachment; filename="'..fname..'"', + } + return {fname=path..fname, headers=headers} + end}, {"GET", "/repo/([%w_-]+)/commit/([%w_-]+)/tree/(.*)", function (req, rname, cid, path) local repo = self.repos[rname] @@ -247,7 +288,7 @@ function Cogit:routes() end local env = { title=self.title, is_admin=is_admin, rname=rname, cid=cid, - path=path, base=base, parts=parts, node=node, + path=path, base=base, parts=parts, node=node, fmt=self.archive_fmt, } if node.type_ == "dir" then return {fname="view/dir.html", env=env} @@ -267,6 +308,7 @@ local function new_cogit(path, port, title, log_level) limit=20, session_age=3*24*60*60, sessions={}, + archive_fmt="tar.gz", initialized=false, } self = setmetatable(self, Cogit) diff --git a/view/dir.html b/view/dir.html index 33859c9..7256e56 100644 --- a/view/dir.html +++ b/view/dir.html @@ -16,8 +16,15 @@ > <a href="/repo/{{$rname}}/commit/{{$cid}}">{{$cid}}</a> > + % if #$parts == 0 then + % set archive_name = $rname.."-"..$cid.."."..$fmt + <a href="/repo/{{$rname}}/archive/{{$cid}}" download="{{$archive_name}}"> + {{$archive_name}} + </a> + % else % set partial = "/repo/"..$rname.."/commit/"..$cid.."/tree" <a href="{{$partial}}/">tree</a> + % end % for part in $parts do % set partial = $partial .. "/" .. $part > diff --git a/view/repo.html b/view/repo.html index 120d9a2..0fd82e9 100644 --- a/view/repo.html +++ b/view/repo.html @@ -6,6 +6,7 @@ <style> #nav-bar { float: left; } % include view/auth.css + % include view/table.css </style> </head> <body> @@ -16,20 +17,44 @@ </div> % include view/auth.html <br> - <p>Branches:</p> - <ul> + <h3 class="center">Branches</h3> + <table class="center"> + <tr> + <th>history</th> + <th>archive</th> + </tr> % for bname in $bnames do - <li><a href="/repo/{{$rname}}/history/{{$bname}}">{{$bname}}</a></li> + <tr> + <td><a href="/repo/{{$rname}}/history/{{$bname}}">{{$bname}}</a></td> + % set archive_name = $rname.."-"..$bname.."."..$fmt + <td> + <a href="/repo/{{$rname}}/archive/{{$bname}}" download="{{$archive_name}}"> + {{$archive_name}} + </a> + </td> + </tr> % end - </ul> + </table> % if #$tnames > 0 then - <p>Tags:</p> - <ul> + <h3 class="center">Tags</h3> + <table class="center"> + <tr> + <th>commit</th> + <th>archive</th> + </tr> % for tname in $tnames do % set cid = $repo:commit($tname.."^{}"):id() - <li><a href="/repo/{{$rname}}/commit/{{$cid}}">{{$tname}}</a></li> + <tr> + <td><a href="/repo/{{$rname}}/commit/{{$cid}}">{{$tname}}</a></td> + % set archive_name = $rname.."-"..$tname.."."..$fmt + <td> + <a href="/repo/{{$rname}}/archive/{{$tname}}" download="{{$archive_name}}"> + {{$archive_name}} + </a> + </td> + </tr> % end - </ul> + </table> % end </body> </html>