GAEImageServer

package module
v0.0.0-...-e04b689 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2015 License: Unlicense Imports: 20 Imported by: 0

README

GAE-Image-Server

Use GAE Blobstore to host your images. Upload image and profiles (Quality/Size). Serve Image for a given profile (resize on the fly). Note that Quality indicator does not apply in case of png image. In that case the png format is used for storage to keep transparency. In other cases, file will be saved as jpeg.

The application is written in GO and should be deployed to GAE. As the blostore requires a callback url, to ease local testing, you will find a Dockerfile that will allow you to run locally an AppEngine instance configured for the project. It can also be used to deploy the application.

Prerequisit, is to build the dbenque/goappengine base image. To do so:

go get github.com/dbenque/goAppengineToolkit

Enter the docker folder and:

dbenque/goappengine

Then build your image, go to the docker folder and type

docker build --no-cache -t "gaeimageserver" .

Once the image is built, you can test it locally:

docker run -p 127.0.0.1:8080:8080 -p 127.0.0.1:8000:8000 -p 127.0.0.1:9000:9000 gaeimageserver

If you want to deploy the project on your AppEngine instance, create an application app_id='YOURPROJECTNAME' under the appengine console ( https://appengine.google.com/ ) and then:

docker run -t -i gaeimageserver /bin/bash

Modify the name of the project in app.yaml:

sed -i 's/gae-image-server/YOURPROJECTNAME/' /home/GAE-Image-Server/app.yaml

Deploy to AppEngine:

goapp deploy /home/GAE-Image-Server/

The dependencies are (included in the built docker image):

https://github.com/gorilla/mux

https://github.com/gorilla/context

Upload

To get the "url action" to put in the upload form:

http://{img_baseURL}/action | GET

Example of form to be used in the upload page:

http://{baseURL}/exampleForm | GET

Of course the form will have to post the file to be uploaded, but note also the 2 important fields that help to index the image and continue the flow:

<input type="text" name="entityId" value="myId">
<input type="text" name="callbackurl" value="http://0.0.0.0:8080/callbacktest">

Once the form is posted to the blobstore action, the file will be stored, and the callbackurl will be invoked with the updated form. All the input parameters of the initial form will be transfered.

Image Profiles

Retrieve the list of existing profiles:

http://{baseURL}/imgProfiles | GET

This returns a JSON flat list containing the list of profile names:

[
"original",      // This profil is created by default, and  is associated by default to any uploaded image (+resize if needed)
"small"
]

Retrieve a specific profile:

http://{baseURL}/imgProfile/{profileName} | GET

Delete a specific profile:

http://{baseURL}/imgProfile/{profileName} | DELETE

This removes all the files associated to the profile.

Create or update a specific profile:

http://{baseURL}/imgProfile | POST | JSON {
        "name" : "small",
        "quality" : 50,
        "maxSize" : 100
}

Note that to update a profile you need to post a JSON with the name associated to the profile to update. So far a modification of the profile does dot trig a resizing/recomputation of the images associated to the profile. To force the resizing/recomputation, you need to delete the profile. This will remove (asynchronously) all the images associated to the profile. The each image will be recomputed for the new profile when being queried for the first time.

Images

Retrieve an image associated to an entityId for a given profile:

http://{baseURL}/image/{entityId}/{profileName} | GET

If the image does not exist for the requested profile, it will be computed on the fly, provided an original image is associated to the entityId

Delete an image for a given profile:

http://{baseURL}/image/{entityId}/{profileName} | DELETE

Delete all the images (all profiles) associated to an entityId:

http://{baseURL}/image/{entityId} | DELETE

Note that this kind of deletion is done asynchronously using task queues. This means that the image can still be accessible for a short period.

Documentation

Overview

************************************************************** * * GAE Go automatic blob image optimizer * * Created by Tomi Hiltunen 2013. * http://www.linkedin.com/in/tomihiltunen * * https://github.com/TomiHiltunen/GAE-Go-image-optimizer * * - Use this script however you wish. * - Do not remove any copyrights/comments on any files included. * - All use is on your own risk. * * Intented use: * - Drop-in replacement for GAE's blobstore.ParseUploads(...) * - Automatically optimized any images uploaded * to Google App Engine blobstore. * - Reduces data amount in the blobstore. * - Reduces download times. * * * Modified by David Benque in order to keep png format for transparency * * **************************************************************

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CreateTasksToDeleteImages

func CreateTasksToDeleteImages(context appengine.Context, q *datastore.Query, baseurl string) error

func NewCompressionOptions

func NewCompressionOptions(r *http.Request) *compressionOptions

* Create new set of options. * * - Sets Quality to 75 as default. 75 is highly compressed but not visually noticable. * - Sets Size to 0 which means that no changes to images dimensions will be made. * - Creates new App Engine context.

func ParseBlobs

func ParseBlobs(options *compressionOptions) (blobs map[string][]*blobstore.BlobInfo, other url.Values, err error)

* This one does the magic. * * - Gets the uploaded blobs by calling blobstore.ParseUpload() * - Maintains all other values that come from blobstore. * - Hands out the results for further processing.

func Resample

func Resample(m image.Image, r image.Rectangle, w, h int) image.Image

Resample returns a resampled copy of the image slice r of m. The returned image has width w and height h.

func Resize

func Resize(m image.Image, r image.Rectangle, w, h int) image.Image

Resize returns a scaled copy of the image slice r of m. The returned image has width w and height h.

Types

type ImageInGAE

type ImageInGAE struct {
	EntityId     string `json:"entityId"`
	ProfileName  string `json:"profileName"`
	BlobstoreKey string `json:"blobstoreKey" datastore:",noindex"`
}

func (*ImageInGAE) GetKey

func (p *ImageInGAE) GetKey() string

func (*ImageInGAE) GetKind

func (p *ImageInGAE) GetKind() string

type ImgProfile

type ImgProfile struct {
	Name    string `json:"name"`
	Quality int    `json:"quality" datastore:",noindex"`
	MaxSize int    `json:"maxSize" datastore:",noindex"`
}

func (*ImgProfile) GetKey

func (p *ImgProfile) GetKey() string

func (*ImgProfile) GetKind

func (p *ImgProfile) GetKind() string

type ImgProfileNameSet

type ImgProfileNameSet struct {
	Index sort.StringSlice `json:"index"` // Index of profiles

}

func GetImgProfileNameSet

func GetImgProfileNameSet(context appengine.Context) ImgProfileNameSet

retrieve the index of profiles (initialize the key if nil)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL