aboutsummaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/db.go24
-rw-r--r--models/feed/feed.go103
-rw-r--r--models/item/item.go118
3 files changed, 245 insertions, 0 deletions
diff --git a/models/db.go b/models/db.go
new file mode 100644
index 0000000..b8bc655
--- /dev/null
+++ b/models/db.go
@@ -0,0 +1,24 @@
+/*
+Package neko/models implements behavior for the entities necessary for the subscription services and handles persistence via a mysql/maridb database
+*/
+package models
+
+import (
+ "database/sql"
+ _ "github.com/go-sql-driver/mysql"
+ "log"
+)
+
+var DB *sql.DB
+
+func InitDB(dataSourceName string) {
+ var err error
+ DB, err = sql.Open("mysql", dataSourceName)
+ if err != nil {
+ log.Panic(err)
+ }
+
+ if err = DB.Ping(); err != nil {
+ log.Panic(err)
+ }
+}
diff --git a/models/feed/feed.go b/models/feed/feed.go
new file mode 100644
index 0000000..4abebb4
--- /dev/null
+++ b/models/feed/feed.go
@@ -0,0 +1,103 @@
+package feed
+
+import (
+ "log"
+ "neko/models"
+)
+
+type Feed struct {
+ Id int64 `json:"_id"`
+ Url string `json:"url"`
+ Title string `json:"title"`
+ // TODO: last_updated scan
+}
+
+func NewFeed(url string) error {
+ stmt, err := models.DB.Prepare("INSERT INTO feed(url) VALUES(?)")
+ if err != nil {
+ return err
+ }
+ _, err = stmt.Exec(url)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func All() ([]*Feed, error) {
+ return filter("")
+}
+
+func filter(where string) ([]*Feed, error) {
+ // todo: add back in title
+ rows, err := models.DB.Query(`SELECT id, url, title
+ FROM feed ` + where)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+
+ feeds := make([]*Feed, 0)
+ for rows.Next() {
+ f := new(Feed)
+ err := rows.Scan(&f.Id, &f.Url, &f.Title)
+ if err != nil {
+ return nil, err
+ }
+ feeds = append(feeds, f)
+ }
+ if err = rows.Err(); err != nil {
+ return nil, err
+ }
+ return feeds, nil
+}
+
+func (f *Feed) Update() {
+ if len(f.Title) == 0 {
+ return
+ }
+
+ if f.Id == 0 {
+ return
+ }
+
+ if len(f.Url) == 0 {
+ return
+ }
+
+ models.DB.Query(`UPDATE feed
+ SET title=?, url=?
+ WHERE id=?`, f.Title, f.Url, f.Id)
+}
+
+func (f *Feed) Delete() {
+ log.Println("lets delete some shiteeee")
+ _, err := models.DB.Exec(`DELETE FROM feed
+ WHERE id=?`, f.Id)
+ if err != nil {
+ log.Println(err)
+ }
+}
+
+func (f *Feed) ByUrl(url string) error {
+ err := models.DB.QueryRow(`SELECT id, url, title
+ FROM feed
+ WHERE url = ?`, url).Scan(&f.Id, &f.Url, &f.Title)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (f *Feed) Create() error {
+ res, err := models.DB.Exec(`INSERT INTO feed(url, title)
+ VALUES(?, ?)`, f.Url, f.Title)
+ if err != nil {
+ return err
+ }
+
+ id, _ := res.LastInsertId()
+ f.Id = id
+
+ return nil
+}
diff --git a/models/item/item.go b/models/item/item.go
new file mode 100644
index 0000000..51166c4
--- /dev/null
+++ b/models/item/item.go
@@ -0,0 +1,118 @@
+package item
+
+import (
+ "fmt"
+ "log"
+ "neko/models"
+ // "database/sql"
+ "github.com/microcosm-cc/bluemonday"
+)
+
+type Item struct {
+ Id int64 `json:"_id,string,omitempty"`
+ Title string `json:"title"`
+ Url string `json:"url"`
+ Description string `json:"description"`
+ ReadState bool `json:"read"`
+ FeedId int64
+ PublishDate string `json:"publish_date"`
+ FeedTitle string `json:"feed_title"`
+ FeedUrl string `json:"feed_url"`
+}
+
+func (i *Item) Print() {
+ fmt.Printf("id: %d\n", i.Id)
+ fmt.Printf("title: %s\n", i.Title)
+ fmt.Printf("ReadState: %d\n", i.ReadState)
+}
+
+func (i *Item) Create() error {
+ res, err := models.DB.Exec(`INSERT INTO
+ item(title, url, description, feed_id)
+ VALUES(?, ?, ?, ?)`, i.Title, i.Url, i.Description, i.FeedId)
+ if err != nil {
+ return err
+ }
+
+ id, _ := res.LastInsertId()
+ i.Id = id
+
+ return nil
+}
+
+func (i *Item) Save() {
+ _, err := models.DB.Exec(`UPDATE item
+ SET read_state=?
+ WHERE id=?`, i.ReadState, i.Id)
+ if err != nil {
+ log.Println(err)
+ }
+}
+
+func (i *Item) FullSave() {
+ _, err := models.DB.Exec(`UPDATE item
+ SET title=?, url=?, description=?, feed_id=?
+ WHERE id=?`, i.Title, i.Url, i.Description, i.FeedId, i.Id)
+ if err != nil {
+ log.Println(err)
+ }
+}
+
+func Filter(max_id int64, feed_id int64, unread_only bool) ([]*Item, error) {
+
+ var args []interface{}
+
+ query := `SELECT item.id, item.title, item.url, item.description,
+ item.read_state, item.publish_date,
+ feed.url, feed.title
+ FROM item,feed
+ WHERE item.feed_id=feed.id `
+
+ if max_id != 0 {
+ query = query + "AND item.id < ? "
+ args = append(args, max_id)
+ }
+
+ if feed_id != 0 {
+ query = query + " AND feed.id=? "
+ args = append(args, feed_id)
+ }
+
+ if unread_only {
+ query = query + " AND item.read_state=0 "
+ }
+
+ query = query + "ORDER BY item.id DESC LIMIT 15"
+ // log.Println(query)
+ // log.Println(args...)
+
+ rows, err := models.DB.Query(query, args...)
+ if err != nil {
+ log.Println(err)
+ return nil, err
+ }
+ defer rows.Close()
+
+ p := bluemonday.NewPolicy()
+ p.AllowElements("blockquote", "a", "img", "p", "h1", "h2", "h3", "h4", "b", "i", "em", "strong")
+ p.AllowAttrs("href").OnElements("a")
+ p.AllowAttrs("src", "alt").OnElements("img")
+
+
+ items := make([]*Item, 0)
+ for rows.Next() {
+ i := new(Item)
+ err := rows.Scan(&i.Id, &i.Title, &i.Url, &i.Description, &i.ReadState, &i.PublishDate, &i.FeedUrl, &i.FeedTitle)
+ if err != nil {
+ log.Println(err)
+ return nil, err
+ }
+ i.Description = p.Sanitize(i.Description)
+ // TODO: sanitize other fields
+ items = append(items, i)
+ }
+ if err = rows.Err(); err != nil {
+ return nil, err
+ }
+ return items, nil
+}