package main import ( "fmt" "golang.org/x/net/html" "html/template" "io/ioutil" "os" "path/filepath" "strings" "time" ) //Post : Is exported type Post struct { Date time.Time NormalDate string Title string URLTitle string Content template.HTML } const htmlDateLayout = "2006-01-02" const normalDateLayout = "02 Jan 2006" var modTime time.Time var PostsCollection []Post func NewPostsCollection() { verifyFolderModification() initializeCollection() go acquirePosts(100) } func initializeCollection() { PostsCollection = nil filepath.Walk("./posts", newPost) PostsCollection = reversePosts() } func acquirePosts(duration time.Duration) { for { if verifyFolderModification() == true { initializeCollection() PostsCollection = reversePosts() } time.Sleep(duration * time.Second) } } func verifyFolderModification() bool { f, err := os.Open("./posts") if err != nil { fmt.Println("file-error here: \n", f) f.Close() return false } info, err := f.Stat() if err != nil { fmt.Println("info here: \n", info) f.Close() return false } _modTime := info.ModTime() if modTime != _modTime { modTime = _modTime f.Close() return true } f.Close() return false } func newPost(path string, f os.FileInfo, err error) error { content, err := ioutil.ReadFile(path) if err != nil { fmt.Println(err) return nil } title := strings.Replace(path, "posts/", "", -1) if title == ".DS_Store" { return nil } s := string(content) doc, _ := html.Parse(strings.NewReader(s)) dateParsed := getDate(doc) dateFormatted := dateParsed.Format(normalDateLayout) var p = Post{ dateParsed, dateFormatted, title, strings.Replace(title, " ", "-", -1), template.HTML(string(content[:len(content)])), } PostsCollection = insertPostAccordingToDate(p, PostsCollection) return nil } func getDate(n *html.Node) time.Time { var zero, d, t time.Time if n.Type == html.ElementNode && n.Data == "time" { for _, a := range n.Attr { if a.Key == "datetime" { t, _ = time.Parse(htmlDateLayout, a.Val) return t } } } for c := n.FirstChild; c != nil; c = c.NextSibling { d = getDate(c) if d != zero { return d } } return t } func reversePosts() []Post { length := len(PostsCollection) s := make([]Post, length) for i := 0; i < length; i++ { s[i] = PostsCollection[length-(i+1)] } return s } func getNewestPosts(numberOfPosts int) []Post { var posts []Post l := len(PostsCollection) for i := l - 1; i >= l-numberOfPosts; i-- { posts = append(posts, PostsCollection[i]) } return posts } func getPostByURLTitle(title string) Post { for _, post := range PostsCollection { if post.URLTitle == title { return post } } return Post{} } func insertPostAccordingToDate(post Post, arr []Post) []Post { for i, p := range arr { if p.Date.After(post.Date) { s := make([]Post, len(arr)+1, cap(arr)+1) copy(s[:], arr[:]) //make a copy of the slice copy(s[i+1:], arr[i:]) //move the upper part of the slice ahead, creating a hole s[i] = post //insert new element into hole return s } } PostsCollection = append(PostsCollection, post) return PostsCollection }