Example #1
0
// Generates the fulltext field by querying the content, resolving it's foreign keys, then trimming them
func generateFulltext(db *mgo.Database, id bson.ObjectId) []string {
	var res interface{}
	db.C("contents").Find(m{"_id": id}).One(&res)
	dat := basic.Convert(res).(map[string]interface{})
	fields := map[string]interface{}{
		"name":  1,
		"slug":  1,
		"title": 1,
	}
	resolver.ResolveOne(db, dat, fields)
	dat = basic.Convert(dat).(map[string]interface{})
	non_split := walkDeep(dat)
	return simpleFulltext(non_split)
}
Example #2
0
// Queries a draft and rebuilds it. Queries its parent too, and merges it with the input fields saved in "data".
// The returned draft will be like a simple draft in the database, but in the data field it will contain fields of the parent plus the fresher saved input data.
// draft_typ example: blog_draft
// Only
func BuildDraft(db *mgo.Database, draft_typ, draft_id_str string) (map[string]interface{}, error) {
	draft_id := patterns.ToIdWithCare(draft_id_str)
	q := m{"_id": draft_id}
	var v interface{}
	err := db.C(Cname + Draft_collection_postfix).Find(q).One(&v)
	if err != nil {
		return nil, err
	}
	draft := basic.Convert(v).(map[string]interface{})
	typ_i, has_typ := draft["type"]
	if !has_typ {
		return nil, fmt.Errorf("Draft has no type.")
	}
	typ, is_str := typ_i.(string)
	if !is_str {
		return nil, fmt.Errorf("Draft type is not a string.")
	}
	if typ != draft_typ {
		return nil, fmt.Errorf("Draft type is not the expected one: %v instead if %v.", typ, draft_typ)
	}
	parent, err := GetParent(db, "contents", draft)
	if err != nil {
		return nil, err
	}
	draft["data"] = mergeWithParent(draft["data"].(map[string]interface{}), parent)
	return draft, nil
}
Example #3
0
func (v *V) Index() error {
	uni := v.uni
	visible_types := []string{}
	types, has := jsonp.GetM(uni.Opt, "Modules.content.types")
	if !has {
		return fmt.Errorf("Can't find content types.")
	}
	for i, _ := range types {
		visible_types = append(visible_types, i)
	}
	q := m{"type": m{"$in": visible_types}}
	search_sl, has := uni.Req.Form["search"]
	if has && len(search_sl[0]) > 0 {
		q["$and"] = content_model.GenerateQuery(search_sl[0])
		uni.Dat["search"] = search_sl[0]
	}
	paging_inf := display_model.DoPaging(uni.Db, "contents", q, "page", map[string][]string(uni.Req.Form), uni.P+"?"+uni.Req.URL.RawQuery, 10)
	var res []interface{}
	uni.Db.C("contents").Find(q).Sort("-created").Skip(paging_inf.Skip).Limit(10).All(&res)
	uni.Dat["paging"] = paging_inf
	res = basic.Convert(res).([]interface{})
	content_model.HaveUpToDateDrafts(uni.Db, res)
	uni.Dat["latest"] = res
	uni.Dat["_points"] = []string{"content/index"}
	return nil
}
Example #4
0
// Called from Front hook.
// Find slug value by given key.
func FindContent(db *mgo.Database, keys []string, val string) (map[string]interface{}, bool) {
	query := bson.M{}
	if len(keys) == 0 {
		return nil, false
	} else if len(keys) == 1 {
		if keys[0] == "_id" && len(val) == 24 { // TODO: check for validity of id.
			query[keys[0]] = bson.ObjectIdHex(val)
		} else {
			query[keys[0]] = val
		}
	} else {
		or := []map[string]interface{}{}
		for _, v := range keys {
			if v == "_id" && len(v) == 24 { // TODO: check fir validity of id.
				or = append(or, map[string]interface{}{v: bson.ObjectIdHex(val)})
			} else {
				or = append(or, map[string]interface{}{v: val})
			}
		}
		query["$or"] = or
	}
	var v interface{}
	db.C(Cname).Find(query).One(&v)
	if v == nil {
		return nil, false
	}
	return basic.Convert(v).(map[string]interface{}), true
}
Example #5
0
// Moves a comment to its final destination (into the valid comments) from moderation queue.
func MoveToFinal(db *mgo.Database, comment_id bson.ObjectId) error {
	var comm interface{}
	q := m{"_id": comment_id}
	err := db.C("comments_moderation").Find(q).One(&comm)
	if err != nil {
		return err
	}
	comment := basic.Convert(comm).(map[string]interface{})
	comment["comment_id"] = comment["_id"]
	delete(comment, "comment_id")
	content_id := comment["_contents_parent"].(bson.ObjectId)
	q2 := m{"_id": content_id}
	upd2 := m{
		"$inc": m{
			"comment_count": 1,
		},
		"$push": m{
			"comments": comment,
		},
	}
	err = db.C("contents").Update(q2, upd2)
	if err != nil {
		return err
	}
	upd := m{
		"$set": m{
			"in_moderation": false,
		},
	}
	err = db.C("comments").Update(q, upd)
	if err != nil {
		return err
	}
	return db.C("comments_moderation").Remove(q)
}
Example #6
0
func (v *V) editContent(typ, id string) (interface{}, error) {
	uni := v.uni
	hasid := len(id) > 0
	uni.Dat["is_content"] = true
	var indb interface{}
	if hasid {
		uni.Dat["op"] = "update"
		err := uni.Db.C("contents").Find(m{"_id": bson.ObjectIdHex(id)}).One(&indb) // Ugly.
		if err != nil {
			return nil, err
		}
		indb = basic.Convert(indb)
		resolver.ResolveOne(uni.Db, indb, nil)
		uni.Dat["content"] = indb
		latest_draft := content_model.GetUpToDateDraft(uni.Db, bson.ObjectIdHex(id), indb.(map[string]interface{}))
		uni.Dat["latest_draft"] = latest_draft
		timeline, err := content_model.ContentTimeline(uni.Db, indb.(map[string]interface{}))
		if err != nil {
			return nil, err
		}
		uni.Dat["timeline"] = timeline
	} else {
		uni.Dat["op"] = "insert"
	}
	return context.Convert(indb), nil
}
Example #7
0
// Find version by id.
func FindVersion(db *mgo.Database, id bson.ObjectId) (map[string]interface{}, error) {
	var v interface{}
	err := db.C("contents_version").Find(m{"_id": id}).One(&v)
	if err != nil {
		return nil, err
	}
	return basic.Convert(v).(map[string]interface{}), err
}
Example #8
0
// Finds he user by name password equality.
func namePass(db *mgo.Database, name, encoded_pass string) (map[string]interface{}, error) {
	var v interface{}
	err := db.C("users").Find(bson.M{"name": name, "password": encoded_pass}).One(&v)
	if err != nil {
		return nil, err
	}
	return basic.Convert(v).(map[string]interface{}), nil
}
Example #9
0
func defaultOpts(db *mgo.Database) (map[string]interface{}, error) {
	// Dohh, a different collection for a single doc, really unmongoish, rewrite.
	var res interface{}
	err := db.C("default_opt").Find(nil).One(&res)
	if err != nil {
		return nil, err
	}
	return basic.Convert(res).(map[string]interface{}), nil
}
Example #10
0
// c: 		collection			string
// q: 		query				map[string]interface{}
// p:		page number key		string							This is used to extract the page nubver from get parameters. Also activates paging.
//																Only works with limit.
// sk: 		skip				float64/int						Hardcoded value, barely useful (see p instead)
// l:		limit				float64/int
// so:		sort				string							Example: "-created"
//
// TODO: check for validity of type assertions.
func RunQueries(db *mgo.Database, queries map[string]interface{}, get map[string][]string, path_n_query string) map[string]interface{} {
	qs := make(map[string]interface{})
	for name, z := range queries {
		v := z.(map[string]interface{})
		_, coll_ok := v["c"]
		_, quer_ok := v["q"]
		if !coll_ok || !quer_ok {
			continue
		}
		q := db.C(v["c"].(string)).Find(v["q"])
		if skip, skok := v["sk"]; skok {
			q.Skip(toInt(skip))
		}
		if limit, lok := v["l"]; lok {
			q.Limit(toInt(limit))
		}
		if sort, sook := v["so"]; sook {
			if sort_string, is_str := sort.(string); is_str {
				q.Sort(sort_string)
			} else if sort_slice, is_sl := sort.([]interface{}); is_sl {
				q.Sort(jsonp.ToStringSlice(sort_slice)...)
			}
		}
		if p, pok := v["p"]; pok {
			if limit, lok := v["l"]; lok { // Only makes sense with limit.
				paging_inf := DoPaging(db, v["c"].(string), v["q"].(map[string]interface{}), p.(string), get, path_n_query, toInt(limit))
				qs[name+"_navi"] = paging_inf
				q.Skip(paging_inf.Skip)
			}
		}
		var res []interface{}
		err := q.All(&res)
		if err != nil {
			qs[name] = err.Error()
			continue
		}
		res = basic.Convert(res).([]interface{})
		if ex, ex_ok := v["ex"]; ex_ok {
			ex_m, ex_is_m := ex.(map[string]interface{})
			if ex_is_m && len(ex_m) == 1 {
				CreateExcerpts(res, ex_m)
			}
		}
		var resolve_fields map[string]interface{}
		if val, has := v["r"]; has {
			resolve_fields = val.(map[string]interface{})
		} else {
			resolve_fields = map[string]interface{}{"password": 0}
		}
		resolver.ResolveAll(db, res, resolve_fields)
		qs[name] = res
	}
	return qs
}
Example #11
0
// returns nil if not found
func find(db *mgo.Database, content_id string) map[string]interface{} {
	content_bsonid := basic.ToIdWithCare(content_id)
	q := bson.M{
		"_id": content_bsonid,
	}
	var v interface{}
	err := db.C("contents").Find(q).One(&v)
	if err != nil {
		return nil
	}
	return basic.Convert(v).(map[string]interface{})
}
Example #12
0
// Finds a doc by query.
func FindQ(db *mgo.Database, coll string, query map[string]interface{}) (map[string]interface{}, error) {
	id, has := query["_id"]
	if has {
		query["_id"] = ToIdWithCare(id)
	}
	var res interface{}
	err := db.C(coll).Find(query).One(&res)
	if err != nil {
		return nil, err
	}
	doc := basic.Convert(res.(bson.M)).(map[string]interface{})
	return doc, nil
}
Example #13
0
func FieldStartsWith(db *mgo.Database, collname, fieldname, val string) ([]interface{}, error) {
	var res []interface{}
	q := m{fieldname: bson.RegEx{"^" + val, "u"}}
	err := db.C(collname).Find(q).All(&res)
	if err != nil {
		return nil, err
	}
	if res == nil {
		return nil, fmt.Errorf("Can't find %v starting with %v.", fieldname, val)
	}
	res = basic.Convert(res).([]interface{})
	return res, nil
}
Example #14
0
// Returns the type of a given content.
func TypeOf(db *mgo.Database, content_id bson.ObjectId) (string, error) {
	var v interface{}
	q := m{"_id": content_id}
	err := db.C("contents").Find(q).One(&v)
	if err != nil {
		return "", err
	}
	con := basic.Convert(v.(bson.M)).(map[string]interface{})
	typ, has := con["type"]
	if !has {
		return "", fmt.Errorf("Content is malformed: has no type.")
	}
	return typ.(string), nil
}
Example #15
0
// See *1 below.
func FindChildren(db *mgo.Database, children_coll, parent_fk_field string, parent_id bson.ObjectId, additional_query map[string]interface{}) ([]interface{}, error) {
	q := map[string]interface{}{}
	if additional_query != nil {
		q = additional_query
	}
	q[parent_fk_field] = parent_id
	var children []interface{}
	err := db.C(children_coll).Find(q).All(&children)
	if err != nil {
		return nil, err
	}
	if children == nil {
		return nil, fmt.Errorf("Can't find children.")
	}
	children = basic.Convert(children).([]interface{})
	return children, nil
}
Example #16
0
// Creates slugs from the tagnames, queries all tags which exists in the database with those slugs.
// Returns the ids of the existing tags, and returns all tagnames which is not in the database.
func separateTags(db *mgo.Database, tagnames []string) ([]bson.ObjectId, []string) {
	var i []interface{}
	slugs := []string{}
	for _, val := range tagnames {
		slug := slugify.S(val)
		slugs = append(slugs, slug)
	}
	db.C(Tag_cname).Find(m{"slug": m{"$in": slugs}}).Limit(0).All(&i)
	ret_ids := []bson.ObjectId{}
	contains := createM(slugs, tagnames)
	i = basic.Convert(i).([]interface{})
	for _, v := range i {
		val := v.(map[string]interface{})
		ret_ids = append(ret_ids, val["_id"].(bson.ObjectId))
		delete(contains, val["slug"].(string))
	}
	return ret_ids, mToSSlice(contains)
}
Example #17
0
// Lists contents of a givn type.
func (v *V) Type() error {
	uni := v.uni
	typ := uni.Req.Form["type"][0]
	q := m{"type": typ}
	search_sl, has := uni.Req.Form["search"]
	if has && len(search_sl[0]) > 0 {
		q["$and"] = content_model.GenerateQuery(search_sl[0])
		uni.Dat["search"] = search_sl[0]
	}
	paging_inf := display_model.DoPaging(uni.Db, "contents", q, "page", map[string][]string(uni.Req.Form), uni.P+"?"+uni.Req.URL.RawQuery, 10)
	var res []interface{}
	uni.Db.C("contents").Find(q).Sort("-created").Skip(paging_inf.Skip).Limit(10).All(&res)
	uni.Dat["paging"] = paging_inf
	res = basic.Convert(res).([]interface{})
	content_model.HaveUpToDateDrafts(uni.Db, res)
	uni.Dat["type"] = typ
	uni.Dat["latest"] = res
	return nil
}
Example #18
0
// Takes a draft and gets.
func GetParent(db *mgo.Database, coll string, draft map[string]interface{}) (map[string]interface{}, error) {
	version_parent, has_vp := draft["draft_of_version"]
	_, has_draft_of := draft["draft_of"]
	// If a draft is a draft of an existing content, than it must have a parent version.
	if !has_vp && has_draft_of {
		return nil, fmt.Errorf("State of draft is inconsistent, parent version is not set.")
	}
	// Simply the draft is not connected to anything saved.
	if !has_vp { // && !has_draft_of
		return nil, nil
	}
	var par interface{}
	parent_id := version_parent.(bson.ObjectId)
	q := m{"_id": parent_id}
	err := db.C(Cname + "_version").Find(q).One(&par)
	if err != nil {
		return nil, err
	}
	return basic.Convert(par).(map[string]interface{}), nil
}
Example #19
0
func findComment(db *mgo.Database, content_id, comment_id string) (map[string]interface{}, error) {
	var v interface{}
	q := bson.M{
		"_id": bson.ObjectIdHex(content_id),
		//"comments.comment_id": bson.ObjectIdHex(comment_id),
	}
	find_err := db.C("contents").Find(q).One(&v)
	if find_err != nil {
		return nil, find_err
	}
	if v == nil {
		return nil, fmt.Errorf("Can't find content with id %v.", content_id)
	}
	v = basic.Convert(v)
	comments_i, has := v.(map[string]interface{})["comments"]
	if !has {
		return nil, fmt.Errorf("No comments in given content.")
	}
	comments, ok := comments_i.([]interface{})
	if !ok {
		return nil, fmt.Errorf("comments member is not a slice in content %v", content_id)
	}
	// TODO: there must be a better way.
	for _, v_i := range comments {
		v, is_map := v_i.(map[string]interface{})
		if !is_map {
			continue
		}
		if val_i, has := v["comment_id"]; has {
			if val_id, ok := val_i.(bson.ObjectId); ok {
				if val_id.Hex() == comment_id {
					return v, nil
				}
			}
		}
	}
	return nil, fmt.Errorf("Comment not found.")
}