package main import ( "encoding/base64" "errors" "image" _ "image/gif" "image/jpeg" _ "image/png" "io" "os" "path" "sort" "time" "github.com/nfnt/resize" ) type PictureExplorer struct { FileBackend PublishedImgDir string NextImgDir string } type Picture struct { path string basename string Name string `json:"name"` UploadTime time.Time `json:"upload_time"` } type ByUploadTime []*Picture func (a ByUploadTime) Len() int { return len(a) } func (a ByUploadTime) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByUploadTime) Less(i, j int) bool { return a[i].UploadTime.Sub(a[j].UploadTime).Nanoseconds() < 0 } func (e *PictureExplorer) GetNextImages() (pictures []*Picture, err error) { pictures, err = e.ListPictures(e.NextImgDir) sort.Sort(ByUploadTime(pictures)) return } func (e *PictureExplorer) GetPublishedImages() (pictures []*Picture, err error) { pictures, err = e.ListPictures(e.PublishedImgDir) sort.Sort(ByUploadTime(pictures)) return } func (e *PictureExplorer) GetLastImage() (*Picture, error) { picts, err := e.GetPublishedImages() if err != nil { return nil, err } return picts[len(picts)-1], nil } func (e *PictureExplorer) GetPublishedImage(fname string) (*Picture, error) { return e.GetPictureInfo(e.PublishedImgDir, fname) } func (e *PictureExplorer) GetNextImage(fname string) (*Picture, error) { return e.GetPictureInfo(e.NextImgDir, fname) } func (e *PictureExplorer) IsUniqueName(filename string) bool { if pict, _ := e.GetPublishedImage(filename); pict != nil { return false } if pict, _ := e.GetNextImage(filename); pict != nil { return false } return true } func (e *PictureExplorer) AddImage(filename string, blob io.ReadCloser) error { // Check the name is not already used if ok := e.IsUniqueName(filename); !ok { return errors.New("This filename is already used, please choose another one.") } // Convert to JPEG img, _, err := image.Decode(base64.NewDecoder(base64.StdEncoding, blob)) if err != nil { return err } // Save file if err := e.PutPicture(e.NextImgDir, filename, &img); err != nil { return err } thumb := resize.Thumbnail(300, 185, img, resize.Lanczos3) // Save thumbnail fw, err := os.Create(path.Join(ThumbsDir, filename+".jpg")) if err != nil { return err } defer fw.Close() return jpeg.Encode(fw, thumb, nil) } func (e *PictureExplorer) Publish(p *Picture) error { return e.MovePicture(e.NextImgDir, e.PublishedImgDir, p.Name) } func (e *PictureExplorer) Unpublish(p *Picture) error { return e.MovePicture(e.PublishedImgDir, e.NextImgDir, p.Name) } func (e *PictureExplorer) Remove(p *Picture) error { return e.DeletePicture(path.Dir(p.path), p.Name) }