Пример #1
0
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,
	})
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
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
}
Пример #8
0
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
}
Пример #9
0
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
}
Пример #10
0
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
}
Пример #11
0
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)
}
Пример #12
0
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)
}
Пример #13
0
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
}
Пример #14
0
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
}
Пример #15
0
//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)
}
Пример #16
0
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
}
Пример #17
0
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
}
Пример #18
0
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
}