Files
comitium/core/entries.go
T
cage e68b88405f add date for each feed entry's link, to match gemlog specs.
Hi!

This is a little patch (and I  guess not well written as I never coded
in golang, before!) to make the  output of comitium matches the gemlog
specification.

This way  clients can subscribe to  the feed (if clients  supports the
standard, of course!).

Please consider merging if you find useful.

Bye!
C.
2026-04-26 08:57:22 -06:00

168 lines
4.5 KiB
Go

// Copyright (C) 2021 nytpu
// SPDX-License-Identifier: AGPL-3.0-only
// For more license details, see LICENSE or <https://www.gnu.org/licenses/agpl-3.0.html>.
// This file incorporates code from makeworld's amfora:
// https://github.com/makeworld-the-better-one/amfora/blob/master/subscriptions/structs.go
// Original source is Copyright 2020 makeworld and is licensed under the
// terms of the GNU General Public License Version 3.0.
// https://www.gnu.org/licenses/gpl-3.0-standalone.html
package core
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
"time"
"golang.nytpu.com/comitium/localizations"
)
// getPageEntries returns a full list of page entries from a FullData. It will
// always be sorted from newest to oldest.
func (d *FullData) getPageEntries() *PageEntries {
var pe PageEntries
d.RLock()
for _, feed := range d.Feeds {
for _, item := range feed.Items {
// Ignore items without links
if item.Link == "" {
continue
}
var prefix string
if feed.Title != "" {
prefix = feed.Title
} else {
prefix = feed.Link
}
if item.Published.After(HistoryDays) {
pe.Entries = append(pe.Entries, &PageEntry{
Prefix: prefix,
Title: item.Title,
Published: item.Published,
URL: item.Link,
})
}
}
}
for _, page := range d.Pages {
var prefix string
if page.Title != "" {
prefix = page.Title
} else {
prefix = page.Link
}
if page.Updated.After(HistoryDays) {
pe.Entries = append(pe.Entries, &PageEntry{
Prefix: prefix,
Published: page.Updated,
URL: page.Link,
})
}
}
d.RUnlock()
sort.Sort(&pe)
return &pe
}
// toLocalDay truncates the provided time to a date only, but converts to the
// local time first.
func toLocalDay(t time.Time) time.Time {
t = t.Local()
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
}
// genDay returns a string with the current date and time
func genDay() string {
return TranslateString("%s\n", "files.generated_on", &localizations.Replacements{"date": time.Now().Format("2006-01-02 at 15:04 MST")})
}
func (d *FullData) WriteSubs(dataPath string) error {
path := filepath.Join(dataPath, "subscriptions.gmi.new")
rawPage := TranslateString("# %s\n\n", "files.subscriptions_subscribed_feeds", nil)
rawPage += genDay()
rawPage += TranslateString("\n\n## %s\n\n", "files.subscriptions_feeds_title", nil)
rawPage += TranslateString("%s\n\n\n", "files.subscriptions_feeds_subtitle", nil)
d.FeedsMu.RLock()
for _, v := range d.Feeds {
var link string
if v.FeedLink != "" {
link = v.FeedLink
} else {
link = v.Link
}
rawPage += fmt.Sprintf("=> %v %v\n", link, v.Title)
}
d.FeedsMu.RUnlock()
rawPage += TranslateString("\n\n## %s\n\n", "files.subscriptions_pages_title", nil)
rawPage += TranslateString("%s\n\n\n", "files.subscriptions_pages_subtitle", nil)
d.PagesMu.RLock()
for _, v := range d.Pages {
rawPage += fmt.Sprintf("=> %v", v.Link)
if v.Title != "" {
rawPage += fmt.Sprintf(" %v", v.Title)
}
rawPage += "\n"
}
d.PagesMu.RUnlock()
rawPage += Footer
err := ioutil.WriteFile(path, []byte(rawPage), 0666)
if err != nil {
return err
}
// if full write was successful then overwrite original
err = os.Rename(path, filepath.Join(dataPath, "subscriptions.gmi"))
return err
}
func (d *FullData) WriteFeed(dataPath string) error {
path := filepath.Join(dataPath, "feed.gmi.new")
rawPage := Header
d.RLock()
pe := d.getPageEntries()
rawPage += TranslateString("\n=> subscriptions.gmi %s\n\n", "files.feed_subscriptions_link", &localizations.Replacements{"num": len(d.Feeds) + len(d.Pages)})
d.RUnlock()
rawPage += genDay()
if len(pe.Entries) > 0 {
curDay := toLocalDay(pe.Entries[0].Published)
rawPage += fmt.Sprintf("\n\n## %s\n\n", curDay.Format("2006-01-02"))
for _, entry := range pe.Entries {
// get just the date it was published
pub := toLocalDay(entry.Published)
formattedPubDay := entry.Published.Format("2006-01-02")
if pub.Before(curDay) {
curDay = pub
rawPage += fmt.Sprintf("\n\n## %s\n\n", formattedPubDay)
}
if entry.Title == "" {
rawPage += fmt.Sprintf("=> %s %s %s\n", entry.URL, formattedPubDay, entry.Prefix)
} else {
rawPage += fmt.Sprintf("=> %s %s %s — %s\n", entry.URL, formattedPubDay, entry.Prefix, entry.Title)
}
}
}
rawPage += Footer
err := ioutil.WriteFile(path, []byte(rawPage), 0666)
if err != nil {
return err
}
// if full write was successful then overwrite original
err = os.Rename(path, filepath.Join(dataPath, "feed.gmi"))
return err
}