Created
November 4, 2013 10:28
-
-
Save veer66/7300745 to your computer and use it in GitHub Desktop.
Photo web server in Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"github.com/hoisie/web" | |
"github.com/mattn/go-session-manager" | |
"log" | |
"os" | |
"labix.org/v2/mgo" | |
"labix.org/v2/mgo/bson" | |
"io" | |
"crypto/rand" | |
"encoding/hex" | |
"github.com/nfnt/resize" | |
"image/jpeg" | |
//"flag" | |
) | |
type AlbumForAdding struct { | |
Name string | |
Deleted bool | |
} | |
type AlbumForListing struct { | |
Id bson.ObjectId "_id" | |
Name string | |
Deleted bool | |
} | |
type Photo struct { | |
Path string | |
Description string | |
} | |
type Album struct { | |
Id bson.ObjectId "_id" | |
Name string | |
Photos []Photo | |
Deleted bool | |
} | |
type PhotoInfo struct { | |
Path string; | |
Type string; | |
} | |
type Bangbut struct { | |
DbSession *mgo.Session | |
PhotoDb *mgo.Database | |
logger *log.Logger | |
manager *session.SessionManager | |
} | |
func (app *Bangbut) getSession(ctx *web.Context) *session.Session { | |
id, _ := ctx.GetSecureCookie("SessionId") | |
app.logger.Printf("SESS ID = %v\n", id); | |
session := app.manager.GetSessionById(id) | |
app.logger.Println(session.Value) | |
ctx.SetSecureCookie("SessionId", session.Id, int64(app.manager.GetTimeout())) | |
ctx.SetHeader("Pragma", "no-cache", true) | |
return session | |
} | |
func (app *Bangbut) initDb () { | |
var err error | |
app.DbSession, err = mgo.Dial("localhost") | |
if err != nil { | |
panic(err) | |
} | |
app.DbSession.SetMode(mgo.Monotonic, true) | |
app.PhotoDb = app.DbSession.DB("photodb") | |
} | |
func (app *Bangbut) initSession () { | |
app.logger = log.New(os.Stdout, "", log.Ldate|log.Ltime) | |
app.manager = session.NewSessionManager(app.logger) | |
app.manager.OnStart(func(session *session.Session) { | |
app.logger.Printf("Start session(\"%s\")", session.Id) | |
}) | |
app.manager.OnEnd(func(session *session.Session) { | |
app.logger.Printf("End session(\"%s\")", session.Id) | |
}) | |
app.manager.SetTimeout(100000) | |
} | |
func (app *Bangbut) private (ctx *web.Context) { | |
session := app.getSession(ctx) | |
if session.Value != nil { | |
ctx.WriteString("DONE") | |
} else { | |
ctx.Abort(401, "Permission deny") | |
} | |
} | |
func (app *Bangbut) albums (ctx *web.Context) { | |
session := app.getSession(ctx) | |
app.logger.Println(session.Value) | |
i := app.PhotoDb.C("album").Find(bson.M{"deleted": false}).Iter() | |
var album_names []AlbumForListing | |
err := i.All(&album_names) | |
if err != nil { | |
ctx.Abort(500, "Internal server error") | |
} else { | |
album_json, err := json.Marshal(album_names) | |
if err != nil { | |
ctx.Abort(500, "Internal server error") | |
} else { | |
ctx.ContentType("application/json") | |
ctx.ResponseWriter.Write(album_json) | |
} | |
} | |
} | |
func (app *Bangbut) album (ctx *web.Context) { | |
session := app.getSession(ctx) | |
app.logger.Println(session.Value) | |
_id := ctx.Params["id"] | |
i := app.PhotoDb.C("album").Find(bson.M{"_id": bson.ObjectIdHex(_id)}).Iter() | |
var album Album | |
if i.Next(&album) { | |
album_json, err := json.Marshal(album) | |
if err != nil { | |
ctx.Abort(500, "Internal server error") | |
} else { | |
ctx.ContentType("application/json") | |
ctx.ResponseWriter.Write(album_json) | |
} | |
} else { | |
ctx.Abort(404, "Album not found") | |
} | |
} | |
func (app *Bangbut) login (ctx *web.Context) { | |
session := app.getSession(ctx) | |
app.logger.Println(session.Value) | |
ctx.Request.ParseForm() | |
username := ctx.Params["username"] | |
password := ctx.Params["password"] | |
if Auth(app.PhotoDb, username, password) { | |
session.Value = username | |
ctx.WriteString("Login") | |
} else { | |
ctx.Abort(401, "Permission deny") | |
} | |
} | |
func (app *Bangbut) add_album (ctx *web.Context) { | |
session := app.getSession(ctx) | |
app.logger.Println(session.Value) | |
if session.Value == nil { | |
ctx.Abort(401, "Permission deny") | |
return | |
} | |
album := AlbumForAdding{"New album", false} | |
err := app.PhotoDb.C("album").Insert(album) | |
if err != nil { | |
app.logger.Println(fmt.Sprintf("%v", err)) | |
ctx.Abort(500, "Internal server error") | |
} else { | |
ctx.WriteString("DONE") | |
} | |
} | |
func (app *Bangbut) save_album (ctx *web.Context) { | |
session := app.getSession(ctx) | |
if session.Value == nil { | |
ctx.Abort(401, "Permission deny") | |
return | |
} | |
raw_album := ctx.Params["album"] | |
app.logger.Println("json = ", raw_album) | |
var album Album; | |
jsonErr := json.Unmarshal([]byte(raw_album), &album) | |
if jsonErr != nil { | |
app.logger.Println("Cannot convert JSON: ", jsonErr) | |
ctx.Abort(500, "Internal server error") | |
return | |
} | |
err := app.PhotoDb.C("album").UpdateId(album.Id, album) | |
if err != nil { | |
app.logger.Println("Cannot update") | |
ctx.Abort(500, "Internal server error") | |
return | |
} | |
ctx.WriteString("DONE") | |
} | |
func (app *Bangbut) delete_album (ctx *web.Context) { | |
session := app.getSession(ctx) | |
if session.Value == nil { | |
ctx.Abort(401, "Permission deny") | |
return | |
} | |
_id := ctx.Params["id"] | |
err := app.PhotoDb.C("album").Update(bson.M{"_id": bson.ObjectIdHex(_id)}, | |
bson.M{"$set": bson.M{"deleted": true}}) | |
if err == nil { | |
ctx.WriteString("DONE") | |
} else { | |
ctx.Abort(500, "Internal server error") | |
} | |
} | |
func resizeImage(filename string) error { | |
file, err := os.Open("static/photos/" + filename) | |
if err != nil { | |
return err | |
} | |
img, err := jpeg.Decode(file) | |
if err != nil { | |
return err | |
} | |
file.Close() | |
m := resize.Resize(300, 0, img, resize.Lanczos3) | |
out, err := os.Create("static/s/" + filename) | |
if err != nil { | |
return err | |
} | |
defer out.Close() | |
jpeg.Encode(out, m, nil) | |
return nil | |
} | |
func (app *Bangbut) upload (ctx *web.Context) { | |
session := app.getSession(ctx) | |
if session.Value == nil { | |
ctx.Abort(401, "Permission deny") | |
return | |
} | |
ctx.Request.ParseMultipartForm(10 * 1024 * 1024) | |
form := ctx.Request.MultipartForm | |
photoInfo := PhotoInfo{} | |
fileHeader := form.File["file"][0] | |
photoInfo.Type = fileHeader.Header["Content-Type"][0] | |
_, err := fileHeader.Open() | |
if err != nil { | |
app.logger.Println("Cannon open uploaded file"); | |
ctx.Abort(500, "Internal server error") | |
return | |
} | |
buf := make([]byte, 32) | |
rand.Read(buf) | |
/* FIXME check type */ | |
newFilename := hex.EncodeToString(buf) + ".jpg" | |
newFile, fileErr := os.Create("static/photos/" + newFilename) | |
if fileErr != nil { | |
app.logger.Println("Cannot open target file") | |
ctx.Abort(500, "Internal server error") | |
return | |
} | |
defer newFile.Close() | |
uploadedFile, uploadedFileErr := fileHeader.Open() | |
if uploadedFileErr != nil { | |
app.logger.Println("Cannot open uploaded file") | |
ctx.Abort(500, "Internal server error") | |
return | |
} | |
go func(file io.Reader, filename string) { | |
newFile, _ := os.Create("static/s/" + filename) | |
io.Copy(newFile, file) | |
newFile.Close() | |
}(uploadedFile, newFilename) | |
defer uploadedFile.Close() | |
photoInfo.Path = "/photos/" + newFilename | |
io.Copy(newFile, uploadedFile) | |
photoInfoJson, jsonErr := json.Marshal(photoInfo) | |
if jsonErr != nil { | |
ctx.Abort(500, "Internal server error") | |
return | |
} | |
ctx.ContentType("application/json") | |
ctx.ResponseWriter.Write(photoInfoJson) | |
} | |
func (app *Bangbut) logout (ctx *web.Context) { | |
session := app.getSession(ctx) | |
app.logger.Println(session.Value) | |
session.Abandon() | |
ctx.WriteString("* Logout"); | |
} | |
func main() { | |
web.Config.CookieSecret = "SECRET" // Please change this | |
app := Bangbut{} | |
app.initDb() | |
app.initSession() | |
web.Post("/upload", app.upload) | |
web.Get("/private", app.private) | |
web.Get("/albums", app.albums) | |
web.Get("/album", app.album) | |
web.Get("/add_album", app.add_album) | |
web.Post("/save_album", app.save_album) | |
web.Get("/delete_album", app.delete_album) | |
web.Post("/login", app.login) | |
web.Get("/logout", app.logout) | |
web.Run("0.0.0.0:80") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment