PageRenderTime 49ms CodeModel.GetById 19ms app.highlight 27ms RepoModel.GetById 1ms app.codeStats 0ms

/models/posts.go

http://github.com/TheOnly92/bloody.go
Go | 266 lines | 233 code | 29 blank | 4 comment | 53 complexity | 78ccc9869e5ca18885e7cf52f9520304 MD5 | raw file
  1package main
  2
  3import (
  4	"launchpad.net/gobson/bson"
  5	"launchpad.net/mgo"
  6	"time"
  7	"hash"
  8	"crypto/sha1"
  9	"encoding/hex"
 10	"math"
 11	"strconv"
 12	"github.com/russross/blackfriday"
 13)
 14
 15type Post struct {
 16	Id			bson.ObjectId "_id,omitempty"
 17	Title		string
 18	Content		string
 19	Created		int64 "timestamp"
 20	Modified	int64
 21	Status		uint64
 22	Type		uint
 23	Comments	[]Comment
 24}
 25
 26type Comment struct {
 27	Id			string
 28	Content		string
 29	Author		string
 30	Created		int64
 31}
 32
 33type PostModel struct {
 34	c			mgo.Collection
 35	extensions	int
 36	html_flags	int
 37}
 38
 39func PostModelInit() *PostModel {
 40	p := new(PostModel)
 41	p.c = mSession.DB(config.Get("mongodb")).C("posts")
 42	p.extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS
 43	p.extensions |= blackfriday.EXTENSION_TABLES
 44	p.extensions |= blackfriday.EXTENSION_FENCED_CODE
 45	p.extensions |= blackfriday.EXTENSION_AUTOLINK
 46	p.extensions |= blackfriday.EXTENSION_STRIKETHROUGH
 47	p.extensions |= blackfriday.EXTENSION_SPACE_HEADERS
 48	p.extensions |= blackfriday.EXTENSION_HARD_LINE_BREAK
 49	p.html_flags |= blackfriday.HTML_USE_XHTML
 50	p.html_flags |= blackfriday.HTML_USE_SMARTYPANTS
 51	p.html_flags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS
 52	p.html_flags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES
 53	return p
 54}
 55
 56func (post *PostModel) FrontPage() []map[string]string {
 57	var result *Post
 58	results := []map[string]string{}
 59	posts, _ := strconv.Atoi(blogConfig.Get("postsPerPage"))
 60	err := post.c.Find(bson.M{"status":1}).Sort(bson.M{"timestamp":-1}).Limit(posts).For(&result, func() error {
 61		t := time.Unix(result.Created, 0)
 62		if result.Type == 1 {
 63			renderer := blackfriday.HtmlRenderer(post.html_flags,"","")
 64			result.Content = string(blackfriday.Markdown([]byte(result.Content), renderer, post.extensions))
 65		}
 66		results = append(results, map[string]string {"Title":result.Title, "Content":result.Content, "Date":t.Format(blogConfig.Get("dateFormat")), "Id": objectIdHex(result.Id.String())})
 67		return nil
 68	})
 69	if err != nil {
 70		panic(err)
 71	}
 72	
 73	return results
 74}
 75
 76func (post *PostModel) RSS() []map[string]string {
 77	var result *Post
 78	results := []map[string]string{}
 79	err := post.c.Find(bson.M{"status":1}).Sort(bson.M{"timestamp":-1}).Limit(20).For(&result, func() error {
 80		t := time.Unix(result.Created, 0)
 81		if result.Type == 1 {
 82			renderer := blackfriday.HtmlRenderer(post.html_flags,"","")
 83			result.Content = string(blackfriday.Markdown([]byte(result.Content), renderer, post.extensions))
 84		}
 85		results = append(results, map[string]string {"Title":result.Title, "Content":result.Content, "Date":t.Format(time.RFC1123), "Id": objectIdHex(result.Id.String())})
 86		return nil
 87	})
 88	if err != nil {
 89		panic(err)
 90	}
 91	
 92	return results
 93}
 94
 95func (post *PostModel) RenderPost(postId string) *Post {
 96	result := post.Get(postId)
 97	renderer := blackfriday.HtmlRenderer(post.html_flags,"","")
 98	if result.Type == 1 {
 99		result.Content = string(blackfriday.Markdown([]byte(result.Content), renderer, post.extensions))
100	}
101	
102	// Also render all blog comments as markdown
103	for i, v := range result.Comments {
104		result.Comments[i].Content = string(blackfriday.Markdown([]byte(v.Content), renderer, post.extensions))
105	}
106	return result
107}
108
109func (post *PostModel) Get(postId string) *Post {
110	var result *Post
111	err := post.c.Find(bson.M{"_id": bson.ObjectIdHex(postId)}).One(&result)
112	if err != nil {
113		panic(err)
114	}
115	
116	return result
117}
118
119func (post *PostModel) GetNextId(postId string) (string, bool) {
120	var next *Post
121	result := post.Get(postId)
122	err := post.c.Find(bson.M{"status":1, "timestamp": bson.M{"$gt":result.Created}}).Sort(bson.M{"timestamp":1}).One(&next)
123	if err != nil && err != mgo.NotFound {
124		panic(err)
125	}
126	
127	if err == mgo.NotFound {
128		return "", false
129	}
130	return objectIdHex(next.Id.String()), true
131}
132
133func (post *PostModel) GetLastId(postId string) (string, bool) {
134	var last *Post
135	result := post.Get(postId)
136	err := post.c.Find(bson.M{"status":1, "timestamp": bson.M{"$lt":result.Created}}).Sort(bson.M{"timestamp":-1}).One(&last)
137	if err != nil && err != mgo.NotFound {
138		panic(err)
139	}
140	
141	if err == mgo.NotFound {
142		return "", false
143	}
144	return objectIdHex(last.Id.String()), true
145}
146
147func (post *PostModel) TotalPages() int {
148	total, err := post.c.Find(bson.M{"status":1}).Count()
149	if err != nil {
150		panic(err)
151	}
152	posts, _ := strconv.Atoi(blogConfig.Get("postsPerPage"))
153	pages := float64(total) / float64(posts)
154	return int(math.Ceil(pages))
155}
156
157func (post *PostModel) PostListing(page int) []map[string]string {
158	var result *Post
159	results := []map[string]string{}
160	callback := func() error {
161		t := time.Unix(result.Created, 0)
162		p := map[string]string {"Title":result.Title, "Date":t.Format(blogConfig.Get("dateFormat")), "Id": objectIdHex(result.Id.String())}
163		if (result.Status == 0) {
164			p["Draft"] = "1"
165		}
166		results = append(results, p)
167		return nil
168	}
169	var err error
170	if page == 0 {
171		err = post.c.Find(nil).Sort(bson.M{"timestamp":-1}).For(&result, callback)
172	} else {
173		posts, _ := strconv.Atoi(blogConfig.Get("postsPerPage"))
174		err = post.c.Find(bson.M{"status":1}).Sort(bson.M{"timestamp":-1}).Skip(posts * (page - 1)).Limit(posts).For(&result, callback)
175	}
176	if err != nil {
177		panic(err)
178	}
179	return results
180}
181
182func (post *PostModel) Create(title string, content string, status string, markdown uint) {
183	t := time.Now()
184	tmp, _ := strconv.ParseUint(status, 10, 64)
185	err := post.c.Insert(&Post{"", title, content, t.Unix(), 0, tmp, markdown, make([]Comment,0)})
186	if err != nil {
187		panic(err)
188	}
189}
190
191func (post *PostModel) InsertComment(postId string, content string, author string) {
192	result := post.Get(postId)
193	if author == "" {
194		author = "Anonymous"
195	}
196	// Generate ID
197	t := time.Now()
198	var h hash.Hash = sha1.New()
199	h.Write([]byte(author+strconv.FormatInt(t.Unix(),10)))
200	id := hex.EncodeToString(h.Sum(nil))
201	comment := Comment{id, content, author, t.Unix()}
202	result.Comments = append(result.Comments, comment)
203	err := post.c.Update(bson.M{"_id":bson.ObjectIdHex(postId)},result)
204	if err != nil {
205		panic(err)
206	}
207}
208
209func (post *PostModel) DeleteComment(postId string, id string) {
210	result := post.Get(postId)
211	
212	// Copy everything from the old one and skip those that we want to delete
213	newComments := make([]Comment,0)
214	for _, comment := range result.Comments {
215		if comment.Id != id {
216			newComments = append(newComments, comment)
217		}
218	}
219	result.Comments = newComments
220	
221	// Save result
222	err := post.c.Update(bson.M{"_id":bson.ObjectIdHex(postId)},result)
223	if err != nil {
224		panic(err)
225	}
226}
227
228func (post *PostModel) Update(title string, content string, status string, postId string) {
229	result := post.Get(postId)
230	result.Title = title
231	result.Content = content
232	result.Modified = time.Now().Unix()
233	result.Status, _ = strconv.ParseUint(status,0,64)
234	err := post.c.Update(bson.M{"_id":bson.ObjectIdHex(postId)},result)
235	if err != nil {
236		panic(err)
237	}
238}
239
240func (post *PostModel) Publish(postId string) {
241	result := post.Get(postId)
242	result.Status = 1
243	err := post.c.Update(bson.M{"_id":bson.ObjectIdHex(postId)},result)
244	if err != nil {
245		panic(err)
246	}
247}
248
249func (post *PostModel) Delete(postId string) {
250	err := post.c.Remove(bson.M{"_id":bson.ObjectIdHex(postId)})
251	if err != nil {
252		panic(err)
253	}
254}
255
256func (post *PostModel) DeleteBulk(postIds []string) {
257	for _, v := range postIds {
258		post.Delete(v)
259	}
260}
261
262func (post *PostModel) PublishBulk(postIds []string) {
263	for _, v := range postIds {
264		post.Publish(v)
265	}
266}