summaryrefslogtreecommitdiff
path: root/internal/server/handler/handler.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2024-05-19 12:24:47 +0300
committerPaul Buetow <paul@buetow.org>2024-05-19 12:24:47 +0300
commitfc6cd1078bf9f9c0966a0dff4e1b5f825a677123 (patch)
treedd4f4b947b9c492038c5c8e7bbf064f0b174d3b2 /internal/server/handler/handler.go
parent7111e1bd5c2ecb43cf86a43b9781269f2abe265c (diff)
rename handle to handler
Diffstat (limited to 'internal/server/handler/handler.go')
-rw-r--r--internal/server/handler/handler.go143
1 files changed, 143 insertions, 0 deletions
diff --git a/internal/server/handler/handler.go b/internal/server/handler/handler.go
new file mode 100644
index 0000000..bc751dd
--- /dev/null
+++ b/internal/server/handler/handler.go
@@ -0,0 +1,143 @@
+package handler
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+ "regexp"
+ "time"
+
+ "codeberg.org/snonux/gos/internal"
+ "codeberg.org/snonux/gos/internal/config/server"
+ "codeberg.org/snonux/gos/internal/easyhttp"
+ "codeberg.org/snonux/gos/internal/server/repository"
+ "codeberg.org/snonux/gos/internal/types"
+)
+
+type Handler struct {
+ conf server.ServerConfig
+ getIdRe *regexp.Regexp
+}
+
+func New(conf server.ServerConfig) Handler {
+ return Handler{
+ conf: conf,
+ getIdRe: regexp.MustCompile(`^/[0-9]{4}/[a-z0-9]{64}\.json$`),
+ }
+}
+
+// TODO: Use repository.Repository to store the file to the file system
+func (h Handler) Submit(w http.ResponseWriter, r *http.Request) error {
+ if r.Method != "POST" {
+ return fmt.Errorf("expexted POST request")
+ }
+
+ bytes, err := io.ReadAll(r.Body)
+ if err != nil {
+ return err
+ }
+
+ entry, err := types.NewEntry(bytes)
+ if err != nil {
+ return err
+ }
+ filePath := fmt.Sprintf("%s/%s/%s.json", h.conf.DataDir, time.Now().Format("2006"), entry.ID)
+
+ jsonStr, err := entry.Serialize()
+ if err != nil {
+ return err
+ }
+
+ if err := internal.SaveFile(filePath, jsonStr); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (h Handler) List(w http.ResponseWriter, r *http.Request) error {
+ if r.Method != "GET" {
+ return fmt.Errorf("expexted GET request")
+ }
+
+ list, err := repository.Instance(h.conf.DataDir).List()
+ if err != nil {
+ return err
+ }
+
+ _, err = w.Write(list)
+ return err
+}
+
+func (h Handler) Get(w http.ResponseWriter, r *http.Request) error {
+ id := r.URL.Query().Get("id")
+ if !h.getIdRe.MatchString(id) {
+ return fmt.Errorf("invalid id %s", id)
+ }
+
+ data, err := os.ReadFile(fmt.Sprintf("%s/%s", h.conf.DataDir, id))
+ if err != err {
+ return err
+ }
+
+ fmt.Fprint(w, string(data))
+ return nil
+}
+
+func (h Handler) Merge(w http.ResponseWriter, r *http.Request) error {
+ var errs []error
+
+ for _, partner := range h.conf.Partners() {
+ if err := h.mergeFromPartner(partner); err != nil {
+ errs = append(errs, err)
+ }
+ }
+
+ if len(errs) > 0 {
+ return errors.Join(errs...)
+ }
+
+ fmt.Fprint(w, "Okiedokie")
+ return nil
+}
+
+func (h Handler) mergeFromPartner(partner string) error {
+ var (
+ errs []error
+ uri = fmt.Sprintf("%s/list", partner)
+ repo = repository.Instance(h.conf.DataDir)
+ pairs []repository.EntryPair
+ )
+
+ if err := easyhttp.GetData(uri, h.conf.ApiKey, &pairs); err != nil {
+ return err
+ }
+
+ for _, pair := range pairs {
+ if repo.HasEntry(pair) {
+ continue
+ }
+
+ var (
+ entry types.Entry
+ uri = fmt.Sprintf("%s/get?id=%s", partner, pair.ID)
+ )
+
+ if err := easyhttp.GetData(uri, h.conf.ApiKey, &entry); err != nil {
+ errs = append(errs, err)
+ continue
+ }
+
+ // In theory, this should never happen
+ if pair.ID != entry.ID {
+ errs = append(errs, fmt.Errorf("pair ID %s does not match entry id %s", pair.ID, entry.ID))
+ continue
+ }
+
+ repo.Merge(entry)
+ }
+
+ return errors.Join(errs...)
+}