Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support author #91

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/assets/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ <h1><b>{{ itemSelectedDetails.title || 'untitled' }}</b></h1>
<div class="text-muted">
<div>{{ feedsById[itemSelectedDetails.feed_id].title }}</div>
<time>{{ formatDate(itemSelectedDetails.date) }}</time>
<div v-html="itemSelectedDetails.author"></div>
</div>
<hr>
<div v-if="!itemSelectedReadability">
Expand Down
3 changes: 3 additions & 0 deletions src/parser/atom.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type atomEntry struct {
OrigLink string `xml:"http://rssnamespace.org/feedburner/ext/1.0 origLink"`

media

Author string `xml:"author>name"`
}

type atomText struct {
Expand Down Expand Up @@ -90,6 +92,7 @@ func ParseAtom(r io.Reader) (*Feed, error) {
Content: firstNonEmpty(srcitem.Content.String(), srcitem.Summary.String(), srcitem.firstMediaDescription()),
ImageURL: srcitem.firstMediaThumbnail(),
AudioURL: "",
Author: srcitem.Author,
})
}
return dstfeed, nil
Expand Down
1 change: 1 addition & 0 deletions src/parser/atom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func TestAtom(t *testing.T) {
Content: `<div xmlns="http://www.w3.org/1999/xhtml"><p>This is the entry content.</p></div>`,
ImageURL: "",
AudioURL: "",
Author: "John Doe",
},
},
}
Expand Down
13 changes: 13 additions & 0 deletions src/parser/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package parser
import (
"encoding/json"
"io"
"strings"
)

type jsonFeed struct {
Expand All @@ -23,6 +24,7 @@ type jsonItem struct {
DatePublished string `json:"date_published"`
DateModified string `json:"date_modified"`
Attachments []jsonAttachment `json:"attachments"`
Authors []jsonAuthor `json:"authors"`
}

type jsonAttachment struct {
Expand All @@ -33,6 +35,12 @@ type jsonAttachment struct {
Duration int `json:"duration_in_seconds"`
}

type jsonAuthor struct {
Name string `json:"name"`
URL string `json:"url"`
Avatar string `json:"avatar"`
}

func ParseJSON(data io.Reader) (*Feed, error) {
srcfeed := new(jsonFeed)
decoder := json.NewDecoder(data)
Expand All @@ -45,12 +53,17 @@ func ParseJSON(data io.Reader) (*Feed, error) {
SiteURL: srcfeed.SiteURL,
}
for _, srcitem := range srcfeed.Items {
authors := []string{}
for _, v := range srcitem.Authors {
authors = append(authors, v.Name)
}
dstfeed.Items = append(dstfeed.Items, Item{
GUID: firstNonEmpty(srcitem.ID, srcitem.URL),
Date: dateParse(firstNonEmpty(srcitem.DatePublished, srcitem.DateModified)),
URL: srcitem.URL,
Title: srcitem.Title,
Content: firstNonEmpty(srcitem.HTML, srcitem.Text, srcitem.Summary),
Author: strings.Join(authors, ", "),
})
}
return dstfeed, nil
Expand Down
16 changes: 14 additions & 2 deletions src/parser/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,19 @@ func TestJSONFeed(t *testing.T) {
{
"id": "2",
"content_text": "This is a second item.",
"url": "https://example.org/second-item"
"url": "https://example.org/second-item",
"authors": [
{
"name": "Optional Author 1",
"url": "https://example.org/authors/optional-author",
"avatar": "https://example.org/authors/optional-author/avatar-512x512.png"
},
{
"name": "Optional Author 2",
"url": "https://example.org/authors/optional-author-2",
"avatar": "https://example.org/authors/optional-author/avatar-512x512.png"
}
]
},
{
"id": "1",
Expand All @@ -29,7 +41,7 @@ func TestJSONFeed(t *testing.T) {
Title: "My Example Feed",
SiteURL: "https://example.org/",
Items: []Item{
{GUID: "2", Content: "This is a second item.", URL: "https://example.org/second-item"},
{GUID: "2", Content: "This is a second item.", URL: "https://example.org/second-item", Author: "Optional Author 1, Optional Author 2"},
{GUID: "1", Content: "<p>Hello, world!</p>", URL: "https://example.org/initial-post"},
},
}
Expand Down
9 changes: 5 additions & 4 deletions src/parser/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ type Feed struct {
}

type Item struct {
GUID string
Date time.Time
URL string
Title string
GUID string
Date time.Time
URL string
Title string
Author string

Content string
ImageURL string
Expand Down
8 changes: 8 additions & 0 deletions src/parser/rdf.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ type rdfItem struct {

DublinCoreDate string `xml:"http://purl.org/dc/elements/1.1/ date"`
ContentEncoded string `xml:"http://purl.org/rss/1.0/modules/content/ encoded"`

DublinCoreCreator string `xml:"http://purl.org/dc/elements/1.1/ creator"`
Author string `xml:"author"`
}

func ParseRDF(r io.Reader) (*Feed, error) {
Expand All @@ -37,12 +40,17 @@ func ParseRDF(r io.Reader) (*Feed, error) {
SiteURL: srcfeed.Link,
}
for _, srcitem := range srcfeed.Items {
author := srcitem.DublinCoreCreator
if len(author) == 0 {
author = srcitem.Author
}
dstfeed.Items = append(dstfeed.Items, Item{
GUID: srcitem.Link,
URL: srcitem.Link,
Date: dateParse(srcitem.DublinCoreDate),
Title: srcitem.Title,
Content: firstNonEmpty(srcitem.ContentEncoded, srcitem.Description),
Author: author,
})
}
return dstfeed, nil
Expand Down
3 changes: 2 additions & 1 deletion src/parser/rdf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func TestRDFFeed(t *testing.T) {
<item>
<title>New Status Updates</title>
<link>http://www.mozilla.org/status/</link>
<author>Doe John, Stelvio Runner</author>
</item>

<item>
Expand All @@ -42,7 +43,7 @@ func TestRDFFeed(t *testing.T) {
Title: "Mozilla Dot Org",
SiteURL: "http://www.mozilla.org",
Items: []Item{
{GUID: "http://www.mozilla.org/status/", URL: "http://www.mozilla.org/status/", Title: "New Status Updates"},
{GUID: "http://www.mozilla.org/status/", URL: "http://www.mozilla.org/status/", Title: "New Status Updates", Author: "Doe John, Stelvio Runner"},
{GUID: "http://www.mozilla.org/bugs/", URL: "http://www.mozilla.org/bugs/", Title: "Bugzilla Reorganized"},
},
}
Expand Down
9 changes: 9 additions & 0 deletions src/parser/rss.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ type rssItem struct {
OrigEnclosureLink string `xml:"http://rssnamespace.org/feedburner/ext/1.0 origEnclosureLink"`

media

DublinCoreCreator string `xml:"http://purl.org/dc/elements/1.1/ creator"`
Author string `xml:"author"`
}

type rssLink struct {
Expand Down Expand Up @@ -81,6 +84,11 @@ func ParseRSS(r io.Reader) (*Feed, error) {
}
}

author := srcitem.DublinCoreCreator
if len(author) == 0 {
author = srcitem.Author
}

dstfeed.Items = append(dstfeed.Items, Item{
GUID: firstNonEmpty(srcitem.GUID, srcitem.Link),
Date: dateParse(firstNonEmpty(srcitem.DublinCoreDate, srcitem.PubDate)),
Expand All @@ -89,6 +97,7 @@ func ParseRSS(r io.Reader) (*Feed, error) {
Content: firstNonEmpty(srcitem.ContentEncoded, srcitem.Description),
AudioURL: podcastURL,
ImageURL: srcitem.firstMediaThumbnail(),
Author: author,
})
}
return dstfeed, nil
Expand Down
2 changes: 2 additions & 0 deletions src/parser/rss_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func TestRSSFeed(t *testing.T) {
<title>Title 1</title>
<link>http://www.scripting.com/one/</link>
<description>Description 1</description>
<author>Doe John, Stelvio Runner</author>
</item>
<item>
<title>Title 2</title>
Expand All @@ -38,6 +39,7 @@ func TestRSSFeed(t *testing.T) {
URL: "http://www.scripting.com/one/",
Title: "Title 1",
Content: "Description 1",
Author: "Doe John, Stelvio Runner",
},
{
GUID: "http://www.scripting.com/two/",
Expand Down
20 changes: 12 additions & 8 deletions src/storage/item.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ type Item struct {
Status ItemStatus `json:"status"`
ImageURL *string `json:"image"`
AudioURL *string `json:"podcast_url"`
Author string `json:"author"`
}

type ItemFilter struct {
Expand Down Expand Up @@ -83,13 +84,14 @@ func (s *Storage) CreateItems(items []Item) bool {
insert into items (
guid, feed_id, title, link, date,
content, image, podcast_url,
date_arrived, status
date_arrived, status,
author
)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
on conflict (feed_id, guid) do nothing`,
item.GUID, item.FeedId, item.Title, item.Link, item.Date,
item.Content, item.ImageURL, item.AudioURL,
now, UNREAD,
now, UNREAD, item.Author,
)
if err != nil {
log.Print(err)
Expand Down Expand Up @@ -194,12 +196,14 @@ func (s *Storage) GetItem(id int64) *Item {
err := s.db.QueryRow(`
select
i.id, i.guid, i.feed_id, i.title, i.link, i.content,
i.date, i.status, i.image, i.podcast_url
i.date, i.status, i.image, i.podcast_url,
i.author
from items i
where i.id = ?
`, id).Scan(
&i.Id, &i.GUID, &i.FeedId, &i.Title, &i.Link, &i.Content,
&i.Date, &i.Status, &i.ImageURL, &i.AudioURL,
&i.Author,
)
if err != nil {
log.Print(err)
Expand Down Expand Up @@ -256,7 +260,7 @@ func (s *Storage) FeedStats() []FeedStat {

func (s *Storage) SyncSearch() {
rows, err := s.db.Query(`
select id, title, content
select id, title, content, author
from items
where search_rowid is null;
`)
Expand All @@ -268,14 +272,14 @@ func (s *Storage) SyncSearch() {
items := make([]Item, 0)
for rows.Next() {
var item Item
rows.Scan(&item.Id, &item.Title, &item.Content)
rows.Scan(&item.Id, &item.Title, &item.Content, &item.Author)
items = append(items, item)
}

for _, item := range items {
result, err := s.db.Exec(`
insert into search (title, description, content) values (?, "", ?)`,
item.Title, htmlutil.ExtractText(item.Content),
insert into search (title, description, content, author) values (?, "", ?, ?)`,
item.Title, htmlutil.ExtractText(item.Content), item.Author,
)
if err != nil {
log.Print(err)
Expand Down
2 changes: 1 addition & 1 deletion src/storage/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func m01_initial(tx *sql.Tx) error {
val blob
);

create virtual table if not exists search using fts4(title, description, content);
create virtual table if not exists search using fts4(title, description, content, author);

create trigger if not exists del_item_search after delete on items begin
delete from search where rowid = old.search_rowid;
Expand Down
2 changes: 2 additions & 0 deletions src/worker/crawler.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/url"
"strings"

"github.com/nkanaev/yarr/src/content/htmlutil"
"github.com/nkanaev/yarr/src/content/scraper"
"github.com/nkanaev/yarr/src/parser"
"github.com/nkanaev/yarr/src/storage"
Expand Down Expand Up @@ -161,6 +162,7 @@ func ConvertItems(items []parser.Item, feed storage.Feed) []storage.Item {
Status: storage.UNREAD,
ImageURL: imageURL,
AudioURL: audioURL,
Author: htmlutil.ExtractText(item.Author),
}
}
return result
Expand Down