Example #1
0
func MakeLoader(config *Configuration) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		id := r.URL.Query().Get(config.IdentifierName)
		if id == "" {
			http.NotFound(w, r)
			return
		}
		thumbName := r.URL.Query().Get(config.ThumbnailParamName)
		if thumbName == "" {
			http.NotFound(w, r)
			return
		}

		var spec *ThumbnailSpec
		for _, ts := range config.ThumbnailSpecs {
			if ts.Name == thumbName {
				spec = ts
				break
			}
		}

		if spec == nil {
			log.Println("tenpu/thumbnails: Can't find thumbnail spec %+v in %+v", thumbName, config.ThumbnailSpecs)
			http.NotFound(w, r)
			return
		}

		var att *tenpu.Attachment
		config.Storage.Database().FindOne(tenpu.CollectionName, bson.M{"_id": id}, &att)
		if att == nil {
			http.NotFound(w, r)
			return
		}

		var thumb *Thumbnail
		config.Storage.Find(CollectionName, bson.M{"parentid": id, "name": thumbName}, &thumb)

		if thumb == nil {
			var buf bytes.Buffer
			config.Storage.Copy(att, &buf)
			thumbAtt := &tenpu.Attachment{}

			body, width, height, err := resizeThumbnail(&buf, spec)

			if err != nil {
				log.Printf("tenpu/thumbnails: %+v", err)
				http.NotFound(w, r)
				return
			}

			config.Storage.Put(att.Filename, att.ContentType, body, thumbAtt)

			config.Storage.Database().Save(tenpu.CollectionName, thumbAtt)

			thumb = &Thumbnail{
				Name:     thumbName,
				ParentId: id,
				BodyId:   thumbAtt.Id,
				Width:    int64(width),
				Height:   int64(height),
			}
			config.Storage.Database().Save(CollectionName, thumb)
		}

		dbc := tenpu.DatabaseClient{Database: config.Storage.Database()}
		thumbAttachment := dbc.AttachmentById(thumb.BodyId)
		if thumbAttachment == nil {
			log.Printf("tenpu/thumbnails: Can't find body attachment by %+v", thumb)
			http.NotFound(w, r)
			return
		}

		w.Header().Set("Content-Type", thumbAttachment.ContentType)
		w.Header().Set("Content-Length", fmt.Sprintf("%d", thumbAttachment.ContentLength))

		err := config.Storage.Copy(thumbAttachment, w)

		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		return
	}
}