openidec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 7d79355321b60472b8ff26d463b18147becbbd47
parent f161f78881d3a1cdaaa1eac2e7c66bbe09f3c6a9
Author: Peter Kosyh <p.kosyh@gmail.com>
Date:   Fri,  5 Feb 2021 08:11:52 +0000

Merge branch 'master' of https://github.com/gl00my/ii-go

Diffstat:
Aii-gemini/main.go | 177+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mii-tool/main.go | 32++++++++++++++++++++++++++++++++
2 files changed, 209 insertions(+), 0 deletions(-)

diff --git a/ii-gemini/main.go b/ii-gemini/main.go @@ -0,0 +1,177 @@ +package main + +import ( + "../ii" + "bufio" + "flag" + "fmt" + "io" + "io/ioutil" + "os" + "sort" + "strings" + "time" +) + +func open_db(path string) *ii.DB { + db := ii.OpenDB(path) + if db == nil { + fmt.Printf("Can no open db: %s\n", path) + os.Exit(1) + } + return db +} + +func GetFile(path string) string { + var file *os.File + var err error + if path == "-" { + file = os.Stdin + } else { + file, err = os.Open(path) + if err != nil { + fmt.Printf("Can not open file %s: %s\n", path, err) + os.Exit(1) + } + defer file.Close() + } + b, err := ioutil.ReadAll(file) + if err != nil { + fmt.Printf("Can not read file %s: %s\n", path, err) + os.Exit(1) + } + return string(b) +} + +func gemini(f io.Writer, m *ii.Msg) { + fmt.Fprintln(f, "# " + m.Subj) + if m.To != "All" { + fmt.Fprintf(f, "To: %s\n\n", m.To) + } + d := time.Unix(m.Date, 0).Format("2006-01-02 15:04:05") + fmt.Fprintf(f, "by %s on %s\n\n", m.From, d) + temp := strings.Split(m.Text, "\n") + pre := false + xpm := false + for _, l := range temp { + l = strings.Replace(l, "\r", "", -1) + if pre { + if l == "====\r" { + l = "````\r" + pre = false + } + } else if xpm { + if strings.HasSuffix(l, "};\r") { + xpm = false + fmt.Fprintln(f, l) + fmt.Fprintln(f, "```\r") + continue + } + } else { + if l == "====\r" { + l = "```" + pre = true + } else if strings.HasPrefix(l, "/* XPM */") { + fmt.Fprintln(f, "```\r") + xpm = true + } + } + fmt.Fprintln(f, l) + } + fmt.Fprintln(f, "") + fmt.Fprintf(f, "=> https://hugeping.tk/"+m.MsgId + " Ссылка на статью на станции ping\n") +} + +func str_esc(l string) string { + l = strings.Replace(l, "&", "&amp;", -1) + l = strings.Replace(l, "<", "&lt;", -1) + l = strings.Replace(l, ">", "&gt;", -1) + return l +} + +func main() { + ii.OpenLog(ioutil.Discard, os.Stdout, os.Stderr) + + db_opt := flag.String("db", "./db", "II database path (directory)") + data_opt := flag.String("data", "./data", "Output path (directory)") + url_opt := flag.String("url", "localhost", "Url of station") + verbose_opt := flag.Bool("v", false, "Verbose") + title_opt := flag.String("title", "ii/idec networks", "Title") + author_opt := flag.String("author", "anonymous", "Author") + flag.Parse() + if *verbose_opt { + ii.OpenLog(os.Stdout, os.Stdout, os.Stderr) + } + + args := flag.Args() + if len(args) < 1 { + fmt.Printf(`Help: %s [options] command [arguments] +Commands: + -data <path> gemini - generate gemini data +Options: + -db=<path> - database path +`, os.Args[0]) + os.Exit(1) + } + switch cmd := args[0]; cmd { + case "gemini": + db := open_db(*db_opt) + db.Lock() + defer db.Unlock() + db.LoadIndex() + + scanner := bufio.NewScanner(os.Stdin) + var mis []*ii.Msg + for scanner.Scan() { + mi := db.LookupFast(scanner.Text(), false) + if mi != nil { + mis = append(mis, db.Get(mi.Id)) + } + } + sort.SliceStable(mis, func(i, j int) bool { + return mis[i].Date > mis[j].Date + }) + data := strings.TrimSuffix(*data_opt, "/") + atom, err := os.Create(data + "/atom.xml") + if err != nil { + return + } + defer atom.Close() + fmt.Fprintf(atom, `<?xml version="1.0" encoding="utf-8"?> +<feed xmlns="http://www.w3.org/2005/Atom"> + <title>%s</title> + <link href="gemini://%s/atom.xml" rel="self"/> + <link href="gemini://%s/" rel="alternate"/> + <updated>%s</updated> + <author> + <name>%s</name> + </author> + <id>gemini://%s/</id> +`, *title_opt, *url_opt, *url_opt, time.Now().Format(time.RFC3339), *author_opt, *url_opt) + for _, v := range mis { + m := v + if m != nil { + f, err := os.Create(data + "/" + m.MsgId + ".gmi") + if err == nil { + gemini(f, m) + d := time.Unix(m.Date, 0).Format("2006-01-02") + fmt.Println("=> /"+ m.MsgId + ".gmi " + d + " - " + m.Subj) + } + f.Close() + fmt.Fprintf(atom, `<entry> +<title>%s</title> +<link href="gemini://%s/%s.gmi" rel="alternate"/> +<id>gemini://%s/%s.gmi</id> +<updated>%s</updated> +</entry> +`, str_esc(m.Subj), *url_opt, m.MsgId, + *url_opt, m.MsgId, time.Unix(m.Date, 0).Format(time.RFC3339)) + } + } + fmt.Fprintf(atom, `</feed> +`) + default: + fmt.Printf("Wrong cmd: %s\n", cmd) + os.Exit(1) + } +} diff --git a/ii-tool/main.go b/ii-tool/main.go @@ -59,6 +59,7 @@ func main() { force_opt := flag.Bool("f", false, "Force full sync") users_opt := flag.String("u", "points.txt", "Users database") conns_opt := flag.Int("j", 6, "Maximum parallel jobs") + topics_opt := flag.Bool("t", false, "Select topics only") flag.Parse() ii.MaxConnections = *conns_opt @@ -85,6 +86,7 @@ Options: -db=<path> - database path -lim=<lim> - fetch lim last messages -u=<path> - points account file + -t - topics only (select,get) `, os.Args[0]) os.Exit(1) } @@ -325,6 +327,33 @@ Options: os.Exit(1) } db := open_db(*db_opt) + + if *topics_opt { + mi := db.Lookup(args[1]) + if mi == nil { + return + } + mis := db.LookupIDS(db.SelectIDS(ii.Query{Echo: mi.Echo})) + topic := mi.Id + for p := mi; p != nil; p = db.LookupFast(p.Repto, false) { + if p.Repto == p.Id { + break + } + if p.Echo != mi.Echo { + continue + } + topic = p.Id + } + ids := db.GetTopics(mis)[topic] + if len(ids) == 0 { + ids = append(ids, args[1]) + } + for _, m := range ids { + fmt.Println(m) + } + return + } + m := db.Get(args[1]) if m != nil { fmt.Println(m) @@ -354,6 +383,9 @@ Options: } db := open_db(*db_opt) req := ii.Query{Echo: args[1]} + if *topics_opt { + req.Repto = "!" + } if len(args) > 2 { fmt.Sscanf(args[2], "%d:%d", &req.Start, &req.Lim) }