From e29d27533725819ec3f6d05a27048d3d2627b53e Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Tue, 8 Apr 2025 19:25:36 +0200 Subject: refactor: port fetchers to Go * Austria: upgraded to RIS API v2.6 because v2.5 has been turned off --- lex-fetch/main.go | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 lex-fetch/main.go (limited to 'lex-fetch/main.go') diff --git a/lex-fetch/main.go b/lex-fetch/main.go new file mode 100644 index 0000000..57019b4 --- /dev/null +++ b/lex-fetch/main.go @@ -0,0 +1,133 @@ +package main + +import ( + "context" + "encoding/json" + "flag" + "fmt" + "io" + "log/slog" + "maps" + "net" + "net/http" + "os" + "slices" + + "golang.org/x/term" + "push-f.com/lex-surf/internal/lex" + "push-f.com/lex-surf/lex-fetch/at" + "push-f.com/lex-surf/lex-fetch/de" + "push-f.com/lex-surf/lex-fetch/progress" + "push-f.com/lex-surf/lex-fetch/uk" +) + +type Fetcher interface { + Fetch(log *slog.Logger, client *http.Client, reporter *progress.Reporter) ([]lex.Law, error) +} + +var fetchers = map[string]Fetcher{ + "at": &at.Fetcher{}, + "de": &de.Fetcher{}, + "uk": &uk.Fetcher{}, +} + +var logger *slog.Logger + +func printUsage() { + fmt.Printf("usage: %s [options] \n", os.Args[0]) + fmt.Printf("where is one of %v\n", slices.Sorted(maps.Keys(fetchers))) + fmt.Println("options are:") + flag.PrintDefaults() +} + +func main() { + debug := flag.Bool("debug", false, "Enable debug logging") + flag.Usage = printUsage + flag.Parse() + + args := flag.Args() + if len(args) != 2 { + printUsage() + os.Exit(1) + } + + country := args[0] + out := args[1] + + client := http.Client{ + Transport: &CustomTransport{}, + } + + fetcher, ok := fetchers[country] + if !ok { + printUsage() + os.Exit(1) + } + + logOptions := slog.HandlerOptions{} + if *debug { + logOptions.Level = slog.LevelDebug + } + logger = slog.New(slog.NewTextHandler(os.Stderr, &logOptions)) + + var progressReporter progress.Reporter + if term.IsTerminal(int(os.Stdout.Fd())) { + progressReporter = progress.NewReporter(os.Stdout) + } else { + progressReporter = progress.NewReporter(io.Discard) + } + + laws, err := fetcher.Fetch(logger, &client, &progressReporter) + if err != nil { + logger.Error("fetching failed", "error", err) + os.Exit(1) + } + + if len(laws) == 0 { + logger.Error("fetcher found 0 laws") + os.Exit(1) + } + + file, err := os.Create(out) + if err != nil { + logger.Error("failed to create file", "err", err, "path", out) + os.Exit(1) + } + defer file.Close() + + err = json.NewEncoder(file).Encode(laws) + if err != nil { + logger.Error("failed to encode laws as JSON", "err", err) + os.Exit(1) + } + + socketPath := os.Getenv("SOCKET_PATH") + if socketPath == "" { + logger.Info("not notifyng lex-serve because SOCKET_PATH isn't set") + } else { + client = http.Client{ + Transport: &http.Transport{ + DialContext: func(ctx context.Context, network string, addr string) (net.Conn, error) { + return net.Dial("unix", socketPath) + }, + }, + } + resp, err := client.Get("http://internal.invalid/update?country=" + country) + if err != nil { + logger.Error("failed to update lex-serve", "err", err) + os.Exit(1) + } + if resp.StatusCode != 200 { + logger.Error("unexpected status code from lex-serve", "statusCode", resp.StatusCode) + os.Exit(1) + } + } +} + +type CustomTransport struct{} + +func (t *CustomTransport) RoundTrip(req *http.Request) (*http.Response, error) { + logger.Debug("request", "method", req.Method, "url", req.URL) + req.Header["User-Agent"] = []string{"lex-surf"} + return http.DefaultTransport.RoundTrip(req) +} -- cgit v1.2.3