]> Sergey Matveev's repositories - linksexp.git/blob - main.go
urls export support
[linksexp.git] / main.go
1 /*
2 linksexp -- Texinfo/XBEL/OPML/urls autogeneration from recfile bookmark
3 Copyright (C) 2021 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 package main
19
20 import (
21         "flag"
22         "fmt"
23         "io"
24         "os"
25         "sort"
26         "strings"
27         "time"
28
29         "go.cypherpunks.ru/recfile"
30 )
31
32 type ByTitle []map[string][]string
33
34 func (a ByTitle) Len() int      { return len(a) }
35 func (a ByTitle) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
36 func (a ByTitle) Less(i, j int) bool {
37         return strings.Compare(a[i]["Title"][0], a[j]["Title"][0]) < 0
38 }
39
40 func main() {
41         doXBEL := flag.Bool("xbel", false, "Make XBEL")
42         doOPML := flag.Bool("opml", false, "Make OPML")
43         doURLS := flag.Bool("urls", false, "Make newsboat urls")
44         flag.Parse()
45
46         r := recfile.NewReader(os.Stdin)
47
48         if *doURLS {
49                 for {
50                         m, err := r.NextMapWithSlice()
51                         if err == io.EOF {
52                                 break
53                         }
54                         if err != nil {
55                                 panic(err)
56                         }
57                         if m["%rec"] != nil {
58                                 continue
59                         }
60                         sort.Strings(m["Category"])
61                         cats := strings.Join(m["Category"], " ")
62                         for _, f := range m["Feed"] {
63                                 fmt.Println(f, cats)
64                         }
65                 }
66                 os.Exit(0)
67         }
68
69         if *doOPML {
70                 data := make([]map[string][]string, 0)
71                 for {
72                         m, err := r.NextMapWithSlice()
73                         if err == io.EOF {
74                                 break
75                         }
76                         if err != nil {
77                                 panic(err)
78                         }
79                         if m["%rec"] != nil {
80                                 continue
81                         }
82                         sort.Strings(m["Category"])
83                         data = append(data, m)
84                 }
85                 sort.Sort(ByTitle(data))
86                 opml(data)
87                 os.Exit(0)
88         }
89
90         data := make(map[string][]map[string][]string)
91         for {
92                 m, err := r.NextMapWithSlice()
93                 if err == io.EOF {
94                         break
95                 }
96                 if err != nil {
97                         panic(err)
98                 }
99                 if m["%rec"] != nil {
100                         continue
101                 }
102                 sort.Strings(m["Category"])
103                 if cs := m["Category"]; len(cs) == 0 {
104                         data["Uncategorized"] = append(data["Uncategorized"], m)
105                 } else {
106                         for _, cat := range cs {
107                                 data[cat] = append(data[cat], m)
108                         }
109                 }
110         }
111         cats := make([]string, 0, len(data))
112         for c := range data {
113                 cats = append(cats, c)
114                 sort.Sort(ByTitle(data[c]))
115         }
116         sort.Strings(cats)
117
118         if *doXBEL {
119                 xbel(cats, data)
120                 os.Exit(0)
121         }
122
123         fmt.Println("Updated:", time.Now().Format(time.RFC3339))
124         fmt.Println("@table @strong")
125         for _, cat := range cats {
126                 fmt.Println("@item", cat)
127                 fmt.Println("@multitable @columnfractions .05 .8 .1 .05")
128                 ents := data[cat]
129                 for n, ent := range ents {
130                         catsOther := make([]string, 0)
131                         for _, c := range ent["Category"] {
132                                 if c != cat {
133                                         catsOther = append(catsOther, c)
134                                 }
135                         }
136                         var note string
137                         if len(ent["Note"]) > 0 {
138                                 note = "(" + ent["Note"][0] + ")"
139                         }
140                         fmt.Printf(
141                                 "  @item %d @tab @url{%s, %s} %s @tab %s @tab\n",
142                                 n, ent["URL"][0], ent["Title"][0], note,
143                                 strings.Join(catsOther, ", "),
144                         )
145                         switch feeds := ent["Feed"]; len(feeds) {
146                         case 0:
147                                 fmt.Printf("    @emph{STATIC}\n")
148                         case 1:
149                                 fmt.Printf("    @url{%s, feed}\n", feeds[0])
150                         default:
151                                 for i, feed := range feeds {
152                                         fmt.Printf("    @url{%s, feed%d}\n", feed, i)
153                                 }
154                         }
155                 }
156                 fmt.Println("@end multitable")
157         }
158         fmt.Println("@end table")
159 }