func Admin(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { if ctx.User == nil || !ctx.User.Admin { return perform_status(w, req, http.StatusForbidden) } photoCount, _ := ctx.C(P).Find(nil).Count() pp := NewPagination(photoCount, req.URL.Query()) photoSkip := pp.PerPage * (pp.Current - 1) var photos []*models.Photo if err := ctx.C(P).Find(nil).Skip(photoSkip).Limit(pp.PerPage).All(&photos); err != nil { models.Log("error getting photos: ", err.Error()) return err } userCount, _ := ctx.C(U).Find(nil).Count() up := NewPagination(userCount, req.URL.Query()) userSkip := up.PerPage * (up.Current - 1) var users []*models.User if err := ctx.C(U).Find(nil).Skip(userSkip).Limit(up.PerPage).All(&users); err != nil { models.Log("error getting users: ", err.Error()) return err } return T("admin.html").Execute(w, map[string]interface{}{ "ctx": ctx, "pp": pp, "photos": photos, "up": up, "users": users, }) }
func ResetPassword(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { // should not be logged in if ctx.User != nil { ctx.Session.AddFlash(models.F(models.SUCCESS, trans("Already logged in!", ctx))) http.Redirect(w, req, reverse("index"), http.StatusSeeOther) return nil } form := models.UserForm form.Fields = form.Fields[2:3] r := (&form).Load(req) ctx.Data["result"] = r if r.Err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem reseting password:"******"csrf_token") != ctx.Session.Values["csrf_token"] { return perform_status(w, req, http.StatusForbidden) } if len(r.Errors) != 0 { return ResetPasswordForm(w, req, ctx) } email := r.Values["email"] u := &models.User{} err := ctx.C(U).Find(bson.M{"email": email}).One(&u) if err == nil { pt := &models.PasswordToken{ Uuid: models.GenUUID(), User: u.Id, CreatedOn: time.Now(), } // set new password to database if err := ctx.C(PT).Insert(pt); err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem reseting password:"******"Subject: lov3ly.me password reset\r\n\r\nChange password link: http://%s\n\nIf you have NOT requested this, please ignore. Link available for 24 hours.\n\nHave fun,\nlov3ly.me Team", req.Host+reverse("change_token", "uuid", pt.Uuid)) go func() { err := models.SendEmail([]byte(body), email) if err != nil { models.Log("Error sending mail: ", err.Error()) } }() ctx.Session.AddFlash(models.F(models.SUCCESS, trans("Email sent succesfully!", ctx))) } else { ctx.Session.AddFlash(models.F(models.NOTICE, trans("Email not in our database:", ctx), err.Error())) } http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return nil }
func GlLogin(w http.ResponseWriter, req *http.Request, ctx *models.Context) (err error) { // Set up a configuration if auth_error := req.FormValue("error"); auth_error != "" { models.Log("Google login error: ", err.Error()) http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return nil } code := req.FormValue("code") if code == "" { return nil } config := GlConfig() // Set up a Transport with our config, define the cache t := &oauth.Transport{Config: config} if _, err := t.Exchange(code); err != nil { http.Redirect(w, req, reverse("login"), http.StatusSeeOther) models.Log("Google exchange: ", err.Error()) return err } // Make the request. r, err := t.Client().Get("https://www.googleapis.com/oauth2/v1/userinfo") if err != nil { models.Log("Google profile request: ", err.Error()) http.Redirect(w, req, reverse("login"), http.StatusSeeOther) } defer r.Body.Close() profile, err := ioutil.ReadAll(r.Body) if err != nil { models.Log("Google profile read error: ", err.Error()) http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return err } p := models.GoogleProfile{} err = json.Unmarshal(profile, &p) if err != nil { models.Log("Google unmarsahlling gl profile: ", err.Error()) http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return err } user, redirect, err := models.LoginWithGoogle(ctx, &p) //store the user id in the values and redirect to index ctx.Session.Values["user"] = user.Id http.Redirect(w, req, reverse(redirect), http.StatusSeeOther) return nil }
func ChangePasswordToken(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { go models.RemoveOldPasswordTokens() // should not be logged in if ctx.User != nil { ctx.Session.AddFlash(models.F(models.SUCCESS, trans("You can change password normally!", ctx))) http.Redirect(w, req, reverse("index"), http.StatusSeeOther) return nil } uuid := req.URL.Query().Get(":uuid") if uuid == "" { return perform_status(w, req, http.StatusForbidden) } pt := &models.PasswordToken{} if err := ctx.C(PT).FindId(uuid).One(&pt); err != nil { ctx.Session.AddFlash(models.F(models.SUCCESS, trans("Password token expired!", ctx))) http.Redirect(w, req, reverse("index"), http.StatusSeeOther) return nil } if req.FormValue("csrf_token") != ctx.Session.Values["csrf_token"] { return perform_status(w, req, http.StatusForbidden) } new_pass := req.FormValue("password1") if len(new_pass) < 5 { ctx.Session.AddFlash(models.F(models.ERROR, trans("Passwords too short (5 chars or more)", ctx))) return ChangePasswordForm(w, req, ctx) } vfy_pass := req.FormValue("password2") if new_pass != vfy_pass { ctx.Session.AddFlash(models.F(models.ERROR, trans("Password did not match", ctx))) return ChangePasswordForm(w, req, ctx) } hpass, err := models.EncryptPassword(new_pass) if err != nil { return internal_error(w, req, err.Error()) } // set new password to database if err := ctx.C(U).UpdateId(pt.User, bson.M{"$set": bson.M{"password": hpass}}); err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem changing password:"******"user"] = pt.User // delete password token if err := ctx.C(PT).RemoveId(pt.Uuid); err != nil { models.Log("error deleting password token: ", err.Error()) } ctx.Session.AddFlash(models.F(models.SUCCESS, trans("Password changed succesfully!", ctx))) http.Redirect(w, req, reverse("index"), http.StatusSeeOther) return nil }
func FbLogin(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { // Set up a configurgation if auth_error := req.FormValue("error"); auth_error != "" { models.Log("Facebook login error: ", auth_error) http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return nil } code := req.FormValue("code") if code == "" { return nil } config := FbConfig() // Set up a Transport with our config, define the cache t := &oauth.Transport{Config: config} if _, err := t.Exchange(code); err != nil { http.Redirect(w, req, reverse("login"), http.StatusSeeOther) models.Log("Facebook exchange: ", err.Error()) return err } // Make the request. r, err := t.Client().Get("https://graph.facebook.com/me") if err != nil { models.Log("Facebook profile request: ", err.Error()) http.Redirect(w, req, reverse("login"), http.StatusSeeOther) } defer r.Body.Close() profile, err := ioutil.ReadAll(r.Body) if err != nil { models.Log("Facebook profile read: ", err.Error()) http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return err } p := models.FacebookProfile{} err = json.Unmarshal(profile, &p) if err != nil { models.Log("Facebook unmarsahlling fb profile: ", err.Error()) http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return err } user, redirect, err := models.LoginWithFacebook(ctx, &p) //store the user id in the values and redirect to index ctx.Session.Values["user"] = user.Id http.Redirect(w, req, reverse(redirect), http.StatusSeeOther) return nil }
func Delete(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { if ctx.User == nil { http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return nil } if req.URL.Query().Get(":csrf_token") != ctx.Session.Values["csrf_token"] { return perform_status(w, req, http.StatusForbidden) } id := req.URL.Query().Get(":id") if !bson.IsObjectIdHex(id) { return perform_status(w, req, http.StatusForbidden) } if rc, _ := ctx.C(C).Find(bson.M{"registered.photo": bson.ObjectIdHex(id)}).Count(); rc != 0 { // the photo is registered in contests // only mark as deleted if err := ctx.C(P).UpdateId(bson.ObjectIdHex(id), bson.M{"$set": bson.M{"deleted": true, "active": false}}); err != nil { return perform_status(w, req, http.StatusNotFound) } // delete non contest votes // delete related votes if _, err := ctx.C(V).RemoveAll(bson.M{"photo": bson.ObjectIdHex(id), "contest": bson.M{"$exists": false}}); err != nil { models.Log("Error deleting votes on photo delete: ", err.Error()) } } else { // the photo is not registered in any contest if err := ctx.C(P).RemoveId(bson.ObjectIdHex(id)); err != nil { return perform_status(w, req, http.StatusNotFound) } // delete from disk err := os.Remove(path.Join(models.DATA_DIR, models.UPLOADS, fmt.Sprintf("%s.jpg", id))) if err != nil { models.Log("Error deleting image:", err.Error()) } err = os.Remove(path.Join(models.DATA_DIR, models.UPLOADS, fmt.Sprintf("%s_thumb.jpg", id))) if err != nil { models.Log("Error deleting image:", err.Error()) } // delete related votes if _, err := ctx.C(V).RemoveAll(bson.M{"photo": bson.ObjectIdHex(id)}); err != nil { models.Log("Error deleting votes on photo delete: ", err.Error()) } } http.Redirect(w, req, reverse("upload", "id", ""), http.StatusSeeOther) return nil }
func SendMessage(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { if ctx.User == nil { http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return nil } to := req.URL.Query().Get(":to") if !bson.IsObjectIdHex(to) { return perform_status(w, req, http.StatusForbidden) } if to == ctx.User.Id.Hex() { return perform_status(w, req, http.StatusForbidden) } m := models.Message{ Id: bson.NewObjectId(), From: ctx.User.Id, To: bson.ObjectIdHex(to), UserName: ctx.User.FullName(), Avatar: ctx.User.Avatar, Subject: req.FormValue("subject"), Body: req.FormValue("body"), } if err := ctx.C(M).Insert(m); err != nil { models.Log("Error sending message: ", err.Error()) } return nil }
func DelMessage(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { if ctx.User == nil { http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return nil } id := req.URL.Query().Get(":id") if !bson.IsObjectIdHex(id) { return perform_status(w, req, http.StatusForbidden) } if err := ctx.C(M).Remove(bson.M{"_id": bson.ObjectIdHex(id), "to": ctx.User.Id}); err != nil { models.Log("error removing message: ", err.Error()) return err } fmt.Fprint(w, "ok") return nil }
func ChangePassword(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { if ctx.User == nil { http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return nil } if req.FormValue("csrf_token") != ctx.Session.Values["csrf_token"] { return perform_status(w, req, http.StatusForbidden) } old_pass := req.FormValue("password") u := models.User{} if err := ctx.C(U).Find(bson.M{"email": ctx.User.Email}).One(&u); err != nil { return perform_status(w, req, http.StatusNotFound) } if len(u.Password) > 0 { // if the account was not created with social auth err := bcrypt.CompareHashAndPassword(u.Password, []byte(old_pass)) if err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Invalid Old Password", ctx))) return ChangePasswordForm(w, req, ctx) } } new_pass := req.FormValue("password1") if len(new_pass) < 5 { ctx.Session.AddFlash(models.F(models.ERROR, trans("Passwords too short (5 chars or more)", ctx))) return ChangePasswordForm(w, req, ctx) } vfy_pass := req.FormValue("password2") if new_pass != vfy_pass { ctx.Session.AddFlash(models.F(models.ERROR, trans("Password did not match", ctx))) return ChangePasswordForm(w, req, ctx) } hpass, err := models.EncryptPassword(new_pass) if err != nil { return internal_error(w, req, err.Error()) } // set new password to database if err := ctx.C(U).UpdateId(ctx.User.Id, bson.M{"$set": bson.M{"password": hpass}}); err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem changing password:"******"Password changed succesfully!", ctx))) http.Redirect(w, req, reverse("index"), http.StatusSeeOther) return nil }
func DelUser(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { if ctx.User == nil || !ctx.User.Admin { return perform_status(w, req, http.StatusForbidden) } id := req.URL.Query().Get(":id") if !bson.IsObjectIdHex(id) { return perform_status(w, req, http.StatusForbidden) } if err := ctx.C(U).RemoveId(bson.ObjectIdHex(id)); err != nil { models.Log("error deleting user: "******"Problem deleting user:"******"admin"), http.StatusSeeOther) return err } ctx.Session.AddFlash(models.F(models.SUCCESS, trans("User deleted!", ctx))) http.Redirect(w, req, reverse("admin"), http.StatusSeeOther) return nil }
func Contact(w http.ResponseWriter, req *http.Request, ctx *models.Context) (err error) { if req.FormValue("csrf_token") != ctx.Session.Values["csrf_token"] { return perform_status(w, req, http.StatusForbidden) } r := models.ContactForm.Load(req) if len(r.Errors) != 0 { ctx.Data["result"] = r return ContactForm(w, req, ctx) } body := fmt.Sprintf("Subject: lov3ly.me message\r\n\r\n %s\n%s\n\n%s", r.Values["name"], r.Values["email"], r.Values["message"]) go func() { err := models.SendEmail([]byte(body), "*****@*****.**") if err != nil { models.Log("Error sending mail: ", err.Error()) } }() ctx.Session.AddFlash(models.F(models.SUCCESS, "Message sent. Thank you!")) return ContactForm(w, req, ctx) }
func Profile(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { if ctx.User == nil { http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return nil } if req.FormValue("csrf_token") != ctx.Session.Values["csrf_token"] { return perform_status(w, req, http.StatusForbidden) } ctx.Data["title"] = "Profile" form := models.UserForm form.Fields = form.Fields[2:] // remove passwords r := (&form).Load(req) ctx.Data["result"] = r if len(r.Errors) != 0 { return ProfileForm(w, req, ctx) } u := r.Value.(map[string]interface{}) gender := u["gender"].(string) if gender != "m" && gender != "f" { r.Errors["gender"] = errors.New("Please select Male or Female") } now := time.Now() oldest := time.Date(now.Year()-120, 1, 1, 0, 0, 0, 0, time.UTC) bDate := u["birthdate"].(time.Time) if bDate.Before(oldest) || bDate.After(now) { r.Errors["birthdate"] = errors.New("Invalid birth date") } if r.Err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem editing profile:", ctx), r.Err.Error())) return ProfileForm(w, req, ctx) } if len(r.Errors) != 0 { return ProfileForm(w, req, ctx) } if err := ctx.C(U).UpdateId(ctx.User.Id, bson.M{"$set": u}); err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem editing profile:", ctx), err.Error())) models.Log(err.Error()) r.Err = err } ctx.Session.AddFlash(models.F(models.SUCCESS, trans("Profile updated succesfully!", ctx))) return ProfileForm(w, req, ctx) }
func Random(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { page := 1 page, err := strconv.Atoi(req.URL.Query().Get(":page")) if err != nil && page == 0 { page = 1 } skip := ITEMS_PER_PAGE * (page - 1) query := bson.M{"active": true} if f, ok := ctx.Session.Values["filter"]; ok { f.(*models.Filter).AddQuery(query) } //execute the query var photos []*models.Photo if err := ctx.C("photos").Find(query).Skip(skip).Limit(ITEMS_PER_PAGE).Sort("-_id").All(&photos); err != nil { return internal_error(w, req, err.Error()) } data := "" var layer bytes.Buffer for _, i := range rand.Perm(len(photos)) { p := photos[i] err := layerTemplate.Execute(&layer, map[string]interface{}{"p": p, "ctx": ctx}) if err != nil { models.Log("layer template: ", err.Error()) } data += fmt.Sprintf(`{"image":"%s","thumb":"%s","title":"%s","description":"%s","layer":"%s"},`, models.ImageUrl(p.Id.Hex(), ""), models.ImageUrl(p.Id.Hex(), "thumb"), p.Title, p.Description, strings.Replace(layer.String(), "\n", "", -1), ) layer.Reset() } data = strings.TrimRight(data, ",") w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, "["+data+"]") return nil }
func Vote(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { if ctx.User == nil { return perform_status(w, req, http.StatusForbidden) } if req.URL.Query().Get(":csrf_token") != ctx.Session.Values["csrf_token"] { return perform_status(w, req, http.StatusForbidden) } photoId := req.URL.Query().Get(":photo") if !bson.IsObjectIdHex(photoId) { return perform_status(w, req, http.StatusForbidden) } photo := models.Photo{} if err := ctx.C(P).FindId(bson.ObjectIdHex(photoId)).One(&photo); err != nil { return perform_status(w, req, http.StatusNotFound) } // check photo is own photo and return forbidden if c, _ := ctx.C(P).Find(bson.M{"_id": bson.ObjectIdHex(photoId), "user": ctx.User.Id}).Limit(1).Count(); c != 0 { return perform_status(w, req, http.StatusForbidden) } contestId := req.URL.Query().Get(":contest") var contest bson.ObjectId if contestId != "" && bson.IsObjectIdHex(contestId) { contest = bson.ObjectIdHex(contestId) // check contest is in voting period now := time.Now() query := ctx.C(C).Find(bson.M{ "_id": contest, "admissiondeadline": bson.M{"$lt": now}, "votingdeadline": bson.M{"$gt": now}, }).Limit(1) if count, err := query.Count(); count != 1 || err != nil { return perform_status(w, req, http.StatusForbidden) } } hearts, err := strconv.ParseFloat(req.FormValue("v"), 64) if err != nil || hearts < 1 || hearts > 5 { return perform_status(w, req, http.StatusForbidden) } v := &models.Vote{ Photo: photo.Id, PhotoUser: photo.User, Title: photo.Title, Description: photo.Description, Country: photo.Country, Location: photo.Location, Age: photo.Age, Gender: photo.Gender, Active: photo.Active, Contest: contest, Score: hearts, UpdatedOn: time.Now(), User: ctx.User.Id, } query := bson.M{"photo": v.Photo, "user": v.User} if contestId != "" { query["contest"] = contest } else { query["contest"] = bson.M{"$exists": false} } if _, err := ctx.C(V).Upsert(query, v); err != nil { models.Log("vote err: ", err.Error()) } return nil }
//internal_error is what is called when theres an error processing something func internal_error(w http.ResponseWriter, req *http.Request, err string) error { models.Log("!!!!error serving request page: ", err) return perform_status(w, req, http.StatusInternalServerError) }
func Register(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { if ctx.User != nil { http.Redirect(w, req, reverse("logout"), http.StatusSeeOther) return nil } if req.FormValue("csrf_token") != ctx.Session.Values["csrf_token"] { return perform_status(w, req, http.StatusForbidden) } ctx.Data["title"] = "Register" r := (&models.UserForm).Load(req) ctx.Data["result"] = r if len(r.Errors) != 0 { return RegisterForm(w, req, ctx) } u := r.Value.(map[string]interface{}) password1 := u["password1"].(string) if len(password1) < 5 { r.Errors["password1"] = errors.New("Passwords too short (5 chars or more)") } password2 := u["password2"].(string) if password2 != password1 { r.Errors["password2"] = errors.New("Passwords do not match") } gender := u["gender"].(string) if gender != "m" && gender != "f" { r.Errors["gender"] = errors.New("Please select Male or Female") } now := time.Now() oldest := time.Date(now.Year()-120, 1, 1, 0, 0, 0, 0, time.UTC) bDate := u["birthdate"].(time.Time) if bDate.Before(oldest) || bDate.After(now) { r.Errors["birthdate"] = errors.New("Invalid birth date") } if len(r.Errors) != 0 { return RegisterForm(w, req, ctx) } if r.Err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem registering user:"******"captchaId"), req.FormValue("captchaSolution")) { ctx.Session.AddFlash(models.F(models.ERROR, trans("The control numbers do not match!", ctx))) return RegisterForm(w, req, ctx) } pass, err := models.EncryptPassword(u["password1"].(string)) if err != nil { return internal_error(w, req, err.Error()) // bcrypt errors on invalid costs } u["password"] = pass delete(u, "password1") delete(u, "password2") u["_id"] = bson.NewObjectId() u["avatar"] = gravatar.UrlSize(u["email"].(string), 80) if err := ctx.C("users").Insert(u); err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem registering user:"******"user"] = u["_id"] ctx.Session.AddFlash(models.F(models.SUCCESS, trans("Welcome to lov3ly.me!", ctx))) http.Redirect(w, req, reverse("index"), http.StatusSeeOther) return nil }
func Upload(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { if ctx.User == nil { http.Redirect(w, req, reverse("login"), http.StatusSeeOther) return nil } form := models.UploadForm r := (&form).Load(req) ctx.Data["result"] = r if len(r.Errors) != 0 { return UploadForm(w, req, ctx) } p := r.Value.(map[string]interface{}) rand, err := crand.Int(crand.Reader, big.NewInt(1000000)) if err != nil { models.Log("error generating random number:", err.Error()) } photo := &models.Photo{ Title: p["title"].(string), Description: p["description"].(string), Country: p["country"].(string), Location: p["location"].(string), Age: p["age"].(int), Gender: p["gender"].(string), Active: p["active"].(bool), Deleted: false, User: ctx.User.Id, UpdatedOn: time.Now(), Rand: rand.Int64(), } var objectToBeUpdated interface{} var nid bson.ObjectId id := "" if id = req.URL.Query().Get(":id"); bson.IsObjectIdHex(id) { //edit mode nid = bson.ObjectIdHex(id) if nid != ctx.User.Id { // doesn't belong to the registered user return perform_status(w, req, http.StatusForbidden) } objectToBeUpdated = p // update previous votes if _, err := ctx.C(V).UpdateAll(bson.M{"photo": nid}, bson.M{"$set": bson.M{ "title": photo.Title, "description": photo.Description, "country": photo.Country, "location": photo.Location, "age": photo.Age, "gender": photo.Gender, "active": photo.Active, }}); err != nil { models.Log("Error updating votes on photo edit: ", err.Error()) } } else { // upload mode objectToBeUpdated = photo x1, _ := strconv.Atoi(req.FormValue("x1")) y1, _ := strconv.Atoi(req.FormValue("y1")) x2, _ := strconv.Atoi(req.FormValue("x2")) y2, _ := strconv.Atoi(req.FormValue("y2")) ff, _, err := req.FormFile("photo") if err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem uploading photo:", ctx), err.Error())) models.Log(err.Error()) return UploadForm(w, req, ctx) } defer ff.Close() // decode jpeg into image.Image img, err := jpeg.Decode(ff) if err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem uploading photo:", ctx), err.Error())) models.Log(err.Error()) r.Err = err return UploadForm(w, req, ctx) } photo.Id = bson.NewObjectId() nid = photo.Id if err := photo.SaveImage(img, x1, y1, x2, y2); err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem uploading photo:", ctx), err.Error())) models.Log(err.Error()) r.Err = err return UploadForm(w, req, ctx) } } photo.Id = "" if _, err := ctx.C(P).UpsertId(nid, bson.M{"$set": objectToBeUpdated}); err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem editing photo:", ctx), err.Error())) models.Log(err.Error()) r.Err = err return UploadForm(w, req, ctx) } ctx.Session.AddFlash(models.F(models.SUCCESS, trans("Photo updated succesfully!", ctx))) http.Redirect(w, req, reverse("upload", "id", id), http.StatusSeeOther) return nil }
func TopVoted(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { page := 1 page, err := strconv.Atoi(req.URL.Query().Get(":page")) if err != nil && page == 0 { page = 1 } skip := ITEMS_PER_PAGE * (page - 1) match := bson.M{"active": true} if f, ok := ctx.Session.Values["filter"]; ok { f.(*models.Filter).AddQuery(match) } var results models.WilsonSorter pipe := ctx.C(V).Pipe([]bson.M{ {"$match": match}, {"$group": bson.M{ "_id": "$photo", "scores": bson.M{"$push": "$score"}, "title": bson.M{"$addToSet": "$title"}, "description": bson.M{"$addToSet": "$description"}, "user": bson.M{"$addToSet": "$photouser"}, }}, {"$skip": skip}, {"$limit": ITEMS_PER_PAGE}, {"$unwind": "$user"}, {"$unwind": "$title"}, {"$unwind": "$description"}, }) pipe.All(&results) // calculate wilson rating http://www.goproblems.com/test/wilson/wilson-new.php vc := make([]int, 5) for _, r := range results { scores := r["scores"].([]interface{}) for _, s := range scores { index := int(s.(float64) - 1) vc[index] += 1 } sum := 0.0 for i, c := range vc { w := float64(i) / 4.0 sum += float64(c) * w } r["wilson"] = models.Wilson(len(scores), sum) vc[0], vc[1], vc[2], vc[3], vc[4] = 0, 0, 0, 0, 0 } sort.Sort(results) data := "" var layer bytes.Buffer for _, r := range results { p := &models.Photo{ Id: r["_id"].(bson.ObjectId), User: r["user"].(bson.ObjectId), Title: r["title"].(string), Description: r["description"].(string), } err := layerTemplate.Execute(&layer, map[string]interface{}{"p": p, "ctx": ctx}) if err != nil { models.Log("layer template: ", err.Error()) } data += fmt.Sprintf(`{"image":"%s","thumb":"%s","title":"%s","description":"%s", "layer":"%s"},`, models.ImageUrl(p.Id.Hex(), ""), models.ImageUrl(p.Id.Hex(), "thumb"), p.Title, p.Description, strings.Replace(layer.String(), "\n", "", -1), ) layer.Reset() } data = strings.TrimRight(data, ",") w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, "["+data+"]") return nil }