Example #1
0
func recordPagingFunc(c *mgo.Collection, first, last string, args ...interface{}) (query bson.M, err error) {
	record := &Record{}

	if bson.IsObjectIdHex(first) {
		if err := c.FindId(bson.ObjectIdHex(first)).One(record); err != nil {
			return nil, err
		}
		query = bson.M{
			"starttime": bson.M{
				"$gte": record.PubTime,
			},
		}
	} else if bson.IsObjectIdHex(last) {
		if err := c.FindId(bson.ObjectIdHex(last)).One(record); err != nil {
			return nil, err
		}
		query = bson.M{
			"starttime": bson.M{
				"$lte": record.PubTime,
			},
		}
	}

	return
}
Example #2
0
func txPagingFunc(c *mgo.Collection, first, last string, args ...interface{}) (query bson.M, err error) {
	tx := &Tx{}

	if bson.IsObjectIdHex(first) {
		if err := c.FindId(bson.ObjectIdHex(first)).One(tx); err != nil {
			return nil, err
		}
		query = bson.M{
			"time": bson.M{
				"$gte": tx.Time,
			},
		}
	} else if bson.IsObjectIdHex(last) {
		if err := c.FindId(bson.ObjectIdHex(last)).One(tx); err != nil {
			return nil, err
		}
		query = bson.M{
			"time": bson.M{
				"$lte": tx.Time,
			},
		}
	}

	return
}
Example #3
0
func articlePagingFunc(c *mgo.Collection, first, last string, args ...interface{}) (query bson.M, err error) {
	article := &Article{}

	if bson.IsObjectIdHex(first) {
		if err := c.FindId(bson.ObjectIdHex(first)).One(article); err != nil {
			return nil, err
		}
		query = bson.M{
			"pub_time": bson.M{
				"$gte": article.PubTime,
			},
		}
	} else if bson.IsObjectIdHex(last) {
		if err := c.FindId(bson.ObjectIdHex(last)).One(article); err != nil {
			return nil, err
		}
		query = bson.M{
			"pub_time": bson.M{
				"$lte": article.PubTime,
			},
		}
	}

	return
}
Example #4
0
// getId returns bson.ObjectId form given id.
// id must be a valid bson.ObjectId or a valid ObjectIdHex
func getId(id string) (bson.ObjectId, error) {
	if !bson.IsObjectIdHex(id) {
		return "", authmodel.ErrInvalidId
	}

	return bson.ObjectIdHex(id), nil
}
Example #5
0
func ExternalPhoto(w http.ResponseWriter, req *http.Request, ctx *models.Context) error {
	id := req.URL.Query().Get(":id")
	photoId := req.URL.Query().Get(":photo")
	if !bson.IsObjectIdHex(id) || (photoId != "" && !bson.IsObjectIdHex(photoId)) {
		return perform_status(w, req, http.StatusForbidden)
	}
	muxName := "photos"
	if req.URL.Query().Get(":kind") == "c" {
		muxName = "view_contest"
	}
	return T("ajax_wrapper.html").Execute(w, map[string]interface{}{
		"ajaxurl": reverse(muxName, "id", id, "photo", photoId),
		"ctx":     ctx,
	})
	return nil
}
Example #6
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
}
Example #7
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,
	})
}
Example #8
0
func GetTicket(ctx *auth.AuthContext, rw http.ResponseWriter, req *http.Request) (int, error) {
	sid := mux.Vars(req)["ticket_id"]
	if !bson.IsObjectIdHex(sid) {
		return http.StatusBadRequest, errors.New("Invalid id")
	}

	db, ok := ctx.Value(DBKey).(*mgo.Database)
	if !ok {
		ctx.Logs.Errorf("Cannot access database")
		return http.StatusInternalServerError, errors.New("Cannot access database")
	}

	t := Ticket{}
	err := db.C("tickets").FindId(bson.ObjectIdHex(sid)).One(&t)
	if err != nil {
		if err == mgo.ErrNotFound {
			return http.StatusNotFound, err
		}

		return http.StatusInternalServerError, err
	}

	json.NewEncoder(rw).Encode(&t)
	return http.StatusOK, nil
}
Example #9
0
// Retrieve an instance of the resource given the id. Assumes the resource name matches the collection name
func GetResource(p martini.Params, r render.Render, db *mgo.Database) {
	resource := p["resource"]
	id := p["id"]

	// TODO use reflection
	var result *interface{}
	if !bson.IsObjectIdHex(id) {
		r.JSON(400, map[string]string{"error": "Invalid id"})
		return
	}

	err := db.C(resource).Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&result)
	if err != nil {
		var status int
		if err == mgo.ErrNotFound {
			status = 404
		} else {
			status = 500
		}

		r.JSON(status, map[string]string{"error": err.Error()})
		return
	}
	r.JSON(200, result)
}
Example #10
0
// URL: /site/{siteId}/delete
// 删除站点,提交者自己或者管理员可以删除
func deleteSiteHandler(handler Handler) {
	user, _ := currentUser(handler)

	siteId := mux.Vars(handler.Request)["siteId"]

	if !bson.IsObjectIdHex(siteId) {
		http.NotFound(handler.ResponseWriter, handler.Request)
		return
	}

	var site Site
	c := handler.DB.C(CONTENTS)

	err := c.Find(bson.M{"_id": bson.ObjectIdHex(siteId)}).One(&site)

	if err != nil {
		message(handler, "错误的连接", "错误的连接", "error")
		return
	}

	if !site.CanEdit(user.Username, handler.DB) {
		message(handler, "没有权限", "你没有权限可以删除站点", "error")
		return
	}

	c.Remove(bson.M{"_id": site.Id_})

	http.Redirect(handler.ResponseWriter, handler.Request, "/sites", http.StatusFound)
}
Example #11
0
// a handler that checks that the current session id is still active
func LoginCheckHandler(cmd *CmdMessage) error {
	sessId, ok := cmd.Data["session_id"].(string)
	if !ok || !bson.IsObjectIdHex(sessId) {
		return errors.New("Invalid session id supplied")
	}
	data := make(map[string]interface{})
	ClearOldSessions()

	if cmd.Conn.owner.IsUser() {
		id, err := AuthFromSession(sessId)

		if err == nil {
			// everything is ok, logging in user
			err = cmd.Conn.owner.Authenticate(id)
			if err != nil {
				data["status"] = "UNAUTHORIZED"
			} else {
				// sending back the success message
				data["status"] = "OK"
			}
		} else {
			// sending back the failure message
			data["status"] = "UNAUTHORIZED"
		}

		DispatchMessage("loginCheck", data, cmd.Conn)
		return err
	}

	return errors.New("This handler is only available for users")
}
Example #12
0
func thumbnailImageHandlerFunc(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	urlVars := mux.Vars(r)
	documentIDHex := urlVars["documentIDHex"]
	if !bson.IsObjectIdHex(documentIDHex) {
		http.NotFound(w, r)
		return
	}
	documentID := bson.ObjectIdHex(documentIDHex)

	fileName := fmt.Sprintf("document-thumbnails/%s.png", documentID.Hex())
	file, err := gridFS.Open(fileName)
	if err != nil {
		if err == mgo.ErrNotFound {
			http.NotFound(w, r)
			return
		}
		log.Printf("error looking up files in gridFS (%s): %s\n", fileName, err)
		http.Error(w, "error", http.StatusInternalServerError)
		return
	}
	defer file.Close()

	w.Header().Set("Content-Type", "image/png")
	_, err = io.Copy(w, file)
	if err != nil {
		log.Printf("error writing png file (%s) to http client: %s\n", fileName, err)
		return
	}
	// all done :)
}
Example #13
0
func cropImageHandlerFunc(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	urlVars := mux.Vars(r)
	cropIDHex := urlVars["cropIDHex"]
	if !bson.IsObjectIdHex(cropIDHex) {
		http.NotFound(w, r)
		return
	}
	cropID := bson.ObjectIdHex(cropIDHex)

	file, err := gridFS.OpenId(cropID)
	if err != nil {
		if err == mgo.ErrNotFound {
			http.NotFound(w, r)
			return
		}
		log.Printf("error looking up files in gridFS (%s): %s\n", cropIDHex, err)
		http.Error(w, "error", http.StatusInternalServerError)
		return
	}
	defer file.Close()

	w.Header().Set("Content-Type", file.ContentType())
	_, err = io.Copy(w, file)
	if err != nil {
		log.Printf("error writing png file (%s) to http client: %s\n", cropIDHex, err)
		return
	}
	// all done :)
}
Example #14
0
func delChatHandler(w http.ResponseWriter, redis *models.RedisLogger, form delChatForm) {

	msg := &models.Message{}

	if bson.IsObjectIdHex(form.Id) {
		msg.Id = bson.ObjectIdHex(form.Id)
		if err := msg.RemoveId(); err != nil {
			writeResponse(w, err)
		} else {
			writeResponse(w, map[string]int{"count": 1})
		}
		return
	}

	var start, end time.Time
	if form.FromTime == 0 {
		start = time.Unix(0, 0)
	} else {
		start = time.Unix(form.FromTime, 0)
	}
	if form.ToTime == 0 {
		end = time.Now()
	} else {
		end = time.Unix(form.ToTime, 0)
	}

	count, err := msg.Delete(form.From, form.To, start, end)
	if err != nil {
		writeResponse(w, err)
		return
	}
	writeResponse(w, map[string]int{"count": count})
}
Example #15
0
// URL: /p/{packageId}/delete
// 删除第三方包
func deletePackageHandler(handler Handler) {
	vars := mux.Vars(handler.Request)
	packageId := vars["packageId"]

	if !bson.IsObjectIdHex(packageId) {
		http.NotFound(handler.ResponseWriter, handler.Request)
		return
	}

	c := DB.C(CONTENTS)

	package_ := Package{}
	err := c.Find(bson.M{"_id": bson.ObjectIdHex(packageId), "content.type": TypePackage}).One(&package_)

	if err != nil {
		return
	}

	c.Remove(bson.M{"_id": bson.ObjectIdHex(packageId)})

	// 修改分类下的数量
	c = DB.C(PACKAGE_CATEGORIES)
	c.Update(bson.M{"_id": package_.CategoryId}, bson.M{"$inc": bson.M{"packagecount": -1}})

	http.Redirect(handler.ResponseWriter, handler.Request, "/packages", http.StatusFound)
}
Example #16
0
// URL: /p/{packageId}
// 显示第三方包详情
func showPackageHandler(handler Handler) {
	vars := mux.Vars(handler.Request)

	packageId := vars["packageId"]

	if !bson.IsObjectIdHex(packageId) {
		http.NotFound(handler.ResponseWriter, handler.Request)
		return
	}

	c := DB.C(CONTENTS)

	package_ := Package{}
	err := c.Find(bson.M{"_id": bson.ObjectIdHex(packageId), "content.type": TypePackage}).One(&package_)

	if err != nil {
		message(handler, "没找到该包", "请检查链接是否正确", "error")
		fmt.Println("showPackageHandler:", err.Error())
		return
	}

	var categories []PackageCategory

	c = DB.C(PACKAGE_CATEGORIES)
	c.Find(nil).All(&categories)

	renderTemplate(handler, "package/show.html", BASE, map[string]interface{}{
		"package":    package_,
		"categories": categories,
		"active":     "package",
	})
}
Example #17
0
func (a *AuthMongoDBCtx) LogginUser(id string, remember int) error {
	if !bson.IsObjectIdHex(id) {
		return ErrInvalidId
	}
	oid := bson.ObjectIdHex(id)
	if remember > 0 {
		//use cookie a rememberColl
		r := rememberInfo{}
		r.Id = oid
		r.Exp = time.Now().Add(time.Duration(remember) * time.Second)
		r.Token = base64.URLEncoding.EncodeToString(secure.RandomToken(128))
		http.SetCookie(a.respw, &http.Cookie{
			Name:    a.cookieName,
			Value:   id + "|" + r.Token,
			Expires: r.Exp,
		})
		return a.rememberColl.Insert(&r)
	} else {
		//use session
		s := sessionInfo{}
		s.At = time.Now()
		s.Id = oid
		return a.sess.Set(a.sessionName, s)
	}
	return nil
}
Example #18
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,
	})
}
Example #19
0
File: sio.go Project: giorgil/kaiju
func onGetComments(ns *socketio.NameSpace, message string) {
	jww.INFO.Println("Comment request Received", message)

	var jsonMap map[string]string
	err := json.Unmarshal([]byte(message), &jsonMap)

	fmt.Println(jsonMap)

	//forumStr := jsonMap["forum"]
	forumStr := "5346e494331583002c7de60e"
	if bson.IsObjectIdHex(forumStr) == false {
		jww.ERROR.Printf("`forum` is not valid. Received: `%v`\n", forumStr)
	}
	forum := bson.ObjectIdHex(forumStr)

	comments, err := GetAllComments(db, forum, jsonMap["page"])
	if err != nil {
		jww.ERROR.Printf("Error: %v\n", err)
	}

	bComments, err := json.Marshal(comments)
	if err != nil {
		jww.ERROR.Printf("Error: %v\n", err)
	}

	fmt.Println(string(bComments))
	ns.Emit("commentsFor", string(bComments))

	if err != nil {
		jww.ERROR.Println(err.Error())
	}
}
Example #20
0
// URL: /a/{articleId}/delete
// 删除文章
func deleteArticleHandler(handler Handler) {
	user, _ := currentUser(handler.Request)

	vars := mux.Vars(handler.Request)
	articleId := vars["articleId"]
	if !bson.IsObjectIdHex(articleId) {
		http.NotFound(handler.ResponseWriter, handler.Request)
		return
	}

	c := DB.C(CONTENTS)

	article := new(Article)

	err := c.Find(bson.M{"_id": bson.ObjectIdHex(articleId)}).One(&article)

	if err != nil {
		fmt.Println("deleteArticleHandler:", err.Error())
		return
	}

	if article.CanDelete(user.Username) {
		c.Remove(bson.M{"_id": article.Id_})

		c = DB.C(COMMENTS)
		c.Remove(bson.M{"contentid": article.Id_})

		http.Redirect(handler.ResponseWriter, handler.Request, "/articles", http.StatusFound)
	}
}
Example #21
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
}
Example #22
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
}
Example #23
0
//Status/{mongoId} Handler
func StatusById(w http.ResponseWriter, r *http.Request) {
	//var pass string
	vars := mux.Vars(r)
	fwRequestId := vars["fwRequestId"]

	if bson.IsObjectIdHex(fwRequestId) {
		firewallReq := firewall.GetFirewallStatusByID(fwRequestId)

		// DELETE ME - TESTING SEND MAIL
		firewall.SendStatusUpdateEmail(firewallReq)

		//Serialize to JSON
		jsonFirewallReq, err := json.MarshalIndent(firewallReq, "", "    ")
		if err != nil {
			log.Println(err)
		}
		log.Println(string(jsonFirewallReq))

		statusObject := status_page{Id: firewallReq.Id, FirewallJSON: string(jsonFirewallReq)}

		var firewallStatusTemplate = template.Must(template.New("statusbyid").ParseFiles("templates/base.html", "templates/requeststatus.html"))
		err = firewallStatusTemplate.ExecuteTemplate(w, "base", statusObject)
		if err != nil {
			log.Println(err)
		}
	} else {
		http.Redirect(w, r, "/status", 302)
	}

}
Example #24
0
// NameToID - Converts name to ObjectId if its one.
// If `create` is true and name is empty it creates new id and `created` is true.
func NameToID(name interface{}, create bool) (id interface{}, created bool) {
	// If create is true and name is empty - create new id
	if create {
		// If name is nil or empty string
		if n, ok := name.(string); name == nil || ok && n == "" {
			id = bson.NewObjectId()
			created = true
			return
		}
	}

	// Try to cast name to ObjectId
	var ok bool
	if id, ok = name.(bson.ObjectId); ok {
		return
	}

	// By default id is a name
	id = name

	// If name is ObjectIdHex convert it
	if n, ok := name.(string); ok && bson.IsObjectIdHex(n) {
		id = bson.ObjectIdHex(n)
	}

	return
}
Example #25
0
// DecodeId returns a valid bson.ObjectId if the given hex is valid. If not it
// will return an invalid bson.ObjectId
func (ctx *DBCtx) DecodeId(hex string) bson.ObjectId {
	if bson.IsObjectIdHex(hex) {
		return bson.ObjectIdHex(hex)
	}
	var invalid bson.ObjectId
	return invalid
}
Example #26
0
func createItem(t *testing.T, url string, item interface{}) (id string) {

	data, err := json.Marshal(item)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := http.Post(url, "application/json", bytes.NewReader(data))
	if err != nil {
		t.Fatal(err)
	}

	if resp.StatusCode != http.StatusCreated {
		fmt.Println(body(resp).String())
		t.Fatal("Failed to create item: " + resp.Status + ".")
	}

	json.Unmarshal(body(resp).Bytes(), &id)

	if !bson.IsObjectIdHex(id) {
		t.Fatal("Create event returned successfully but did not provide a valid event id: " + id + ".")
	}

	return
}
Example #27
0
// PingSessionHandler ...
func PingSessionHandler(w http.ResponseWriter, r *http.Request, c *Context) {
	sessionIdHex := r.PostFormValue("session_id")
	machineId := r.PostFormValue("machine_id")
	if len(r.PostForm) != 2 || sessionIdHex == "" || machineId == "" {
		http.Error(w, "Retry with POST parameters: session_id, machine_id", http.StatusBadRequest)
		return
	}
	if !bson.IsObjectIdHex(sessionIdHex) {
		http.Error(w, fmt.Sprintf("Invalid session id %s", sessionIdHex), http.StatusBadRequest)
		return
	}
	sessionId := bson.ObjectIdHex(sessionIdHex)
	err := c.Store.PingSession(&Session{Id: sessionId, MachineId: machineId})
	switch err {
	case nil:
		fmt.Fprintln(w, sessionIdHex)
	case mgo.ErrNotFound:
		http.Error(w, fmt.Sprintf("Session %s does not exist or is already closed", sessionIdHex),
			http.StatusBadRequest)
	default:
		http.Error(w, fmt.Sprintf("Failed to ping session %s", sessionIdHex),
			http.StatusInternalServerError)
		log.Println(err)
	}
}
Example #28
0
func NewArticles(ids []string, last string) (int, error) {
	total := 0

	query := bson.M{
		"parent":    nil,
		"privilege": bson.M{"$ne": 2},
		"author":    bson.M{"$in": ids},
	}
	if bson.IsObjectIdHex(last) {
		article := &Article{}
		findOne(articleColl, bson.M{"_id": bson.ObjectIdHex(last)}, nil, article)
		if len(article.Id) == 0 {
			return 0, nil
		}

		query["pub_time"] = bson.M{
			"$gte": article.PubTime,
		}
		query["_id"] = bson.M{
			"$ne": article.Id,
		}
	}
	sortFields := []string{"-pub_time", "-_id"}
	err := search(articleColl, query, nil, 0, 0, sortFields, &total, nil)

	return total, err
}
Example #29
0
func GetBookById(s *mgo.Session, Id string) *Book {
	if bson.IsObjectIdHex(Id) {
		ObjectId := bson.ObjectIdHex(Id)
		return GetBookByObjectId(s, ObjectId)
	} else {
		return new(Book)
	}
}
Example #30
0
func (this *Article) Save() error {
	this.Id = bson.NewObjectId()
	if len(this.Parent) == 0 {
		if err := save(articleColl, this, true); err != nil {
			return errors.NewError(errors.DbError, err.Error())
		}
		return nil
	}

	if !bson.IsObjectIdHex(this.Parent) {
		return errors.NewError(errors.InvalidMsgError)
	}

	update := bson.M{
		"$push": bson.M{
			"reviews": this.Id.Hex(),
		},
		"$inc": bson.M{
			"review_count": 1,
		},
	}
	if this.Type == ArticleCoach {
		update = bson.M{
			"$addToSet": bson.M{
				"coaches": this.Author,
			},
			"$inc": bson.M{
				"coach_review_count": 1,
			},
		}
	}

	f := func(c *mgo.Collection) error {
		runner := txn.NewRunner(c)
		ops := []txn.Op{
			{
				C:      articleColl,
				Id:     this.Id,
				Assert: txn.DocMissing,
				Insert: this,
			},
			{
				C:      articleColl,
				Id:     bson.ObjectIdHex(this.Parent),
				Assert: txn.DocExists,
				Update: update,
			},
		}

		return runner.Run(ops, bson.NewObjectId(), nil)
	}

	if err := withCollection("comment_tx", &mgo.Safe{}, f); err != nil {
		log.Println(err)
		return errors.NewError(errors.DbError, err.Error())
	}
	return nil
}