示例#1
0
func Photos(w http.ResponseWriter, req *http.Request, ctx *models.Context) error {
	id := req.URL.Query().Get(":id")
	if !bson.IsObjectIdHex(id) {
		return perform_status(w, req, http.StatusNotFound)
	}
	var photos []*models.Photo
	if err := ctx.C(P).Find(bson.M{"user": bson.ObjectIdHex(id), "active": true}).All(&photos); err != nil {
		return perform_status(w, req, http.StatusNotFound)
	}
	user := new(models.User)
	if err := ctx.C("users").FindId(bson.ObjectIdHex(id)).One(user); err != nil {
		return perform_status(w, req, http.StatusNotFound)
	}
	// find the index of the photo
	photoId := req.URL.Query().Get(":photo")
	ctx.Data["index"] = 0
	var pIds []bson.ObjectId
	for i, p := range photos {
		if p.Id.Hex() == photoId {
			ctx.Data["index"] = i
		}
		pIds = append(pIds, p.Id)
	}

	return AJAX("galleria.html").Execute(w, map[string]interface{}{
		"photos": photos,
		"user":   user,
		"hash":   models.GenUUID(),
		"ctx":    ctx,
	})
}
示例#2
0
func report(w http.ResponseWriter, req *http.Request, ctx *models.Context, repType string) 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)
	}
	query := bson.M{"_id": bson.ObjectIdHex(photoId), "active": true, repType + "reporters": bson.M{"$ne": ctx.User.Id}}
	update := bson.M{
		"$push": bson.M{repType + "reporters": ctx.User.Id},
		"$inc":  bson.M{repType + "count": 1},
	}
	if err := ctx.C(P).Update(query, update); err != nil {
		// toggle report
		// This query succeeds when the voter has already voted on the story.
		//query   = {_id: ObjectId("4bcc9e697e020f2d44471d27"), voters: user_id};

		// Update to remove the user from the array and decrement the number of votes.
		//update  = {'$pull': {'voters': user_id}, '$inc': {vote_count: -1}}

		//db.stories.update(query, update);
	}
	return nil
}
示例#3
0
func CommentForm(w http.ResponseWriter, req *http.Request, ctx *models.Context) error {
	//set up the collection and query
	id := req.URL.Query().Get(":id")
	kind := req.URL.Query().Get(":kind")
	if !bson.IsObjectIdHex(id) {
		return perform_status(w, req, http.StatusForbidden)
	}
	var object models.Commenter
	switch kind {
	case "p":
		query := ctx.C(P).FindId(bson.ObjectIdHex(id))

		//execute the query
		photo := &models.Photo{}
		if err := query.One(&photo); err != nil {
			return perform_status(w, req, http.StatusNotFound)
		}
		object = photo
	case "c":
		query := ctx.C(C).FindId(bson.ObjectIdHex(id))
		//execute the query
		contest := &models.Contest{}
		if err := query.One(&contest); err != nil {
			return perform_status(w, req, http.StatusNotFound)
		}
		object = contest
	}

	//execute the template
	return AJAX("comments.html").Execute(w, map[string]interface{}{
		"object": object,
		"kind":   kind,
		"ctx":    ctx,
	})
}
示例#4
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
}
示例#5
0
func GetPhotoVotes(w http.ResponseWriter, req *http.Request, ctx *models.Context) error {
	id := req.URL.Query().Get(":id")
	if !bson.IsObjectIdHex(id) {
		return perform_status(w, req, http.StatusForbidden)
	}
	match := bson.M{"photo": bson.ObjectIdHex(id)}
	if f, ok := ctx.Session.Values["filter"]; ok {
		f.(*models.Filter).AddQuery(match)
	}
	var result bson.M
	pipe := ctx.C(V).Pipe([]bson.M{
		{"$match": match},
		{"$group": bson.M{
			"_id":   "$photo",
			"avg":   bson.M{"$avg": "$score"},
			"count": bson.M{"$sum": 1},
			"user":  bson.M{"$addToSet": "$photouser"},
		}},
		{"$unwind": "$user"},
	})
	pipe.One(&result)
	if result["user"] != nil && result["user"].(bson.ObjectId) != ctx.User.Id {
		return perform_status(w, req, http.StatusForbidden)
	}
	w.Header().Set("Content-Type", "application/json")
	fmt.Fprintf(w, `{"avg": %.1f, "count": %d}`, result["avg"], result["count"])
	return nil
}
示例#6
0
func Messages(w http.ResponseWriter, req *http.Request, ctx *models.Context) error {
	if ctx.User == nil {
		http.Redirect(w, req, reverse("login"), http.StatusSeeOther)
		return nil
	}
	var messages []*models.Message
	ctx.C(M).Find(bson.M{"to": ctx.User.Id}).All(&messages)
	return T("messages.html").Execute(w, map[string]interface{}{
		"ctx":      ctx,
		"messages": messages,
	})
}
示例#7
0
文件: auth.go 项目: vichetuc/lov3lyme
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
}
示例#8
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,
	})
}
示例#9
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
}
示例#10
0
func SetAvatar(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) {
		newAvatar := models.ImageUrl(photoId, "thumb")
		ctx.User.Avatar = newAvatar
		ctx.C(U).UpdateId(ctx.User.Id, bson.M{"$set": bson.M{"avatar": newAvatar}})
		//ctx.C(P).Update(bson.M{"comments.user": ctx.User.Id}, bson.M{"comments.$.avatar": bson.M{"$set": ctx.User.Gravatar(80)}})
	}
	return nil
}
示例#11
0
文件: auth.go 项目: vichetuc/lov3lyme
func typeAhead(field, q string, ctx *models.Context) string {
	var users []map[string]string
	query := bson.M{field: bson.RegEx{"^" + q, "i"}}
	ctx.C(U).Find(query).Select(bson.M{field: 1, "_id": 0}).All(&users)
	distinct := make(map[string]bool)
	for _, u := range users {
		if _, ok := distinct[u[field]]; !ok {
			distinct[u[field]] = true
		}
	}
	var result string
	for k, _ := range distinct {
		result += `"` + k + `",`
	}
	result = strings.TrimRight(result, ",")
	return `{"options":[` + result + `]}`
}
示例#12
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
}
示例#13
0
文件: auth.go 项目: vichetuc/lov3lyme
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
}
示例#14
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
}
示例#15
0
文件: auth.go 项目: vichetuc/lov3lyme
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)
}
示例#16
0
func Rankings(w http.ResponseWriter, req *http.Request, ctx *models.Context) error {
	var results models.WilsonSorter
	pipe := ctx.C(V).Pipe([]bson.M{
		{"$match": bson.M{"active": true}},
		{"$group": bson.M{
			"_id":         "$photo",
			"count":       bson.M{"$sum": 1},
			"avg":         bson.M{"$avg": "$score"},
			"scores":      bson.M{"$push": "$score"},
			"title":       bson.M{"$addToSet": "$title"},
			"description": bson.M{"$addToSet": "$description"},
			"user":        bson.M{"$addToSet": "$photouser"},
		}},
		{"$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)
	return AJAX("rankings.html").Execute(w, map[string]interface{}{
		"results": results,
		"ctx":     ctx,
	})
}
示例#17
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
}
示例#18
0
func Search(w http.ResponseWriter, req *http.Request, ctx *models.Context) (err error) {
	var users []*models.User
	q := req.FormValue("q")
	query := bson.M{"$or": []bson.M{
		{"firstname": bson.RegEx{q, "i"}},
		{"lastname": bson.RegEx{q, "i"}},
	},
	}
	if err := ctx.C(U).Find(query).Select(bson.M{"password": 0, "birthdate": 0}).Limit(10).All(&users); err != nil {
		return err
	}
	response := ""
	var text bytes.Buffer
	for _, u := range users {
		responseTemplate.Execute(&text, u)
		response += fmt.Sprintf(`{"id":"%s","text":"%s", "name":"%s"},`, u.Id.Hex(), text.String(), u.FullName())
		text.Reset()
	}
	response = strings.TrimRight(response, ",")
	w.Header().Set("Content-Type", "application/json")
	fmt.Fprint(w, "["+response+"]")
	return nil
}
示例#19
0
func Comment(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)
	}
	form := models.CommentForm
	r := form.Load(req)
	ctx.Data["result"] = r
	if len(r.Errors) != 0 {
		return CommentForm(w, req, ctx)
	}

	id := req.URL.Query().Get(":id")
	if !bson.IsObjectIdHex(id) {
		return perform_status(w, req, http.StatusForbidden)
	}
	c := &models.Comment{
		Id:       bson.NewObjectId(),
		User:     ctx.User.Id,
		UserName: ctx.User.FullName(),
		Avatar:   ctx.User.Avatar,
		Body:     r.Values["body"],
	}
	col := P
	if req.URL.Query().Get(":kind") == "c" {
		col = C
	}
	if err := ctx.C(col).UpdateId(bson.ObjectIdHex(id), bson.M{"$push": bson.M{"comments": c}}); err != nil {
		r.Errors["body"] = err
		return CommentForm(w, req, ctx)
	}
	return CommentForm(w, req, ctx)
}
示例#20
0
func GetVote(w http.ResponseWriter, req *http.Request, ctx *models.Context) error {
	if ctx.User == nil {
		return perform_status(w, req, http.StatusForbidden)
	}
	photoId := req.URL.Query().Get(":photo")
	if !bson.IsObjectIdHex(photoId) {
		return perform_status(w, req, http.StatusForbidden)
	}
	contestId := req.URL.Query().Get(":contest")
	if contestId != "" && !bson.IsObjectIdHex(contestId) {
		return perform_status(w, req, http.StatusForbidden)
	}
	query := bson.M{"photo": bson.ObjectIdHex(photoId), "user": ctx.User.Id}
	if contestId != "" {
		query["contest"] = bson.ObjectIdHex(contestId)
	}
	vote := &models.Vote{}

	ctx.C(V).Find(query).One(vote) // on error we still want the stars

	hearts := ""
	for i := 0; i < 5; i++ {
		if float64(i) < vote.Score {
			hearts += `<s class="voted">`
		} else {
			hearts += "<s>"
		}
	}
	return AJAX("vote.html").Execute(w, map[string]interface{}{
		"v":         vote,
		"photoId":   photoId,
		"contestId": contestId,
		"hearts":    SafeHtml(hearts),
		"ctx":       ctx,
	})
}
示例#21
0
文件: auth.go 项目: vichetuc/lov3lyme
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
}
示例#22
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
}
示例#23
0
文件: auth.go 项目: vichetuc/lov3lyme
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
}
示例#24
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
}
示例#25
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
}
示例#26
0
func UploadForm(w http.ResponseWriter, req *http.Request, ctx *models.Context) (err error) {
	if ctx.User == nil {
		http.Redirect(w, req, reverse("login"), http.StatusSeeOther)
		return nil
	}
	//set up the collection and query
	query := ctx.C(P).Find(bson.M{"user": ctx.User.Id, "deleted": false}).Sort("-_id")

	var photos []*models.Photo
	if err = query.All(&photos); err != nil {
		return perform_status(w, req, http.StatusNotFound)
	}

	// get id for edit mode
	id := req.URL.Query().Get(":id")
	if bson.IsObjectIdHex(id) {
		p := &models.Photo{}
		if err := ctx.C(P).Find(bson.M{"_id": bson.ObjectIdHex(id), "user": ctx.User.Id, "deleted": false}).One(p); err != nil {
			return perform_status(w, req, http.StatusNotFound)
		}
		if p == nil {
			return perform_status(w, req, http.StatusNotFound)
		}
		r, ok := ctx.Data["result"]
		a := ""
		if p.Active {
			a = "yes"
		}
		if !ok {
			r = forms.Result{
				Values: map[string]string{
					"title":       p.Title,
					"description": p.Description,
					"country":     p.Country,
					"location":    p.Location,
					"age":         strconv.Itoa(p.Age),
					"gender":      p.Gender,
					"active":      a,
				},
			}
			ctx.Data["result"] = r
		}
	}

	// default values
	r, ok := ctx.Data["result"]
	if !ok {
		r = forms.Result{Values: map[string]string{"active": "yes"}}
		ctx.Data["result"] = r
		r.(forms.Result).Values["country"] = ctx.User.Country
		r.(forms.Result).Values["location"] = ctx.User.Location
		r.(forms.Result).Values["gender"] = ctx.User.Gender
		r.(forms.Result).Values["age"] = strconv.Itoa(ctx.User.Age())
	}
	// find the index of the photo
	ctx.Data["index"] = 0
	for i, p := range photos {
		if p.Id.Hex() == id {
			ctx.Data["index"] = i
			break
		}
	}

	return T("upload.html").Execute(w, map[string]interface{}{
		"photos": photos,
		"id":     id,
		"ctx":    ctx,
	})
}