-
Notifications
You must be signed in to change notification settings - Fork 1
/
entity.go
141 lines (127 loc) · 3.62 KB
/
entity.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2015 The Warren Authors
// Use of this source code is governed by an MIT license that can be found in
// the LICENSE file.
package models
import (
"fmt"
"strings"
elastigo "github.com/mattbaird/elastigo/lib"
"gopkg.in/errgo.v1"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"github.com/warren-community/warren/contenttype"
)
// An entity represents a post to be displayed on the site. It has an
// associated content type, is associated with an owner, and may be a share
// of a previous post.
type Entity struct {
Id bson.ObjectId `bson:"_id"`
ContentType string
Owner string
OriginalOwner string
IsShare bool
Title string
Tags []string
Content interface{}
RenderedContent string
IndexedContent string
Assets []bson.ObjectId
}
type esIndex struct {
IndexedContent string
Title string
Tags []string
}
// Retrive an entity given an ID
func GetEntity(id string, db *mgo.Database) (Entity, error) {
var entity Entity
q := db.C("entities").FindId(bson.ObjectIdHex(id))
if c, err := q.Count(); c == 0 {
return entity, err
}
err := q.One(&entity)
return entity, err
}
// Create a new entity with a new ID.
func NewEntity(contentType string, owner string, originalOwner string, isShare bool, title string, tags []string, content interface{}) Entity {
return Entity{
Id: bson.NewObjectId(),
ContentType: contentType,
Owner: owner,
OriginalOwner: originalOwner,
IsShare: isShare,
Title: title,
Tags: tags,
Content: content,
}
}
// Convert a string containing comma-separated tags to an array of tags.
func TagStringToTags(tagString string) []string {
tags := strings.Split(tagString, ",")
for i, tag := range tags {
tags[i] = strings.TrimSpace(tag)
}
return tags
}
// Save the current entity in the database, generating display and index
// content in the process
func (e *Entity) Save(db *mgo.Database, es *elastigo.Conn) error {
err := e.updateRenderedContent(false)
if err != nil {
return errgo.Mask(err)
}
err = e.updateIndexedContent(false)
if err != nil {
return errgo.Mask(err)
}
_, err = es.Index("warren", "entity", e.Id.Hex(), nil, esIndex{
IndexedContent: e.IndexedContent,
Title: e.Title,
Tags: e.Tags,
})
if err != nil {
return errgo.Mask(err)
}
_, err = db.C("entities").UpsertId(e.Id, e)
return errgo.Mask(err)
}
// Render the content using the content type renderer for display.
func (e *Entity) updateRenderedContent(allowUnsafe bool) error {
ct, ok := contenttype.Registry[e.ContentType]
if !ok {
ct = contenttype.DefaultContentType
}
if !allowUnsafe && !ct.Safe() {
return fmt.Errorf("Attempted unsafe content-type usage: %s", e.ContentType)
}
rendered, err := ct.RenderDisplayContent(e.Content)
if err != nil {
return err
}
e.RenderedContent = rendered
return nil
}
// Render the content using the content type renderer for indexing.
func (e *Entity) updateIndexedContent(allowUnsafe bool) error {
ct, ok := contenttype.Registry[e.ContentType]
if !ok {
ct = contenttype.DefaultContentType
}
if !allowUnsafe && !ct.Safe() {
return fmt.Errorf("Attempted unsafe content-type usage: %s", e.ContentType)
}
rendered, err := ct.RenderIndexContent(e.Content)
if err != nil {
return err
}
e.IndexedContent = rendered
return nil
}
// Delete an entity from the database
func (e *Entity) Delete(db *mgo.Database) error {
return db.C("entities").RemoveId(e.Id)
}
// Determine whether or not the entity belongs to the user.
func (e *Entity) BelongsToUser(user User) bool {
return e.Owner == user.Username
}