diff options
| author | Xe Iaso <me@xeiaso.net> | 2023-07-26 11:57:32 -0400 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2023-07-26 11:57:32 -0400 |
| commit | 1640e2c5b0b070cb2118aade61084e092947f85f (patch) | |
| tree | 007d80a5b0fa429b388970d67c8780932522f63b | |
| parent | 4b1553f221474f22a7176c1c9dab5e9be00ef47d (diff) | |
| download | x-1640e2c5b0b070cb2118aade61084e092947f85f.tar.xz x-1640e2c5b0b070cb2118aade61084e092947f85f.zip | |
cmd: add new command sanguisuga
Signed-off-by: Xe Iaso <me@xeiaso.net>
| -rw-r--r-- | cmd/sanguisuga/.gitignore | 2 | ||||
| -rw-r--r-- | cmd/sanguisuga/config.default.ts | 55 | ||||
| -rw-r--r-- | cmd/sanguisuga/config.go | 32 | ||||
| -rw-r--r-- | cmd/sanguisuga/main.go | 298 | ||||
| -rw-r--r-- | go.mod | 9 | ||||
| -rw-r--r-- | go.sum | 24 | ||||
| -rw-r--r-- | gomod2nix.toml | 25 |
7 files changed, 440 insertions, 5 deletions
diff --git a/cmd/sanguisuga/.gitignore b/cmd/sanguisuga/.gitignore new file mode 100644 index 0000000..5841fb6 --- /dev/null +++ b/cmd/sanguisuga/.gitignore @@ -0,0 +1,2 @@ +config.ts +data.json diff --git a/cmd/sanguisuga/config.default.ts b/cmd/sanguisuga/config.default.ts new file mode 100644 index 0000000..12b8632 --- /dev/null +++ b/cmd/sanguisuga/config.default.ts @@ -0,0 +1,55 @@ +export type IRC = { + server: string; + password: string; + channel: string; + nick: string; + user: string; + real: string; +}; + +export type Show = { + title: string; + diskPath: string; + quality: string; +}; + +export type Transmission = { + host: string; + user: string; + password: string; + https: bool; + rpcURI: string; +}; + +export type Config = { + irc: IRC; + transmission: Transmission; + shows: Show[]; + rssKey: string; +}; + +export default { + irc: { + server: "", + password: "", + channel: "", + nick: "", + user: "", + real: "" + }, + transmission: { + host: "", + user: "", + password: "", + https: true, + rpcURI: "/transmission/rpc" + }, + shows: [ + { + title: "Show Name", + diskPath: "/data/TV/Show Name", + quality: "1080p" + } + ], + rssKey: "", +} satisfies Config; diff --git a/cmd/sanguisuga/config.go b/cmd/sanguisuga/config.go new file mode 100644 index 0000000..589501d --- /dev/null +++ b/cmd/sanguisuga/config.go @@ -0,0 +1,32 @@ +package main + +type IRC struct { + Server string `json:"server"` + Password string `json:"password"` + Channel string `json:"channel"` + Regex string `json:"regex"` + Nick string `json:"nick"` + User string `json:"user"` + Real string `json:"real"` +} + +type Show struct { + Title string `json:"title"` + DiskPath string `json:"diskPath"` + Quality string `json:"quality"` +} + +type Transmission struct { + Host string `json:"host"` + User string `json:"user"` + Password string `json:"password"` + HTTPS bool `json:"https"` + RPCURI string `json:"rpcURI"` +} + +type Config struct { + IRC IRC `json:"irc"` + Transmission Transmission `json:"transmission"` + Shows []Show `json:"shows"` + RSSKey string `json:"rssKey"` +} diff --git a/cmd/sanguisuga/main.go b/cmd/sanguisuga/main.go new file mode 100644 index 0000000..e6f64f3 --- /dev/null +++ b/cmd/sanguisuga/main.go @@ -0,0 +1,298 @@ +package main + +import ( + "context" + "flag" + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/hekmon/transmissionrpc/v2" + irc "github.com/thoj/go-ircevent" + "go.jetpack.io/tyson" + "golang.org/x/exp/slog" + "tailscale.com/hostinfo" + "tailscale.com/jsondb" + "within.website/x/internal" +) + +var ( + dbLoc = flag.String("db-loc", "./data.json", "path to data file") + tysonConfig = flag.String("tyson-config", "./config.ts", "path to configuration secrets (TySON)") + slogLevel = flag.String("slog-level", "INFO", "log level") + + annRegex = regexp.MustCompile(`^New Torrent Announcement: <([^>]*)>\s+Name:'(.*)' uploaded by '.*' ?(freeleech)?\s+-\s+https://\w+.\w+.\w+./\w+./([0-9]+)$`) + showName = regexp.MustCompile(`^(.*)\s+(S[0-9]+E[0-9]+)\s+([0-9]+p)\s+(\w+)\s+(.*)$`) +) + +type ShowMeta struct { + Name string + SeasonEpisode *SeasonEpisode + Quality string + Kind string + Group string +} + +func (sm ShowMeta) StateKey() string { + return fmt.Sprintf("%s %s", sm.Name, sm.SeasonEpisode) +} + +func ParseShowMeta(input string) (*ShowMeta, error) { + match := showName.FindStringSubmatch(input) + + if match == nil { + return nil, fmt.Errorf("invalid input for TV show name: %q", input) + } + + result := ShowMeta{ + Name: strings.TrimSpace(match[1]), + Quality: match[3], + Kind: match[4], + Group: match[5], + } + + se, err := ParseSeasonEpisode(match[2]) + if err != nil { + return nil, err + } + + result.SeasonEpisode = se + + return &result, nil +} + +type SeasonEpisode struct { + Season string + Episode string +} + +func (se SeasonEpisode) GetFormattedSeason() string { + return "Season " + se.Season +} + +func (se *SeasonEpisode) String() string { + return "S" + se.Season + "E" + se.Episode +} + +func ParseSeasonEpisode(input string) (*SeasonEpisode, error) { + re := regexp.MustCompile(`S([0-9]+)E([0-9]+)`) + match := re.FindStringSubmatch(input) + + if match == nil { + return nil, fmt.Errorf("invalid input for SeasonEpisode: %q", input) + } + + season := match[1] + episode := match[2] + se := &SeasonEpisode{ + Season: season, + Episode: episode, + } + + return se, nil +} + +func ConvertURL(torrentID, rssKey, name string) string { + name = strings.ReplaceAll(name, " ", ".") + ".torrent" + return fmt.Sprintf("https://torrentleech.org/rss/download/%s/%s/%s", torrentID, rssKey, name) +} + +type TorrentAnnouncement struct { + Category string + Name string + Freeleech bool + TorrentID string +} + +func ParseTorrentAnnouncement(input string) (*TorrentAnnouncement, error) { + match := annRegex.FindStringSubmatch(input) + + if match == nil { + return nil, fmt.Errorf("invalid torrent announcement format") + } + + torrent := &TorrentAnnouncement{ + Category: match[1], + Name: strings.TrimSpace(match[2]), + Freeleech: match[3] != "", + TorrentID: match[4], + } + + return torrent, nil +} + +func main() { + internal.HandleStartup() + hostinfo.SetApp("within.website/x/cmd/sanguisuga") + + var programLevel slog.Level + if err := (&programLevel).UnmarshalText([]byte(*slogLevel)); err != nil { + fmt.Fprintf(os.Stderr, "invalid log level %s: %v, using info\n", *slogLevel, err) + programLevel = slog.LevelInfo + } + + h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ + AddSource: true, + Level: programLevel, + }) + slog.SetDefault(slog.New(h)) + + var c Config + if err := tyson.Unmarshal(*tysonConfig, &c); err != nil { + slog.Error("can't unmarshal config", "err", err) + os.Exit(1) + } + + db, err := jsondb.Open[State](*dbLoc) + if err != nil { + slog.Error("can't set up database", "err", err) + os.Exit(1) + } + if db.Data == nil { + db.Data = &State{ + Seen: map[string]TorrentAnnouncement{}, + } + } + if err := db.Save(); err != nil { + slog.Error("can't ping database", "err", err) + os.Exit(1) + } + + tm, err := transmissionrpc.New(c.Transmission.Host, c.Transmission.User, c.Transmission.Password, &transmissionrpc.AdvancedConfig{ + Port: 443, + HTTPS: c.Transmission.HTTPS, + RPCURI: c.Transmission.RPCURI, + }) + if err != nil { + slog.Error("can't connect to transmission", "err", err) + os.Exit(1) + } + _ = tm + + portOpen, err := tm.PortTest(context.Background()) + if err != nil { + slog.Error("can't test if port is open", "err", err) + os.Exit(1) + } + + slog.Info("port status", "open", portOpen) + + s := &Sanguisuga{ + Config: c, + tc: tm, + db: db, + } + + ircCli := irc.IRC(c.IRC.Nick, c.IRC.User) + ircCli.Password = c.IRC.Password + ircCli.RealName = c.IRC.Real + ircCli.AddCallback("PRIVMSG", s.HandleIRCMessage) + ircCli.AddCallback("001", func(ev *irc.Event) { + ircCli.Join(c.IRC.Channel) + }) + ircCli.Log = slog.NewLogLogger(h.WithAttrs([]slog.Attr{slog.String("from", "ircevent")}), slog.LevelInfo) + ircCli.Timeout = 5 * time.Second + + if err := ircCli.Connect(c.IRC.Server); err != nil { + slog.Error("can't connect to IRC server", "server", c.IRC.Server, "err", err) + os.Exit(1) + } + + ircCli.Loop() +} + +type Sanguisuga struct { + Config Config + tc *transmissionrpc.Client + db *jsondb.DB[State] +} + +func (s *Sanguisuga) DelayedStartTorrent(tid int64) { + s.tc.TorrentStopIDs(context.Background(), []int64{tid}) + time.Sleep(5 * time.Second) // delay a bit + s.tc.TorrentStartNowIDs(context.Background(), []int64{tid}) +} + +type State struct { + // Name + " " + SeasonEpisode -> TorrentAnnouncement + Seen map[string]TorrentAnnouncement +} + +func (s *Sanguisuga) HandleIRCMessage(ev *irc.Event) { + // check if in channel + if ev.Code != "PRIVMSG" { + return + } + + if ev.Arguments[0] != s.Config.IRC.Channel { + return + } + + ta, err := ParseTorrentAnnouncement(ev.MessageWithoutFormat()) + if err != nil { + slog.Debug("can't parse torrent announcment", "err", err, "msg", ev.MessageWithoutFormat()) + return + } + + slog.Debug("found torrent announcment", "category", ta.Category, "freeleech", ta.Freeleech, "name", ta.Name) + + if ta.Category == "TV :: Episodes HD" { + sm, err := ParseShowMeta(ta.Name) + if err != nil { + slog.Debug("can't parse ShowMeta", "err", err, "name", ta.Name) + return + } + id := sm.SeasonEpisode.String() + slog.Debug("found ShowMeta", "title", sm.Name, "id", id, "quality", sm.Quality, "group", sm.Group) + + for _, show := range s.Config.Shows { + if s.db.Data == nil { + s.db.Data = &State{ + Seen: map[string]TorrentAnnouncement{}, + } + } + if _, found := s.db.Data.Seen[sm.StateKey()]; found { + slog.Info("already snatched", "title", sm.Name, "id", id) + return + } + + if show.Title != sm.Name { + slog.Debug("wrong name") + continue + } + + if show.Quality != sm.Quality { + slog.Debug("wrong quality") + continue + } + + torrentURL := ConvertURL(ta.TorrentID, s.Config.RSSKey, ta.Name) + + slog.Debug("found url", "url", torrentURL) + downloadDir := filepath.Join(show.DiskPath, sm.SeasonEpisode.GetFormattedSeason()) + + t, err := s.tc.TorrentAdd(context.Background(), transmissionrpc.TorrentAddPayload{ + DownloadDir: &downloadDir, + Filename: aws.String(torrentURL), + Paused: aws.Bool(false), + }) + if err != nil { + slog.Error("error adding torrent", "err", err, "torrentID", ta.TorrentID) + return + } + + go s.DelayedStartTorrent(*t.ID) + + slog.Info("added torrent", "title", sm.Name, "id", id, "path", downloadDir) + + s.db.Data.Seen[sm.StateKey()] = *ta + if err := s.db.Save(); err != nil { + slog.Error("error saving state", "err", err) + } + } + } +} @@ -16,6 +16,7 @@ require ( github.com/go-shiori/go-readability v0.0.0-20230421032831-c66949dfc0ad github.com/google/go-github v17.0.0+incompatible github.com/google/uuid v1.3.0 + github.com/hekmon/transmissionrpc/v2 v2.0.1 github.com/hullerob/go.farbfeld v0.0.0-20181222022525-3661193c725f github.com/jackc/pgx/v5 v5.4.2 github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43 @@ -36,6 +37,7 @@ require ( github.com/thoj/go-ircevent v0.0.0-20210723090443-73e444401d64 github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef go.etcd.io/bbolt v1.3.7 + go.jetpack.io/tyson v0.1.1 go4.org v0.0.0-20190313082347-94abd6928b1d golang.org/x/crypto v0.11.0 golang.org/x/oauth2 v0.10.0 @@ -51,11 +53,16 @@ require ( require ( github.com/andybalholm/brotli v1.0.5 // indirect github.com/andybalholm/cascadia v1.3.2 // indirect + github.com/dop251/goja v0.0.0-20211115154819-26ebff68a7d5 // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/evanw/esbuild v0.18.6 // indirect github.com/fasthttp/router v1.4.19 // indirect github.com/go-shiori/dom v0.0.0-20210627111528-4e4722cd0d65 // indirect + github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hekmon/cunits/v2 v2.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/puddle/v2 v2.2.0 // indirect @@ -157,7 +164,7 @@ require ( github.com/x448/float16 v0.8.4 // indirect go4.org/mem v0.0.0-20220726221520-4f986261bf13 // indirect go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 // indirect - golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 + golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb golang.org/x/image v0.7.0 // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.12.0 // indirect @@ -141,8 +141,12 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/dblohm7/wingoes v0.0.0-20230426155039-111c8c3b57c8 h1:vtIE3GO4hKplR58aTRx3yLPqAbfWyoyYrE8PXUv0Prw= github.com/disintegration/imaging v1.6.1 h1:JnBbK6ECIZb1NsWIikP9pd8gIlTIRx7fuDNpU9fsxOE= github.com/disintegration/imaging v1.6.1/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dop251/goja v0.0.0-20211115154819-26ebff68a7d5 h1:7eyn0Cp9ezNbo2Vb4ttgJyWsFrRWP3oyHEw4PHKYlps= +github.com/dop251/goja v0.0.0-20211115154819-26ebff68a7d5/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/eaburns/peggy v0.0.0-20180405011029-d685ddd3cbcb/go.mod h1:5tfPwI6ukiK3W5vJzkj5MBQKHHY9Gcy2y6k1FC/23Xk= @@ -162,6 +166,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanw/esbuild v0.18.6 h1:lu5hNfVlPZRwyXEcFvSUOgYNyG2GQ6vqKaL8oW+0AJU= +github.com/evanw/esbuild v0.18.6/go.mod h1:iINY06rn799hi48UqEnaQvVfZWe6W9bET78LbvN8VWk= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= @@ -202,6 +208,8 @@ github.com/go-shiori/dom v0.0.0-20210627111528-4e4722cd0d65 h1:zx4B0AiwqKDQq+Agq github.com/go-shiori/dom v0.0.0-20210627111528-4e4722cd0d65/go.mod h1:NPO1+buE6TYOWhUI98/hXLHHJhunIpXRuvDN4xjkCoE= github.com/go-shiori/go-readability v0.0.0-20230421032831-c66949dfc0ad h1:3VP5Q8Mh165h2DHmXWFT4LJlwwvgTRlEuoe2vnsVnJ4= github.com/go-shiori/go-readability v0.0.0-20230421032831-c66949dfc0ad/go.mod h1:2DpZlTJO/ycxp/vsc/C11oUyveStOgIXB88SYV1lncI= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= @@ -318,6 +326,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= @@ -325,6 +335,10 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/hekmon/cunits/v2 v2.1.0 h1:k6wIjc4PlacNOHwKEMBgWV2/c8jyD4eRMs5mR1BBhI0= +github.com/hekmon/cunits/v2 v2.1.0/go.mod h1:9r1TycXYXaTmEWlAIfFV8JT+Xo59U96yUJAYHxzii2M= +github.com/hekmon/transmissionrpc/v2 v2.0.1 h1:WkILCEdbNy3n/N/w7mi449waMPdH2AA1THyw7TfnN/w= +github.com/hekmon/transmissionrpc/v2 v2.0.1/go.mod h1:+s96Pkg7dIP3h2PT3fzhXPvNb3OdLryh5J8PIvQg3aA= github.com/hullerob/go.farbfeld v0.0.0-20181222022525-3661193c725f h1:1LkiAnH6RhOEbQAcfcEcixM5IsegqFi6IH0Nz0ZGqYs= github.com/hullerob/go.farbfeld v0.0.0-20181222022525-3661193c725f/go.mod h1:mQEoc766DxPTAwQ54neWTK/lFqIeSO7OU6bqZsceglw= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -368,6 +382,7 @@ github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -527,6 +542,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.jetpack.io/tyson v0.1.1 h1:9RCOnwvHkrlylVqTwY1IVm0/qp6oDfxHrfrnP5Cn0xA= +go.jetpack.io/tyson v0.1.1/go.mod h1:YWQMHRMtrCpSrqT4F4J8JG+R3GYHe0NuLWJzhpVOo0U= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -560,8 +577,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o= -golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us= +golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/exp/typeparams v0.0.0-20230425010034-47ecfdc1ba53 h1:w/MOPdQ1IoYoDou3L55ZbTx2Nhn7JAhX1BBZor8qChU= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -753,6 +770,7 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1030,11 +1048,13 @@ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gvisor.dev/gvisor v0.0.0-20230504175454-7b0a1988a28f h1:8GE2MRjGiFmfpon8dekPI08jEuNMQzSffVHgdupcO4E= diff --git a/gomod2nix.toml b/gomod2nix.toml index e25c650..124a40d 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -91,12 +91,18 @@ schema = 3 [mod."github.com/dlclark/regexp2"] version = "v1.7.0" hash = "sha256-Z/M62esiZ0fVwvueVQhwz18z0eS22LZ3DJ4O8FKp3AY=" + [mod."github.com/dop251/goja"] + version = "v0.0.0-20211115154819-26ebff68a7d5" + hash = "sha256-ZNsIe01X2yoxJCuaeYOmtxXvSL8I8vgp7/e7ZEHv3tQ=" [mod."github.com/dustin/go-humanize"] version = "v1.0.1" hash = "sha256-yuvxYYngpfVkUg9yAmG99IUVmADTQA0tMbBXe0Fq0Mc=" [mod."github.com/eaburns/peggy"] version = "v1.0.2" hash = "sha256-toux6NpVog1DW+zEWX8dAj+hCZaeMG6z2fe4cAz2LDw=" + [mod."github.com/evanw/esbuild"] + version = "v0.18.6" + hash = "sha256-duHCFPNOFFp6KlIzpnhpJwczR9ksfnxgmxHvlOL8neI=" [mod."github.com/facebookgo/ensure"] version = "v0.0.0-20160127193407-b4ab57deab51" hash = "sha256-jdCvva9KDH6KTTAtW0fBNw67xd0DhxLQbxU8PdhWLKY=" @@ -130,6 +136,9 @@ schema = 3 [mod."github.com/go-shiori/go-readability"] version = "v0.0.0-20230421032831-c66949dfc0ad" hash = "sha256-67CfGKvCghUq+1XMcAMF+O9xsbQNkwma4L9cxA4pLtw=" + [mod."github.com/go-sourcemap/sourcemap"] + version = "v2.1.3+incompatible" + hash = "sha256-eXhXPPLnAy/rmt/zDgeqni2G3o58UtnHjR8vHLXvISI=" [mod."github.com/goccy/go-json"] version = "v0.10.2" hash = "sha256-6fMD2/Rku8HT0zDdeA23pX0YxbohiIOC8OJNYbylJTQ=" @@ -169,12 +178,21 @@ schema = 3 [mod."github.com/hashicorp/errwrap"] version = "v1.1.0" hash = "sha256-6lwuMQOfBq+McrViN3maJTIeh4f8jbEqvLy2c9FvvFw=" + [mod."github.com/hashicorp/go-cleanhttp"] + version = "v0.5.2" + hash = "sha256-N9GOKYo7tK6XQUFhvhImtL7PZW/mr4C4Manx/yPVvcQ=" [mod."github.com/hashicorp/go-multierror"] version = "v1.1.1" hash = "sha256-ANzPEUJIZIlToxR89Mn7Db73d9LGI51ssy7eNnUgmlA=" [mod."github.com/hdevalence/ed25519consensus"] version = "v0.1.0" hash = "sha256-MkqFWnyXt653RaJQUMWWxcW6NCskIxou8VEfj+8vd3Y=" + [mod."github.com/hekmon/cunits/v2"] + version = "v2.1.0" + hash = "sha256-NqaZD9wPP0z2x/An3c+o2GDAXuwRvfwMmOIe7TOb8xY=" + [mod."github.com/hekmon/transmissionrpc/v2"] + version = "v2.0.1" + hash = "sha256-qKZ0uFDRyE10Zg0Aog+vB678u4q9quZzWBY+bwsh614=" [mod."github.com/hullerob/go.farbfeld"] version = "v0.0.0-20181222022525-3661193c725f" hash = "sha256-vUAM6JDuNV+W8bhOcY8lqZVevdQ7nIl7lwwntRBo/Sw=" @@ -382,6 +400,9 @@ schema = 3 [mod."go.etcd.io/bbolt"] version = "v1.3.7" hash = "sha256-poZk8tPLDWwW95oCOkTJcQtEvOJTD9UXAZ2TqGJutwk=" + [mod."go.jetpack.io/tyson"] + version = "v0.1.1" + hash = "sha256-c4ROLn+BSX7v/4C9/IeU6HiE2YvnqDuXXGp2iZhAVk4=" [mod."go4.org"] version = "v0.0.0-20190313082347-94abd6928b1d" hash = "sha256-/hCsgDZzSnd5kPI5u6diLud6sEZm9e+tyCMVFRy5O1k=" @@ -395,8 +416,8 @@ schema = 3 version = "v0.11.0" hash = "sha256-aFI8cpvSZRiQO2HQm6+a4e9OiSf7GUfj69SSta2iZ44=" [mod."golang.org/x/exp"] - version = "v0.0.0-20230425010034-47ecfdc1ba53" - hash = "sha256-wjUFZRfjU+lf/XqSZ4drxtbVDJbhML5FBMnNJ70RcrM=" + version = "v0.0.0-20230711153332-06a737ee72cb" + hash = "sha256-Cbw10ZJ+jATPV232G47xZrn6ExO1FDtiT6nlMRCH7EI=" [mod."golang.org/x/image"] version = "v0.7.0" hash = "sha256-8ymOoG5nFlSCJOgn/apVzP4Zk5jtoYNLwd5TJKlP2X8=" |
