package image import ( "fmt" "io/ioutil" "log" "net/http" "path" "time" "github.com/matoous/go-nanoid" "github.com/pkg/errors" "go.ofmax.li/tmpl" ) // Servicer image management type Servicer interface { NewID() (string, error) AddFile(extension, fileType string, fileBytes []byte) (string, string, error) GetFile(fileUrl string) (*PostMeta, error) Render(w http.ResponseWriter, templateName string, data interface{}) error } // NewService new image service func NewService(repo Repo, storagePath string, renderer *tmpl.HTML) *Service { return &Service{repo, storagePath, renderer, } } // Service a container for working with images type Service struct { db Repo storagePath string tmpl *tmpl.HTML } // Render renders templates func (is *Service) Render(w http.ResponseWriter, templateName string, data interface{}) error { return is.tmpl.Render(w, templateName, data) } // NewID create an uniqueish ID func (is *Service) NewID() (string, error) { return gonanoid.Nanoid() } // AddFile writes to disk, writes meta to db func (is *Service) AddFile(extension, fileType string, fileBytes []byte) (string, string, error) { fileID, err := is.NewID() if err != nil { return "", "", errors.Wrap(err, "generated id for fileID failed") } fileName := fmt.Sprintf("%s.%s", fileID, extension) filePath := path.Join(is.storagePath, fileName) if err := ioutil.WriteFile(filePath, fileBytes, 0750); err != nil { log.Fatal(err) return "", "", errors.Wrap(err, "couldn't write image file") } postID, err := is.NewID() if err != nil { return "", "", errors.Wrap(err, "generating postid for uuid") } t := time.Now().UTC() postMeta := &PostMeta{ FilePath: fileName, CreatedAt: t.Format(time.RFC3339), UserID: "1", MimeType: fileType, } is.db.AddNewFile(postID, postMeta, 946080000) if err := is.db.AddNewFile(postID, postMeta, 946080000); err != nil { log.Fatal(err) return "", "", errors.Wrap(err, "couldn't write to redis") } return fileName, postID, nil } // GetFile fetch file from db interface func (is *Service) GetFile(fileUrl string) (*PostMeta, error) { result, err := is.db.GetFile(fileUrl) return result, err }