Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

Commit a6b26f7

Browse files
committed
Implement OPML importing and version printing
1 parent a573979 commit a6b26f7

File tree

4 files changed

+94
-9
lines changed

4 files changed

+94
-9
lines changed

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ You need to have Go >=1.19 installed.
3838
`add [feed name] [feed url]`
3939
- Adds a new feed to the config file
4040

41+
`import [OPML URL or file path]`
42+
- Imports feeds from OPML file
43+
44+
`version`
45+
- Prints the rssnix version
46+
4147
## Config
4248

4349
Config file is expected to be at `~/.config/rssnix/config.ini`.

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/PuerkitoBio/goquery v1.5.1 // indirect
77
github.com/andybalholm/cascadia v1.1.0 // indirect
88
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
9+
github.com/gilliek/go-opml v1.0.0 // indirect
910
github.com/go-ini/ini v1.67.0 // indirect
1011
github.com/json-iterator/go v1.1.10 // indirect
1112
github.com/mmcdole/gofeed v1.1.3 // indirect

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHH
88
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
99
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1010
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11+
github.com/gilliek/go-opml v1.0.0 h1:X8xVjtySRXU/x6KvaiXkn7OV3a4DHqxY8Rpv6U/JvCY=
12+
github.com/gilliek/go-opml v1.0.0/go.mod h1:fOxmtlzyBvUjU6bjpdjyxCGlWz+pgtAHrHf/xRZl3lk=
1113
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
1214
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
1315
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=

main.go

+85-9
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,38 @@ import (
44
"errors"
55
"os"
66
"os/exec"
7+
"strings"
78
"syscall"
89

10+
"github.com/gilliek/go-opml/opml"
11+
"github.com/go-ini/ini"
912
log "github.com/sirupsen/logrus"
1013
"github.com/urfave/cli/v2"
1114
)
1215

16+
const Version = "0.2.0"
17+
18+
func addFeed(name string, url string) error {
19+
homePath, err := os.UserHomeDir()
20+
if err != nil {
21+
log.Error("Failed to get home path")
22+
os.Exit(1)
23+
}
24+
cfg, err := ini.Load(homePath + "/.config/rssnix/config.ini")
25+
for _, key := range cfg.Section("feeds").Keys() {
26+
if key.Name() == name {
27+
return errors.New("Feed named '" + name + "' already exists")
28+
}
29+
}
30+
file, err := os.OpenFile(homePath+"/.config/rssnix/config.ini", os.O_APPEND|os.O_WRONLY, 0644)
31+
if err != nil {
32+
return err
33+
}
34+
defer file.Close()
35+
_, err = file.WriteString("\n" + name + " = " + url)
36+
return err
37+
}
38+
1339
func main() {
1440
syscall.Umask(0)
1541
LoadConfig()
@@ -75,18 +101,68 @@ func main() {
75101
if cCtx.Args().Len() != 2 {
76102
return errors.New("exactly two arguments are required, first being feed name, second being URL")
77103
}
78-
homePath, err := os.UserHomeDir()
79-
if err != nil {
80-
log.Error("Failed to get home path")
81-
os.Exit(1)
104+
return addFeed(cCtx.Args().Get(0), cCtx.Args().Get(1))
105+
},
106+
},
107+
{
108+
Name: "import",
109+
Aliases: []string{"i"},
110+
Usage: "import an OPML file",
111+
Action: func(cCtx *cli.Context) error {
112+
if cCtx.Args().Len() != 1 {
113+
return errors.New("argument specifying OPML file path or URL is required")
82114
}
83-
file, err := os.OpenFile(homePath+"/.config/rssnix/config.ini", os.O_APPEND|os.O_WRONLY, 0644)
115+
doc, err := opml.NewOPMLFromFile(cCtx.Args().Get(0))
84116
if err != nil {
85-
return err
117+
doc, err = opml.NewOPMLFromURL(cCtx.Args().Get(0))
118+
if err != nil {
119+
return err
120+
}
86121
}
87-
defer file.Close()
88-
_, err = file.WriteString("\n" + cCtx.Args().Get(0) + " = " + cCtx.Args().Get(1))
89-
return err
122+
for _, outline := range doc.Body.Outlines {
123+
if len(outline.XMLURL) > 0 {
124+
var title string
125+
if len(outline.Title) > 0 {
126+
title = outline.Title
127+
} else if len(outline.Text) > 0 {
128+
title = outline.Text
129+
} else {
130+
continue
131+
}
132+
err = addFeed(strings.ReplaceAll(title, " ", "-"), outline.XMLURL)
133+
if err != nil {
134+
log.Error("Failed to add feed titled '" + title + "', error: " + err.Error())
135+
continue
136+
}
137+
}
138+
for _, innerOutline := range outline.Outlines {
139+
if len(innerOutline.XMLURL) > 0 {
140+
var title string
141+
if len(outline.Title) > 0 {
142+
title = outline.Title
143+
} else if len(outline.Text) > 0 {
144+
title = outline.Text
145+
} else {
146+
continue
147+
}
148+
err = addFeed(strings.ReplaceAll(title, " ", "-"), innerOutline.XMLURL)
149+
if err != nil {
150+
log.Error("Failed to add feed titled '" + title + "', error: " + err.Error())
151+
continue
152+
}
153+
}
154+
}
155+
}
156+
return nil
157+
},
158+
},
159+
{
160+
Name: "version",
161+
Aliases: []string{"v"},
162+
Usage: "display the version",
163+
Action: func(cCtx *cli.Context) error {
164+
log.Info(Version)
165+
return nil
90166
},
91167
},
92168
},

0 commit comments

Comments
 (0)