-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathlist_cmd.go
132 lines (101 loc) · 2.72 KB
/
list_cmd.go
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//
// List our configured-feeds.
//
package main
import (
"flag"
"fmt"
"log/slog"
"time"
"github.com/skx/rss2email/configfile"
"github.com/skx/rss2email/httpfetch"
)
var (
maxInt = int(^uint(0) >> 1)
)
// Structure for our options and state.
type listCmd struct {
// Configuration file, used for testing
config *configfile.ConfigFile
// verbose controls whether our feed-list contains information
// about feed entries and their ages
verbose bool
}
// Arguments handles argument-flags we might have.
//
// In our case we use this as a hook to setup our configuration-file,
// which allows testing.
func (l *listCmd) Arguments(flags *flag.FlagSet) {
// Setup configuration file
l.config = configfile.New()
// Are we listing verbosely?
flags.BoolVar(&l.verbose, "verbose", false, "Show extra information about each feed (slow)?")
}
// Info is part of the subcommand-API
func (l *listCmd) Info() (string, string) {
return "list", `Output the list of feeds which are being polled.
This subcommand lists the feeds which are specified in the
configuration file.
To see details of the configuration file, including the location,
please run:
$ rss2email help config
You can add '-verbose' to see details about the feed contents, but note
that this will require downloading the contents of each feed and will
thus be slow - a simpler way of showing history would be to run:
$ rss2email seen
Example:
$ rss2email list
`
}
func (l *listCmd) showFeedDetails(entry configfile.Feed) {
// Fetch the details
helper := httpfetch.New(entry, logger, version)
feed, err := helper.Fetch()
if err != nil {
fmt.Fprintf(out, "# %s\n%s\n", err.Error(), entry.URL)
return
}
// Handle single vs. plural entries
entriesString := "entries"
if len(feed.Items) == 1 {
entriesString = "entry"
}
// get the age-range of the feed-entries
oldest := -1
newest := maxInt
for _, item := range feed.Items {
if item.PublishedParsed == nil {
break
}
age := int(time.Since(*item.PublishedParsed) / (24 * time.Hour))
if age > oldest {
oldest = age
}
if age < newest {
newest = age
}
}
// Now show the details, which is a bit messy.
fmt.Fprintf(out, "# %d %s, aged %d-%d days\n", len(feed.Items), entriesString, newest, oldest)
fmt.Fprintf(out, "%s\n", entry.URL)
}
// Entry-point.
func (l *listCmd) Execute(args []string) int {
// Now do the parsing
entries, err := l.config.Parse()
if err != nil {
logger.Error("failed to parse configuration file",
slog.String("configfile", l.config.Path()),
slog.String("error", err.Error()))
return 1
}
// Show the feeds
for _, entry := range entries {
if l.verbose {
l.showFeedDetails(entry)
} else {
fmt.Fprintf(out, "%s\n", entry.URL)
}
}
return 0
}