summaryrefslogtreecommitdiff
path: root/lex-fetch/main.go
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2025-04-08 19:25:36 +0200
committerMartin Fischer <martin@push-f.com>2025-04-14 07:04:45 +0200
commite29d27533725819ec3f6d05a27048d3d2627b53e (patch)
tree5afba50408b25179edb4ea6445acfe1d3e051488 /lex-fetch/main.go
parent96236c9d80cea2d6ba83591a7d08a8cc096fd8d3 (diff)
refactor: port fetchers to Go
* Austria: upgraded to RIS API v2.6 because v2.5 has been turned off
Diffstat (limited to 'lex-fetch/main.go')
-rw-r--r--lex-fetch/main.go133
1 files changed, 133 insertions, 0 deletions
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] <country> <out>\n", os.Args[0])
+ fmt.Printf("where <country> 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)
+}