Exemplo n.º 1
0
func uploadFile(req *http.Request, mpf multipart.File, hdr *multipart.FileHeader) (string, error) {

	ext, err := fileFilter(req, hdr)
	if err != nil {
		return "", err
	}
	name := getSha(mpf) + `.` + ext

	rand.Seed(time.Now().Unix())
	x := rand.Intn(3)
	fmt.Println(x)

	var pfx string
	switch x {
	case 0:
		pfx = "bob/"
	case 1:
		pfx = "james/"
	case 2:
		pfx = "stacey/"
	}

	name = pfx + name

	mpf.Seek(0, 0)

	ctx := appengine.NewContext(req)
	return name, putFile(ctx, name, mpf)
}
Exemplo n.º 2
0
func generateThumbnails(file multipart.File, userId, pathPrefix string, bucket *s3.Bucket) error {
	file.Seek(0, 0)

	img, _, err := image.Decode(file)
	if err != nil {
		log.Println("Error decoding image", err)
		return err
	}

	var buf bytes.Buffer
	for _, i := range THUMBNAIL_SIZES {
		resized := resize.Resize(uint(i), 0, img, resize.Lanczos3)
		err = jpeg.Encode(&buf, resized, nil)
		if err != nil {
			return err
		}
		path := fmt.Sprintf("%s/%d.jpg", pathPrefix, i)
		err = bucket.Put(path, buf.Bytes(), "image/jpeg", s3.PublicRead)
		if err != nil {
			return err
		}
		buf.Reset()
	}

	return err
}
Exemplo n.º 3
0
/**
takes a multipart file. Does not close it. creates a thumbnail and returns the file path
*/
func ThumbnailMultipart(file multipart.File, fileName string) (string, error) {
	var (
		err      error
		img      image.Image
		thumbImg *image.NRGBA
	)
	if _, err := file.Seek(0, 0); err != nil {
		log.Printf("failed to seek to beginning of img " + err.Error())
		return "", err
	}
	var thumbPath string = "/tmp/" + time.Now().String() + fileName
	img, _, err = image.Decode(file)
	if nil != err {
		log.Printf("failed to decode img " + err.Error())
		return "", err
	}

	thumbImg = imaging.Thumbnail(img, 300, 300, imaging.Lanczos)

	out, err := os.Create(thumbPath)

	if nil != err {
		log.Printf("failed to create thumb path " + err.Error())
		return "", err
	}

	defer out.Close()

	// write new image to file
	err = jpeg.Encode(out, thumbImg, nil)

	return thumbPath, err
}
Exemplo n.º 4
0
// Create takes the Profile Folder, a content-type (passed to S3), and the binary file
// data, and saves the file to S3, then saving the S3 information to the database.
// It returns the number of bytes sent to S3, for no particular reason, and any error.
func (p *Photo) Create(folder, ctype string, file multipart.File) (int64, error) {
	end, err := file.Seek(0, 2)
	if err != nil {
		return 0, err
	}
	_, err = file.Seek(0, 0)
	if err != nil {
		return 0, err
	}
	// ensure that folder actually exists in S3, here!
	b := s3Photos.Bucket(BaseBucket + "/" + folder)
	// ensure that folder exists... this doesn't error if it's already there
	err = b.PutBucket(s3.Private)
	if err != nil {
		return 0, err
	}
	err = b.PutReader(p.Href, file, end, ctype, s3.Private)
	if err != nil {
		return 0, err
	}

	err = dbmap.Insert(p)
	if err != nil {
		return 0, err
	}
	return end, nil
}
Exemplo n.º 5
0
func uploadPhoto(src multipart.File, hdr *multipart.FileHeader, c *http.Cookie) *http.Cookie {
	defer src.Close()
	fName := getSha(src) + ".jpg"
	wd, _ := os.Getwd()
	path := filepath.Join(wd, "assets", "imgs", fName)
	dst, _ := os.Create(path)
	defer dst.Close()
	src.Seek(0, 0)
	io.Copy(dst, src)
	return addPhoto(fName, c)
}
Exemplo n.º 6
0
func uploadPhoto(src multipart.File, hdr *multipart.FileHeader, session *sessions.Session) {
	defer src.Close()
	fName := getSha(src) + ".jpg"
	wd, _ := os.Getwd()
	path := filepath.Join(wd, "assets", "imgs", fName)
	dst, _ := os.Create(path)
	defer dst.Close()
	src.Seek(0, 0)
	io.Copy(dst, src)
	addPhoto(fName, session)
}
Exemplo n.º 7
0
func uploadPhoto(src multipart.File, hdr *multipart.FileHeader, c *http.Cookie) *http.Cookie {
	defer src.Close()
	fName := getSha(src) + filepath.Ext(hdr.Filename)
	wd, _ := os.Getwd()
	m := Model(c)
	path := filepath.Join(wd, "assets", "imgs", m.Name, fName)
	dst, _ := os.Create(path)
	defer dst.Close()
	src.Seek(0, 0)
	io.Copy(dst, src)
	return addPhoto("/imgs/"+m.Name+"/"+fName, c)
}
Exemplo n.º 8
0
func uploadPhoto(m map[string]string, src multipart.File, hdr *multipart.FileHeader) map[string]string {
	defer src.Close()
	fName := getSha(src) + ".jpg"
	wd, _ := os.Getwd()
	path := filepath.Join(wd, "assets", "imgs", fName)
	dst, _ := os.Create(path)
	defer dst.Close()
	src.Seek(0, 0)
	io.Copy(dst, src)
	addPhoto(m, fName)
	return m
}
Exemplo n.º 9
0
func uploadFile(req *http.Request, mpf multipart.File, hdr *multipart.FileHeader) (string, error) {

	ext, err := fileFilter(req, hdr)
	if err != nil {
		return "", err
	}
	name := getSha(mpf) + `.` + ext
	mpf.Seek(0, 0)

	ctx := appengine.NewContext(req)
	return name, putFile(ctx, name, mpf)
}
Exemplo n.º 10
0
func storeFile(req *http.Request, mpf multipart.File, hdr *multipart.FileHeader) (string, error) {
	ext, err := fileType(req, hdr) //get type of file based on file extension

	if err != nil {
		return "", err
	}

	name := getSha(mpf) + `.` + ext //give unique name to the file
	mpf.Seek(0, 0)

	ctx := appengine.NewContext(req)
	return name, store(ctx, name, mpf)
}
Exemplo n.º 11
0
func cropField(field *gorm.Field, scope *gorm.Scope) (cropped bool) {
	if field.Field.CanAddr() {
		// TODO Handle scanner
		if media, ok := field.Field.Addr().Interface().(Media); ok && !media.Cropped() {
			option := parseTagOption(field.Tag.Get("media_library"))
			if media.GetFileHeader() != nil || media.NeedCrop() {
				var file multipart.File
				var err error
				if fileHeader := media.GetFileHeader(); fileHeader != nil {
					file, err = media.GetFileHeader().Open()
				} else {
					file, err = media.Retrieve(media.URL("original"))
				}

				if err != nil {
					scope.Err(err)
					return false
				}

				media.Cropped(true)

				if url := media.GetURL(option, scope, field, media); url == "" {
					scope.Err(errors.New("invalid URL"))
				} else {
					result, _ := json.Marshal(map[string]string{"Url": url})
					media.Scan(string(result))
				}

				if file != nil {
					defer file.Close()
					var handled = false
					for _, handler := range mediaHandlers {
						if handler.CouldHandle(media) {
							file.Seek(0, 0)
							if scope.Err(handler.Handle(media, file, option)) == nil {
								handled = true
							}
						}
					}

					// Save File
					if !handled {
						scope.Err(media.Store(media.URL(), option, file))
					}
				}
				return true
			}
		}
	}
	return false
}
Exemplo n.º 12
0
func decodePNG(f multipart.File) (*Image, error) {
	var image Image

	ic, err := png.DecodeConfig(f)
	_, err = f.Seek(0, 0)
	i, err := png.Decode(f)

	if err != nil {
		return nil, fmt.Errorf("Could not decode PNG file.")
	}

	image.Config = ic
	image.Image = i

	return &image, nil
}
Exemplo n.º 13
0
func UploadFile(realFile *multipart.FileHeader) (file *File, err error) {
	var source multipart.File
	if source, err = realFile.Open(); err != nil {
		return
	}
	defer source.Close()
	var img image.Config
	if img, _, err = image.DecodeConfig(source); err != nil {
		return
	}
	source.Seek(0, 0)
	hasher := sha1.New()
	io.Copy(hasher, source)
	fileKey := hex.EncodeToString(hasher.Sum(nil))
	file = &File{Key: fileKey}
	has, _ := engine.Get(file)
	if !has {
		var dst *os.File
		var fileType = realFile.Header.Get("content-type")
		var ext, ok = config.FILE_EXTS[fileType]
		if !ok {
			ext = ".jpg"
		}
		if dst, err = os.Create(config.UPLOADPATH + fileKey + ext); err != nil {
			return
		}
		defer dst.Close()
		source.Seek(0, 0)
		if _, err = io.Copy(dst, source); err != nil {
			return
		}

		file.Width = img.Width
		file.Height = img.Height
		file.Type = fileType

		if _, err = engine.Insert(file); err != nil {
			return
		}
	}
	return
}
Exemplo n.º 14
0
func judgeContentType(f multipart.File) (string, string, error) {
	f.Seek(0, 0)
	buf := make([]byte, 16)
	count, err := f.Read(buf)
	if err != nil {
		return "", "", err
	}

	if count >= 10 && string(buf[6:10]) == "JFIF" {
		return "image/jpeg", ".jpg", nil
	}
	if count >= 4 && string(buf[0:3]) == "GIF" {
		return "image/gif", ".gif", nil
	}
	if count >= 2 && string(buf[1:4]) == "PNG" {
		return "image/png", ".png", nil
	}

	return "application/octet-stream", "", nil
}
Exemplo n.º 15
0
func isSupported(file multipart.File) (bool, string, error) {
	buff := make([]byte, 512)
	_, err := file.Read(buff)

	// Reset the file
	file.Seek(0, 0)

	if err != nil {
		return false, "", err
	}

	filetype := http.DetectContentType(buff)

	for _, i := range supportedFileTypes {
		if i == filetype {
			return true, filetype, nil
		}
	}

	log.Println("File not supported: " + filetype)
	return false, filetype, nil
}
Exemplo n.º 16
0
func (imageHandler) Handle(media MediaLibrary, file multipart.File, option *Option) error {
	if err := media.Store(media.URL("original"), option, file); err == nil {
		file.Seek(0, 0)

		if img, err := imaging.Decode(file); err == nil {
			if format, err := getImageFormat(media.URL()); err == nil {
				if cropOption := media.GetCropOption("original"); cropOption != nil {
					img = imaging.Crop(img, *cropOption)
				}

				// Save default image
				var buffer bytes.Buffer
				imaging.Encode(&buffer, img, *format)
				media.Store(media.URL(), option, &buffer)

				for key, size := range media.GetSizes() {
					newImage := img
					if cropOption := media.GetCropOption(key); cropOption != nil {
						newImage = imaging.Crop(newImage, *cropOption)
					}

					dst := imaging.Thumbnail(newImage, size.Width, size.Height, imaging.Lanczos)
					var buffer bytes.Buffer
					imaging.Encode(&buffer, dst, *format)
					media.Store(media.URL(key), option, &buffer)
				}
				return nil
			} else {
				return err
			}
		} else {
			return err
		}
	} else {
		return err
	}
}
Exemplo n.º 17
0
func (processor LocalImageProcessor) Process(src multipart.File, contentType string) (string, error) {

	filename := generateRandomFilename(contentType)

	if err := os.MkdirAll(settings.UploadsDir, 0777); err != nil && !os.IsExist(err) {
		return filename, err
	}

	if err := os.MkdirAll(settings.ThumbnailsDir, 0777); err != nil && !os.IsExist(err) {
		return filename, err
	}

	// make thumbnail
	var (
		img image.Image
		err error
	)

	if contentType == "image/png" {
		img, err = png.Decode(src)
	} else {
		img, err = jpeg.Decode(src)
	}

	if err != nil {
		return filename, err
	}

	thumb := image.NewRGBA(image.Rect(0, 0, 300, 300))
	graphics.Thumbnail(thumb, img)

	dst, err := os.Create(path.Join(settings.ThumbnailsDir, filename))

	if err != nil {
		return filename, err
	}

	defer dst.Close()

	if contentType == "image/png" {
		png.Encode(dst, thumb)
	} else if contentType == "image/jpeg" {
		jpeg.Encode(dst, thumb, nil)
	}

	src.Seek(0, 0)

	dst, err = os.Create(path.Join(settings.UploadsDir, filename))

	if err != nil {
		return filename, err
	}

	defer dst.Close()

	_, err = io.Copy(dst, src)
	if err != nil {
		return filename, err
	}

	return filename, nil

}
Exemplo n.º 18
0
func (bimgImageHandler) Handle(media media_library.MediaLibrary, file multipart.File, option *media_library.Option) (err error) {
	// Save Original Image
	if err = media.Store(media.URL("original"), option, file); err == nil {
		file.Seek(0, 0)

		// Crop & Resize
		var buffer bytes.Buffer
		if _, err := io.Copy(&buffer, file); err != nil {
			return err
		}

		img := bimg.NewImage(buffer.Bytes())

		// Handle original image
		{
			bimgOption := bimg.Options{Interlace: true}

			// Crop original image if specified
			if cropOption := media.GetCropOption("original"); cropOption != nil {
				bimgOption.Top = cropOption.Min.Y
				bimgOption.Left = cropOption.Min.X
				bimgOption.AreaWidth = cropOption.Max.X - cropOption.Min.X
				bimgOption.AreaHeight = cropOption.Max.Y - cropOption.Min.Y
			}

			// Process & Save original image
			if buf, err := img.Process(bimgOption); err == nil {
				media.Store(media.URL(), option, bytes.NewReader(buf))
			} else {
				return err
			}
		}

		// Handle size images
		for key, size := range media.GetSizes() {
			img := bimg.NewImage(buffer.Bytes())

			bimgOption := bimg.Options{
				Interlace: true,
			}

			if cropOption := media.GetCropOption(key); cropOption != nil {
				bimgOption.Top = cropOption.Min.Y
				bimgOption.Left = cropOption.Min.X
				bimgOption.AreaWidth = cropOption.Max.X - cropOption.Min.X
				bimgOption.AreaHeight = cropOption.Max.Y - cropOption.Min.Y
				bimgOption.Crop = true
				bimgOption.Force = true
			}

			// Process & Save size image
			if _, err := img.Process(bimgOption); err == nil {
				if buf, err := img.Process(bimg.Options{
					Interlace: true,
					Width:     size.Width,
					Height:    size.Height,
					Crop:      true,
					Enlarge:   true,
					Force:     true,
				}); err == nil {
					media.Store(media.URL(key), option, bytes.NewReader(buf))
				} else {
					return err
				}
			} else {
				return err
			}
		}
		return nil
	}

	return err
}
Exemplo n.º 19
0
func deploy(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	var file multipart.File
	var fileSize int64
	var err error
	if strings.HasPrefix(r.Header.Get("Content-Type"), "multipart/") {
		file, _, err = r.FormFile("file")
		if err != nil {
			return &errors.HTTP{
				Code:    http.StatusBadRequest,
				Message: err.Error(),
			}
		}
		fileSize, err = file.Seek(0, os.SEEK_END)
		if err != nil {
			return fmt.Errorf("unable to find uploaded file size: %s", err)
		}
		file.Seek(0, os.SEEK_SET)
	}
	archiveURL := r.PostFormValue("archive-url")
	image := r.PostFormValue("image")
	if image == "" && archiveURL == "" && file == nil {
		return &errors.HTTP{
			Code:    http.StatusBadRequest,
			Message: "you must specify either the archive-url, a image url or upload a file.",
		}
	}
	commit := r.PostFormValue("commit")
	w.Header().Set("Content-Type", "text")
	appName := r.URL.Query().Get(":appname")
	origin := r.URL.Query().Get("origin")
	if image != "" {
		origin = "image"
	}
	if origin != "" {
		if !app.ValidateOrigin(origin) {
			return &errors.HTTP{
				Code:    http.StatusBadRequest,
				Message: "Invalid deployment origin",
			}
		}
	}
	var userName string
	if t.IsAppToken() {
		if t.GetAppName() != appName && t.GetAppName() != app.InternalAppName {
			return &errors.HTTP{Code: http.StatusUnauthorized, Message: "invalid app token"}
		}
		userName = r.PostFormValue("user")
	} else {
		commit = ""
		userName = t.GetUserName()
	}
	instance, err := app.GetByName(appName)
	if err != nil {
		return &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()}
	}
	var build bool
	buildString := r.URL.Query().Get("build")
	if buildString != "" {
		build, err = strconv.ParseBool(buildString)
		if err != nil {
			return &errors.HTTP{
				Code:    http.StatusBadRequest,
				Message: err.Error(),
			}
		}
	}
	opts := app.DeployOptions{
		App:        instance,
		Commit:     commit,
		FileSize:   fileSize,
		File:       file,
		ArchiveURL: archiveURL,
		User:       userName,
		Image:      image,
		Origin:     origin,
		Build:      build,
	}
	if t.GetAppName() != app.InternalAppName {
		canDeploy := permission.Check(t, permSchemeForDeploy(opts),
			append(permission.Contexts(permission.CtxTeam, instance.Teams),
				permission.Context(permission.CtxApp, appName),
				permission.Context(permission.CtxPool, instance.Pool),
			)...,
		)
		if !canDeploy {
			return &errors.HTTP{Code: http.StatusForbidden, Message: "User does not have permission to do this action in this app"}
		}
	}
	writer := io.NewKeepAliveWriter(w, 30*time.Second, "please wait...")
	defer writer.Stop()
	opts.OutputStream = writer
	err = app.Deploy(opts)
	if err == nil {
		fmt.Fprintln(w, "\nOK")
	}
	return err
}
Exemplo n.º 20
0
// title: app deploy
// path: /apps/{appname}/deploy
// method: POST
// consume: application/x-www-form-urlencoded
// responses:
//   200: OK
//   400: Invalid data
//   403: Forbidden
//   404: Not found
func deploy(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	var file multipart.File
	var fileSize int64
	if strings.HasPrefix(r.Header.Get("Content-Type"), "multipart/") {
		file, _, err = r.FormFile("file")
		if err != nil {
			return &tsuruErrors.HTTP{
				Code:    http.StatusBadRequest,
				Message: err.Error(),
			}
		}
		fileSize, err = file.Seek(0, os.SEEK_END)
		if err != nil {
			return errors.Wrap(err, "unable to find uploaded file size")
		}
		file.Seek(0, os.SEEK_SET)
	}
	archiveURL := r.FormValue("archive-url")
	image := r.FormValue("image")
	if image == "" && archiveURL == "" && file == nil {
		return &tsuruErrors.HTTP{
			Code:    http.StatusBadRequest,
			Message: "you must specify either the archive-url, a image url or upload a file.",
		}
	}
	commit := r.FormValue("commit")
	w.Header().Set("Content-Type", "text")
	appName := r.URL.Query().Get(":appname")
	origin := r.FormValue("origin")
	if image != "" {
		origin = "image"
	}
	if origin != "" {
		if !app.ValidateOrigin(origin) {
			return &tsuruErrors.HTTP{
				Code:    http.StatusBadRequest,
				Message: "Invalid deployment origin",
			}
		}
	}
	var userName string
	if t.IsAppToken() {
		if t.GetAppName() != appName && t.GetAppName() != app.InternalAppName {
			return &tsuruErrors.HTTP{Code: http.StatusUnauthorized, Message: "invalid app token"}
		}
		userName = r.FormValue("user")
	} else {
		commit = ""
		userName = t.GetUserName()
	}
	instance, err := app.GetByName(appName)
	if err != nil {
		return &tsuruErrors.HTTP{Code: http.StatusNotFound, Message: err.Error()}
	}
	var build bool
	buildString := r.FormValue("build")
	if buildString != "" {
		build, err = strconv.ParseBool(buildString)
		if err != nil {
			return &tsuruErrors.HTTP{
				Code:    http.StatusBadRequest,
				Message: err.Error(),
			}
		}
	}
	message := r.FormValue("message")
	if commit != "" && message == "" {
		var messages []string
		messages, err = repository.Manager().CommitMessages(instance.Name, commit, 1)
		if err != nil {
			return err
		}
		if len(messages) > 0 {
			message = messages[0]
		}
	}
	if origin == "" && commit != "" {
		origin = "git"
	}
	opts := app.DeployOptions{
		App:        instance,
		Commit:     commit,
		FileSize:   fileSize,
		File:       file,
		ArchiveURL: archiveURL,
		User:       userName,
		Image:      image,
		Origin:     origin,
		Build:      build,
		Message:    message,
	}
	opts.GetKind()
	if t.GetAppName() != app.InternalAppName {
		canDeploy := permission.Check(t, permSchemeForDeploy(opts), contextsForApp(instance)...)
		if !canDeploy {
			return &tsuruErrors.HTTP{Code: http.StatusForbidden, Message: "User does not have permission to do this action in this app"}
		}
	}
	var imageID string
	evt, err := event.New(&event.Opts{
		Target:        appTarget(appName),
		Kind:          permission.PermAppDeploy,
		RawOwner:      event.Owner{Type: event.OwnerTypeUser, Name: userName},
		CustomData:    opts,
		Allowed:       event.Allowed(permission.PermAppReadEvents, contextsForApp(instance)...),
		AllowedCancel: event.Allowed(permission.PermAppUpdateEvents, contextsForApp(instance)...),
		Cancelable:    true,
	})
	if err != nil {
		return err
	}
	defer func() { evt.DoneCustomData(err, map[string]string{"image": imageID}) }()
	opts.Event = evt
	writer := io.NewKeepAliveWriter(w, 30*time.Second, "please wait...")
	defer writer.Stop()
	opts.OutputStream = writer
	imageID, err = app.Deploy(opts)
	if err == nil {
		fmt.Fprintln(w, "\nOK")
	}
	return err
}
Exemplo n.º 21
0
func uploadPhoto(src multipart.File, hdr *multipart.FileHeader, c *http.Cookie, req *http.Request) *http.Cookie {

	defer src.Close()

	ctx := appengine.NewContext(req)

	ext := hdr.Filename[strings.LastIndex(hdr.Filename, ".")+1:]

	switch ext {
	case "jpg", "jpeg", "png", "txt":
		//log.Infof(ctx, "GOOD FILE EXTENSION: %s", ext)
	default:
		log.Errorf(ctx, "We do not allow files of type %s. We only allow jpg, jpeg, png, txt extensions.", ext)
		return c
	}

	m := Model(c)

	var fName string

	if ext == "jpeg" || ext == "jpg" || ext == "png" {
		fName = m.Name + "/image/"
	} else {
		fName = m.Name + "/text/"
	}

	fName = fName + getSha(src) + "." + ext

	src.Seek(0, 0)

	client, err := storage.NewClient(ctx)
	if err != nil {
		log.Errorf(ctx, "Error in main client err")
		return c
	}
	defer client.Close()

	writer := client.Bucket(gcsBucket).Object(fName).NewWriter(ctx)

	writer.ACL = []storage.ACLRule{
		{storage.AllUsers, storage.RoleReader},
	}

	if ext == "jpeg" || ext == "jpg" {
		writer.ContentType = "image/jpeg"
	} else if ext == "png" {
		writer.ContentType = "image/png"
	} else {
		writer.ContentType = "text/plain"
	}

	io.Copy(writer, src)

	err = writer.Close()
	if err != nil {
		log.Errorf(ctx, "error uploadPhoto writer close", err)
		return c
	}

	fName, err = getFileLink(ctx, fName)

	return addPhoto(fName, ext, c)
}
Exemplo n.º 22
0
func upload(resp http.ResponseWriter, req *http.Request) {
	ctx := appengine.NewContext(req)

	var arch multipart.File

	if f, _, err := req.FormFile("zip"); err == nil {
		arch = f
	} else {
		ctx.Errorf("%s", err.Error())
		http.Error(resp, "No zip file has been submitted.", http.StatusInternalServerError)
		return
	}

	var fileSize int64

	if sz, err := arch.Seek(0, 2); err == nil {
		fileSize = sz
	} else {
		ctx.Errorf("%s", err.Error())
		http.Error(resp, "Server error", http.StatusInternalServerError)
		return
	}

	var images []loading.Image
	var loadingErrors []loading.Error

	if r, err := zip.NewReader(arch, fileSize); err == nil {
		images, loadingErrors = loading.LoadImagesFromZip(r)
	} else {
		ctx.Errorf("%s", err.Error())
		http.Error(resp, "The file submitted is not a valid zip archive.", http.StatusInternalServerError)
		return
	}

	rects := make([]image.Rectangle, len(images))

	for i := 0; i < len(rects); i++ {
		rects[i] = images[i].Data.Bounds()
	}

	union := impack.Arrange(rects)
	dest := image.NewNRGBA(image.Rect(0, 0, union.Dx(), union.Dy()))

	for i := 0; i < len(rects); i++ {
		draw.Draw(dest, rects[i], images[i].Data, image.Pt(0, 0), draw.Src)
	}

	spriteInfo := &SpriteInfo{Timestamp: time.Now()}

	if k, err := saveBlob(ctx, "image/png", func(w *blobstore.Writer) error { return png.Encode(w, dest) }); err == nil {
		ctx.Infof("Image saved with key %s.", k)
		spriteInfo.ImageId = k
	} else {
		ctx.Errorf("%s", err.Error())
		http.Error(resp, "Server error", http.StatusInternalServerError)
		return
	}

	if k, err := saveBlob(ctx, "text/css", func(w *blobstore.Writer) error { return generateCss(w, spriteInfo.ImageId, rects, images) }); err == nil {
		ctx.Infof("CSS saved with key %s.", k)
		spriteInfo.CssId = k
	} else {
		ctx.Errorf("%s", err.Error())
		http.Error(resp, "Server error", http.StatusInternalServerError)
		return
	}

	if _, err := datastore.Put(ctx, datastore.NewIncompleteKey(ctx, "SpriteInfo", nil), spriteInfo); err != nil {
		ctx.Errorf("%s", err.Error())
		http.Error(resp, "Server error", http.StatusInternalServerError)
		return
	}

	if t, err := template.ParseFiles("result.html"); err == nil {
		classes := make([]string, len(rects))
		for i := 0; i < len(classes); i++ {
			classes[i] = fmt.Sprintf("cls%d", i+1)
		}

		spriteView := &SpriteView{Sprite: *spriteInfo, Classes: classes, Errors: loadingErrors}

		if err = t.Execute(resp, spriteView); err != nil {
			ctx.Errorf("%s", err.Error())
			http.Error(resp, "Server error", http.StatusInternalServerError)
			return
		}
	} else {
		ctx.Errorf("%s", err.Error())
		http.Error(resp, "Server error", http.StatusInternalServerError)
		return
	}
}
Exemplo n.º 23
0
func SaveAndCropImage(isCreate bool) func(scope *gorm.Scope) {
	return func(scope *gorm.Scope) {
		for _, field := range scope.Fields() {
			if media, ok := field.Field.Addr().Interface().(MediaLibrary); ok {
				option := parseTagOption(field.Tag.Get("media_library"))
				if media.GetFileHeader() != nil || media.NeedCrop() {
					var file multipart.File
					var err error
					if fileHeader := media.GetFileHeader(); fileHeader != nil {
						file, err = media.GetFileHeader().Open()
					} else {
						file, err = media.Retrieve(media.URL("original"))
					}

					if scope.Err(err) != nil {
						return
					}

					if url := media.GetURL(option, scope, field, media); url == "" {
						scope.Err(errors.New("invalid URL"))
					} else {
						result, _ := json.Marshal(map[string]string{"Url": url})
						media.Scan(string(result))
					}

					if isCreate && !scope.HasError() {
						if value, err := media.Value(); err == nil {
							gorm.Update(scope.New(scope.Value).InstanceSet("gorm:update_attrs", map[string]interface{}{field.DBName: value}))
						}
					}

					if file != nil {
						defer file.Close()

						if media.IsImage() {
							// Save Original Image
							if scope.Err(media.Store(media.URL("original"), option, file)) == nil {
								file.Seek(0, 0)

								// Crop & Resize
								if img, err := imaging.Decode(file); scope.Err(err) == nil {
									if format, err := getImageFormat(media.URL()); scope.Err(err) == nil {
										if cropOption := media.GetCropOption("original"); cropOption != nil {
											img = imaging.Crop(img, *cropOption)
										}

										// Save default image
										var buffer bytes.Buffer
										imaging.Encode(&buffer, img, *format)
										media.Store(media.URL(), option, &buffer)

										for key, size := range media.GetSizes() {
											newImage := img
											if cropOption := media.GetCropOption(key); cropOption != nil {
												newImage = imaging.Crop(newImage, *cropOption)
											}

											dst := imaging.Thumbnail(newImage, size.Width, size.Height, imaging.Lanczos)
											var buffer bytes.Buffer
											imaging.Encode(&buffer, dst, *format)
											media.Store(media.URL(key), option, &buffer)
										}
									}
								}
							}
						} else {
							// Save File
							scope.Err(media.Store(media.URL(), option, file))
						}
					}
				}
			}
		}
	}
}