+
-
diff --git a/src/assets/javascripts/api.js b/src/assets/javascripts/api.js
index d14d219..3422465 100644
--- a/src/assets/javascripts/api.js
+++ b/src/assets/javascripts/api.js
@@ -71,6 +71,9 @@
}
},
items: {
+ get: function(id) {
+ return api('get', './api/items/' + id).then(json)
+ },
list: function(query) {
return api('get', './api/items' + param(query)).then(json)
},
diff --git a/src/assets/javascripts/app.js b/src/assets/javascripts/app.js
index 900de46..14749aa 100644
--- a/src/assets/javascripts/app.js
+++ b/src/assets/javascripts/app.js
@@ -233,7 +233,7 @@ var vm = new Vue({
'num': 1,
},
'itemSelected': null,
- 'itemSelectedDetails': {},
+ 'itemSelectedDetails': null,
'itemSelectedReadability': '',
'itemSearch': '',
'itemSortNewestFirst': undefined,
@@ -281,9 +281,6 @@ var vm = new Vue({
feedsById: function() {
return this.feeds.reduce(function(acc, feed) { acc[feed.id] = feed; return acc }, {})
},
- itemsById: function() {
- return this.items.reduce(function(acc, item) { acc[item.id] = item; return acc }, {})
- },
itemSelectedContent: function() {
if (!this.itemSelected) return ''
@@ -296,7 +293,7 @@ var vm = new Vue({
else if (this.itemSelectedDetails.description)
content = this.itemSelectedDetails.description
- return sanitize(content, this.itemSelectedDetails.link)
+ return content
},
},
watch: {
@@ -345,12 +342,14 @@ var vm = new Vue({
}
if (this.$refs.content) this.$refs.content.scrollTop = 0
- this.itemSelectedDetails = this.itemsById[newVal]
- if (this.itemSelectedDetails.status == 'unread') {
- this.itemSelectedDetails.status = 'read'
- this.feedStats[this.itemSelectedDetails.feed_id].unread -= 1
- api.items.update(this.itemSelectedDetails.id, {status: this.itemSelectedDetails.status})
- }
+ api.items.get(newVal).then(function(item) {
+ this.itemSelectedDetails = item
+ if (this.itemSelectedDetails.status == 'unread') {
+ this.itemSelectedDetails.status = 'read'
+ this.feedStats[this.itemSelectedDetails.feed_id].unread -= 1
+ api.items.update(this.itemSelectedDetails.id, {status: this.itemSelectedDetails.status})
+ }
+ }.bind(this))
},
'itemSearch': debounce(function(newVal) {
this.refreshItems()
diff --git a/src/server/routes.go b/src/server/routes.go
index 21d810d..b27b9b2 100644
--- a/src/server/routes.go
+++ b/src/server/routes.go
@@ -227,12 +227,22 @@ func (s *Server) handleFeed(c *router.Context) {
}
func (s *Server) handleItem(c *router.Context) {
- if c.Req.Method == "PUT" {
- id, err := c.VarInt64("id")
- if err != nil {
+ id, err := c.VarInt64("id")
+ if err != nil {
+ c.Out.WriteHeader(http.StatusBadRequest)
+ return
+ }
+ if c.Req.Method == "GET" {
+ item := s.db.GetItem(id)
+ if item == nil {
c.Out.WriteHeader(http.StatusBadRequest)
return
}
+ item.Content = scraper.Sanitize(item.Link, item.Content)
+ item.Description = scraper.Sanitize(item.Link, item.Description)
+
+ c.JSON(http.StatusOK, item)
+ } else if c.Req.Method == "PUT" {
var body ItemUpdateForm
if err := json.NewDecoder(c.Req.Body).Decode(&body); err != nil {
log.Print(err)
diff --git a/src/storage/item.go b/src/storage/item.go
index 71dc463..4546dae 100644
--- a/src/storage/item.go
+++ b/src/storage/item.go
@@ -3,7 +3,6 @@ package storage
import (
"encoding/json"
"fmt"
- xhtml "golang.org/x/net/html"
"html"
"log"
"strings"
@@ -49,8 +48,8 @@ type Item struct {
FeedId int64 `json:"feed_id"`
Title string `json:"title"`
Link string `json:"link"`
- Description string `json:"description"`
- Content string `json:"content"`
+ Description string `json:"description,omitempty"`
+ Content string `json:"content,omitempty"`
Author string `json:"author"`
Date *time.Time `json:"date"`
DateUpdated *time.Time `json:"date_updated"`
@@ -166,8 +165,8 @@ func (s *Storage) ListItems(filter ItemFilter, offset, limit int, newestFirst bo
query := fmt.Sprintf(`
select
- i.id, i.guid, i.feed_id, i.title, i.link, i.description,
- i.content, i.author, i.date, i.date_updated, i.status, i.image, i.podcast_url
+ i.id, i.guid, i.feed_id, i.title, i.link,
+ i.author, i.date, i.date_updated, i.status, i.image, i.podcast_url
from items i
join feeds f on f.id = i.feed_id
where %s
@@ -187,8 +186,6 @@ func (s *Storage) ListItems(filter ItemFilter, offset, limit int, newestFirst bo
&x.FeedId,
&x.Title,
&x.Link,
- &x.Description,
- &x.Content,
&x.Author,
&x.Date,
&x.DateUpdated,
@@ -205,6 +202,25 @@ func (s *Storage) ListItems(filter ItemFilter, offset, limit int, newestFirst bo
return result
}
+func (s *Storage) GetItem(id int64) *Item {
+ i := &Item{}
+ err := s.db.QueryRow(`
+ select
+ i.id, i.guid, i.feed_id, i.title, i.link, i.content, i.description,
+ i.author, i.date, i.date_updated, i.status, i.image, i.podcast_url
+ from items i
+ where i.id = ?
+ `, id).Scan(
+ &i.Id, &i.GUID, &i.FeedId, &i.Title, &i.Link, &i.Content, &i.Description,
+ &i.Author, &i.Date, &i.DateUpdated, &i.Status, &i.Image, &i.PodcastURL,
+ )
+ if err != nil {
+ log.Print(err)
+ return nil
+ }
+ return i
+}
+
func (s *Storage) CountItems(filter ItemFilter) int64 {
predicate, args := listQueryPredicate(filter)
query := fmt.Sprintf(`
@@ -285,24 +301,6 @@ func (s *Storage) FeedStats() []FeedStat {
return result
}
-func HTMLText(s string) string {
- tokenizer := xhtml.NewTokenizer(strings.NewReader(s))
- contents := make([]string, 0)
- for {
- token := tokenizer.Next()
- if token == xhtml.ErrorToken {
- break
- }
- if token == xhtml.TextToken {
- content := strings.TrimSpace(xhtml.UnescapeString(string(tokenizer.Text())))
- if len(content) > 0 {
- contents = append(contents, content)
- }
- }
- }
- return strings.Join(contents, " ")
-}
-
func (s *Storage) SyncSearch() {
// TODO: cleaning up once feeds/items are deleted?
rows, err := s.db.Query(`
diff --git a/src/storage/utils.go b/src/storage/utils.go
new file mode 100644
index 0000000..2e8bad0
--- /dev/null
+++ b/src/storage/utils.go
@@ -0,0 +1,24 @@
+package storage
+
+import (
+ "strings"
+ "golang.org/x/net/html"
+)
+
+func HTMLText(s string) string {
+ tokenizer := html.NewTokenizer(strings.NewReader(s))
+ contents := make([]string, 0)
+ for {
+ token := tokenizer.Next()
+ if token == html.ErrorToken {
+ break
+ }
+ if token == html.TextToken {
+ content := strings.TrimSpace(html.UnescapeString(string(tokenizer.Text())))
+ if len(content) > 0 {
+ contents = append(contents, content)
+ }
+ }
+ }
+ return strings.Join(contents, " ")
+}