mirror of
https://github.com/makeworld-the-better-one/amfora.git
synced 2024-08-17 18:50:25 +03:00
Handle multiple links per post, prefer item author over feed author
This commit is contained in:
parent
8875af6c57
commit
ef8295b0a4
3
NOTES.md
3
NOTES.md
@ -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
148
feeds/entries.go
Normal 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
|
||||
}
|
109
feeds/feeds.go
109
feeds/feeds.go
@ -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
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
/*
|
||||
Example JSON
|
||||
Example stored JSON.
|
||||
|
||||
{
|
||||
"feeds": {
|
||||
|
2
go.mod
2
go.mod
@ -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
4
go.sum
@ -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=
|
||||
|
Loading…
Reference in New Issue
Block a user