mirror of
				https://github.com/mickael-kerjean/filestash.git
				synced 2025-10-31 18:16:00 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			192 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			192 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package plg_image_light
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"net/http"
 | |
| 	"os"
 | |
| 	"path/filepath"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 
 | |
| 	. "github.com/mickael-kerjean/filestash/server/common"
 | |
| )
 | |
| 
 | |
| func init() {
 | |
| 	plugin_enable := func() bool {
 | |
| 		return Config.Get("features.image.enable_image").Schema(func(f *FormElement) *FormElement {
 | |
| 			if f == nil {
 | |
| 				f = &FormElement{}
 | |
| 			}
 | |
| 			f.Name = "enable_image"
 | |
| 			f.Type = "enable"
 | |
| 			f.Target = []string{"image_thumbsize", "image_thumbquality", "image_imagequality", "image_thumbcache", "image_imagecache"}
 | |
| 			f.Default = true
 | |
| 			return f
 | |
| 		}).Bool()
 | |
| 	}
 | |
| 	thumb_size := func() int {
 | |
| 		return Config.Get("features.image.thumbnail_size").Schema(func(f *FormElement) *FormElement {
 | |
| 			if f == nil {
 | |
| 				f = &FormElement{}
 | |
| 			}
 | |
| 			f.Type = "number"
 | |
| 			f.Id = "image_thumbsize"
 | |
| 			f.Name = "thumbnail_size"
 | |
| 			f.Description = "Thumbnail size in pixel"
 | |
| 			f.Placeholder = "Default: 300"
 | |
| 			f.Default = 300
 | |
| 			return f
 | |
| 		}).Int()
 | |
| 	}
 | |
| 	thumb_quality := func() int {
 | |
| 		return Config.Get("features.image.thumbnail_quality").Schema(func(f *FormElement) *FormElement {
 | |
| 			if f == nil {
 | |
| 				f = &FormElement{}
 | |
| 			}
 | |
| 			f.Id = "image_thumbquality"
 | |
| 			f.Type = "number"
 | |
| 			f.Name = "thumbnail_quality"
 | |
| 			f.Description = "image quality on thumbnails. A lower number means smaller size at the cost of potential visual artifacts"
 | |
| 			f.Placeholder = "Default: 50"
 | |
| 			f.Default = 50
 | |
| 			return f
 | |
| 		}).Int()
 | |
| 	}
 | |
| 	thumb_caching := func() int {
 | |
| 		return Config.Get("features.image.thumbnail_caching").Schema(func(f *FormElement) *FormElement {
 | |
| 			if f == nil {
 | |
| 				f = &FormElement{}
 | |
| 			}
 | |
| 			f.Id = "image_thumbcache"
 | |
| 			f.Type = "number"
 | |
| 			f.Name = "thumbnail_caching"
 | |
| 			f.Description = "How much time in seconds we want to store a thumbnail in the browser"
 | |
| 			f.Placeholder = "Default: 259200 => 3 days"
 | |
| 			f.Default = 259200
 | |
| 			return f
 | |
| 		}).Int()
 | |
| 	}
 | |
| 	image_quality := func() int {
 | |
| 		return Config.Get("features.image.image_quality").Schema(func(f *FormElement) *FormElement {
 | |
| 			if f == nil {
 | |
| 				f = &FormElement{}
 | |
| 			}
 | |
| 			f.Id = "image_imagequality"
 | |
| 			f.Type = "number"
 | |
| 			f.Name = "image_quality"
 | |
| 			f.Description = "image quality on fullsize images. A lower number means smaller size at the cost of potential visual artifacts"
 | |
| 			f.Placeholder = "Default: 90"
 | |
| 			f.Default = 90
 | |
| 			return f
 | |
| 		}).Int()
 | |
| 	}
 | |
| 	image_caching := func() int {
 | |
| 		return Config.Get("features.image.image_caching").Schema(func(f *FormElement) *FormElement {
 | |
| 			if f == nil {
 | |
| 				f = &FormElement{}
 | |
| 			}
 | |
| 			f.Id = "image_imagecache"
 | |
| 			f.Type = "number"
 | |
| 			f.Name = "image_caching"
 | |
| 			f.Description = "How much time in seconds we want to store images on the browser"
 | |
| 			f.Placeholder = "Default: 3600 => 1 hour"
 | |
| 			f.Default = 3600
 | |
| 			return f
 | |
| 		}).Int()
 | |
| 	}
 | |
| 	Hooks.Register.Onload(func() {
 | |
| 		plugin_enable()
 | |
| 		thumb_size()
 | |
| 		thumb_quality()
 | |
| 		thumb_caching()
 | |
| 		image_quality()
 | |
| 		image_caching()
 | |
| 	})
 | |
| 
 | |
| 	Hooks.Register.ProcessFileContentBeforeSend(func(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
 | |
| 		if plugin_enable() == false {
 | |
| 			return reader, nil
 | |
| 		}
 | |
| 
 | |
| 		query := req.URL.Query()
 | |
| 		mType := GetMimeType(query.Get("path"))
 | |
| 
 | |
| 		if strings.HasPrefix(mType, "image/") == false {
 | |
| 			return reader, nil
 | |
| 		} else if mType == "image/svg+xml" {
 | |
| 			return reader, nil
 | |
| 		} else if mType == "image/x-icon" {
 | |
| 			return reader, nil
 | |
| 		} else if query.Get("thumbnail") != "true" && query.Get("size") == "" {
 | |
| 			return reader, nil
 | |
| 		} else if query.Get("thumbnail") != "true" && mType == "image/gif" {
 | |
| 			return reader, nil
 | |
| 		}
 | |
| 
 | |
| 		/////////////////////////
 | |
| 		// Specify transformation
 | |
| 		transform := &Transform{
 | |
| 			Input:   filepath.Join(GetAbsolutePath(TMP_PATH), "imagein_"+QuickString(10)),
 | |
| 			Size:    thumb_size(),
 | |
| 			Crop:    true,
 | |
| 			Quality: thumb_quality(),
 | |
| 			Exif:    false,
 | |
| 		}
 | |
| 		if query.Get("thumbnail") == "true" {
 | |
| 			(*res).Header().Set("Cache-Control", fmt.Sprintf("max-age=%d", thumb_caching()))
 | |
| 		} else if query.Get("size") != "" {
 | |
| 			(*res).Header().Set("Cache-Control", fmt.Sprintf("max-age=%d", image_caching()))
 | |
| 			size, err := strconv.ParseInt(query.Get("size"), 10, 64)
 | |
| 			if err != nil {
 | |
| 				return reader, nil
 | |
| 			}
 | |
| 			transform.Size = int(size)
 | |
| 			transform.Crop = false
 | |
| 			transform.Quality = image_quality()
 | |
| 			transform.Exif = true
 | |
| 		}
 | |
| 
 | |
| 		/////////////////////////////
 | |
| 		// Insert file in the fs
 | |
| 		// => impedance matching with something usable by CGO
 | |
| 		file, err := os.OpenFile(transform.Input, os.O_WRONLY|os.O_CREATE, os.ModePerm)
 | |
| 		if err != nil {
 | |
| 			return reader, ErrFilesystemError
 | |
| 		}
 | |
| 		io.Copy(file, reader)
 | |
| 		file.Close()
 | |
| 		reader.Close()
 | |
| 		defer func() {
 | |
| 			os.Remove(transform.Input)
 | |
| 		}()
 | |
| 
 | |
| 		/////////////////////////
 | |
| 		// Transcode RAW image
 | |
| 		if IsRaw(mType) {
 | |
| 			if ExtractPreview(transform) == nil {
 | |
| 				mType = "image/jpeg"
 | |
| 				(*res).Header().Set("Content-Type", mType)
 | |
| 			} else {
 | |
| 				return reader, nil
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/////////////////////////
 | |
| 		// final stage: resizing
 | |
| 		if mType != "image/jpeg" && mType != "image/png" && mType != "image/gif" && mType != "image/tiff" {
 | |
| 			return reader, nil
 | |
| 		}
 | |
| 
 | |
| 		return CreateThumbnail(transform)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| type Transform struct {
 | |
| 	Input   string
 | |
| 	Size    int
 | |
| 	Crop    bool
 | |
| 	Quality int
 | |
| 	Exif    bool
 | |
| }
 | 
