1
0
mirror of https://github.com/makew0rld/amfora.git synced 2024-06-19 19:25:24 +00:00

Handle multiple links per post, prefer item author over feed author

This commit is contained in:
makeworld 2020-11-22 20:04:09 -05:00
parent 8875af6c57
commit ef8295b0a4
6 changed files with 158 additions and 110 deletions

View File

@ -1,7 +1,8 @@
# Notes
## Feeds (temp)
- Feed page doesn't update automatically if you add a feed by bottom bar URL while already on the feed page
- Support multiple links in Atom feeds
- Display gemini one if it exist, then HTTP(S), then whatever is first
- TODO: remove all logger lines
## Issues

148
feeds/entries.go Normal file
View File

@ -0,0 +1,148 @@
package feeds
import (
"net/url"
"sort"
"strings"
"time"
"github.com/makeworld-the-better-one/amfora/logger"
)
// This file contains funcs for creating PageEntries, which
// are consumed by display/feeds.go
// getURL returns a URL to be used in a PageEntry, from a
// list of URLs for that item. It prefers gemini URLs, then
// HTTP(S), then by order.
func getURL(urls []string) string {
if len(urls) == 0 {
return ""
}
var firstHTTP string
for _, u := range urls {
if strings.HasPrefix(u, "gemini://") {
return u
}
if (strings.HasPrefix(u, "http://") || strings.HasPrefix(u, "https://")) && firstHTTP == "" {
// First HTTP(S) URL in the list
firstHTTP = u
}
}
if firstHTTP != "" {
return firstHTTP
}
return urls[0]
}
// GetPageEntries returns the current list of PageEntries
// for use in rendering a page.
// The contents of the returned entries will never change,
// so this function needs to be called again to get updates.
// It always returns sorted entries - by post time, from newest to oldest.
func GetPageEntries() *PageEntries {
logger.Log.Println("feeds.GetPageEntries called")
var pe PageEntries
data.RLock()
for _, feed := range data.Feeds {
for _, item := range feed.Items {
if item.Links == nil || len(item.Links) == 0 {
// Ignore items without links
continue
}
// Set pub
var pub time.Time
// Try to use updated time first, then published
if !item.UpdatedParsed.IsZero() {
pub = *item.UpdatedParsed
} else if !item.PublishedParsed.IsZero() {
pub = *item.PublishedParsed
} else {
// No time on the post
pub = time.Now()
}
// Set prefix
// Prefer using the feed title over anything else.
// Many feeds in Gemini only have this due to gemfeed's default settings.
prefix := feed.Title
if prefix == "" {
// feed.Title was empty
if item.Author != nil {
// Prefer using the item author over the feed author
prefix = item.Author.Name
} else {
if feed.Author != nil {
prefix = feed.Author.Name
} else {
prefix = "[author unknown]"
}
}
} else {
// There's already a title, so add the author (if exists) to
// the end of the title in parentheses.
// Don't add the author if it's the same as the title.
if item.Author != nil && item.Author.Name != prefix {
// Prefer using the item author over the feed author
prefix += " (" + item.Author.Name + ")"
} else if feed.Author != nil && feed.Author.Name != prefix {
prefix += " (" + feed.Author.Name + ")"
}
}
pe.Entries = append(pe.Entries, &PageEntry{
Prefix: prefix,
Title: item.Title,
URL: getURL(item.Links),
Published: pub,
})
}
}
for u, page := range data.Pages {
parsed, _ := url.Parse(u)
// Path is title
title := parsed.Path
if strings.HasPrefix(title, "/~") {
// A user dir
title = title[2:] // Remove beginning slash and tilde
// Remove trailing slash if the root of a user dir is being tracked
if strings.Count(title, "/") <= 1 && title[len(title)-1] == '/' {
title = title[:len(title)-1]
}
} else if strings.HasPrefix(title, "/users/") {
// "/users/" is removed for aesthetics when tracking hosted users
title = strings.TrimPrefix(title, "/users/")
title = strings.TrimPrefix(title, "~") // Remove leading tilde
// Remove trailing slash if the root of a user dir is being tracked
if strings.Count(title, "/") <= 1 && title[len(title)-1] == '/' {
title = title[:len(title)-1]
}
}
pe.Entries = append(pe.Entries, &PageEntry{
Prefix: parsed.Host,
Title: title,
URL: u,
Published: page.Changed,
})
}
data.RUnlock()
sort.Sort(&pe)
return &pe
}

View File

@ -7,11 +7,9 @@ import (
"fmt"
"io"
"mime"
urlPkg "net/url"
"os"
"path"
"reflect"
"sort"
"strings"
"sync"
"time"
@ -170,6 +168,8 @@ func AddFeed(url string, feed *gofeed.Feed) error {
feed.DublinCoreExt = nil
feed.ITunesExt = nil
feed.Custom = nil
feed.Link = ""
feed.Links = nil
for _, item := range feed.Items {
item.Description = ""
item.Content = ""
@ -180,6 +180,7 @@ func AddFeed(url string, feed *gofeed.Feed) error {
item.ITunesExt = nil
item.Extensions = nil
item.Custom = nil
item.Link = "" // Links is used instead
}
data.feedMu.Lock()
@ -361,107 +362,3 @@ func updateAll() {
wg.Wait()
}
// GetPageEntries returns the current list of PageEntries
// for use in rendering a page.
// The contents of the returned entries will never change,
// so this function needs to be called again to get updates.
// It always returns sorted entries - by post time, from newest to oldest.
func GetPageEntries() *PageEntries {
logger.Log.Println("feeds.GetPageEntries called")
var pe PageEntries
data.RLock()
for _, feed := range data.Feeds {
for _, item := range feed.Items {
var pub time.Time
// Try to use updated time first, then published
if !item.UpdatedParsed.IsZero() {
pub = *item.UpdatedParsed
} else if !item.PublishedParsed.IsZero() {
pub = *item.PublishedParsed
} else {
// No time on the post
pub = time.Now()
}
// Prefer using the feed title over anything else.
// Many feeds in Gemini only have this due to gemfeed's default settings.
prefix := feed.Title
if prefix == "" {
// feed.Title was empty
if feed.Author != nil {
// Prefer using the feed author over the item author
prefix = feed.Author.Name
} else {
if item.Author != nil {
prefix = item.Author.Name
} else {
prefix = "[author unknown]"
}
}
} else {
// There's already a title, so add the author (if exists) to
// the end of the title in parentheses.
// Don't add the author if it's the same as the title.
if feed.Author != nil && feed.Author.Name != prefix {
// Prefer using the feed author over the item author
prefix += " (" + feed.Author.Name + ")"
} else {
if item.Author != nil && item.Author.Name != prefix {
prefix += " (" + item.Author.Name + ")"
}
}
}
pe.Entries = append(pe.Entries, &PageEntry{
Prefix: prefix,
Title: item.Title,
URL: item.Link,
Published: pub,
})
}
}
for url, page := range data.Pages {
parsed, _ := urlPkg.Parse(url)
// Path is title
title := parsed.Path
if strings.HasPrefix(title, "/~") {
// A user dir
title = title[2:] // Remove beginning slash and tilde
// Remove trailing slash if the root of a user dir is being tracked
if strings.Count(title, "/") <= 1 && title[len(title)-1] == '/' {
title = title[:len(title)-1]
}
} else if strings.HasPrefix(title, "/users/") {
// "/users/" is removed for aesthetics when tracking hosted users
title = strings.TrimPrefix(title, "/users/")
title = strings.TrimPrefix(title, "~") // Remove leading tilde
// Remove trailing slash if the root of a user dir is being tracked
if strings.Count(title, "/") <= 1 && title[len(title)-1] == '/' {
title = title[:len(title)-1]
}
}
pe.Entries = append(pe.Entries, &PageEntry{
Prefix: parsed.Host,
Title: title,
URL: url,
Published: page.Changed,
})
}
data.RUnlock()
sort.Sort(&pe)
return &pe
}

View File

@ -8,7 +8,7 @@ import (
)
/*
Example JSON
Example stored JSON.
{
"feeds": {

2
go.mod
View File

@ -27,3 +27,5 @@ require (
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/ini.v1 v1.57.0 // indirect
)
replace github.com/mmcdole/gofeed => github.com/makeworld-the-better-one/gofeed v1.1.1-0.20201123002655-c0c6354134fe

4
go.sum
View File

@ -137,6 +137,8 @@ github.com/makeworld-the-better-one/go-gemini v0.9.1 h1:/Vc6Y4Y1aOi4lZIBA1wDe+4N
github.com/makeworld-the-better-one/go-gemini v0.9.1/go.mod h1:P7/FbZ+IEIbA/d+A0Y3w2GNgD8SA2AcNv7aDGJbaWG4=
github.com/makeworld-the-better-one/go-isemoji v1.1.0 h1:wZBHOKB5zAIgaU2vaWnXFDDhatebB8TySrNVxjVV84g=
github.com/makeworld-the-better-one/go-isemoji v1.1.0/go.mod h1:FBjkPl9rr0G4vlZCc+Mr+QcnOfGCTbGWYW8/1sp06I0=
github.com/makeworld-the-better-one/gofeed v1.1.1-0.20201123002655-c0c6354134fe h1:i3b9Qy5z23DcXRnrsMYcM5s9Ng5VIidM1xZd+szuTsY=
github.com/makeworld-the-better-one/gofeed v1.1.1-0.20201123002655-c0c6354134fe/go.mod h1:QQO3maftbOu+hiVOGOZDRLymqGQCos4zxbA4j89gMrE=
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f h1:YEUlTs5gb35UlBLTgqrub9axWTYB3d7/8TxrkJDZpRI=
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f/go.mod h1:X6sxWNi9PBgQybpR4fpXPVD5fm7svLqZTQ5DJuERIoM=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@ -161,8 +163,6 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA=
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mmcdole/gofeed v1.1.0 h1:T2WrGLVJRV04PY2qwhEJLHCt9JiCtBhb6SmC8ZvJH08=
github.com/mmcdole/gofeed v1.1.0/go.mod h1:PPiVwgDXLlz2N83KB4TrIim2lyYM5Zn7ZWH9Pi4oHUk=
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf h1:sWGE2v+hO0Nd4yFU/S/mDBM5plIU8v/Qhfz41hkDIAI=
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf/go.mod h1:pasqhqstspkosTneA62Nc+2p9SOBBYAPbnmRRWPQ0V8=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=