summaryrefslogtreecommitdiff
path: root/core/entries.go
blob: fb9ab250a986bf8f06223409a6fbf0fce1314ef1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Copyright (C) 2021 nytpu
// SPDX-License-Identifier: AGPL-3.0-or-later
// 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"
	"os"
	"path/filepath"
	"sort"
	"time"
)

// 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
			}
			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
		}
		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())
}

func (d *FullData) WriteSubs(dataPath string) error {
	path := filepath.Join(dataPath, "subscriptions.gmi.new")

	d.RLock()
	pe := d.getPageEntries()
	d.RUnlock()

	rawPage := "# Subscriptions"

	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)
			if pub.Before(curDay) {
				curDay = pub
				rawPage += fmt.Sprintf("\n## %s\n\n", curDay.Format("2006-01-02"))
			}

			if entry.Title == "" {
				rawPage += fmt.Sprintf("=> %s %s\n", entry.URL, entry.Prefix)
			} else {
				rawPage += fmt.Sprintf("=> %s %s — %s\n", entry.URL, entry.Prefix, entry.Title)
			}
		}
	}

	err := os.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
}