add book store
This commit is contained in:
parent
e0d7eeadc3
commit
ae27d07170
@ -9,6 +9,8 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const URL = "/"
|
||||||
|
|
||||||
func Handler() func(http.ResponseWriter, *http.Request) {
|
func Handler() func(http.ResponseWriter, *http.Request) {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
|
|||||||
@ -12,6 +12,8 @@ import (
|
|||||||
"librapi/templates"
|
"librapi/templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const URL = "/login"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrInvalidUsername = errors.New("username must not be empty")
|
ErrInvalidUsername = errors.New("username must not be empty")
|
||||||
ErrInvalidPassword = errors.New("password must not be empty")
|
ErrInvalidPassword = errors.New("password must not be empty")
|
||||||
|
|||||||
@ -4,10 +4,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -17,7 +15,10 @@ import (
|
|||||||
"librapi/templates"
|
"librapi/templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
const MaxFileSize = 200 // in MB
|
const (
|
||||||
|
URL = "/upload"
|
||||||
|
MaxFileSize = 200 // in MB
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrInvalidName = errors.New("book name must not be empty")
|
ErrInvalidName = errors.New("book name must not be empty")
|
||||||
@ -99,13 +100,13 @@ func (bf *BookForm) IsSuccess() bool {
|
|||||||
return bf.Method == http.MethodPost && bf.Error == "" && !bf.HasErrors()
|
return bf.Method == http.MethodPost && bf.Error == "" && !bf.HasErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Handler(a services.IAuthenticate) func(http.ResponseWriter, *http.Request) {
|
func Handler(a services.IAuthenticate, s services.IStore) func(http.ResponseWriter, *http.Request) {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case http.MethodGet:
|
case http.MethodGet:
|
||||||
getUploadFile(w, r)
|
getUploadFile(w, r)
|
||||||
case http.MethodPost:
|
case http.MethodPost:
|
||||||
postUploadFile(w, r, a)
|
postUploadFile(w, r, a, s)
|
||||||
default:
|
default:
|
||||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||||
}
|
}
|
||||||
@ -163,7 +164,7 @@ func extractBookForm(r *http.Request) BookForm {
|
|||||||
return bf
|
return bf
|
||||||
}
|
}
|
||||||
|
|
||||||
func postUploadFile(w http.ResponseWriter, r *http.Request, a services.IAuthenticate) {
|
func postUploadFile(w http.ResponseWriter, r *http.Request, a services.IAuthenticate, s services.IStore) {
|
||||||
uploadForm := templates.GetUploadForm()
|
uploadForm := templates.GetUploadForm()
|
||||||
|
|
||||||
if !a.IsLogged(r) {
|
if !a.IsLogged(r) {
|
||||||
@ -171,6 +172,7 @@ func postUploadFile(w http.ResponseWriter, r *http.Request, a services.IAuthenti
|
|||||||
if err := uploadForm.Execute(buf, &BookForm{Error: services.ErrUnauthorized.Error()}); err != nil {
|
if err := uploadForm.Execute(buf, &BookForm{Error: services.ErrUnauthorized.Error()}); err != nil {
|
||||||
log.Err(err).Msg("unable to generate template")
|
log.Err(err).Msg("unable to generate template")
|
||||||
http.Error(w, "unexpected error occurred", http.StatusInternalServerError)
|
http.Error(w, "unexpected error occurred", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
@ -183,6 +185,7 @@ func postUploadFile(w http.ResponseWriter, r *http.Request, a services.IAuthenti
|
|||||||
if err := uploadForm.Execute(buf, &bf); err != nil {
|
if err := uploadForm.Execute(buf, &bf); err != nil {
|
||||||
log.Err(err).Msg("unable to generate template")
|
log.Err(err).Msg("unable to generate template")
|
||||||
http.Error(w, "unexpected error occurred", http.StatusInternalServerError)
|
http.Error(w, "unexpected error occurred", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if bf.HasErrors() {
|
if bf.HasErrors() {
|
||||||
@ -194,9 +197,8 @@ func postUploadFile(w http.ResponseWriter, r *http.Request, a services.IAuthenti
|
|||||||
filename := bf.File.Value.GetFilename()
|
filename := bf.File.Value.GetFilename()
|
||||||
log.Info().Str("filename", filename).Msg("file is uploading...")
|
log.Info().Str("filename", filename).Msg("file is uploading...")
|
||||||
|
|
||||||
dst, err := os.Create(filename)
|
if err := s.Save(filename, bf.File.Value.file); err != nil {
|
||||||
if err != nil {
|
if err := uploadForm.Execute(buf, &BookForm{Error: err.Error()}); err != nil {
|
||||||
if err := uploadForm.Execute(buf, &BookForm{Error: "unexpected error occurred while creating file"}); err != nil {
|
|
||||||
log.Err(err).Msg("unable to generate template")
|
log.Err(err).Msg("unable to generate template")
|
||||||
http.Error(w, "unexpected error occurred", http.StatusInternalServerError)
|
http.Error(w, "unexpected error occurred", http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@ -206,20 +208,6 @@ func postUploadFile(w http.ResponseWriter, r *http.Request, a services.IAuthenti
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
defer dst.Close()
|
|
||||||
|
|
||||||
if _, err := io.Copy(dst, bf.File.Value.file); err != nil {
|
|
||||||
if err := uploadForm.Execute(buf, &BookForm{Error: "unexpected error occurred while uploading file"}); err != nil {
|
|
||||||
log.Err(err).Msg("unable to generate template")
|
|
||||||
http.Error(w, "unexpected error occurred", http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
fmt.Fprint(w, buf.String())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
if err := uploadForm.Execute(buf, &BookForm{Method: http.MethodPost}); err != nil {
|
if err := uploadForm.Execute(buf, &BookForm{Method: http.MethodPost}); err != nil {
|
||||||
log.Err(err).Msg("unable to generate template")
|
log.Err(err).Msg("unable to generate template")
|
||||||
|
|||||||
8
main.go
8
main.go
@ -27,16 +27,18 @@ func main() {
|
|||||||
defer fnCancel()
|
defer fnCancel()
|
||||||
|
|
||||||
auth := services.NewAuthentication(ctx)
|
auth := services.NewAuthentication(ctx)
|
||||||
|
bs := services.NewBookStore(services.GetEnv().GetDir())
|
||||||
|
|
||||||
srv := server.NewServer(
|
srv := server.NewServer(
|
||||||
ctx,
|
ctx,
|
||||||
services.GetEnv().GetPort(),
|
services.GetEnv().GetPort(),
|
||||||
server.NewHandler("/", home.Handler()),
|
server.NewHandler(home.URL, home.Handler()),
|
||||||
server.NewHandler("/upload", upload.Handler(auth)),
|
server.NewHandler(upload.URL, upload.Handler(auth, bs)),
|
||||||
server.NewHandler("/login", login.Handler(auth)),
|
server.NewHandler(login.URL, login.Handler(auth)),
|
||||||
)
|
)
|
||||||
srv.Serve()
|
srv.Serve()
|
||||||
|
|
||||||
<-srv.Done()
|
<-srv.Done()
|
||||||
<-auth.Done()
|
<-auth.Done()
|
||||||
|
<-bs.Done()
|
||||||
}
|
}
|
||||||
|
|||||||
69
services/book_store.go
Normal file
69
services/book_store.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrFileCreation = errors.New("unexpected error occurred while creating book file")
|
||||||
|
ErrFileCopy = errors.New("unexpected error occurred while copying book file")
|
||||||
|
)
|
||||||
|
|
||||||
|
type IStore interface {
|
||||||
|
Save(name string, content io.ReadCloser) error
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ IStore = (*BookStore)(nil)
|
||||||
|
|
||||||
|
type BookStore struct {
|
||||||
|
processing *sync.WaitGroup
|
||||||
|
dir string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBookStore(dir string) *BookStore {
|
||||||
|
if err := os.MkdirAll(dir, 0755); err != nil { //nolint
|
||||||
|
log.Fatal().Err(err).Msg("unable to create store dir")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &BookStore{
|
||||||
|
processing: &sync.WaitGroup{},
|
||||||
|
dir: dir,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BookStore) Done() <-chan struct{} {
|
||||||
|
chDone := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
bs.processing.Wait()
|
||||||
|
chDone <- struct{}{}
|
||||||
|
log.Info().Msg("book store processing done")
|
||||||
|
}()
|
||||||
|
return chDone
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BookStore) Save(name string, content io.ReadCloser) error {
|
||||||
|
bs.processing.Add(1)
|
||||||
|
defer bs.processing.Done()
|
||||||
|
|
||||||
|
defer content.Close()
|
||||||
|
|
||||||
|
dst, err := os.Create(filepath.Join(GetEnv().GetDir(), name))
|
||||||
|
if err != nil {
|
||||||
|
log.Err(err).Msg(ErrFileCreation.Error())
|
||||||
|
return ErrFileCreation
|
||||||
|
}
|
||||||
|
defer dst.Close()
|
||||||
|
|
||||||
|
if _, err := io.Copy(dst, content); err != nil {
|
||||||
|
log.Err(err).Msg(ErrFileCopy.Error())
|
||||||
|
return ErrFileCopy
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -71,11 +71,6 @@ func newEnv() environment {
|
|||||||
if storeDir == "" {
|
if storeDir == "" {
|
||||||
storeDir = defaultMainDir
|
storeDir = defaultMainDir
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.MkdirAll(storeDir, 0755); err != nil { //nolint
|
|
||||||
log.Fatal().Err(err).Msg("unable to create store dir")
|
|
||||||
}
|
|
||||||
|
|
||||||
env.storeDir = storeDir
|
env.storeDir = storeDir
|
||||||
|
|
||||||
return env
|
return env
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user