e68b88405f
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.
168 lines
4.5 KiB
Go
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
|
|
}
|