2023-09-12 00:11:45 +00:00
|
|
|
/*
|
2024-01-14 18:39:14 +00:00
|
|
|
Copyright © 2024 Seednode <seednode@seedno.de>
|
2023-09-12 00:11:45 +00:00
|
|
|
*/
|
|
|
|
|
2023-09-13 04:35:17 +00:00
|
|
|
package text
|
2023-09-12 00:11:45 +00:00
|
|
|
|
|
|
|
import (
|
2023-09-12 00:38:38 +00:00
|
|
|
"errors"
|
2023-09-12 00:11:45 +00:00
|
|
|
"fmt"
|
2024-01-30 19:07:59 +00:00
|
|
|
"net/http"
|
2023-09-12 00:11:45 +00:00
|
|
|
"os"
|
2023-09-12 21:32:19 +00:00
|
|
|
"strings"
|
2023-09-12 00:11:45 +00:00
|
|
|
"unicode/utf8"
|
2023-09-13 04:35:17 +00:00
|
|
|
|
|
|
|
"seedno.de/seednode/roulette/types"
|
2023-09-12 00:11:45 +00:00
|
|
|
)
|
|
|
|
|
2024-01-14 18:39:14 +00:00
|
|
|
type Format struct{}
|
2023-09-12 21:32:19 +00:00
|
|
|
|
2024-01-30 19:07:59 +00:00
|
|
|
func (t Format) CSP(w http.ResponseWriter) string {
|
2024-01-30 19:27:45 +00:00
|
|
|
nonce := types.GetNonce()
|
2024-01-30 19:22:42 +00:00
|
|
|
|
|
|
|
w.Header().Add("Content-Security-Policy", fmt.Sprintf("default-src 'self' 'nonce-%s';", nonce))
|
|
|
|
|
|
|
|
return nonce
|
2024-01-30 19:07:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t Format) CSS() string {
|
2023-09-13 01:56:39 +00:00
|
|
|
var css strings.Builder
|
2023-09-12 21:32:19 +00:00
|
|
|
|
2023-09-13 01:56:39 +00:00
|
|
|
css.WriteString(`html,body{margin:0;padding:0;height:100%;}`)
|
|
|
|
css.WriteString(`a{color:inherit;display:block;height:100%;width:100%;text-decoration:none;overflow:hidden;}`)
|
|
|
|
css.WriteString(`textarea{border:none;caret-color:transparent;outline:none;margin:.5rem;`)
|
|
|
|
css.WriteString(`height:99%;width:99%;white-space:pre;overflow:auto;}`)
|
2023-09-12 00:11:45 +00:00
|
|
|
|
2023-09-13 01:56:39 +00:00
|
|
|
return css.String()
|
|
|
|
}
|
|
|
|
|
2023-09-15 19:28:21 +00:00
|
|
|
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
|
|
|
return fmt.Sprintf(`<title>%s</title>`, fileName), nil
|
2023-09-13 01:56:39 +00:00
|
|
|
}
|
|
|
|
|
2024-01-30 19:07:59 +00:00
|
|
|
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime, nonce string) (string, error) {
|
2023-09-13 01:56:39 +00:00
|
|
|
body, err := os.ReadFile(filePath)
|
|
|
|
if err != nil {
|
|
|
|
body = []byte{}
|
|
|
|
}
|
|
|
|
|
2023-09-14 04:24:29 +00:00
|
|
|
return fmt.Sprintf(`<a href="%s"><textarea autofocus readonly>%s</textarea></a>`,
|
|
|
|
rootUrl,
|
2023-09-15 19:28:21 +00:00
|
|
|
body), nil
|
2023-09-13 01:56:39 +00:00
|
|
|
}
|
2023-09-12 00:38:38 +00:00
|
|
|
|
2023-09-13 04:35:17 +00:00
|
|
|
func (t Format) Extensions() map[string]string {
|
2023-09-13 01:56:39 +00:00
|
|
|
return map[string]string{
|
2023-09-15 02:02:48 +00:00
|
|
|
`.csv`: `text/csv`,
|
|
|
|
`.txt`: `text/plain`,
|
2023-09-13 01:56:39 +00:00
|
|
|
}
|
|
|
|
}
|
2023-09-12 00:38:38 +00:00
|
|
|
|
2023-10-09 14:47:17 +00:00
|
|
|
func (t Format) MediaType(extension string) string {
|
2023-09-14 22:37:22 +00:00
|
|
|
extensions := t.Extensions()
|
|
|
|
|
|
|
|
value, exists := extensions[extension]
|
|
|
|
if exists {
|
|
|
|
return value
|
2023-09-12 00:11:45 +00:00
|
|
|
}
|
2023-09-14 22:37:22 +00:00
|
|
|
|
|
|
|
return ""
|
2023-09-12 00:11:45 +00:00
|
|
|
}
|
2023-09-13 01:56:39 +00:00
|
|
|
|
2023-09-13 04:35:17 +00:00
|
|
|
func (t Format) Validate(filePath string) bool {
|
2023-09-13 01:56:39 +00:00
|
|
|
file, err := os.Open(filePath)
|
|
|
|
switch {
|
|
|
|
case errors.Is(err, os.ErrNotExist):
|
|
|
|
return false
|
|
|
|
case err != nil:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
head := make([]byte, 512)
|
|
|
|
file.Read(head)
|
|
|
|
|
|
|
|
return utf8.Valid(head)
|
|
|
|
}
|
2023-09-13 04:35:17 +00:00
|
|
|
|
2023-09-15 20:13:45 +00:00
|
|
|
func (t Format) Type() string {
|
2023-09-15 20:30:52 +00:00
|
|
|
return "inline"
|
2023-09-15 20:13:45 +00:00
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func init() {
|
2023-09-29 19:36:11 +00:00
|
|
|
types.SupportedFormats.Register(Format{})
|
2023-09-13 04:35:17 +00:00
|
|
|
}
|