Add log channel, add --exit-on-error option
This commit is contained in:
parent
f5eb1f56f4
commit
1ed9df3932
55
README.md
55
README.md
|
@ -112,33 +112,34 @@ Usage:
|
|||
roulette <path> [path]... [flags]
|
||||
|
||||
Flags:
|
||||
-a, --all enable all supported file types
|
||||
--audio enable support for audio files
|
||||
-b, --bind string address to bind to (default "0.0.0.0")
|
||||
-c, --cache generate directory cache at startup
|
||||
--cache-file string path to optional persistent cache file
|
||||
--code enable support for source code files
|
||||
--code-theme string theme for source code syntax highlighting (default "solarized-dark256")
|
||||
-f, --filter enable filtering
|
||||
--flash enable support for shockwave flash files (via ruffle.rs)
|
||||
--handlers display registered handlers (for debugging)
|
||||
-h, --help help for roulette
|
||||
--images enable support for image files
|
||||
-i, --info expose informational endpoints
|
||||
--maximum-files uint32 skip directories with file counts above this value (default 4294967295)
|
||||
--minimum-files uint32 skip directories with file counts below this value (default 1)
|
||||
--page-length uint32 pagination length for info pages
|
||||
-p, --port uint16 port to listen on (default 8080)
|
||||
--prefix string root path for http handlers (for reverse proxying) (default "/")
|
||||
--profile register net/http/pprof handlers
|
||||
-r, --recursive recurse into subdirectories
|
||||
--refresh enable automatic page refresh via query parameter
|
||||
--russian remove selected images after serving
|
||||
-s, --sort enable sorting
|
||||
--text enable support for text files
|
||||
-v, --verbose log accessed files and other information to stdout
|
||||
-V, --version display version and exit
|
||||
--video enable support for video files
|
||||
-a, --all enable all supported file types
|
||||
--audio enable support for audio files
|
||||
-b, --bind string address to bind to (default "0.0.0.0")
|
||||
-c, --cache generate directory cache at startup
|
||||
--cache-file string path to optional persistent cache file
|
||||
--code enable support for source code files
|
||||
--code-theme string theme for source code syntax highlighting (default "solarized-dark256")
|
||||
--exit-on-error shut down webserver on error, instead of just printing the error
|
||||
-f, --filter enable filtering
|
||||
--flash enable support for shockwave flash files (via ruffle.rs)
|
||||
--handlers display registered handlers (for debugging)
|
||||
-h, --help help for roulette
|
||||
--images enable support for image files
|
||||
-i, --info expose informational endpoints
|
||||
--maximum-files uint skip directories with file counts above this value (default 4294967295)
|
||||
--minimum-files uint skip directories with file counts below this value (default 1)
|
||||
--page-length uint32 pagination length for info pages
|
||||
-p, --port uint16 port to listen on (default 8080)
|
||||
--prefix string root path for http handlers (for reverse proxying) (default "/")
|
||||
--profile register net/http/pprof handlers
|
||||
-r, --recursive recurse into subdirectories
|
||||
--refresh enable automatic page refresh via query parameter
|
||||
--russian remove selected images after serving
|
||||
-s, --sort enable sorting
|
||||
--text enable support for text files
|
||||
-v, --verbose log accessed files and other information to stdout
|
||||
-V, --version display version and exit
|
||||
--video enable support for video files
|
||||
```
|
||||
|
||||
## Building the Docker container
|
||||
|
|
|
@ -6,7 +6,6 @@ package cmd
|
|||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
|
@ -129,11 +128,11 @@ func (cache *fileCache) Import(path string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func serveCacheClear(args []string, cache *fileCache, formats *types.Types) httprouter.Handle {
|
||||
func serveCacheClear(args []string, cache *fileCache, formats *types.Types, errorChannel chan<- error) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
list, err := fileList(args, &filters{}, "", &fileCache{}, formats)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
errorChannel <- err
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -146,7 +145,7 @@ func serveCacheClear(args []string, cache *fileCache, formats *types.Types) http
|
|||
}
|
||||
}
|
||||
|
||||
func registerCacheHandlers(mux *httprouter.Router, args []string, cache *fileCache, formats *types.Types) error {
|
||||
func registerCacheHandlers(mux *httprouter.Router, args []string, cache *fileCache, formats *types.Types, errorChannel chan<- error) error {
|
||||
skipIndex := false
|
||||
|
||||
if CacheFile != "" {
|
||||
|
@ -165,7 +164,7 @@ func registerCacheHandlers(mux *httprouter.Router, args []string, cache *fileCac
|
|||
cache.set(list)
|
||||
}
|
||||
|
||||
register(mux, Prefix+"/clear_cache", serveCacheClear(args, cache, formats))
|
||||
register(mux, Prefix+"/clear_cache", serveCacheClear(args, cache, formats, errorChannel))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ package cmd
|
|||
import (
|
||||
"bytes"
|
||||
"embed"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -27,12 +28,16 @@ const (
|
|||
<meta name="theme-color" content="#ffffff">`
|
||||
)
|
||||
|
||||
func serveFavicons() httprouter.Handle {
|
||||
func serveFavicons(errorChannel chan<- error) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
errorChannel <- errors.New("test")
|
||||
|
||||
fname := strings.TrimPrefix(r.URL.Path, "/")
|
||||
|
||||
data, err := favicons.ReadFile(fname)
|
||||
if err != nil {
|
||||
errorChannel <- err
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
10
cmd/info.go
10
cmd/info.go
|
@ -133,7 +133,7 @@ func serveIndexHtml(args []string, cache *fileCache, paginate bool) httprouter.H
|
|||
}
|
||||
}
|
||||
|
||||
func serveIndexJson(args []string, index *fileCache) httprouter.Handle {
|
||||
func serveIndexJson(args []string, index *fileCache, errorChannel chan<- error) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
|
@ -168,7 +168,7 @@ func serveIndexJson(args []string, index *fileCache) httprouter.Handle {
|
|||
|
||||
response, err := json.MarshalIndent(cachedFiles[startIndex:stopIndex], "", " ")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
|
@ -272,16 +272,16 @@ func serveEnabledMimeTypes(formats *types.Types) httprouter.Handle {
|
|||
}
|
||||
}
|
||||
|
||||
func registerInfoHandlers(mux *httprouter.Router, args []string, cache *fileCache, formats *types.Types) {
|
||||
func registerInfoHandlers(mux *httprouter.Router, args []string, cache *fileCache, formats *types.Types, errorChannel chan<- error) {
|
||||
if Cache {
|
||||
register(mux, Prefix+"/html/", serveIndexHtml(args, cache, false))
|
||||
if PageLength != 0 {
|
||||
register(mux, Prefix+"/html/:page", serveIndexHtml(args, cache, true))
|
||||
}
|
||||
|
||||
register(mux, Prefix+"/json", serveIndexJson(args, cache))
|
||||
register(mux, Prefix+"/json", serveIndexJson(args, cache, errorChannel))
|
||||
if PageLength != 0 {
|
||||
register(mux, Prefix+"/json/:page", serveIndexJson(args, cache))
|
||||
register(mux, Prefix+"/json/:page", serveIndexJson(args, cache, errorChannel))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
ReleaseVersion string = "0.88.1"
|
||||
ReleaseVersion string = "0.89.0"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -22,6 +22,7 @@ var (
|
|||
CacheFile string
|
||||
Code bool
|
||||
CodeTheme string
|
||||
ExitOnError bool
|
||||
Filtering bool
|
||||
Flash bool
|
||||
Handlers bool
|
||||
|
@ -72,6 +73,7 @@ func init() {
|
|||
rootCmd.Flags().StringVar(&CacheFile, "cache-file", "", "path to optional persistent cache file")
|
||||
rootCmd.Flags().BoolVar(&Code, "code", false, "enable support for source code files")
|
||||
rootCmd.Flags().StringVar(&CodeTheme, "code-theme", "solarized-dark256", "theme for source code syntax highlighting")
|
||||
rootCmd.Flags().BoolVar(&ExitOnError, "exit-on-error", false, "shut down webserver on error, instead of just printing the error")
|
||||
rootCmd.Flags().BoolVarP(&Filtering, "filter", "f", false, "enable filtering")
|
||||
rootCmd.Flags().BoolVar(&Flash, "flash", false, "enable support for shockwave flash files (via ruffle.rs)")
|
||||
rootCmd.Flags().BoolVar(&Handlers, "handlers", false, "display registered handlers (for debugging)")
|
||||
|
|
80
cmd/web.go
80
cmd/web.go
|
@ -6,6 +6,7 @@ package cmd
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -39,7 +40,7 @@ const (
|
|||
timeout time.Duration = 10 * time.Second
|
||||
)
|
||||
|
||||
func serveStaticFile(paths []string, cache *fileCache) httprouter.Handle {
|
||||
func serveStaticFile(paths []string, cache *fileCache, errorChannel chan<- error) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
prefix := Prefix + sourcePrefix
|
||||
|
||||
|
@ -47,7 +48,7 @@ func serveStaticFile(paths []string, cache *fileCache) httprouter.Handle {
|
|||
|
||||
prefixedFilePath, err := stripQueryParams(path)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
|
@ -56,7 +57,7 @@ func serveStaticFile(paths []string, cache *fileCache) httprouter.Handle {
|
|||
|
||||
filePath, err := filepath.EvalSymlinks(strings.TrimPrefix(prefixedFilePath, prefix))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
|
@ -71,6 +72,8 @@ func serveStaticFile(paths []string, cache *fileCache) httprouter.Handle {
|
|||
|
||||
exists, err := fileExists(filePath)
|
||||
if err != nil {
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
return
|
||||
|
@ -86,6 +89,8 @@ func serveStaticFile(paths []string, cache *fileCache) httprouter.Handle {
|
|||
|
||||
buf, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
return
|
||||
|
@ -98,6 +103,8 @@ func serveStaticFile(paths []string, cache *fileCache) httprouter.Handle {
|
|||
if Russian {
|
||||
err = os.Remove(filePath)
|
||||
if err != nil {
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
return
|
||||
|
@ -120,11 +127,11 @@ func serveStaticFile(paths []string, cache *fileCache) httprouter.Handle {
|
|||
}
|
||||
}
|
||||
|
||||
func serveRoot(paths []string, regexes *regexes, cache *fileCache, formats *types.Types) httprouter.Handle {
|
||||
func serveRoot(paths []string, regexes *regexes, cache *fileCache, formats *types.Types, errorChannel chan<- error) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
refererUri, err := stripQueryParams(refererToUri(r.Referer()))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
|
@ -147,7 +154,7 @@ func serveRoot(paths []string, regexes *regexes, cache *fileCache, formats *type
|
|||
if refererUri != "" {
|
||||
filePath, err = nextFile(strippedRefererUri, sortOrder, regexes, formats)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
|
@ -174,7 +181,7 @@ func serveRoot(paths []string, regexes *regexes, cache *fileCache, formats *type
|
|||
|
||||
return
|
||||
case err != nil:
|
||||
fmt.Println(err)
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
|
@ -194,7 +201,7 @@ func serveRoot(paths []string, regexes *regexes, cache *fileCache, formats *type
|
|||
}
|
||||
}
|
||||
|
||||
func serveMedia(paths []string, regexes *regexes, formats *types.Types) httprouter.Handle {
|
||||
func serveMedia(paths []string, regexes *regexes, formats *types.Types, errorChannel chan<- error) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
filters := &filters{
|
||||
included: splitQueryParams(r.URL.Query().Get("include"), regexes),
|
||||
|
@ -211,7 +218,7 @@ func serveMedia(paths []string, regexes *regexes, formats *types.Types) httprout
|
|||
|
||||
exists, err := fileExists(path)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
|
@ -252,19 +259,37 @@ func serveMedia(paths []string, regexes *regexes, formats *types.Types) httprout
|
|||
htmlBody.WriteString(`<!DOCTYPE html><html class="bg" lang="en"><head>`)
|
||||
htmlBody.WriteString(faviconHtml)
|
||||
htmlBody.WriteString(fmt.Sprintf(`<style>%s</style>`, format.Css()))
|
||||
htmlBody.WriteString((format.Title(rootUrl, fileUri, path, fileName, Prefix, mimeType)))
|
||||
|
||||
title, err := format.Title(rootUrl, fileUri, path, fileName, Prefix, mimeType)
|
||||
if err != nil {
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
return
|
||||
}
|
||||
htmlBody.WriteString(title)
|
||||
htmlBody.WriteString(`</head><body>`)
|
||||
if refreshInterval != "0ms" {
|
||||
htmlBody.WriteString(fmt.Sprintf("<script>window.onload = function(){setInterval(function(){window.location.href = '%s';}, %d);};</script>",
|
||||
rootUrl,
|
||||
refreshTimer))
|
||||
}
|
||||
htmlBody.WriteString((format.Body(rootUrl, fileUri, path, fileName, Prefix, mimeType)))
|
||||
|
||||
body, err := format.Body(rootUrl, fileUri, path, fileName, Prefix, mimeType)
|
||||
if err != nil {
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
return
|
||||
}
|
||||
htmlBody.WriteString(body)
|
||||
htmlBody.WriteString(`</body></html>`)
|
||||
|
||||
_, err = io.WriteString(w, gohtml.Format(htmlBody.String()))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
errorChannel <- err
|
||||
|
||||
serverError(w, r, nil)
|
||||
|
||||
|
@ -387,7 +412,9 @@ func ServePage(args []string) error {
|
|||
Prefix = Prefix + "/"
|
||||
}
|
||||
|
||||
register(mux, Prefix, serveRoot(paths, regexes, cache, formats))
|
||||
errorChannel := make(chan error)
|
||||
|
||||
register(mux, Prefix, serveRoot(paths, regexes, cache, formats, errorChannel))
|
||||
|
||||
Prefix = strings.TrimSuffix(Prefix, "/")
|
||||
|
||||
|
@ -395,22 +422,25 @@ func ServePage(args []string) error {
|
|||
register(mux, "/", redirectRoot())
|
||||
}
|
||||
|
||||
register(mux, Prefix+"/favicons/*favicon", serveFavicons())
|
||||
register(mux, Prefix+"/favicons/*favicon", serveFavicons(errorChannel))
|
||||
|
||||
register(mux, Prefix+"/favicon.ico", serveFavicons())
|
||||
register(mux, Prefix+"/favicon.ico", serveFavicons(errorChannel))
|
||||
|
||||
register(mux, Prefix+mediaPrefix+"/*media", serveMedia(paths, regexes, formats))
|
||||
register(mux, Prefix+mediaPrefix+"/*media", serveMedia(paths, regexes, formats, errorChannel))
|
||||
|
||||
register(mux, Prefix+sourcePrefix+"/*static", serveStaticFile(paths, cache))
|
||||
register(mux, Prefix+sourcePrefix+"/*static", serveStaticFile(paths, cache, errorChannel))
|
||||
|
||||
register(mux, Prefix+"/version", serveVersion())
|
||||
|
||||
if Cache {
|
||||
registerCacheHandlers(mux, args, cache, formats)
|
||||
err = registerCacheHandlers(mux, args, cache, formats, errorChannel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if Info {
|
||||
registerInfoHandlers(mux, args, cache, formats)
|
||||
registerInfoHandlers(mux, args, cache, formats, errorChannel)
|
||||
}
|
||||
|
||||
if Profile {
|
||||
|
@ -421,6 +451,18 @@ func ServePage(args []string) error {
|
|||
fmt.Printf("WARNING! Files *will* be deleted after serving!\n\n")
|
||||
}
|
||||
|
||||
go func() {
|
||||
for err := range errorChannel {
|
||||
fmt.Printf("%s | Error: %v\n", time.Now().Format(logDate), err)
|
||||
|
||||
if ExitOnError {
|
||||
fmt.Printf("%s | Shutting down...\n", time.Now().Format(logDate))
|
||||
|
||||
srv.Shutdown(context.Background())
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
err = srv.ListenAndServe()
|
||||
if !errors.Is(err, http.ErrServerClosed) {
|
||||
return err
|
||||
|
|
|
@ -22,16 +22,16 @@ func (t Format) Css() string {
|
|||
return css.String()
|
||||
}
|
||||
|
||||
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) string {
|
||||
return fmt.Sprintf(`<title>%s</title>`, fileName)
|
||||
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
||||
return fmt.Sprintf(`<title>%s</title>`, fileName), nil
|
||||
}
|
||||
|
||||
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) string {
|
||||
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
||||
return fmt.Sprintf(`<a href="%s"><audio controls autoplay loop preload="auto"><source src="%s" type="%s" alt="Roulette selected: %s">Your browser does not support the audio tag.</audio></a>`,
|
||||
rootUrl,
|
||||
fileUri,
|
||||
mime,
|
||||
fileName)
|
||||
fileName), nil
|
||||
}
|
||||
|
||||
func (t Format) Extensions() map[string]string {
|
||||
|
|
|
@ -60,14 +60,14 @@ func (t Format) Css() string {
|
|||
return css.String()
|
||||
}
|
||||
|
||||
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) string {
|
||||
return fmt.Sprintf(`<title>%s</title>`, fileName)
|
||||
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
||||
return fmt.Sprintf(`<title>%s</title>`, fileName), nil
|
||||
}
|
||||
|
||||
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) string {
|
||||
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
||||
contents, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return ""
|
||||
return "", err
|
||||
}
|
||||
|
||||
contentString := string(contents)
|
||||
|
@ -97,24 +97,24 @@ func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string)
|
|||
|
||||
iterator, err := lexer.Tokenise(nil, contentString)
|
||||
if err != nil {
|
||||
return ""
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = formatter.Format(w, style, iterator)
|
||||
if err != nil {
|
||||
return ""
|
||||
return "", err
|
||||
}
|
||||
|
||||
w.Flush()
|
||||
|
||||
b, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return ""
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf(`<a href="%s">%s</a>`,
|
||||
rootUrl,
|
||||
string(b))
|
||||
string(b)), nil
|
||||
}
|
||||
|
||||
func (t Format) Extensions() map[string]string {
|
||||
|
|
|
@ -22,17 +22,17 @@ func (t Format) Css() string {
|
|||
return css.String()
|
||||
}
|
||||
|
||||
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) string {
|
||||
return fmt.Sprintf(`<title>%s</title>`, fileName)
|
||||
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
||||
return fmt.Sprintf(`<title>%s</title>`, fileName), nil
|
||||
}
|
||||
|
||||
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) string {
|
||||
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
||||
var html strings.Builder
|
||||
|
||||
html.WriteString(fmt.Sprintf(`<script src="https://unpkg.com/@ruffle-rs/ruffle"></script><script>window.RufflePlayer.config = {autoplay:"on"};</script><embed src="%s"></embed>`, fileUri))
|
||||
html.WriteString(fmt.Sprintf(`<br /><button onclick="window.location.href = '%s';">Next</button>`, rootUrl))
|
||||
|
||||
return html.String()
|
||||
return html.String(), nil
|
||||
}
|
||||
|
||||
func (t Format) Extensions() map[string]string {
|
||||
|
|
|
@ -37,22 +37,22 @@ func (t Format) Css() string {
|
|||
return css.String()
|
||||
}
|
||||
|
||||
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) string {
|
||||
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
||||
dimensions, err := ImageDimensions(filePath)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf(`<title>%s (%dx%d)</title>`,
|
||||
fileName,
|
||||
dimensions.width,
|
||||
dimensions.height)
|
||||
dimensions.height), nil
|
||||
}
|
||||
|
||||
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) string {
|
||||
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
||||
dimensions, err := ImageDimensions(filePath)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf(`<a href="%s"><img src="%s" width="%d" height="%d" type="%s" alt="Roulette selected: %s"></a>`,
|
||||
|
@ -61,7 +61,7 @@ func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string)
|
|||
dimensions.width,
|
||||
dimensions.height,
|
||||
mime,
|
||||
fileName)
|
||||
fileName), nil
|
||||
}
|
||||
|
||||
func (t Format) Extensions() map[string]string {
|
||||
|
|
|
@ -27,11 +27,11 @@ func (t Format) Css() string {
|
|||
return css.String()
|
||||
}
|
||||
|
||||
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) string {
|
||||
return fmt.Sprintf(`<title>%s</title>`, fileName)
|
||||
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
||||
return fmt.Sprintf(`<title>%s</title>`, fileName), nil
|
||||
}
|
||||
|
||||
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) string {
|
||||
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
||||
body, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
body = []byte{}
|
||||
|
@ -39,7 +39,7 @@ func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string)
|
|||
|
||||
return fmt.Sprintf(`<a href="%s"><textarea autofocus readonly>%s</textarea></a>`,
|
||||
rootUrl,
|
||||
body)
|
||||
body), nil
|
||||
}
|
||||
|
||||
func (t Format) Extensions() map[string]string {
|
||||
|
|
|
@ -16,8 +16,8 @@ var SupportedFormats = &Types{
|
|||
|
||||
type Type interface {
|
||||
Css() string
|
||||
Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) string
|
||||
Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) string
|
||||
Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error)
|
||||
Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error)
|
||||
Extensions() map[string]string
|
||||
MimeType(string) string
|
||||
Validate(filePath string) bool
|
||||
|
|
|
@ -25,16 +25,16 @@ func (t Format) Css() string {
|
|||
return css.String()
|
||||
}
|
||||
|
||||
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) string {
|
||||
return fmt.Sprintf(`<title>%s</title>`, fileName)
|
||||
func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
||||
return fmt.Sprintf(`<title>%s</title>`, fileName), nil
|
||||
}
|
||||
|
||||
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) string {
|
||||
func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime string) (string, error) {
|
||||
return fmt.Sprintf(`<a href="%s"><video controls autoplay loop preload="auto"><source src="%s" type="%s" alt="Roulette selected: %s">Your browser does not support the video tag.</video></a>`,
|
||||
rootUrl,
|
||||
fileUri,
|
||||
mime,
|
||||
fileName)
|
||||
fileName), nil
|
||||
}
|
||||
|
||||
func (t Format) Extensions() map[string]string {
|
||||
|
|
Loading…
Reference in New Issue