2022-05-30 20:34:42 +00:00
|
|
|
package emojy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"embed"
|
|
|
|
"encoding/json"
|
2022-06-08 20:57:24 +00:00
|
|
|
"fmt"
|
2024-03-13 14:57:52 +00:00
|
|
|
"github.com/ggicci/httpin"
|
2022-06-08 20:57:24 +00:00
|
|
|
"io"
|
2022-06-06 14:20:50 +00:00
|
|
|
"io/ioutil"
|
2022-05-30 20:34:42 +00:00
|
|
|
"net/http"
|
2022-06-08 20:57:24 +00:00
|
|
|
"os"
|
2022-06-06 14:20:50 +00:00
|
|
|
"path"
|
2022-06-08 20:57:24 +00:00
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
2022-07-21 15:25:10 +00:00
|
|
|
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
"github.com/rs/zerolog/log"
|
2022-05-30 20:34:42 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
//go:embed *.html
|
|
|
|
var embeddedFS embed.FS
|
|
|
|
|
|
|
|
func (p *EmojyPlugin) registerWeb() {
|
|
|
|
r := chi.NewRouter()
|
|
|
|
r.HandleFunc("/all", p.handleAll)
|
2022-06-08 20:57:24 +00:00
|
|
|
r.HandleFunc("/allFiles", p.handleAllFiles)
|
2024-03-13 14:57:52 +00:00
|
|
|
r.With(httpin.NewInput(UploadReq{})).
|
|
|
|
Post("/upload", p.handleUpload)
|
|
|
|
r.With(httpin.NewInput(EmojyReq{})).
|
|
|
|
HandleFunc("/file/{name}", p.handleEmojy)
|
2024-02-28 02:40:19 +00:00
|
|
|
r.HandleFunc("/stats", p.handleStats)
|
|
|
|
r.HandleFunc("/list", p.handleList)
|
|
|
|
r.HandleFunc("/new", p.handleUploadForm)
|
|
|
|
r.HandleFunc("/", p.handleStats)
|
2024-02-27 19:29:54 +00:00
|
|
|
p.b.GetWeb().RegisterWebName(r, "/emojy", "Emojys")
|
2022-05-30 20:34:42 +00:00
|
|
|
}
|
|
|
|
|
2024-02-28 02:40:19 +00:00
|
|
|
type emojyMap map[string][]EmojyCount
|
|
|
|
|
|
|
|
func (p *EmojyPlugin) handleUploadForm(w http.ResponseWriter, r *http.Request) {
|
|
|
|
p.b.GetWeb().Index("Emojy", p.uploadIndex()).Render(r.Context(), w)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *EmojyPlugin) handleList(w http.ResponseWriter, r *http.Request) {
|
|
|
|
threshold := p.c.GetInt("emojy.statthreshold", 1)
|
|
|
|
emojy, err := p.allCounts(threshold)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Fprintf(w, "Error: %s", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
p.b.GetWeb().Index("Emojy", p.listTempl(emojy)).Render(r.Context(), w)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *EmojyPlugin) handleStats(w http.ResponseWriter, r *http.Request) {
|
|
|
|
threshold := p.c.GetInt("emojy.statthreshold", 1)
|
|
|
|
emojy, err := p.allCounts(threshold)
|
|
|
|
if err != nil {
|
|
|
|
w.WriteHeader(500)
|
|
|
|
log.Error().Err(err).Msgf("handleAll")
|
|
|
|
out, _ := json.Marshal(struct{ err error }{err})
|
|
|
|
w.Write(out)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
p.b.GetWeb().Index("Emojy", p.statsIndex(emojy)).Render(r.Context(), w)
|
2022-07-22 13:44:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *EmojyPlugin) handlePage(file string) func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
index, _ := embeddedFS.ReadFile(file)
|
|
|
|
w.Write(index)
|
|
|
|
}
|
2022-05-30 20:34:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *EmojyPlugin) handleAll(w http.ResponseWriter, r *http.Request) {
|
2022-07-23 16:47:31 +00:00
|
|
|
threshold := p.c.GetInt("emojy.statthreshold", 1)
|
|
|
|
emojy, err := p.allCounts(threshold)
|
2022-05-30 20:34:42 +00:00
|
|
|
if err != nil {
|
|
|
|
w.WriteHeader(500)
|
|
|
|
log.Error().Err(err).Msgf("handleAll")
|
|
|
|
out, _ := json.Marshal(struct{ err error }{err})
|
|
|
|
w.Write(out)
|
|
|
|
}
|
|
|
|
out, _ := json.Marshal(emojy)
|
|
|
|
w.Write(out)
|
|
|
|
}
|
2022-06-06 14:20:50 +00:00
|
|
|
|
2022-06-08 20:57:24 +00:00
|
|
|
func (p *EmojyPlugin) handleAllFiles(w http.ResponseWriter, r *http.Request) {
|
2022-07-22 13:44:42 +00:00
|
|
|
_, urlMap, err := AllFiles(p.emojyPath, p.baseURL)
|
2022-06-08 20:57:24 +00:00
|
|
|
if err != nil {
|
|
|
|
w.WriteHeader(500)
|
|
|
|
out, _ := json.Marshal(struct{ err error }{err})
|
|
|
|
w.Write(out)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
enc := json.NewEncoder(w)
|
|
|
|
err = enc.Encode(urlMap)
|
|
|
|
if err != nil {
|
|
|
|
w.WriteHeader(500)
|
|
|
|
out, _ := json.Marshal(struct{ err error }{err})
|
|
|
|
w.Write(out)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-13 14:57:52 +00:00
|
|
|
type UploadReq struct {
|
|
|
|
Password string `in:"form=password"`
|
|
|
|
Attachment *httpin.File `in:"form=attachment"`
|
|
|
|
}
|
|
|
|
|
2022-06-08 20:57:24 +00:00
|
|
|
func (p *EmojyPlugin) handleUpload(w http.ResponseWriter, r *http.Request) {
|
2024-03-13 14:57:52 +00:00
|
|
|
input := r.Context().Value(httpin.Input).(*UploadReq)
|
|
|
|
log.Printf("handleUpload: %#v", input)
|
|
|
|
newFilePath, err := p.FileSave(input)
|
2022-06-08 20:57:24 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Msgf("could not upload file")
|
|
|
|
w.WriteHeader(500)
|
2024-02-28 02:40:19 +00:00
|
|
|
fmt.Fprintf(w, "Error with file upload")
|
2022-06-08 20:57:24 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
log.Debug().Msgf("uploaded file to %s", newFilePath)
|
|
|
|
w.WriteHeader(200)
|
2024-02-28 02:40:19 +00:00
|
|
|
fmt.Fprintf(w, "success")
|
2022-06-08 20:57:24 +00:00
|
|
|
}
|
|
|
|
|
2024-03-13 14:57:52 +00:00
|
|
|
func (p *EmojyPlugin) FileSave(input *UploadReq) (string, error) {
|
|
|
|
if !p.b.CheckPassword("", input.Password) {
|
2022-06-08 20:57:24 +00:00
|
|
|
return "", fmt.Errorf("incorrect password")
|
|
|
|
}
|
|
|
|
|
2024-03-13 14:57:52 +00:00
|
|
|
file := input.Attachment
|
|
|
|
emojyFileName := file.Filename()
|
|
|
|
emojyName := strings.TrimSuffix(emojyFileName, filepath.Ext(emojyFileName))
|
|
|
|
if ok, _, _, _ := p.isKnownEmojy(emojyName); ok {
|
|
|
|
return "", fmt.Errorf("emojy already exists")
|
|
|
|
}
|
|
|
|
contentType := file.MIMEHeader().Get("Content-Type")
|
|
|
|
if !strings.HasPrefix(contentType, "image") {
|
|
|
|
return "", fmt.Errorf("incorrect mime type - given: %s", contentType)
|
2022-06-08 20:57:24 +00:00
|
|
|
}
|
2024-03-13 14:57:52 +00:00
|
|
|
fullPath := filepath.Clean(filepath.Join(p.emojyPath, emojyFileName))
|
|
|
|
_ = os.MkdirAll(p.emojyPath, os.ModePerm)
|
|
|
|
log.Debug().Msgf("trying to create/open file: %s", fullPath)
|
|
|
|
outFile, err := os.OpenFile(fullPath, os.O_WRONLY|os.O_CREATE, os.ModePerm)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
defer outFile.Close()
|
|
|
|
inFile, _ := file.ReadAll()
|
|
|
|
stream, _ := file.OpenReceiveStream()
|
|
|
|
_, err = outFile.Write(inFile)
|
|
|
|
_, err = io.Copy(outFile, stream)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return emojyFileName, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type EmojyReq struct {
|
|
|
|
Name string `in:"path=name"`
|
2022-06-08 20:57:24 +00:00
|
|
|
}
|
|
|
|
|
2022-06-06 14:20:50 +00:00
|
|
|
func (p *EmojyPlugin) handleEmojy(w http.ResponseWriter, r *http.Request) {
|
2024-03-13 14:57:52 +00:00
|
|
|
input := r.Context().Value(httpin.Input).(*EmojyReq)
|
|
|
|
contents, err := ioutil.ReadFile(path.Join(p.emojyPath, input.Name))
|
2022-06-06 14:20:50 +00:00
|
|
|
if err != nil {
|
|
|
|
w.WriteHeader(404)
|
|
|
|
out, _ := json.Marshal(struct{ err error }{err})
|
|
|
|
w.Write(out)
|
|
|
|
}
|
|
|
|
w.Write(contents)
|
|
|
|
}
|