diff --git a/Makefile b/Makefile index 3f131ed..0f018a9 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,5 @@ build: lint lint: golangci-lint run --fix -# .run-meilisearch: -# docker-compose up -d meilisearch - run: lint - # while [ "`curl --insecure -s -o /dev/null -w ''%{http_code}'' http://localhost:7700/health`" != "200" ]; do sleep 2; echo "waiting..."; done go run main.go \ No newline at end of file diff --git a/handlers/download/handler.go b/handlers/download/handler.go new file mode 100644 index 0000000..0709cb0 --- /dev/null +++ b/handlers/download/handler.go @@ -0,0 +1,47 @@ +package download + +import ( + "fmt" + "librapi/services" + "net/http" + "path/filepath" + + "github.com/rs/zerolog/log" +) + +const URL = "/download" + +func Handler(bs services.IStore) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodGet: + getDownload(w, r, bs) + default: + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + } + } +} + +func getDownload(w http.ResponseWriter, r *http.Request, bs services.IStore) { + queryParams := r.URL.Query() + downloadFiles, ok := queryParams["file"] + if !ok { + log.Error().Msg("file query param does not exist") + http.Error(w, "file does not exists", http.StatusBadRequest) + return + } + + if len(downloadFiles) != 1 { + log.Error().Msg("only one file is allowed to download") + http.Error(w, "only one file is allowed to download", http.StatusBadRequest) + return + } + + filename := downloadFiles[0] + filePath := filepath.Join(bs.GetStoreDir(), filename) + + http.ServeFile(w, r, filePath) + + w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename)) + w.Header().Set("Content-Type", "application/pdf") +} diff --git a/main.go b/main.go index ddbb331..a871d14 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,7 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" + "librapi/handlers/download" "librapi/handlers/home" "librapi/handlers/login" "librapi/handlers/upload" @@ -64,6 +65,7 @@ func main() { server.NewHandler(home.URL, home.Handler(bs)), server.NewHandler(upload.URL, upload.Handler(auth, bs)), server.NewHandler(login.URL, login.Handler(auth)), + server.NewHandler(download.URL, download.Handler(bs)), ) srv.Serve() diff --git a/services/book_store.go b/services/book_store.go index f8582bf..e0e1688 100644 --- a/services/book_store.go +++ b/services/book_store.go @@ -24,6 +24,7 @@ var ( type IStore interface { Save(bm *BookMetadata, content io.ReadCloser) error Search(value string) ([]BookMetadata, error) + GetStoreDir() string } var _ IStore = (*BookStore)(nil) @@ -168,6 +169,10 @@ func (bs *BookStore) Done() <-chan struct{} { return chDone } +func (bs *BookStore) GetStoreDir() string { + return bs.dir +} + func (bs *BookStore) Save(bm *BookMetadata, content io.ReadCloser) error { bs.processing.Add(1) defer bs.processing.Done() diff --git a/templates/home.html.tpl b/templates/home.html.tpl index cf1a7b0..6ea9458 100644 --- a/templates/home.html.tpl +++ b/templates/home.html.tpl @@ -1,5 +1,5 @@ {{ define "content" }} -

A simple API to store, search and download books.

+

A simple API to store, search and download books, articles, etc...

No extra JS, CSS or fancy stuff. You click, you search, you found, you're happy.
@@ -27,17 +27,19 @@ + {{range .Results}} - + + - + - + {{ end }}
NameDescription Editor Authors Year
{{.Name}}
{{.Name}}
{{.Description | noDesc}}
{{.Editor}}
{{.Authors | join }}
{{.Authors | join }}
{{.Year}}
{{.Path | bookUrl}}
diff --git a/templates/templates.go b/templates/templates.go index f535538..af36584 100644 --- a/templates/templates.go +++ b/templates/templates.go @@ -39,7 +39,7 @@ var funcMap = template.FuncMap{ if len(s) == 0 { return "" } else { - return strings.Join(s, ",") + return strings.Join(s, ", ") } }, "filename": func(h *multipart.FileHeader) string { @@ -56,7 +56,13 @@ var funcMap = template.FuncMap{ }, "bookUrl": func(path string) string { _, filename := filepath.Split(path) - return fmt.Sprintf("https://books.thegux.fr/downloads/%s", filename) + return fmt.Sprintf("/download?file=%s", filename) + }, + "noDesc": func(desc *string) string { + if desc == nil { + return "" + } + return *desc }, }