add dir view to codeview
") => %s here ", httpURL)) ", url, file.Path)) ", url, file.Path)) ----------------------------- => / Back to home ")
This commit is contained in:
parent
3cc3582d35
commit
9b100e88a2
1 changed files with 93 additions and 5 deletions
|
|
@ -1,10 +1,12 @@
|
||||||
package codeview
|
package codeview
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/kulak/gemini"
|
"github.com/kulak/gemini"
|
||||||
|
|
@ -16,18 +18,16 @@ import (
|
||||||
*
|
*
|
||||||
* Features:
|
* Features:
|
||||||
* - [x] Individual file view with line numbers?
|
* - [x] Individual file view with line numbers?
|
||||||
* - [ ] Dir view with links to files
|
* - [x] Dir view with links to files
|
||||||
* - [ ] Project root view with markdown to gemtxt conversion and file tree
|
* - [ ] Project root view with markdown to gemtxt conversion and file tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// https://git.travisshears.com/travisshears/personal-gemini-capsule/raw/branch/main/internal/guestbook/guestbook.go
|
|
||||||
// /codeview/raw/personal-gemini-capsule/src/branch/main/internal/guestbook/guestbook.go
|
|
||||||
func HandleRequest(w gemini.ResponseWriter, req *gemini.Request) {
|
func HandleRequest(w gemini.ResponseWriter, req *gemini.Request) {
|
||||||
path := req.URL.Path
|
path := req.URL.Path
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
// case path == "/gemlog" || path == "/gemlog/":
|
case strings.HasPrefix(path, "/codeview/dir"):
|
||||||
// g.serveIndex(w, req)
|
serveDir(w, req, path)
|
||||||
case strings.HasPrefix(path, "/codeview/raw/"):
|
case strings.HasPrefix(path, "/codeview/raw/"):
|
||||||
serveFile(w, req, path)
|
serveFile(w, req, path)
|
||||||
default:
|
default:
|
||||||
|
|
@ -35,6 +35,94 @@ func HandleRequest(w gemini.ResponseWriter, req *gemini.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func serveDir(w gemini.ResponseWriter, req *gemini.Request, path string) {
|
||||||
|
repo := req.URL.Query().Get("repo")
|
||||||
|
filepath := url.QueryEscape(req.URL.Query().Get("filepath"))
|
||||||
|
branch := req.URL.Query().Get("branch")
|
||||||
|
commit := req.URL.Query().Get("commit")
|
||||||
|
slog.Info("Serving directory", "repo", repo, "filepath", filepath, "branch", branch, "commit", commit)
|
||||||
|
var gitURL string
|
||||||
|
ref := ""
|
||||||
|
if branch != "" {
|
||||||
|
ref = branch
|
||||||
|
} else if commit != "" {
|
||||||
|
ref = commit
|
||||||
|
}
|
||||||
|
|
||||||
|
if filepath == "." {
|
||||||
|
gitURL = "https://git.travisshears.com/api/v1/repos/travisshears/" + repo + "/contents?ref=" + ref
|
||||||
|
} else {
|
||||||
|
gitURL = "https://git.travisshears.com/api/v1/repos/travisshears/" + repo + "/contents/" + filepath + "?ref=" + ref
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.Info("Fetching directory contents", "url", gitURL)
|
||||||
|
httpReq, err := http.NewRequest("GET", gitURL, nil)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("Failed to create request to git server", "error", err)
|
||||||
|
w.WriteStatusMsg(gemini.StatusGeneralPermFail, "Problem connecting to git server")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := http.DefaultClient.Do(httpReq)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("Failed to send request to git server", "error", err)
|
||||||
|
w.WriteStatusMsg(gemini.StatusGeneralPermFail, "Problem connecting to git server")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("Failed to read res body", "error", err)
|
||||||
|
w.WriteStatusMsg(gemini.StatusGeneralPermFail, "Problem connecting to git server")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if res.StatusCode < 200 || res.StatusCode >= 300 {
|
||||||
|
slog.Error("unexpected status code", "statusCode", res.StatusCode, "body", string(body))
|
||||||
|
w.WriteStatusMsg(gemini.StatusGeneralPermFail, "Problem connecting to git server")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var dirRes []struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
URL string `json:"html_url"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(body, &dirRes); err != nil {
|
||||||
|
slog.Error("failed to parse response", "error", err)
|
||||||
|
w.WriteStatusMsg(gemini.StatusGeneralPermFail, "Problem parsing response from git server")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
slog.Info("Successfully parsed response from git server", "res", dirRes)
|
||||||
|
|
||||||
|
var content strings.Builder
|
||||||
|
w.WriteStatusMsg(gemini.StatusSuccess, "text/gemini")
|
||||||
|
content.WriteString("# Dir CodeView\n")
|
||||||
|
httpURL := fmt.Sprintf("https://git.travisshears.com/travisshears/personal-gemini-capsule/src/branch/main/%s", filepath)
|
||||||
|
if branch != "" {
|
||||||
|
httpURL = fmt.Sprintf("https://git.travisshears.com/travisshears/personal-gemini-capsule/src/branch/%s/%s", branch, filepath)
|
||||||
|
} else if commit != "" {
|
||||||
|
httpURL = fmt.Sprintf("https://git.travisshears.com/travisshears/personal-gemini-capsule/src/commit/%s/%s", commit, filepath)
|
||||||
|
}
|
||||||
|
content.WriteString(fmt.Sprintf("This is a code view which proxies my personal git server. On the clearnet the following dir is available:\n=> %s here\n\n", httpURL))
|
||||||
|
|
||||||
|
for _, file := range dirRes {
|
||||||
|
switch file.Type {
|
||||||
|
case "dir":
|
||||||
|
url := fmt.Sprintf("/codeview/dir?repo=%s&filepath=%s&commit=%s&branch=%s", repo, file.Path, commit, branch)
|
||||||
|
content.WriteString(fmt.Sprintf("=> %s %s/\n", url, file.Path))
|
||||||
|
case "file":
|
||||||
|
p := strings.TrimPrefix(file.URL, "https://git.travisshears.com/travisshears/")
|
||||||
|
url := fmt.Sprintf("/codeview/raw/%s", p)
|
||||||
|
content.WriteString(fmt.Sprintf("=> %s %s\n", url, file.Path))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
content.WriteString("\n\n-----------------------------\n\n=> / Back to home\n")
|
||||||
|
w.WriteBody([]byte(content.String()))
|
||||||
|
}
|
||||||
|
|
||||||
func serveFile(w gemini.ResponseWriter, req *gemini.Request, path string) {
|
func serveFile(w gemini.ResponseWriter, req *gemini.Request, path string) {
|
||||||
path = strings.TrimPrefix(path, "/codeview/raw/")
|
path = strings.TrimPrefix(path, "/codeview/raw/")
|
||||||
rawURL := strings.Replace(path, "src", "raw", 1)
|
rawURL := strings.Replace(path, "src", "raw", 1)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue