misc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.alexwennerberg.com/misc
Log | Files | Refs | README | LICENSE

commit 2f2183cd2349530513ca8aa7b2d856827ea9d61e
parent 5df16c096c92cbe1008ed8bb3ee1d0b53bd27762
Author: alex wennerberg <alex@alexwennerberg.com>
Date:   Sun, 24 Oct 2021 18:03:20 -0700

Create pinky client

Diffstat:
Apinky.go | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 105 insertions(+), 0 deletions(-)

diff --git a/pinky.go b/pinky.go @@ -0,0 +1,105 @@ +package main + +// A very simple client for the Pinky aggregation format +// https://alex.flounder.online/tech/pinky.gmi +// Only supports finger ATM + +import ( + "bufio" + "fmt" + "log" + "net" + "net/url" + "os" + "strings" + "time" +) + +const LAYOUT = "2006-01" + +func main() { + configPath := "pinky-urls" + file, err := os.Open(configPath) + if err != nil { + log.Fatal(err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + + dates := make(map[string][]string) + for scanner.Scan() { + t := scanner.Text() + // TODO goroutine + date, err := getDate(t) // yyyy-mm formatted date + if err != nil { + // log.Println(err) + continue + } + _, ok := dates[date] + if !ok { + dates[date] = []string{} + } + dates[date] = append(dates[date], t) + } + + if err := scanner.Err(); err != nil { + log.Fatal(err) + } + + keys := make([]string, 0, len(dates)) + for k := range dates { + keys = append(keys, k) + } + for _, k := range keys { + fmt.Println(k) + for _, u := range dates[k] { + fmt.Println(u) + } + } +} + +// returns yyyy-mm +func getDate(myurl string) (string, error) { + log.Println("Getting date for " + myurl) + u, err := url.Parse(myurl) + if err != nil { + return "", err + } + switch u.Scheme { + // This is a draft spec: https://datatracker.ietf.org/doc/html/draft-ietf-uri-url-finger-02 + case "finger": + return getFingerDate(u) + } + return "", fmt.Errorf("invalid protocol") +} + +func getFingerDate(url *url.URL) (string, error) { + conn, err := net.DialTimeout("tcp", url.Host+":79", 5*time.Second) + if err != nil { + return "", err + } + defer conn.Close() + _, err = conn.Write([]byte(url.Path[1:] + "\r\n")) + scanner := bufio.NewScanner(conn) + n := 0 + for scanner.Scan() { + t := scanner.Text() + // fmt.Println(t) + if strings.HasPrefix(t, "Updated: ") { + spl := strings.Split(t, " ") + u, err := time.Parse(LAYOUT, spl[1]) + if u.After(time.Now()) { + return "", fmt.Errorf("In the future") + } + if err == nil { + return spl[1], nil + } + } + n++ + if n >= 3 { + break + } + } + return "", fmt.Errorf("No valid updated field found") +}