gitlin/pages/fileview.go

102 行
2.7 KiB
Go

package pages
import (
"bufio"
"bytes"
"codeberg.org/gothub/gothub/utils"
"context"
"encoding/base64"
htmlfmt "github.com/alecthomas/chroma/v2/formatters/html"
"github.com/alecthomas/chroma/v2/lexers"
"github.com/alecthomas/chroma/v2/styles"
"github.com/carlmjohnson/requests"
"github.com/gofiber/fiber/v2"
"html/template"
"net/http"
"path/filepath"
)
// FileView is the file view page
func FileView(c *fiber.Ctx) error {
var file string
url := "https://raw.githubusercontent.com/" + c.Params("user") + "/" + c.Params("repo") + "/" + c.Params("branch") + "/" + c.Params("+")
err := requests.
URL(url).
ToString(&file).
Fetch(context.Background())
if err != nil {
return c.Status(404).Render("error", fiber.Map{
"error": err,
})
}
ext := filepath.Ext(c.Params("+"))
// Make an issue for other formats thanks
if ext == ".jpeg" || ext == ".jpg" || ext == ".png" || ext == ".svg" || ext == ".gif" || ext == ".webp" {
data := []byte(file)
dst := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
base64.StdEncoding.Encode(dst, data)
dstStr := string(dst)
// Detect content-type since base64 encoding needs content-type
mimeType := http.DetectContentType(data)
if ext == ".svg" {
mimeType = "image/svg+xml"
}
css := `img {
object-fit: cover;
width: 100%;
height: 250px;
}`
html := "<img src='data:" + mimeType + ";base64," + dstStr + "' alt=" + c.Params("+") + ">"
return c.Render("file", fiber.Map{
"title": c.Params("+") + " | " + c.Params("user") + "/" + c.Params("repo"),
"branch": utils.Branch,
"file": html,
"css": css,
"fullname": c.Params("user") + "/" + c.Params("repo"),
"name": c.Params("+"),
"fileBranch": c.Params("branch"),
"type": "img",
})
}
lexer := lexers.Match(c.Params("+"))
if lexer == nil {
lexer = lexers.Fallback
}
formatter := htmlfmt.New(
htmlfmt.WithClasses(true),
htmlfmt.WithLineNumbers(true),
htmlfmt.PreventSurroundingPre(false),
)
buf := bytes.Buffer{}
writer := bufio.NewWriter(&buf)
style := styles.Get("native")
tokens, err := lexer.Tokenise(nil, file)
if err != nil {
return c.Status(500).Render("error", fiber.Map{
"error": err,
})
}
formatter.Format(writer, style, tokens)
cssbuf := bytes.Buffer{}
cssw := bufio.NewWriter(&cssbuf)
formatter.WriteCSS(cssw, style)
writer.Flush()
cssw.Flush()
return c.Render("file", fiber.Map{
"title": c.Params("+") + " | " + c.Params("user") + "/" + c.Params("repo"),
"branch": utils.Branch,
"file": template.HTML(buf.String()),
"css": template.CSS(cssbuf.String()),
"fullname": c.Params("user") + "/" + c.Params("repo"),
"name": c.Params("+"),
"fileBranch": c.Params("branch"),
"type": "code",
})
}