8000 [pull] main from miniflux:main by pull[bot] · Pull Request #214 · suhaoGe/miniflux · GitHub
[go: up one dir, main page]

Skip to content
Merged
< 8000 /div>
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
6 changes: 3 additions & 3 deletions internal/reader/atom/atom_03_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (a *atom03Adapter) buildFeed(baseURL string) *model.Feed {
// Populate the feed URL.
feedURL := a.atomFeed.Links.firstLinkWithRelation("self")
if feedURL != "" {
if absoluteFeedURL, err := urllib.AbsoluteURL(baseURL, feedURL); err == nil {
if absoluteFeedURL, err := urllib.ResolveToAbsoluteURL(baseURL, feedURL); err == nil {
feed.FeedURL = absoluteFeedURL
}
} else {
Expand All @@ -34,7 +34,7 @@ func (a *atom03Adapter) buildFeed(baseURL string) *model.Feed {
// Populate the site URL.
siteURL := a.atomFeed.Links.originalLink()
if siteURL != "" {
if absoluteSiteURL, err := urllib.AbsoluteURL(baseURL, siteURL); err == nil {
if absoluteSiteURL, err := urllib.ResolveToAbsoluteURL(baseURL, siteURL); err == nil {
feed.SiteURL = absoluteSiteURL
}
} else {
Expand All @@ -53,7 +53,7 @@ func (a *atom03Adapter) buildFeed(baseURL string) *model.Feed {
// Populate the entry URL.
entry.URL = atomEntry.Links.originalLink()
if entry.URL != "" {
if absoluteEntryURL, err := urllib.AbsoluteURL(feed.SiteURL, entry.URL); err == nil {
if absoluteEntryURL, err := urllib.ResolveToAbsoluteURL(feed.SiteURL, entry.URL); err == nil {
entry.URL = absoluteEntryURL
}
}
Expand Down
18 changes: 9 additions & 9 deletions internal/reader/atom/atom_10_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (a *atom10Adapter) BuildFeed(baseURL string) *model.Feed {
// Populate the feed URL.
feedURL := a.atomFeed.Links.firstLinkWithRelation("self")
if feedURL != "" {
if absoluteFeedURL, err := urllib.AbsoluteURL(baseURL, feedURL); err == nil {
if absoluteFeedURL, err := urllib.ResolveToAbsoluteURL(baseURL, feedURL); err == nil {
feed.FeedURL = absoluteFeedURL
}
} else {
Expand All @@ -42,7 +42,7 @@ func (a *atom10Adapter) BuildFeed(baseURL string) *model.Feed {
// Populate the site URL.
siteURL := a.atomFeed.Links.originalLink()
if siteURL != "" {
if absoluteSiteURL, err := urllib.AbsoluteURL(baseURL, siteURL); err == nil {
if absoluteSiteURL, err := urllib.ResolveToAbsoluteURL(baseURL, siteURL); err == nil {
feed.SiteURL = absoluteSiteURL
}
} else {
Expand All @@ -60,11 +60,11 @@ func (a *atom10Adapter) BuildFeed(baseURL string) *model.Feed {

// Populate the feed icon.
if a.atomFeed.Icon != "" {
if absoluteIconURL, err := urllib.AbsoluteURL(feed.SiteURL, a.atomFeed.Icon); err == nil {
if absoluteIconURL, err := urllib.ResolveToAbsoluteURL(feed.SiteURL, a.atomFeed.Icon); err == nil {
feed.IconURL = absoluteIconURL
}
} else if a.atomFeed.Logo != "" {
if absoluteLogoURL, err := urllib.AbsoluteURL(feed.SiteURL, a.atomFeed.Logo); err == nil {
if absoluteLogoURL, err := urllib.ResolveToAbsoluteURL(feed.SiteURL, a.atomFeed.Logo); err == nil {
feed.IconURL = absoluteLogoURL
}
}
Expand All @@ -81,7 +81,7 @@ func (a *atom10Adapter) populateEntries(siteURL string) model.Entries {
// Populate the entry URL.
entry.URL = atomEntry.Links.originalLink()
if entry.URL != "" {
if absoluteEntryURL, err := urllib.AbsoluteURL(siteURL, entry.URL); err == nil {
if absoluteEntryURL, err := urllib.ResolveToA 8000 bsoluteURL(siteURL, entry.URL); err == nil {
entry.URL = absoluteEntryURL
}
}
Expand Down Expand Up @@ -168,7 +168,7 @@ func (a *atom10Adapter) populateEntries(siteURL string) model.Entries {
continue
}
if _, found := uniqueEnclosuresMap[mediaURL]; !found {
if mediaAbsoluteURL, err := urllib.AbsoluteURL(siteURL, mediaURL); err != nil {
if mediaAbsoluteURL, err := urllib.ResolveToAbsoluteURL(siteURL, mediaURL); err != nil {
slog.Debug("Unable to build absolute URL for media thumbnail",
slog.String("url", mediaThumbnail.URL),
slog.String("site_url", siteURL),
Expand All @@ -186,7 +186,7 @@ func (a *atom10Adapter) populateEntries(siteURL string) model.Entries {
}

for _, link := range atomEntry.Links.findAllLinksWithRelation("enclosure") {
absoluteEnclosureURL, err := urllib.AbsoluteURL(siteURL, link.Href)
absoluteEnclosureURL, err := urllib.ResolveToAbsoluteURL(siteURL, link.Href)
if err != nil {
slog.Debug("Unable to resolve absolute URL for enclosure",
slog.String("enclosure_url", link.Href),
Expand All @@ -211,7 +211,7 @@ func (a *atom10Adapter) populateEntries(siteURL string) model.Entries {
if mediaURL == "" {
continue
}
if mediaAbsoluteURL, err := urllib.AbsoluteURL(siteURL, mediaURL); err != nil {
if mediaAbsoluteURL, err := urllib.ResolveToAbsoluteURL(siteURL, mediaURL); err != nil {
slog.Debug("Unable to build absolute URL for media content",
slog.String("url", mediaContent.URL),
slog.String("site_url", siteURL),
Expand All @@ -234,7 +234,7 @@ func (a *atom10Adapter) populateEntries(siteURL string) model.Entries {
if mediaURL == "" {
continue
}
if mediaAbsoluteURL, err := urllib.AbsoluteURL(siteURL, mediaURL); err != nil {
if mediaAbsoluteURL, err := urllib.ResolveToAbsoluteURL(siteURL, mediaURL); err != nil {
slog.Debug("Unable to build absolute URL for media peer link",
slog.String("url", mediaPeerLink.URL),
slog.String("site_url", siteURL),
Expand Down
2 changes: 1 addition & 1 deletion internal/reader/icon/finder.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ func findIconURLsFromHTMLDocument(documentURL string, body io.Reader, contentTyp
continue
}

if absoluteIconURL, err := urllib.AbsoluteURL(documentURL, href); err != nil {
if absoluteIconURL, err := urllib.ResolveToAbsoluteURL(documentURL, href); err != nil {
slog.Warn("Unable to convert icon URL to absolute URL", slog.Any("error", err), slog.String("icon_href", href))
} else {
iconURLs = append(iconURLs, absoluteIconURL)
Expand Down
10 changes: 5 additions & 5 deletions internal/reader/json/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ func (j *JSONAdapter) BuildFeed(baseURL string) *model.Feed {
feed.SiteURL = feed.FeedURL
}

if feedURL, err := urllib.AbsoluteURL(baseURL, feed.FeedURL); err == nil {
if feedURL, err := urllib.ResolveToAbsoluteURL(baseURL, feed.FeedURL); err == nil {
feed.FeedURL = feedURL
}

if siteURL, err := urllib.AbsoluteURL(baseURL, feed.SiteURL); err == nil {
if siteURL, err := urllib.ResolveToAbsoluteURL(baseURL, feed.SiteURL); err == nil {
feed.SiteURL = siteURL
}

Expand All @@ -58,7 +58,7 @@ func (j *JSONAdapter) BuildFeed(baseURL string) *model.Feed {
for _, iconURL := range []string{j.jsonFeed.FaviconURL, j.jsonFeed.IconURL} {
iconURL = strings.TrimSpace(iconURL)
if iconURL != "" {
if absoluteIconURL, err := urllib.AbsoluteURL(feed.SiteURL, iconURL); err == nil {
if absoluteIconURL, err := urllib.ResolveToAbsoluteURL(feed.SiteURL, iconURL); err == nil {
feed.IconURL = absoluteIconURL
break
}
Expand All @@ -73,7 +73,7 @@ func (j *JSONAdapter) BuildFeed(baseURL string) *model.Feed {
itemURL = strings.TrimSpace(itemURL)
if itemURL != "" {
// Make sure the entry URL is absolute.
if entryURL, err := urllib.AbsoluteURL(feed.SiteURL, itemURL); err == nil {
if entryURL, err := urllib.ResolveToAbsoluteURL(feed.SiteURL, itemURL); err == nil {
entry.URL = entryURL
}
break
Expand Down Expand Up @@ -144,7 +144,7 @@ func (j *JSONAdapter) BuildFeed(baseURL string) *model.Feed {
for _, attachment := range item.Attachments {
attachmentURL := strings.TrimSpace(attachment.URL)
if attachmentURL != "" {
if absoluteAttachmentURL, err := urllib.AbsoluteURL(feed.SiteURL, attachmentURL); err == nil {
if absoluteAttachmentURL, err := urllib.ResolveToAbsoluteURL(feed.SiteURL, attachmentURL); err == nil {
entry.Enclosures = append(entry.Enclosures, &model.Enclosure{
URL: absoluteAttachmentURL,
MimeType: attachment.MimeType,
Expand Down
4 changes: 2 additions & 2 deletions internal/reader/rdf/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (r *rdfAdapter) buildFeed(baseURL string) *model.Feed {
feed.Title = baseURL
}

if siteURL, err := urllib.AbsoluteURL(feed.FeedURL, feed.SiteURL); err == nil {
if siteURL, err := urllib.ResolveToAbsoluteURL(feed.FeedURL, feed.SiteURL); err == nil {
feed.SiteURL = siteURL
}

Expand All @@ -43,7 +43,7 @@ func (r *rdfAdapter) buildFeed(baseURL string) *model.Feed {
// Populate the entry URL.
if itemLink == "" {
entry.URL = feed.SiteURL // Fallback to the feed URL if the entry URL is empty.
} else if entryURL, err := urllib.AbsoluteURL(feed.SiteURL, itemLink); err == nil {
} else if entryURL, err := urllib.ResolveToAbsoluteURL(feed.SiteURL, itemLink); err == nil {
entry.URL = entryURL
} else {
entry.URL = itemLink
Expand Down
16 changes: 8 additions & 8 deletions internal/reader/rss/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ func (r *rssAdapter) buildFeed(baseURL string) *model.Feed {
}

// Ensure the Site URL is absolute.
if absoluteSiteURL, err := urllib.AbsoluteURL(baseURL, feed.SiteURL); err == nil {
if absoluteSiteURL, err := urllib.ResolveToAbsoluteURL(baseURL, feed.SiteURL); err == nil {
feed.SiteURL = absoluteSiteURL
}

// Try to find the feed URL from the Atom links.
for _, atomLink := range r.rss.Channel.Links {
atomLinkHref := strings.TrimSpace(atomLink.Href)
if atomLinkHref != "" && atomLink.Rel == "self" {
if absoluteFeedURL, err := urllib.AbsoluteURL(feed.FeedURL, atomLinkHref); err == nil {
if absoluteFeedURL, err := urllib.ResolveToAbsoluteURL(feed.FeedURL, atomLinkHref); err == nil {
feed.FeedURL = absoluteFeedURL
break
}
10BC8 Expand All @@ -61,7 +61,7 @@ func (r *rssAdapter) buildFeed(baseURL string) *model.Feed {

// Get the feed icon URL if defined.
if r.rss.Channel.Image != nil {
if absoluteIconURL, err := urllib.AbsoluteURL(feed.SiteURL, r.rss.Channel.Image.URL); err == nil {
if absoluteIconURL, err := urllib.ResolveToAbsoluteURL(feed.SiteURL, r.rss.Channel.Image.URL); err == nil {
feed.IconURL = absoluteIconURL
}
}
Expand All @@ -83,7 +83,7 @@ func (r *rssAdapter) buildFeed(baseURL string) *model.Feed {
entry.URL = feed.SiteURL
}
} else {
if absoluteEntryURL, err := urllib.AbsoluteURL(feed.SiteURL, entryURL); err == nil {
if absoluteEntryURL, err := urllib.ResolveToAbsoluteURL(feed.SiteURL, entryURL); err == nil {
entry.URL = absoluteEntryURL
} else {
entry.URL = entryURL
Expand Down Expand Up @@ -309,7 +309,7 @@ func findEntryEnclosures(rssItem *rssItem, siteURL string) model.EnclosureList {
continue
}
if _, found := duplicates[mediaURL]; !found {
if mediaAbsoluteURL, err := urllib.AbsoluteURL(siteURL, mediaURL); err != nil {
if mediaAbsoluteURL, err := urllib.ResolveToAbsoluteURL(siteURL, mediaURL); err != nil {
slog.Debug("Unable to build absolute URL for media thumbnail",
slog.String("url", mediaThumbnail.URL),
slog.String("site_url", siteURL),
Expand Down Expand Up @@ -341,7 +341,7 @@ func findEntryEnclosures(rssItem *rssItem, siteURL string) model.EnclosureList {
continue
}

if absoluteEnclosureURL, err := urllib.AbsoluteURL(siteURL, enclosureURL); err == nil {
if absoluteEnclosureURL, err := urllib.ResolveToAbsoluteURL(siteURL, enclosureURL); err == nil {
enclosureURL = absoluteEnclosureURL
}

Expand All @@ -363,7 +363,7 @@ func findEntryEnclosures(rssItem *rssItem, siteURL string) model.EnclosureList {
}
if _, found := duplicates[mediaURL]; !found {
mediaURL := strings.TrimSpace(mediaContent.URL)
if mediaAbsoluteURL, err := urllib.AbsoluteURL(siteURL, mediaURL); err != nil {
if mediaAbsoluteURL, err := urllib.ResolveToAbsoluteURL(siteURL, mediaURL); err != nil {
slog.Debug("Unable to build absolute URL for media content",
slog.String("url", mediaContent.URL),
slog.String("site_url", siteURL),
Expand All @@ -387,7 +387,7 @@ func findEntryEnclosures(rssItem *rssItem, siteURL string) model.EnclosureList {
}
if _, found := duplicates[mediaURL]; !found {
mediaURL := strings.TrimSpace(mediaPeerLink.URL)
if mediaAbsoluteURL, err := urllib.AbsoluteURL(siteURL, mediaURL); err != nil {
if mediaAbsoluteURL, err := urllib.ResolveToAbsoluteURL(siteURL, mediaURL); err != nil {
slog.Debug("Unable to build absolute URL for media peer link",
slog.String("url", mediaPeerLink.URL),
slog.String("site_url", siteURL),
Expand Down
20 changes: 2 additions & 18 deletions internal/reader/sanitizer/sanitizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ func sanitizeAttributes(parsedBaseUrl *url.URL, tagName string, attributes []htm
value = attribute.Val
isAnchorLink = true
default:
value, err = absoluteURLParsedBase(parsedBaseUrl, value)
value, err = urllib.ResolveToAbsoluteURLWithParsedBaseURL(parsedBaseUrl, value)
if err != nil {
continue
}
Expand Down Expand Up @@ -575,7 +575,7 @@ func sanitizeSrcsetAttr(parsedBaseURL *url.URL, value string) string {
imageCandidates := ParseSrcSetAttribute(value)

for _, imageCandidate := range imageCandidates {
if absoluteURL, err := absoluteURLParsedBase(parsedBaseURL, imageCandidate.ImageURL); err == nil {
if absoluteURL, err := urllib.ResolveToAbsoluteURLWithParsedBaseURL(parsedBaseURL, imageCandidate.ImageURL); err == nil {
imageCandidate.ImageURL = absoluteURL
}
}
Expand Down Expand Up @@ -627,19 +627,3 @@ func isValidDecodingValue(value string) bool {
}
return false
}

// absoluteURLParsedBase is used instead of urllib.AbsoluteURL to avoid parsing baseURL over and over.
func absoluteURLParsedBase(parsedBaseURL *url.URL, input string) (string, error) {
absURL, u, err := urllib.GetAbsoluteURL(input)
if err != nil {
return "", err
}
if absURL != "" {
return absURL, nil
}
if parsedBaseURL == nil {
return "", nil
}

return parsedBaseURL.ResolveReference(u).String(), nil
}
8 changes: 4 additions & 4 deletions internal/reader/subscription/finder.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (f *subscriptionFinder) findSubscriptionsFromWebPage(websiteURL, contentTyp
subscription.Type = kind

if feedURL, exists := s.Attr("href"); exists && feedURL != "" {
subscription.URL, err = urllib.AbsoluteURL(websiteURL, feedURL)
subscription.URL, err = urllib.ResolveToAbsoluteURL(websiteURL, feedURL)
if err != nil {
return
}
Expand Down Expand Up @@ -195,15 +195,15 @@ func (f *subscriptionFinder) findSubscriptionsFromWellKnownURLs(websiteURL strin
}

// Look for knownURLs in current subdirectory, such as 'example.com/blog/'.
websiteURL, _ = urllib.AbsoluteURL(websiteURL, "./")
websiteURL, _ = urllib.ResolveToAbsoluteURL(websiteURL, "./")
if websiteURL != websiteURLRoot {
baseURLs = append(baseURLs, websiteURL)
}

var subscriptions Subscriptions
for _, baseURL := range baseURLs {
for knownURL, kind := range knownURLs {
fullURL, err := urllib.AbsoluteURL(baseURL, knownURL)
fullURL, err := urllib.ResolveToAbsoluteURL(baseURL, knownURL)
if err != nil {
continue
}
Expand Down Expand Up @@ -347,7 +347,7 @@ func (f *subscriptionFinder) findCanonicalURL(effectiveURL, contentType string,
return effectiveURL
}

canonicalURL, err := urllib.AbsoluteURL(baseURL, strings.TrimSpace(canonicalHref))
canonicalURL, err := urllib.ResolveToAbsoluteURL(baseURL, strings.TrimSpace(canonicalHref))
if err != nil {
return effectiveURL
}
Expand Down
7 changes: 4 additions & 3 deletions internal/timezone/timezone.go
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ var (
}
)

// Convert converts provided date time to actual timezone.
// Convert returns the provided time expressed in the given timezone.
func Convert(tz string, t time.Time) time.Time {
userTimezone := getLocation(tz)

Expand Down Expand Up @@ -494,7 +494,7 @@ func Convert(tz string, t time.Time) time.Time {
return t
}

// Now returns the current time with the given timezone.
// Now returns the current time in the given timezone.
func Now(tz string) time.Time {
return time.Now().In(getLocation(tz))
}
Expand All @@ -513,12 +513,13 @@ func getLocation(tz string) *time.Location {
return loc
}

// IsValid reports whether the timezone string is in the supported list.
func IsValid(timezone string) bool {
_, found := slices.BinarySearch(timezones, timezone)
return found
}

// AvailableTimezones returns an iterator over supported timezones.
// AvailableTimezones returns an iterator over supported timezone names.
func AvailableTimezones() iter.Seq[string] {
return func(yield func(string) bool) {
for _, tz := range timezones {
Expand Down
13 changes: 13 additions & 0 deletions internal/timezone/timezone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package timezone // import "miniflux.app/v2/internal/timezone"

import (
"slices"
"testing"
"time"

Expand Down Expand Up @@ -114,3 +115,15 @@ func TestIsValid(t *testing.T) {
}
}
}

func TestAvailableTimezones(t *testing.T) {
var got []string

for tz := range AvailableTimezones() {
got = append(got, tz)
}

if !slices.Equal(got, timezones) {
t.Fatalf("available timezones differ from source slice: expected %d entries, got %d", len(timezones), len(got))
}
}
Loading
Loading
0