mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 08:49:13 +00:00
Feature: Support multi user per irc network (#78)
* feat: delete irc network in transaction * feat: use compound key for irc handlers * chore: update deps * refactor: start network * refactor: init irc handler * indexers: update network name
This commit is contained in:
parent
f466657ed4
commit
2daeedbdc7
14 changed files with 491 additions and 428 deletions
6
go.mod
6
go.mod
|
@ -15,7 +15,6 @@ require (
|
||||||
github.com/gorilla/sessions v1.2.1
|
github.com/gorilla/sessions v1.2.1
|
||||||
github.com/kr/pretty v0.3.0 // indirect
|
github.com/kr/pretty v0.3.0 // indirect
|
||||||
github.com/lib/pq v1.10.4
|
github.com/lib/pq v1.10.4
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.10
|
github.com/mattn/go-sqlite3 v1.14.10
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/r3labs/sse/v2 v2.7.2
|
github.com/r3labs/sse/v2 v2.7.2
|
||||||
|
@ -29,13 +28,10 @@ require (
|
||||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9
|
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac
|
||||||
golang.org/x/tools v0.1.8 // indirect
|
|
||||||
gopkg.in/ini.v1 v1.64.0 // indirect
|
gopkg.in/ini.v1 v1.64.0 // indirect
|
||||||
gopkg.in/irc.v3 v3.1.4
|
gopkg.in/irc.v3 v3.1.4
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
modernc.org/ccgo/v3 v3.14.0 // indirect
|
|
||||||
modernc.org/libc v1.13.2 // indirect
|
|
||||||
modernc.org/sqlite v1.14.3
|
|
||||||
)
|
)
|
||||||
|
|
151
go.sum
151
go.sum
|
@ -257,7 +257,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
|
@ -280,8 +279,6 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe
|
||||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
|
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
|
||||||
|
@ -342,8 +339,6 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
|
||||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
@ -377,12 +372,9 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y
|
||||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
|
||||||
github.com/mattn/go-sqlite3 v1.7.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.7.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/go-sqlite3 v1.13.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.13.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.10 h1:MLn+5bFRlWMGoSRmJour3CL1w/qL96mvipqpwQW/Sfk=
|
github.com/mattn/go-sqlite3 v1.14.10 h1:MLn+5bFRlWMGoSRmJour3CL1w/qL96mvipqpwQW/Sfk=
|
||||||
github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
|
@ -441,8 +433,6 @@ github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4
|
||||||
github.com/r3labs/sse/v2 v2.7.2 h1:GUyMTu1EPAVUDPZUSkFWx1fXYXXxH4xAcTAIWSs89ZU=
|
github.com/r3labs/sse/v2 v2.7.2 h1:GUyMTu1EPAVUDPZUSkFWx1fXYXXxH4xAcTAIWSs89ZU=
|
||||||
github.com/r3labs/sse/v2 v2.7.2/go.mod h1:hUrYMKfu9WquG9MyI0r6TKiNH+6Sw/QPKm2YbNbU5g8=
|
github.com/r3labs/sse/v2 v2.7.2/go.mod h1:hUrYMKfu9WquG9MyI0r6TKiNH+6Sw/QPKm2YbNbU5g8=
|
||||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
|
@ -504,7 +494,6 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
|
||||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||||
|
@ -569,8 +558,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
|
||||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
|
||||||
golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -617,7 +604,6 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI=
|
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI=
|
||||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
@ -696,7 +682,6 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -716,9 +701,6 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
@ -785,7 +767,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
@ -797,12 +778,9 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||||
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
|
|
||||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
|
@ -970,135 +948,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
|
|
||||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
|
||||||
modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.20/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.22 h1:BzShpwCAP7TWzFppM4k2t03RhXhgYqaibROWkrWq7lE=
|
|
||||||
modernc.org/cc/v3 v3.35.22/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
|
|
||||||
modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw=
|
|
||||||
modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI=
|
|
||||||
modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag=
|
|
||||||
modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw=
|
|
||||||
modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ=
|
|
||||||
modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c=
|
|
||||||
modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo=
|
|
||||||
modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg=
|
|
||||||
modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I=
|
|
||||||
modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs=
|
|
||||||
modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8=
|
|
||||||
modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE=
|
|
||||||
modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk=
|
|
||||||
modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w=
|
|
||||||
modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE=
|
|
||||||
modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8=
|
|
||||||
modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc=
|
|
||||||
modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU=
|
|
||||||
modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE=
|
|
||||||
modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk=
|
|
||||||
modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI=
|
|
||||||
modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE=
|
|
||||||
modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg=
|
|
||||||
modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74=
|
|
||||||
modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU=
|
|
||||||
modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU=
|
|
||||||
modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc=
|
|
||||||
modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM=
|
|
||||||
modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ=
|
|
||||||
modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84=
|
|
||||||
modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ=
|
|
||||||
modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY=
|
|
||||||
modernc.org/ccgo/v3 v3.12.84/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w=
|
|
||||||
modernc.org/ccgo/v3 v3.12.86/go.mod h1:dN7S26DLTgVSni1PVA3KxxHTcykyDurf3OgUzNqTSrU=
|
|
||||||
modernc.org/ccgo/v3 v3.12.88/go.mod h1:0MFzUHIuSIthpVZyMWiFYMwjiFnhrN5MkvBrUwON+ZM=
|
|
||||||
modernc.org/ccgo/v3 v3.12.90/go.mod h1:obhSc3CdivCRpYZmrvO88TXlW0NvoSVvdh/ccRjJYko=
|
|
||||||
modernc.org/ccgo/v3 v3.12.92/go.mod h1:5yDdN7ti9KWPi5bRVWPl8UNhpEAtCjuEE7ayQnzzqHA=
|
|
||||||
modernc.org/ccgo/v3 v3.12.95/go.mod h1:ZcLyvtocXYi8uF+9Ebm3G8EF8HNY5hGomBqthDp4eC8=
|
|
||||||
modernc.org/ccgo/v3 v3.13.1/go.mod h1:aBYVOUfIlcSnrsRVU8VRS35y2DIfpgkmVkYZ0tpIXi4=
|
|
||||||
modernc.org/ccgo/v3 v3.14.0 h1:Zr1Ny9+7r5yAiXpBdgp8XiXqkNA4ARrRphHGHVXeAp0=
|
|
||||||
modernc.org/ccgo/v3 v3.14.0/go.mod h1:hBrkiBlUwvr5vV/ZH9YzXIp982jKE8Ek8tR1ytoAL6Q=
|
|
||||||
modernc.org/ccorpus v1.11.1 h1:K0qPfpVG1MJh5BYazccnmhywH4zHuOgJXgbjzyp6dWA=
|
|
||||||
modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
|
||||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
|
||||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
|
||||||
modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
|
||||||
modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q=
|
|
||||||
modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg=
|
|
||||||
modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M=
|
|
||||||
modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU=
|
|
||||||
modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE=
|
|
||||||
modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso=
|
|
||||||
modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8=
|
|
||||||
modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8=
|
|
||||||
modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I=
|
|
||||||
modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk=
|
|
||||||
modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY=
|
|
||||||
modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE=
|
|
||||||
modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg=
|
|
||||||
modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM=
|
|
||||||
modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg=
|
|
||||||
modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo=
|
|
||||||
modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8=
|
|
||||||
modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ=
|
|
||||||
modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA=
|
|
||||||
modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM=
|
|
||||||
modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg=
|
|
||||||
modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE=
|
|
||||||
modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM=
|
|
||||||
modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU=
|
|
||||||
modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw=
|
|
||||||
modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M=
|
|
||||||
modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18=
|
|
||||||
modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8=
|
|
||||||
modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
|
|
||||||
modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0=
|
|
||||||
modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI=
|
|
||||||
modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE=
|
|
||||||
modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY=
|
|
||||||
modernc.org/libc v1.11.88/go.mod h1:h3oIVe8dxmTcchcFuCcJ4nAWaoiwzKCdv82MM0oiIdQ=
|
|
||||||
modernc.org/libc v1.11.90/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c=
|
|
||||||
modernc.org/libc v1.11.98/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c=
|
|
||||||
modernc.org/libc v1.11.99/go.mod h1:wLLYgEiY2D17NbBOEp+mIJJJBGSiy7fLL4ZrGGZ+8jI=
|
|
||||||
modernc.org/libc v1.11.101/go.mod h1:wLLYgEiY2D17NbBOEp+mIJJJBGSiy7fLL4ZrGGZ+8jI=
|
|
||||||
modernc.org/libc v1.11.104/go.mod h1:2MH3DaF/gCU8i/UBiVE1VFRos4o523M7zipmwH8SIgQ=
|
|
||||||
modernc.org/libc v1.12.0/go.mod h1:2MH3DaF/gCU8i/UBiVE1VFRos4o523M7zipmwH8SIgQ=
|
|
||||||
modernc.org/libc v1.13.1/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk=
|
|
||||||
modernc.org/libc v1.13.2 h1:GCFjY9bmwDZ/TJC4OZOUWaNgxIxwb104C/QZrqpcVEA=
|
|
||||||
modernc.org/libc v1.13.2/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk=
|
|
||||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
|
|
||||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
|
||||||
modernc.org/memory v1.0.5 h1:XRch8trV7GgvTec2i7jc33YlUI0RKVDBvZ5eZ5m8y14=
|
|
||||||
modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
|
|
||||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
|
||||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
|
||||||
modernc.org/sqlite v1.14.3 h1:psrTwgpEujgWEP3FNdsC9yNh5tSeA77U0GeWhHH4XmQ=
|
|
||||||
modernc.org/sqlite v1.14.3/go.mod h1:xMpicS1i2MJ4C8+Ap0vYBqTwYfpFvdnPE6brbFOtV2Y=
|
|
||||||
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
|
|
||||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
|
||||||
modernc.org/tcl v1.9.2 h1:YA87dFLOsR2KqMka371a2Xgr+YsyUwo7OmHVSv/kztw=
|
|
||||||
modernc.org/tcl v1.9.2/go.mod h1:aw7OnlIoiuJgu1gwbTZtrKnGpDqH9wyH++jZcxdqNsg=
|
|
||||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
|
||||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
|
||||||
modernc.org/z v1.2.20 h1:DyboxM1sJR2NB803j2StnbnL6jcQXz273OhHDGu8dGk=
|
|
||||||
modernc.org/z v1.2.20/go.mod h1:zU9FiF4PbHdOTUxw+IF8j7ArBMRPsHgq10uVPt6xTzo=
|
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
|
|
|
@ -49,25 +49,25 @@ func (r *IrcRepo) GetNetworkByID(id int64) (*domain.IrcNetwork, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *IrcRepo) DeleteNetwork(ctx context.Context, id int64) error {
|
func (r *IrcRepo) DeleteNetwork(ctx context.Context, id int64) error {
|
||||||
tx, err := r.db.handler.BeginTx(ctx, nil)
|
tx, err := r.db.BeginTx(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
|
|
||||||
_, err = tx.ExecContext(ctx, `DELETE FROM irc_network WHERE id = ?`, id)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Stack().Err(err).Msgf("error deleting network: %v", id)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = tx.ExecContext(ctx, `DELETE FROM irc_channel WHERE network_id = ?`, id)
|
_, err = tx.ExecContext(ctx, `DELETE FROM irc_channel WHERE network_id = ?`, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("error deleting channels for network: %v", id)
|
log.Error().Stack().Err(err).Msgf("error deleting channels for network: %v", id)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = tx.ExecContext(ctx, `DELETE FROM irc_network WHERE id = ?`, id)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Stack().Err(err).Msgf("error deleting network: %v", id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
err = tx.Commit()
|
err = tx.Commit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("error deleting network: %v", id)
|
log.Error().Stack().Err(err).Msgf("error deleting network: %v", id)
|
||||||
|
|
|
@ -79,3 +79,20 @@ func (db *SqliteDB) Close() error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *SqliteDB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
|
||||||
|
tx, err := db.handler.BeginTx(ctx, opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Tx{
|
||||||
|
Tx: tx,
|
||||||
|
handler: db,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Tx struct {
|
||||||
|
*sql.Tx
|
||||||
|
handler *SqliteDB
|
||||||
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ type ircService interface {
|
||||||
StoreNetwork(ctx context.Context, network *domain.IrcNetwork) error
|
StoreNetwork(ctx context.Context, network *domain.IrcNetwork) error
|
||||||
UpdateNetwork(ctx context.Context, network *domain.IrcNetwork) error
|
UpdateNetwork(ctx context.Context, network *domain.IrcNetwork) error
|
||||||
StoreChannel(networkID int64, channel *domain.IrcChannel) error
|
StoreChannel(networkID int64, channel *domain.IrcChannel) error
|
||||||
StopNetwork(name string) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ircHandler struct {
|
type ircHandler struct {
|
||||||
|
@ -39,7 +38,6 @@ func (h ircHandler) Routes(r chi.Router) {
|
||||||
r.Post("/", h.storeNetwork)
|
r.Post("/", h.storeNetwork)
|
||||||
r.Put("/network/{networkID}", h.updateNetwork)
|
r.Put("/network/{networkID}", h.updateNetwork)
|
||||||
r.Post("/network/{networkID}/channel", h.storeChannel)
|
r.Post("/network/{networkID}/channel", h.storeChannel)
|
||||||
r.Get("/network/{networkID}/stop", h.stopNetwork)
|
|
||||||
r.Get("/network/{networkID}", h.getNetworkByID)
|
r.Get("/network/{networkID}", h.getNetworkByID)
|
||||||
r.Delete("/network/{networkID}", h.deleteNetwork)
|
r.Delete("/network/{networkID}", h.deleteNetwork)
|
||||||
}
|
}
|
||||||
|
@ -132,20 +130,6 @@ func (h ircHandler) storeChannel(w http.ResponseWriter, r *http.Request) {
|
||||||
h.encoder.StatusResponse(ctx, w, nil, http.StatusCreated)
|
h.encoder.StatusResponse(ctx, w, nil, http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h ircHandler) stopNetwork(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var (
|
|
||||||
ctx = r.Context()
|
|
||||||
networkID = chi.URLParam(r, "networkID")
|
|
||||||
)
|
|
||||||
|
|
||||||
err := h.service.StopNetwork(networkID)
|
|
||||||
if err != nil {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
h.encoder.StatusResponse(ctx, w, nil, http.StatusCreated)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h ircHandler) deleteNetwork(w http.ResponseWriter, r *http.Request) {
|
func (h ircHandler) deleteNetwork(w http.ResponseWriter, r *http.Request) {
|
||||||
var (
|
var (
|
||||||
ctx = r.Context()
|
ctx = r.Context()
|
||||||
|
|
|
@ -20,7 +20,7 @@ settings:
|
||||||
help: "Check how to get cookies in your browser and find the uid and pass cookies. Example: uid=1234; pass=asdf12347asdf13"
|
help: "Check how to get cookies in your browser and find the uid and pass cookies. Example: uid=1234; pass=asdf12347asdf13"
|
||||||
|
|
||||||
irc:
|
irc:
|
||||||
network: P2P-NET
|
network: P2P-Network
|
||||||
server: irc.p2p-network.net
|
server: irc.p2p-network.net
|
||||||
port: 6697
|
port: 6697
|
||||||
tls: true
|
tls: true
|
||||||
|
|
|
@ -20,7 +20,7 @@ settings:
|
||||||
regex: /([a-zA-Z0-9\+])
|
regex: /([a-zA-Z0-9\+])
|
||||||
|
|
||||||
irc:
|
irc:
|
||||||
network: p2p-network.net
|
network: P2P-Network
|
||||||
server: irc.p2p-network.net
|
server: irc.p2p-network.net
|
||||||
port: 6697
|
port: 6697
|
||||||
tls: true
|
tls: true
|
||||||
|
|
63
internal/indexer/definitions/mock1.yaml
Normal file
63
internal/indexer/definitions/mock1.yaml
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
---
|
||||||
|
#id: tracker01
|
||||||
|
name: Mock1
|
||||||
|
identifier: mock1
|
||||||
|
description: Mock1 is just a mock indexer
|
||||||
|
language: en-us
|
||||||
|
urls:
|
||||||
|
- http://localhost.test
|
||||||
|
privacy: private
|
||||||
|
protocol: torrent
|
||||||
|
supports:
|
||||||
|
- irc
|
||||||
|
- rss
|
||||||
|
source: custom
|
||||||
|
settings:
|
||||||
|
- name: rsskey
|
||||||
|
type: secret
|
||||||
|
label: RSS key
|
||||||
|
help: "Go to your profile and copy your RSS key"
|
||||||
|
regex: /([\da-fA-F]{20})
|
||||||
|
|
||||||
|
irc:
|
||||||
|
network: LocalHost
|
||||||
|
server: localhost
|
||||||
|
port: 6697
|
||||||
|
tls: true
|
||||||
|
channels:
|
||||||
|
- "#announces"
|
||||||
|
announcers:
|
||||||
|
- _AnnounceBot_
|
||||||
|
settings:
|
||||||
|
- name: nickserv.account
|
||||||
|
type: text
|
||||||
|
required: true
|
||||||
|
label: NickServ Account
|
||||||
|
help: NickServ account. Make sure to group your user and bot. Eg. user_bot
|
||||||
|
- name: nickserv.password
|
||||||
|
type: secret
|
||||||
|
required: false
|
||||||
|
label: NickServ Password
|
||||||
|
help: NickServ password
|
||||||
|
|
||||||
|
parse:
|
||||||
|
type: single
|
||||||
|
lines:
|
||||||
|
- test:
|
||||||
|
- "New Torrent Announcement: <PC :: Iso> Name:'debian live 10 6 0 amd64 standard iso' uploaded by 'Anonymous' - http://www.tracker01.test/torrent/000000"
|
||||||
|
- "New Torrent Announcement: <PC :: Iso> Name:'debian live 10 6 0 amd64 standard iso' uploaded by 'Anonymous' freeleech - http://www.tracker01.test/torrent/000000"
|
||||||
|
pattern: New Torrent Announcement:\s*<([^>]*)>\s*Name:'(.*)' uploaded by '([^']*)'\s*(freeleech)*\s*-\s*(https?\:\/\/[^\/]+\/)torrent\/(\d+)
|
||||||
|
vars:
|
||||||
|
- category
|
||||||
|
- torrentName
|
||||||
|
- uploader
|
||||||
|
- freeleech
|
||||||
|
- baseUrl
|
||||||
|
- torrentId
|
||||||
|
|
||||||
|
match:
|
||||||
|
torrenturl: "{{ .baseUrl }}rss/download/{{ .torrentId }}/{{ .rsskey }}/{{ .torrentName }}.torrent"
|
||||||
|
encode:
|
||||||
|
- torrentName
|
||||||
|
|
||||||
|
|
63
internal/indexer/definitions/mock2.yaml
Normal file
63
internal/indexer/definitions/mock2.yaml
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
---
|
||||||
|
#id: tracker01
|
||||||
|
name: Mock2
|
||||||
|
identifier: mock2
|
||||||
|
description: Mock2 is just a mock indexer
|
||||||
|
language: en-us
|
||||||
|
urls:
|
||||||
|
- http://localhost.test
|
||||||
|
privacy: private
|
||||||
|
protocol: torrent
|
||||||
|
supports:
|
||||||
|
- irc
|
||||||
|
- rss
|
||||||
|
source: custom
|
||||||
|
settings:
|
||||||
|
- name: rsskey
|
||||||
|
type: secret
|
||||||
|
label: RSS key
|
||||||
|
help: "Go to your profile and copy your RSS key"
|
||||||
|
regex: /([\da-fA-F]{20})
|
||||||
|
|
||||||
|
irc:
|
||||||
|
network: LocalHost
|
||||||
|
server: localhost
|
||||||
|
port: 6697
|
||||||
|
tls: true
|
||||||
|
channels:
|
||||||
|
- "#mannounces"
|
||||||
|
announcers:
|
||||||
|
- Jerry
|
||||||
|
settings:
|
||||||
|
- name: nickserv.account
|
||||||
|
type: text
|
||||||
|
required: true
|
||||||
|
label: NickServ Account
|
||||||
|
help: NickServ account. Make sure to group your user and bot. Eg. user_bot
|
||||||
|
- name: nickserv.password
|
||||||
|
type: secret
|
||||||
|
required: false
|
||||||
|
label: NickServ Password
|
||||||
|
help: NickServ password
|
||||||
|
|
||||||
|
parse:
|
||||||
|
type: single
|
||||||
|
lines:
|
||||||
|
- test:
|
||||||
|
- "New Torrent Announcement: <PC :: Iso> Name:'debian live 10 6 0 amd64 standard iso' uploaded by 'Anonymous' - http://www.tracker01.test/torrent/000000"
|
||||||
|
- "New Torrent Announcement: <PC :: Iso> Name:'debian live 10 6 0 amd64 standard iso' uploaded by 'Anonymous' freeleech - http://www.tracker01.test/torrent/000000"
|
||||||
|
pattern: New Torrent Announcement:\s*<([^>]*)>\s*Name:'(.*)' uploaded by '([^']*)'\s*(freeleech)*\s*-\s*(https?\:\/\/[^\/]+\/)torrent\/(\d+)
|
||||||
|
vars:
|
||||||
|
- category
|
||||||
|
- torrentName
|
||||||
|
- uploader
|
||||||
|
- freeleech
|
||||||
|
- baseUrl
|
||||||
|
- torrentId
|
||||||
|
|
||||||
|
match:
|
||||||
|
torrenturl: "{{ .baseUrl }}rss/download/{{ .torrentId }}/{{ .rsskey }}/{{ .torrentName }}.torrent"
|
||||||
|
encode:
|
||||||
|
- torrentName
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ settings:
|
||||||
help: "Go to https://www.trancetraffic.com/links.php, click on RSS Feed and copy your passkey from the url."
|
help: "Go to https://www.trancetraffic.com/links.php, click on RSS Feed and copy your passkey from the url."
|
||||||
|
|
||||||
irc:
|
irc:
|
||||||
network: P2P-NET
|
network: P2P-Network
|
||||||
server: irc.p2p-network.net
|
server: irc.p2p-network.net
|
||||||
port: 6697
|
port: 6697
|
||||||
tls: true
|
tls: true
|
||||||
|
@ -35,7 +35,7 @@ irc:
|
||||||
help: NickServ account. Make sure to group your user and bot. Eg. user|autodl
|
help: NickServ account. Make sure to group your user and bot. Eg. user|autodl
|
||||||
- name: nickserv.password
|
- name: nickserv.password
|
||||||
type: secret
|
type: secret
|
||||||
required: false
|
required: true
|
||||||
label: NickServ Password
|
label: NickServ Password
|
||||||
help: NickServ password
|
help: NickServ password
|
||||||
|
|
||||||
|
|
|
@ -243,6 +243,16 @@ func (s *service) addIndexer(indexer domain.Indexer) error {
|
||||||
|
|
||||||
s.mapIRCIndexerLookup(indexer.Identifier, *indexerDefinition)
|
s.mapIRCIndexerLookup(indexer.Identifier, *indexerDefinition)
|
||||||
|
|
||||||
|
// add to irc server lookup table
|
||||||
|
s.mapIRCServerDefinitionLookup(indexerDefinition.IRC.Server, *indexerDefinition)
|
||||||
|
|
||||||
|
// check if it has api and add to api service
|
||||||
|
if indexerDefinition.Enabled && indexerDefinition.HasApi() {
|
||||||
|
if err := s.apiService.AddClient(indexerDefinition.Identifier, indexerDefinition.SettingsMap); err != nil {
|
||||||
|
log.Error().Stack().Err(err).Msgf("indexer.start: could not init api client for: '%v'", indexer.Identifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ type Handler struct {
|
||||||
filterService filter.Service
|
filterService filter.Service
|
||||||
releaseService release.Service
|
releaseService release.Service
|
||||||
announceProcessors map[string]announce.Processor
|
announceProcessors map[string]announce.Processor
|
||||||
definitions []domain.IndexerDefinition
|
definitions map[string]*domain.IndexerDefinition
|
||||||
|
|
||||||
client *irc.Client
|
client *irc.Client
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
|
@ -79,22 +79,35 @@ func NewHandler(network domain.IrcNetwork, filterService filter.Service, release
|
||||||
network: &network,
|
network: &network,
|
||||||
filterService: filterService,
|
filterService: filterService,
|
||||||
releaseService: releaseService,
|
releaseService: releaseService,
|
||||||
definitions: definitions,
|
definitions: map[string]*domain.IndexerDefinition{},
|
||||||
announceProcessors: map[string]announce.Processor{},
|
announceProcessors: map[string]announce.Processor{},
|
||||||
validAnnouncers: map[string]struct{}{},
|
validAnnouncers: map[string]struct{}{},
|
||||||
validChannels: map[string]struct{}{},
|
validChannels: map[string]struct{}{},
|
||||||
channelHealth: map[string]*channelHealth{},
|
channelHealth: map[string]*channelHealth{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init indexer, announceProcessor
|
||||||
|
h.InitIndexers(definitions)
|
||||||
|
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) InitIndexers(definitions []domain.IndexerDefinition) {
|
||||||
// Networks can be shared by multiple indexers but channels are unique
|
// Networks can be shared by multiple indexers but channels are unique
|
||||||
// so let's add a new AnnounceProcessor per channel
|
// so let's add a new AnnounceProcessor per channel
|
||||||
for _, definition := range definitions {
|
for _, definition := range definitions {
|
||||||
// indexers can use multiple channels, but it's not common, but let's handle that anyway.
|
if _, ok := h.definitions[definition.Identifier]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
h.definitions[definition.Identifier] = &definition
|
||||||
|
|
||||||
|
// indexers can use multiple channels, but it'h not common, but let'h handle that anyway.
|
||||||
for _, channel := range definition.IRC.Channels {
|
for _, channel := range definition.IRC.Channels {
|
||||||
// some channels are defined in mixed case
|
// some channels are defined in mixed case
|
||||||
channel = strings.ToLower(channel)
|
channel = strings.ToLower(channel)
|
||||||
|
|
||||||
h.announceProcessors[channel] = announce.NewAnnounceProcessor(definition, filterService, releaseService)
|
h.announceProcessors[channel] = announce.NewAnnounceProcessor(definition, h.filterService, h.releaseService)
|
||||||
|
|
||||||
h.channelHealth[channel] = &channelHealth{
|
h.channelHealth[channel] = &channelHealth{
|
||||||
name: channel,
|
name: channel,
|
||||||
|
@ -110,20 +123,25 @@ func NewHandler(network domain.IrcNetwork, filterService filter.Service, release
|
||||||
h.validAnnouncers[announcer] = struct{}{}
|
h.validAnnouncers[announcer] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) Run() error {
|
func (h *Handler) removeIndexer() {
|
||||||
//log.Debug().Msgf("server %+v", s.network)
|
// TODO remove validAnnouncers
|
||||||
|
// TODO remove validChannels
|
||||||
|
// TODO remove definition
|
||||||
|
// TODO remove announceProcessor
|
||||||
|
}
|
||||||
|
|
||||||
if s.network.Server == "" {
|
func (h *Handler) Run() error {
|
||||||
|
//log.Debug().Msgf("server %+v", h.network)
|
||||||
|
|
||||||
|
if h.network.Server == "" {
|
||||||
return errors.New("addr not set")
|
return errors.New("addr not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
s.ctx = ctx
|
h.ctx = ctx
|
||||||
s.cancel = cancel
|
h.cancel = cancel
|
||||||
|
|
||||||
dialer := net.Dialer{
|
dialer := net.Dialer{
|
||||||
Timeout: connectTimeout,
|
Timeout: connectTimeout,
|
||||||
|
@ -132,122 +150,49 @@ func (s *Handler) Run() error {
|
||||||
var netConn net.Conn
|
var netConn net.Conn
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
addr := fmt.Sprintf("%v:%v", s.network.Server, s.network.Port)
|
addr := fmt.Sprintf("%v:%v", h.network.Server, h.network.Port)
|
||||||
|
|
||||||
// decide to use SSL or not
|
// decide to use SSL or not
|
||||||
if s.network.TLS {
|
if h.network.TLS {
|
||||||
tlsConf := &tls.Config{
|
tlsConf := &tls.Config{
|
||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
netConn, err = dialer.DialContext(s.ctx, "tcp", addr)
|
netConn, err = dialer.DialContext(h.ctx, "tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msgf("failed to dial %v", addr)
|
log.Error().Err(err).Msgf("failed to dial %v", addr)
|
||||||
return fmt.Errorf("failed to dial %q: %v", addr, err)
|
return fmt.Errorf("failed to dial %q: %v", addr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
netConn = tls.Client(netConn, tlsConf)
|
netConn = tls.Client(netConn, tlsConf)
|
||||||
s.conn = netConn
|
h.conn = netConn
|
||||||
} else {
|
} else {
|
||||||
netConn, err = dialer.DialContext(s.ctx, "tcp", addr)
|
netConn, err = dialer.DialContext(h.ctx, "tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msgf("failed to dial %v", addr)
|
log.Error().Err(err).Msgf("failed to dial %v", addr)
|
||||||
return fmt.Errorf("failed to dial %q: %v", addr, err)
|
return fmt.Errorf("failed to dial %q: %v", addr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.conn = netConn
|
h.conn = netConn
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info().Msgf("Connected to: %v", addr)
|
log.Info().Msgf("Connected to: %v", addr)
|
||||||
|
|
||||||
config := irc.ClientConfig{
|
config := irc.ClientConfig{
|
||||||
Nick: s.network.NickServ.Account,
|
Nick: h.network.NickServ.Account,
|
||||||
User: s.network.NickServ.Account,
|
User: h.network.NickServ.Account,
|
||||||
Name: s.network.NickServ.Account,
|
Name: h.network.NickServ.Account,
|
||||||
Pass: s.network.Pass,
|
Pass: h.network.Pass,
|
||||||
Handler: irc.HandlerFunc(func(c *irc.Client, m *irc.Message) {
|
Handler: irc.HandlerFunc(h.handleMessage),
|
||||||
switch m.Command {
|
|
||||||
case "001":
|
|
||||||
// 001 is a welcome event, so we join channels there
|
|
||||||
err := s.onConnect(s.network.Channels)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Msgf("error joining channels %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
case "372", "375", "376":
|
|
||||||
// Handle MOTD
|
|
||||||
|
|
||||||
// 322 TOPIC
|
|
||||||
// 333 UP
|
|
||||||
// 353 @
|
|
||||||
// 396 Displayed host
|
|
||||||
case "366": // JOINED
|
|
||||||
s.handleJoined(m)
|
|
||||||
|
|
||||||
case "JOIN":
|
|
||||||
log.Trace().Msgf("%v: JOIN %v", s.network.Server, m)
|
|
||||||
|
|
||||||
case "433":
|
|
||||||
// TODO: handle nick in use
|
|
||||||
log.Debug().Msgf("%v: NICK IN USE: %v", s.network.Server, m)
|
|
||||||
|
|
||||||
case "448", "473", "475", "477":
|
|
||||||
// TODO: handle join failed
|
|
||||||
log.Debug().Msgf("%v: JOIN FAILED %v: %v", s.network.Server, m.Params[1], m)
|
|
||||||
|
|
||||||
case "900": // Invite bot logged in
|
|
||||||
log.Debug().Msgf("%v: %v", s.network.Server, m.Trailing())
|
|
||||||
|
|
||||||
case "KICK":
|
|
||||||
log.Debug().Msgf("%v: KICK: %v", s.network.Server, m)
|
|
||||||
|
|
||||||
case "MODE":
|
|
||||||
err := s.handleMode(m)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msgf("error MODE change: %v", m)
|
|
||||||
}
|
|
||||||
|
|
||||||
case "INVITE":
|
|
||||||
// TODO: handle invite
|
|
||||||
log.Debug().Msgf("%v: INVITE: %v", s.network.Server, m)
|
|
||||||
|
|
||||||
case "PART":
|
|
||||||
// TODO: handle parted
|
|
||||||
log.Debug().Msgf("%v: PART: %v", s.network.Server, m)
|
|
||||||
|
|
||||||
case "PRIVMSG":
|
|
||||||
err := s.onMessage(m)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Msgf("error on message %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
case "CAP":
|
|
||||||
log.Debug().Msgf("%v: CAP: %v", s.network.Server, m)
|
|
||||||
|
|
||||||
case "NOTICE":
|
|
||||||
log.Trace().Msgf("%v: %v", s.network.Server, m)
|
|
||||||
|
|
||||||
case "PING":
|
|
||||||
err := s.handlePing(m)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Stack().Err(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
//case "372":
|
|
||||||
// log.Debug().Msgf("372: %v", m)
|
|
||||||
default:
|
|
||||||
log.Trace().Msgf("%v: %v", s.network.Server, m)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the client
|
// Create the client
|
||||||
client := irc.NewClient(s.conn, config)
|
client := irc.NewClient(h.conn, config)
|
||||||
|
|
||||||
s.client = client
|
h.client = client
|
||||||
|
|
||||||
// set connected since now
|
// set connected since now
|
||||||
s.setConnectionStatus()
|
h.setConnectionStatus()
|
||||||
|
|
||||||
// Connect
|
// Connect
|
||||||
err = client.RunContext(ctx)
|
err = client.RunContext(ctx)
|
||||||
|
@ -255,7 +200,7 @@ func (s *Handler) Run() error {
|
||||||
log.Error().Err(err).Msgf("could not connect to %v", addr)
|
log.Error().Err(err).Msgf("could not connect to %v", addr)
|
||||||
|
|
||||||
// reset connection status on handler and channels
|
// reset connection status on handler and channels
|
||||||
s.resetConnectionStatus()
|
h.resetConnectionStatus()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -263,79 +208,172 @@ func (s *Handler) Run() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) setConnectionStatus() {
|
func (h *Handler) handleMessage(c *irc.Client, m *irc.Message) {
|
||||||
// set connected since now
|
switch m.Command {
|
||||||
s.connectedSince = time.Now()
|
case "001":
|
||||||
s.connected = true
|
// 001 is a welcome event, so we join channels there
|
||||||
|
err := h.onConnect(h.network.Channels)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Msgf("error joining channels %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "372", "375", "376":
|
||||||
|
// Handle MOTD
|
||||||
|
|
||||||
|
// 322 TOPIC
|
||||||
|
// 333 UP
|
||||||
|
// 353 @
|
||||||
|
// 396 Displayed host
|
||||||
|
case "366": // JOINED
|
||||||
|
h.handleJoined(m)
|
||||||
|
|
||||||
|
case "JOIN":
|
||||||
|
if h.isOurNick(m.Prefix.Name) {
|
||||||
|
log.Trace().Msgf("%v: JOIN %v", h.network.Server, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "QUIT":
|
||||||
|
if h.isOurNick(m.Prefix.Name) {
|
||||||
|
log.Trace().Msgf("%v: QUIT %v", h.network.Server, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "433":
|
||||||
|
// TODO: handle nick in use
|
||||||
|
log.Debug().Msgf("%v: NICK IN USE: %v", h.network.Server, m)
|
||||||
|
|
||||||
|
case "448", "473", "475", "477":
|
||||||
|
// TODO: handle join failed
|
||||||
|
log.Debug().Msgf("%v: JOIN FAILED %v: %v", h.network.Server, m.Params[1], m)
|
||||||
|
|
||||||
|
case "900": // Invite bot logged in
|
||||||
|
log.Debug().Msgf("%v: %v", h.network.Server, m.Trailing())
|
||||||
|
|
||||||
|
case "KICK":
|
||||||
|
log.Debug().Msgf("%v: KICK: %v", h.network.Server, m)
|
||||||
|
|
||||||
|
case "MODE":
|
||||||
|
err := h.handleMode(m)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msgf("error MODE change: %v", m)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "INVITE":
|
||||||
|
// TODO: handle invite
|
||||||
|
log.Debug().Msgf("%v: INVITE: %v", h.network.Server, m)
|
||||||
|
|
||||||
|
case "PART":
|
||||||
|
// TODO: handle parted
|
||||||
|
if h.isOurNick(m.Prefix.Name) {
|
||||||
|
log.Debug().Msgf("%v: PART: %v", h.network.Server, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "PRIVMSG":
|
||||||
|
err := h.onMessage(m)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Msgf("error on message %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "CAP":
|
||||||
|
log.Debug().Msgf("%v: CAP: %v", h.network.Server, m)
|
||||||
|
|
||||||
|
case "NOTICE":
|
||||||
|
log.Trace().Msgf("%v: %v", h.network.Server, m)
|
||||||
|
|
||||||
|
case "PING":
|
||||||
|
err := h.handlePing(m)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Stack().Err(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
//case "372":
|
||||||
|
// log.Debug().Msgf("372: %v", m)
|
||||||
|
//default:
|
||||||
|
// log.Trace().Msgf("%v: %v", h.network.Server, m)
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) resetConnectionStatus() {
|
func (h *Handler) isOurNick(nick string) bool {
|
||||||
|
return h.network.NickServ.Account == nick
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) setConnectionStatus() {
|
||||||
|
// set connected since now
|
||||||
|
h.connectedSince = time.Now()
|
||||||
|
h.connected = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) resetConnectionStatus() {
|
||||||
// set connected false if we loose connection or stop
|
// set connected false if we loose connection or stop
|
||||||
s.connectedSince = time.Time{}
|
h.connectedSince = time.Time{}
|
||||||
s.connected = false
|
h.connected = false
|
||||||
|
|
||||||
// loop over channelHealth and reset each one
|
// loop over channelHealth and reset each one
|
||||||
for _, h := range s.channelHealth {
|
for _, h := range h.channelHealth {
|
||||||
if h != nil {
|
if h != nil {
|
||||||
h.resetMonitoring()
|
h.resetMonitoring()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) GetNetwork() *domain.IrcNetwork {
|
func (h *Handler) GetNetwork() *domain.IrcNetwork {
|
||||||
return s.network
|
return h.network
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) UpdateNetwork(network *domain.IrcNetwork) {
|
func (h *Handler) UpdateNetwork(network *domain.IrcNetwork) {
|
||||||
s.network = network
|
h.network = network
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) Stop() {
|
func (h *Handler) SetNetwork(network *domain.IrcNetwork) {
|
||||||
s.cancel()
|
h.network = network
|
||||||
|
}
|
||||||
|
|
||||||
if !s.isStopped() {
|
func (h *Handler) Stop() {
|
||||||
close(s.stopped)
|
h.cancel()
|
||||||
|
|
||||||
|
if !h.isStopped() {
|
||||||
|
close(h.stopped)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.conn != nil {
|
if h.conn != nil {
|
||||||
s.conn.Close()
|
h.conn.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) isStopped() bool {
|
func (h *Handler) isStopped() bool {
|
||||||
select {
|
select {
|
||||||
case <-s.stopped:
|
case <-h.stopped:
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) Restart() error {
|
func (h *Handler) Restart() error {
|
||||||
s.cancel()
|
h.cancel()
|
||||||
|
|
||||||
if !s.isStopped() {
|
if !h.isStopped() {
|
||||||
close(s.stopped)
|
close(h.stopped)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.conn != nil {
|
if h.conn != nil {
|
||||||
s.conn.Close()
|
h.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
|
|
||||||
return s.Run()
|
return h.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) onConnect(channels []domain.IrcChannel) error {
|
func (h *Handler) onConnect(channels []domain.IrcChannel) error {
|
||||||
identified := false
|
identified := false
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
|
|
||||||
if s.network.NickServ.Password != "" {
|
if h.network.NickServ.Password != "" {
|
||||||
err := s.handleNickServPRIVMSG(s.network.NickServ.Account, s.network.NickServ.Password)
|
err := h.handleNickServPRIVMSG(h.network.NickServ.Account, h.network.NickServ.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("error nickserv: %v", s.network.Name)
|
log.Error().Stack().Err(err).Msgf("error nickserv: %v", h.network.Name)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
identified = true
|
identified = true
|
||||||
|
@ -343,11 +381,10 @@ func (s *Handler) onConnect(channels []domain.IrcChannel) error {
|
||||||
|
|
||||||
time.Sleep(3 * time.Second)
|
time.Sleep(3 * time.Second)
|
||||||
|
|
||||||
if s.network.InviteCommand != "" {
|
if h.network.InviteCommand != "" {
|
||||||
|
err := h.handleConnectCommands(h.network.InviteCommand)
|
||||||
err := s.handleInvitePRIVMSG(s.network.InviteCommand)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("error sending connect command %v to network: %v", s.network.InviteCommand, s.network.Name)
|
log.Error().Stack().Err(err).Msgf("error sending connect command %v to network: %v", h.network.InviteCommand, h.network.Name)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +393,7 @@ func (s *Handler) onConnect(channels []domain.IrcChannel) error {
|
||||||
|
|
||||||
if !identified {
|
if !identified {
|
||||||
for _, channel := range channels {
|
for _, channel := range channels {
|
||||||
err := s.HandleJoinChannel(channel.Name, channel.Password)
|
err := h.HandleJoinChannel(channel.Name, channel.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err)
|
log.Error().Stack().Err(err)
|
||||||
return err
|
return err
|
||||||
|
@ -367,34 +404,33 @@ func (s *Handler) onConnect(channels []domain.IrcChannel) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) OnJoin(msg string) (interface{}, error) {
|
func (h *Handler) OnJoin(msg string) (interface{}, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) onMessage(msg *irc.Message) error {
|
func (h *Handler) onMessage(msg *irc.Message) error {
|
||||||
// parse announce
|
// parse announce
|
||||||
channel := &msg.Params[0]
|
channel := &msg.Params[0]
|
||||||
announcer := &msg.Name
|
announcer := &msg.Name
|
||||||
message := msg.Trailing()
|
message := msg.Trailing()
|
||||||
// TODO add network
|
|
||||||
|
|
||||||
// check if message is from a valid channel, if not return
|
// check if message is from a valid channel, if not return
|
||||||
validChannel := s.isValidChannel(*channel)
|
validChannel := h.isValidChannel(*channel)
|
||||||
if !validChannel {
|
if !validChannel {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if message is from announce bot, if not return
|
// check if message is from announce bot, if not return
|
||||||
validAnnouncer := s.isValidAnnouncer(*announcer)
|
validAnnouncer := h.isValidAnnouncer(*announcer)
|
||||||
if !validAnnouncer {
|
if !validAnnouncer {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean message
|
// clean message
|
||||||
cleanedMsg := cleanMessage(message)
|
cleanedMsg := cleanMessage(message)
|
||||||
log.Debug().Msgf("%v: %v %v: %v", s.network.Server, *channel, *announcer, cleanedMsg)
|
log.Debug().Msgf("%v: %v %v: %v", h.network.Server, *channel, *announcer, cleanedMsg)
|
||||||
|
|
||||||
if err := s.sendToAnnounceProcessor(*channel, cleanedMsg); err != nil {
|
if err := h.sendToAnnounceProcessor(*channel, cleanedMsg); err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("could not queue line: %v", cleanedMsg)
|
log.Error().Stack().Err(err).Msgf("could not queue line: %v", cleanedMsg)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -402,11 +438,11 @@ func (s *Handler) onMessage(msg *irc.Message) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) sendToAnnounceProcessor(channel string, msg string) error {
|
func (h *Handler) sendToAnnounceProcessor(channel string, msg string) error {
|
||||||
channel = strings.ToLower(channel)
|
channel = strings.ToLower(channel)
|
||||||
|
|
||||||
// check if queue exists
|
// check if queue exists
|
||||||
queue, ok := s.announceProcessors[channel]
|
queue, ok := h.announceProcessors[channel]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("queue '%v' not found", channel)
|
return fmt.Errorf("queue '%v' not found", channel)
|
||||||
}
|
}
|
||||||
|
@ -418,7 +454,7 @@ func (s *Handler) sendToAnnounceProcessor(channel string, msg string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
v, ok := s.channelHealth[channel]
|
v, ok := h.channelHealth[channel]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -428,11 +464,11 @@ func (s *Handler) sendToAnnounceProcessor(channel string, msg string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) sendPrivMessage(msg string) error {
|
func (h *Handler) sendPrivMessage(msg string) error {
|
||||||
msg = strings.TrimLeft(msg, "/")
|
msg = strings.TrimLeft(msg, "/")
|
||||||
privMsg := fmt.Sprintf("PRIVMSG %s", msg)
|
privMsg := fmt.Sprintf("PRIVMSG %h", msg)
|
||||||
|
|
||||||
err := s.client.Write(privMsg)
|
err := h.client.Write(privMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msgf("could not send priv msg: %v", msg)
|
log.Error().Err(err).Msgf("could not send priv msg: %v", msg)
|
||||||
return err
|
return err
|
||||||
|
@ -441,7 +477,7 @@ func (s *Handler) sendPrivMessage(msg string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) HandleJoinChannel(channel string, password string) error {
|
func (h *Handler) HandleJoinChannel(channel string, password string) error {
|
||||||
// support channel password
|
// support channel password
|
||||||
params := []string{channel}
|
params := []string{channel}
|
||||||
if password != "" {
|
if password != "" {
|
||||||
|
@ -453,82 +489,105 @@ func (s *Handler) HandleJoinChannel(channel string, password string) error {
|
||||||
Params: params,
|
Params: params,
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Trace().Msgf("%v: sending %v", s.network.Server, m.String())
|
log.Trace().Msgf("%v: sending %v", h.network.Server, m.String())
|
||||||
|
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
err := s.client.Write(m.String())
|
err := h.client.Write(m.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("error handling join: %v", m.String())
|
log.Error().Stack().Err(err).Msgf("error handling join: %v", m.String())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// only set values if channel is found in map
|
|
||||||
v, ok := s.channelHealth[channel]
|
|
||||||
if ok {
|
|
||||||
v.SetMonitoring()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) HandlePartChannel(channel string) error {
|
func (h *Handler) HandlePartChannel(channel string) error {
|
||||||
m := irc.Message{
|
m := irc.Message{
|
||||||
Command: "PART",
|
Command: "PART",
|
||||||
Params: []string{channel},
|
Params: []string{channel},
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().Msgf("%v: %v", s.network.Server, m.String())
|
log.Debug().Msgf("%v: %v", h.network.Server, m.String())
|
||||||
|
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
err := s.client.Write(m.String())
|
err := h.client.Write(m.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msgf("error handling part: %v", m.String())
|
log.Error().Err(err).Msgf("error handling part: %v", m.String())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info().Msgf("Left channel '%v' on network '%s'", channel, s.network.Server)
|
// reset monitoring status
|
||||||
|
v, ok := h.channelHealth[channel]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v.resetMonitoring()
|
||||||
|
|
||||||
|
// TODO remove announceProcessor
|
||||||
|
|
||||||
|
log.Info().Msgf("Left channel '%v' on network '%h'", channel, h.network.Server)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) handleJoined(msg *irc.Message) {
|
func (h *Handler) handleJoined(msg *irc.Message) {
|
||||||
log.Debug().Msgf("%v: JOINED: %v", s.network.Server, msg.Trailing())
|
log.Debug().Msgf("%v: JOINED: %v", h.network.Server, msg.Params[1])
|
||||||
|
|
||||||
log.Info().Msgf("%v: Monitoring channel %s", s.network.Server, msg.Params[1])
|
// get channel
|
||||||
}
|
channel := &msg.Params[1]
|
||||||
|
|
||||||
func (s *Handler) handleInvitePRIVMSG(msg string) error {
|
// set monitoring on current channelHealth, or add new
|
||||||
msg = strings.TrimPrefix(msg, "/msg")
|
v, ok := h.channelHealth[strings.ToLower(*channel)]
|
||||||
split := strings.Split(msg, " ")
|
if ok {
|
||||||
|
v.SetMonitoring()
|
||||||
m := irc.Message{
|
} else if v == nil {
|
||||||
Command: "PRIVMSG",
|
h.channelHealth[*channel] = &channelHealth{
|
||||||
Params: split,
|
name: *channel,
|
||||||
|
monitoring: true,
|
||||||
|
monitoringSince: time.Now(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info().Msgf("%v: Invite command: %v", s.network.Server, m.String())
|
log.Info().Msgf("%v: Monitoring channel %v", h.network.Server, msg.Params[1])
|
||||||
|
}
|
||||||
|
|
||||||
err := s.client.Write(m.String())
|
func (h *Handler) handleConnectCommands(msg string) error {
|
||||||
if err != nil {
|
connectCommand := strings.ReplaceAll(msg, "/msg", "")
|
||||||
log.Error().Err(err).Msgf("error handling invite: %v", m.String())
|
connectCommands := strings.Split(connectCommand, ",")
|
||||||
return err
|
|
||||||
|
for _, command := range connectCommands {
|
||||||
|
cmd := strings.TrimSpace(command)
|
||||||
|
|
||||||
|
m := irc.Message{
|
||||||
|
Command: "PRIVMSG",
|
||||||
|
Params: strings.Split(cmd, " "),
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Msgf("%v: sending connect command", h.network.Server)
|
||||||
|
|
||||||
|
err := h.client.Write(m.String())
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msgf("error handling invite: %v", m.String())
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) handlePRIVMSG(msg string) error {
|
func (h *Handler) handlePRIVMSG(msg string) error {
|
||||||
msg = strings.TrimLeft(msg, "/")
|
msg = strings.TrimLeft(msg, "/")
|
||||||
|
|
||||||
m := irc.Message{
|
m := irc.Message{
|
||||||
Command: "PRIVMSG",
|
Command: "PRIVMSG",
|
||||||
Params: []string{msg},
|
Params: []string{msg},
|
||||||
}
|
}
|
||||||
log.Debug().Msgf("%v: Handle privmsg: %v", s.network.Server, m.String())
|
log.Debug().Msgf("%v: Handle privmsg: %v", h.network.Server, m.String())
|
||||||
|
|
||||||
err := s.client.Write(m.String())
|
err := h.client.Write(m.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msgf("error handling PRIVMSG: %v", m.String())
|
log.Error().Err(err).Msgf("error handling PRIVMSG: %v", m.String())
|
||||||
return err
|
return err
|
||||||
|
@ -537,15 +596,15 @@ func (s *Handler) handlePRIVMSG(msg string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) handleNickServPRIVMSG(nick, password string) error {
|
func (h *Handler) handleNickServPRIVMSG(nick, password string) error {
|
||||||
m := irc.Message{
|
m := irc.Message{
|
||||||
Command: "PRIVMSG",
|
Command: "PRIVMSG",
|
||||||
Params: []string{"NickServ", "IDENTIFY", nick, password},
|
Params: []string{"NickServ", "IDENTIFY", nick, password},
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().Msgf("%v: NickServ: %v", s.network.Server, m.String())
|
log.Debug().Msgf("%v: NickServ: %v", h.network.Server, m.String())
|
||||||
|
|
||||||
err := s.client.Write(m.String())
|
err := h.client.Write(m.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msgf("error identifying with nickserv: %v", m.String())
|
log.Error().Err(err).Msgf("error identifying with nickserv: %v", m.String())
|
||||||
return err
|
return err
|
||||||
|
@ -554,15 +613,15 @@ func (s *Handler) handleNickServPRIVMSG(nick, password string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) HandleNickServIdentify(nick, password string) error {
|
func (h *Handler) HandleNickServIdentify(nick, password string) error {
|
||||||
m := irc.Message{
|
m := irc.Message{
|
||||||
Command: "PRIVMSG",
|
Command: "PRIVMSG",
|
||||||
Params: []string{"NickServ", "IDENTIFY", nick, password},
|
Params: []string{"NickServ", "IDENTIFY", nick, password},
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().Msgf("%v: NickServ: %v", s.network.Server, m.String())
|
log.Debug().Msgf("%v: NickServ: %v", h.network.Server, m.String())
|
||||||
|
|
||||||
err := s.client.Write(m.String())
|
err := h.client.Write(m.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("error identifying with nickserv: %v", m.String())
|
log.Error().Stack().Err(err).Msgf("error identifying with nickserv: %v", m.String())
|
||||||
return err
|
return err
|
||||||
|
@ -571,15 +630,15 @@ func (s *Handler) HandleNickServIdentify(nick, password string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) HandleNickChange(nick string) error {
|
func (h *Handler) HandleNickChange(nick string) error {
|
||||||
m := irc.Message{
|
m := irc.Message{
|
||||||
Command: "NICK",
|
Command: "NICK",
|
||||||
Params: []string{nick},
|
Params: []string{nick},
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().Msgf("%v: Nick change: %v", s.network.Server, m.String())
|
log.Debug().Msgf("%v: Nick change: %v", h.network.Server, m.String())
|
||||||
|
|
||||||
err := s.client.Write(m.String())
|
err := h.client.Write(m.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("error changing nick: %v", m.String())
|
log.Error().Stack().Err(err).Msgf("error changing nick: %v", m.String())
|
||||||
return err
|
return err
|
||||||
|
@ -588,18 +647,18 @@ func (s *Handler) HandleNickChange(nick string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) handleMode(msg *irc.Message) error {
|
func (h *Handler) handleMode(msg *irc.Message) error {
|
||||||
log.Debug().Msgf("%v: MODE: %v %v", s.network.Server, msg.User, msg.Trailing())
|
log.Debug().Msgf("%v: MODE: %v %v", h.network.Server, msg.User, msg.Trailing())
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
|
|
||||||
if s.network.NickServ.Password != "" && !strings.Contains(msg.String(), s.client.CurrentNick()) || !strings.Contains(msg.String(), "+r") {
|
if h.network.NickServ.Password != "" && !strings.Contains(msg.String(), h.client.CurrentNick()) || !strings.Contains(msg.String(), "+r") {
|
||||||
log.Trace().Msgf("%v: MODE: Not correct permission yet: %v", s.network.Server, msg.String())
|
log.Trace().Msgf("%v: MODE: Not correct permission yet: %v", h.network.Server, msg.String())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ch := range s.network.Channels {
|
for _, ch := range h.network.Channels {
|
||||||
err := s.HandleJoinChannel(ch.Name, ch.Password)
|
err := h.HandleJoinChannel(ch.Name, ch.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msgf("error joining channel: %v", ch.Name)
|
log.Error().Err(err).Msgf("error joining channel: %v", ch.Name)
|
||||||
continue
|
continue
|
||||||
|
@ -611,30 +670,30 @@ func (s *Handler) handleMode(msg *irc.Message) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) handlePing(msg *irc.Message) error {
|
func (h *Handler) handlePing(msg *irc.Message) error {
|
||||||
log.Trace().Msgf("%v: %v", s.network.Server, msg)
|
log.Trace().Msgf("%v: %v", h.network.Server, msg)
|
||||||
|
|
||||||
pong := irc.Message{
|
pong := irc.Message{
|
||||||
Command: "PONG",
|
Command: "PONG",
|
||||||
Params: msg.Params,
|
Params: msg.Params,
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Trace().Msgf("%v: %v", s.network.Server, pong.String())
|
log.Trace().Msgf("%v: %v", h.network.Server, pong.String())
|
||||||
|
|
||||||
err := s.client.Write(pong.String())
|
err := h.client.Write(pong.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msgf("error PING PONG response: %v", pong.String())
|
log.Error().Err(err).Msgf("error PING PONG response: %v", pong.String())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.setLastPing()
|
h.setLastPing()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if announcer is one from the list in the definition
|
// check if announcer is one from the list in the definition
|
||||||
func (s *Handler) isValidAnnouncer(nick string) bool {
|
func (h *Handler) isValidAnnouncer(nick string) bool {
|
||||||
_, ok := s.validAnnouncers[nick]
|
_, ok := h.validAnnouncers[nick]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -643,8 +702,8 @@ func (s *Handler) isValidAnnouncer(nick string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if channel is one from the list in the definition
|
// check if channel is one from the list in the definition
|
||||||
func (s *Handler) isValidChannel(channel string) bool {
|
func (h *Handler) isValidChannel(channel string) bool {
|
||||||
_, ok := s.validChannels[strings.ToLower(channel)]
|
_, ok := h.validChannels[strings.ToLower(channel)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -652,12 +711,12 @@ func (s *Handler) isValidChannel(channel string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) setLastPing() {
|
func (h *Handler) setLastPing() {
|
||||||
s.lastPing = time.Now()
|
h.lastPing = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) GetLastPing() time.Time {
|
func (h *Handler) GetLastPing() time.Time {
|
||||||
return s.lastPing
|
return h.lastPing
|
||||||
}
|
}
|
||||||
|
|
||||||
// irc line can contain lots of extra stuff like color so lets clean that
|
// irc line can contain lots of extra stuff like color so lets clean that
|
||||||
|
|
|
@ -17,7 +17,7 @@ import (
|
||||||
type Service interface {
|
type Service interface {
|
||||||
StartHandlers()
|
StartHandlers()
|
||||||
StopHandlers()
|
StopHandlers()
|
||||||
StopNetwork(name string) error
|
StopNetwork(key handlerKey) error
|
||||||
ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error)
|
ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error)
|
||||||
GetNetworksWithHealth(ctx context.Context) ([]domain.IrcNetworkWithHealth, error)
|
GetNetworksWithHealth(ctx context.Context) ([]domain.IrcNetworkWithHealth, error)
|
||||||
GetNetworkByID(id int64) (*domain.IrcNetwork, error)
|
GetNetworkByID(id int64) (*domain.IrcNetwork, error)
|
||||||
|
@ -33,7 +33,7 @@ type service struct {
|
||||||
indexerService indexer.Service
|
indexerService indexer.Service
|
||||||
releaseService release.Service
|
releaseService release.Service
|
||||||
indexerMap map[string]string
|
indexerMap map[string]string
|
||||||
handlers map[string]*Handler
|
handlers map[handlerKey]*Handler
|
||||||
|
|
||||||
stopWG sync.WaitGroup
|
stopWG sync.WaitGroup
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
|
@ -45,10 +45,15 @@ func NewService(repo domain.IrcRepo, filterService filter.Service, indexerSvc in
|
||||||
filterService: filterService,
|
filterService: filterService,
|
||||||
indexerService: indexerSvc,
|
indexerService: indexerSvc,
|
||||||
releaseService: releaseSvc,
|
releaseService: releaseSvc,
|
||||||
handlers: make(map[string]*Handler),
|
handlers: make(map[handlerKey]*Handler),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type handlerKey struct {
|
||||||
|
server string
|
||||||
|
nick string
|
||||||
|
}
|
||||||
|
|
||||||
func (s *service) StartHandlers() {
|
func (s *service) StartHandlers() {
|
||||||
networks, err := s.repo.FindActiveNetworks(context.Background())
|
networks, err := s.repo.FindActiveNetworks(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -76,8 +81,9 @@ func (s *service) StartHandlers() {
|
||||||
// init new irc handler
|
// init new irc handler
|
||||||
handler := NewHandler(network, s.filterService, s.releaseService, definitions)
|
handler := NewHandler(network, s.filterService, s.releaseService, definitions)
|
||||||
|
|
||||||
// TODO use network.Server? + nick? Need a way to use multiple indexers for one network if same nick
|
// use network.Server + nick to use multiple indexers with different nick per network
|
||||||
s.handlers[network.Server] = handler
|
// this allows for multiple handlers to one network
|
||||||
|
s.handlers[handlerKey{network.Server, network.NickServ.Account}] = handler
|
||||||
s.lock.Unlock()
|
s.lock.Unlock()
|
||||||
|
|
||||||
log.Debug().Msgf("starting network: %+v", network.Name)
|
log.Debug().Msgf("starting network: %+v", network.Name)
|
||||||
|
@ -105,7 +111,7 @@ func (s *service) StopHandlers() {
|
||||||
|
|
||||||
func (s *service) startNetwork(network domain.IrcNetwork) error {
|
func (s *service) startNetwork(network domain.IrcNetwork) error {
|
||||||
// look if we have the network in handlers already, if so start it
|
// look if we have the network in handlers already, if so start it
|
||||||
if existingHandler, found := s.handlers[network.Server]; found {
|
if existingHandler, found := s.handlers[handlerKey{network.Server, network.NickServ.Account}]; found {
|
||||||
log.Debug().Msgf("starting network: %+v", network.Name)
|
log.Debug().Msgf("starting network: %+v", network.Name)
|
||||||
|
|
||||||
if existingHandler.conn != nil {
|
if existingHandler.conn != nil {
|
||||||
|
@ -131,7 +137,7 @@ func (s *service) startNetwork(network domain.IrcNetwork) error {
|
||||||
// init new irc handler
|
// init new irc handler
|
||||||
handler := NewHandler(network, s.filterService, s.releaseService, definitions)
|
handler := NewHandler(network, s.filterService, s.releaseService, definitions)
|
||||||
|
|
||||||
s.handlers[network.Server] = handler
|
s.handlers[handlerKey{network.Server, network.NickServ.Account}] = handler
|
||||||
s.lock.Unlock()
|
s.lock.Unlock()
|
||||||
|
|
||||||
log.Debug().Msgf("starting network: %+v", network.Name)
|
log.Debug().Msgf("starting network: %+v", network.Name)
|
||||||
|
@ -152,9 +158,8 @@ func (s *service) startNetwork(network domain.IrcNetwork) error {
|
||||||
|
|
||||||
func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error {
|
func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error {
|
||||||
// look if we have the network in handlers, if so restart it
|
// look if we have the network in handlers, if so restart it
|
||||||
// TODO check if we need to add indexerDefinitions etc
|
if existingHandler, found := s.handlers[handlerKey{network.Server, network.NickServ.Account}]; found {
|
||||||
if existingHandler, found := s.handlers[network.Server]; found {
|
log.Debug().Msgf("irc: decide if irc network handler needs restart or updating: %+v", network.Server)
|
||||||
log.Debug().Msgf("decide if irc network handler needs restart or updating: %+v", network.Name)
|
|
||||||
|
|
||||||
// if server, tls, invite command, port : changed - restart
|
// if server, tls, invite command, port : changed - restart
|
||||||
// if nickserv account, nickserv password : changed - stay connected, and change those
|
// if nickserv account, nickserv password : changed - stay connected, and change those
|
||||||
|
@ -173,18 +178,20 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
|
||||||
restartNeeded = true
|
restartNeeded = true
|
||||||
}
|
}
|
||||||
if restartNeeded {
|
if restartNeeded {
|
||||||
log.Info().Msgf("irc: restarting network: %+v", network.Name)
|
log.Info().Msgf("irc: restarting network: %+v", network.Server)
|
||||||
|
|
||||||
// we need to reinitialize with new network config
|
// we need to reinitialize with new network config
|
||||||
existingHandler.UpdateNetwork(network)
|
existingHandler.UpdateNetwork(network)
|
||||||
|
|
||||||
|
// todo reset channelHealth?
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if err := existingHandler.Restart(); err != nil {
|
if err := existingHandler.Restart(); err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("failed to restart network %q", existingHandler.network.Name)
|
log.Error().Stack().Err(err).Msgf("failed to restart network %q", existingHandler.network.Name)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// return now since the restart will read the network again OR FIXME
|
// return now since the restart will read the network again
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,6 +237,7 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
|
||||||
channelsToLeave = append(channelsToLeave, handlerChan.Name)
|
channelsToLeave = append(channelsToLeave, handlerChan.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check new channels against handler to see which to join
|
||||||
for _, channel := range network.Channels {
|
for _, channel := range network.Channels {
|
||||||
_, ok := handlerChannels[channel.Name]
|
_, ok := handlerChannels[channel.Name]
|
||||||
if ok {
|
if ok {
|
||||||
|
@ -243,6 +251,7 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
|
||||||
|
|
||||||
// leave channels
|
// leave channels
|
||||||
for _, leaveChannel := range channelsToLeave {
|
for _, leaveChannel := range channelsToLeave {
|
||||||
|
log.Debug().Msgf("%v: part channel %v", network.Server, leaveChannel)
|
||||||
err := existingHandler.HandlePartChannel(leaveChannel)
|
err := existingHandler.HandlePartChannel(leaveChannel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("failed to leave channel: %q", leaveChannel)
|
log.Error().Stack().Err(err).Msgf("failed to leave channel: %q", leaveChannel)
|
||||||
|
@ -251,12 +260,21 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
|
||||||
|
|
||||||
// join channels
|
// join channels
|
||||||
for _, joinChannel := range channelsToJoin {
|
for _, joinChannel := range channelsToJoin {
|
||||||
// TODO handle invite commands before?
|
log.Debug().Msgf("%v: join new channel %v", network.Server, joinChannel)
|
||||||
err := existingHandler.HandleJoinChannel(joinChannel.Name, joinChannel.Password)
|
err := existingHandler.HandleJoinChannel(joinChannel.Name, joinChannel.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("failed to join channel: %q", joinChannel.Name)
|
log.Error().Stack().Err(err).Msgf("failed to join channel: %q", joinChannel.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update network for handler
|
||||||
|
// TODO move all this restart logic inside handler to let it decide what to do
|
||||||
|
existingHandler.SetNetwork(network)
|
||||||
|
|
||||||
|
// find indexer definitions for network and add
|
||||||
|
definitions := s.indexerService.GetIndexersByIRCNetwork(network.Server)
|
||||||
|
|
||||||
|
existingHandler.InitIndexers(definitions)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err := s.startNetwork(*network)
|
err := s.startNetwork(*network)
|
||||||
|
@ -270,7 +288,7 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
|
||||||
|
|
||||||
func (s *service) restartNetwork(network domain.IrcNetwork) error {
|
func (s *service) restartNetwork(network domain.IrcNetwork) error {
|
||||||
// look if we have the network in handlers, if so restart it
|
// look if we have the network in handlers, if so restart it
|
||||||
if existingHandler, found := s.handlers[network.Server]; found {
|
if existingHandler, found := s.handlers[handlerKey{network.Server, network.NickServ.Account}]; found {
|
||||||
log.Info().Msgf("restarting network: %+v", network.Name)
|
log.Info().Msgf("restarting network: %+v", network.Name)
|
||||||
|
|
||||||
if existingHandler.conn != nil {
|
if existingHandler.conn != nil {
|
||||||
|
@ -287,31 +305,31 @@ func (s *service) restartNetwork(network domain.IrcNetwork) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) StopNetwork(name string) error {
|
func (s *service) StopNetwork(key handlerKey) error {
|
||||||
if handler, found := s.handlers[name]; found {
|
if handler, found := s.handlers[key]; found {
|
||||||
handler.Stop()
|
handler.Stop()
|
||||||
log.Debug().Msgf("stopped network: %+v", name)
|
log.Debug().Msgf("stopped network: %+v", key.server)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) StopAndRemoveNetwork(name string) error {
|
func (s *service) StopAndRemoveNetwork(key handlerKey) error {
|
||||||
if handler, found := s.handlers[name]; found {
|
if handler, found := s.handlers[key]; found {
|
||||||
handler.Stop()
|
handler.Stop()
|
||||||
|
|
||||||
// remove from handlers
|
// remove from handlers
|
||||||
delete(s.handlers, name)
|
delete(s.handlers, key)
|
||||||
log.Debug().Msgf("stopped network: %+v", name)
|
log.Debug().Msgf("stopped network: %+v", key)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) StopNetworkIfRunning(name string) error {
|
func (s *service) StopNetworkIfRunning(key handlerKey) error {
|
||||||
if handler, found := s.handlers[name]; found {
|
if handler, found := s.handlers[key]; found {
|
||||||
handler.Stop()
|
handler.Stop()
|
||||||
log.Debug().Msgf("stopped network: %+v", name)
|
log.Debug().Msgf("stopped network: %+v", key.server)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -351,8 +369,6 @@ func (s *service) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error)
|
||||||
}
|
}
|
||||||
n.Channels = append(n.Channels, channels...)
|
n.Channels = append(n.Channels, channels...)
|
||||||
|
|
||||||
// TODO get handler channelHealth
|
|
||||||
|
|
||||||
ret = append(ret, n)
|
ret = append(ret, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +398,7 @@ func (s *service) GetNetworksWithHealth(ctx context.Context) ([]domain.IrcNetwor
|
||||||
Connected: false,
|
Connected: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
handler, ok := s.handlers[n.Server]
|
handler, ok := s.handlers[handlerKey{n.Server, n.NickServ.Account}]
|
||||||
if ok {
|
if ok {
|
||||||
// only set connected and connected since if we have an active handler and connection
|
// only set connected and connected since if we have an active handler and connection
|
||||||
if handler.conn != nil {
|
if handler.conn != nil {
|
||||||
|
@ -441,7 +457,7 @@ func (s *service) DeleteNetwork(ctx context.Context, id int64) error {
|
||||||
|
|
||||||
// Remove network and handler
|
// Remove network and handler
|
||||||
//if err = s.StopNetwork(network.Server); err != nil {
|
//if err = s.StopNetwork(network.Server); err != nil {
|
||||||
if err = s.StopAndRemoveNetwork(network.Server); err != nil {
|
if err = s.StopAndRemoveNetwork(handlerKey{network.Server, network.NickServ.Account}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,9 +494,8 @@ func (s *service) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// TODO take into account multiple channels per network
|
// take into account multiple channels per network
|
||||||
//err := s.StopNetwork(network.Server)
|
err := s.StopAndRemoveNetwork(handlerKey{network.Server, network.NickServ.Account})
|
||||||
err := s.StopAndRemoveNetwork(network.Server)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("could not stop network: %+v", network.Name)
|
log.Error().Stack().Err(err).Msgf("could not stop network: %+v", network.Name)
|
||||||
return fmt.Errorf("could not stop network: %v", network.Name)
|
return fmt.Errorf("could not stop network: %v", network.Name)
|
||||||
|
@ -514,16 +529,23 @@ func (s *service) StoreNetwork(ctx context.Context, network *domain.IrcNetwork)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get channels for existing network
|
||||||
|
existingChannels, err := s.repo.ListChannels(existingNetwork.ID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msgf("failed to list channels for network %q", existingNetwork.Server)
|
||||||
|
}
|
||||||
|
existingNetwork.Channels = existingChannels
|
||||||
|
|
||||||
if network.Channels != nil {
|
if network.Channels != nil {
|
||||||
for _, channel := range network.Channels {
|
for _, channel := range network.Channels {
|
||||||
// TODO store or add. Make sure it doesn't delete before
|
// add channels. Make sure it doesn't delete before
|
||||||
if err := s.repo.StoreChannel(existingNetwork.ID, &channel); err != nil {
|
if err := s.repo.StoreChannel(existingNetwork.ID, &channel); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// append channels to existing network
|
// append channels to existing network
|
||||||
network.Channels = append(network.Channels, existingNetwork.Channels...)
|
existingNetwork.Channels = append(existingNetwork.Channels, network.Channels...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if existingNetwork.Enabled {
|
if existingNetwork.Enabled {
|
||||||
|
@ -531,10 +553,10 @@ func (s *service) StoreNetwork(ctx context.Context, network *domain.IrcNetwork)
|
||||||
// if nickserv account, nickserv password : changed - stay connected, and change those
|
// if nickserv account, nickserv password : changed - stay connected, and change those
|
||||||
// if channels len : changes - join or leave
|
// if channels len : changes - join or leave
|
||||||
|
|
||||||
err := s.checkIfNetworkRestartNeeded(network)
|
err := s.checkIfNetworkRestartNeeded(existingNetwork)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msgf("could not restart network: %+v", network.Name)
|
log.Error().Err(err).Msgf("could not restart network: %+v", existingNetwork.Name)
|
||||||
return fmt.Errorf("could not restart network: %v", network.Name)
|
return fmt.Errorf("could not restart network: %v", existingNetwork.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ export function IndexerAddForm({ isOpen, toggle }: AddProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const network: Network = {
|
const network: Network = {
|
||||||
name: ind.name,
|
name: ind.irc.network,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
server: ind.irc.server,
|
server: ind.irc.server,
|
||||||
port: ind.irc.port,
|
port: ind.irc.port,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue