diff --git a/bot/bot.go b/bot/bot.go index 733b9bb..c130732 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -308,6 +308,10 @@ type BlacklistItem struct { Name string } +func (b BlacklistItem) Key() string { + return b.Channel + b.Name +} + type WhitelistItem struct { Name string } diff --git a/go.mod b/go.mod index 2f6db2d..a040971 100644 --- a/go.mod +++ b/go.mod @@ -34,6 +34,7 @@ require ( github.com/itchyny/gojq v0.12.3 github.com/james-bowman/nlp v0.0.0-20191016091239-d9dbfaff30c6 github.com/james-bowman/sparse v0.0.0-20190423065201-80c6877364c7 // indirect + github.com/jmoiron/sqlx v1.3.4 github.com/kennygrant/sanitize v1.2.4 // indirect github.com/kevinburke/go-types v0.0.0-20200309064045-f2d4aea18a7a // indirect github.com/kevinburke/go.uuid v1.2.0 // indirect @@ -58,10 +59,10 @@ require ( github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect github.com/ttacon/libphonenumber v1.1.0 // indirect github.com/velour/velour v0.0.0-20160303155839-8e090e68d158 + go.etcd.io/bbolt v1.3.6 // indirect golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 golang.org/x/exp v0.0.0-20191014171548-69215a2ee97e // indirect golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4 // indirect - golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 // indirect golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 // indirect golang.org/x/text v0.3.7 // indirect gonum.org/v1/gonum v0.6.0 // indirect @@ -69,4 +70,5 @@ require ( gopkg.in/go-playground/webhooks.v5 v5.13.0 gopkg.in/sourcemap.v1 v1.0.5 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + modernc.org/sqlite v1.14.3 ) diff --git a/go.sum b/go.sum index f8a13e4..b810261 100644 --- a/go.sum +++ b/go.sum @@ -37,6 +37,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-jsonpointer v0.0.0-20160814072949-ba0abeacc3dc h1:tP7tkU+vIsEOKiK+l/NSLN4uUtkyuxc6hgYpQeCWAeI= github.com/dustin/go-jsonpointer v0.0.0-20160814072949-ba0abeacc3dc/go.mod h1:ORH5Qp2bskd9NzSfKqAF7tKfONsEkCarTE5ESr/RVBw= github.com/dustin/gojson v0.0.0-20160307161227-2e71ec9dd5ad h1:Qk76DOWdOp+GlyDKBAG3Klr9cn7N+LcYc82AZ2S7+cA= @@ -48,6 +50,8 @@ github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17/go.mod h1:HfkOCN github.com/go-chi/chi/v5 v5.0.3 h1:khYQBdPivkYG1s1TAzDQG1f6eX4kD2TItYVZexL5rS4= github.com/go-chi/chi/v5 v5.0.3/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= @@ -66,6 +70,8 @@ github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82 h1:EvokxLQsaaQjcWVWSV github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg= github.com/gonum/internal v0.0.0-20181124074243-f884aa714029 h1:8jtTdc+Nfj9AR+0soOeia9UZSvYBvETVHZrugUowJ7M= github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -83,7 +89,11 @@ github.com/james-bowman/nlp v0.0.0-20191016091239-d9dbfaff30c6 h1:k8+n5sfvxlixRN github.com/james-bowman/nlp v0.0.0-20191016091239-d9dbfaff30c6/go.mod h1:kixuaexEqWB+mHZNysgnb6mqgGIT25WvD1/tFRRt0J0= github.com/james-bowman/sparse v0.0.0-20190423065201-80c6877364c7 h1:ph/BDQQDL41apnHSN48I5GyNOQXXAlc79HwGqDSXCss= github.com/james-bowman/sparse v0.0.0-20190423065201-80c6877364c7/go.mod h1:G6EcQnwZKsWtItoaQHd+FHPPk6bDeYVJSeeSP9Sge+I= +github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w= +github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +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/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o= github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak= github.com/kevinburke/go-types v0.0.0-20200309064045-f2d4aea18a7a h1:Z7+SSApKiwPjNic+NF9+j7h657Uyvdp/jA3iTKhpj4E= @@ -94,11 +104,16 @@ github.com/kevinburke/rest v0.0.0-20200429221318-0d2892b400f8 h1:KpuDJTaTPQAyWqE github.com/kevinburke/rest v0.0.0-20200429221318-0d2892b400f8/go.mod h1:pD+iEcdAGVXld5foVN4e24zb/6fnb60tgZPZ3P/3T/I= github.com/kevinburke/twilio-go v0.0.0-20200424172635-4f0b2357b852 h1:wJMykIkD7A4tlwQNzqBJ23hkLlKtRKYeNNt+n8ASqWE= github.com/kevinburke/twilio-go v0.0.0-20200424172635-4f0b2357b852/go.mod h1:Fm9alkN1/LPVY1eqD/psyMwPWE4VWl4P01/nTYZKzBk= +github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA= +github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mmcdole/gofeed v1.0.0-beta2 h1:CjQ0ADhAwNSb08zknAkGOEYqr8zfZKfrzgk9BxpWP2E= github.com/mmcdole/gofeed v1.0.0-beta2/go.mod h1:/BF9JneEL2/flujm8XHoxUcghdTV6vvb3xx/vKyChFU= github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf h1:sWGE2v+hO0Nd4yFU/S/mDBM5plIU8v/Qhfz41hkDIAI= @@ -113,6 +128,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d h1:1VUlQbCfkoSGv7qP7Y+ro3ap1P1pPZxgdGVqiTVy5C4= github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= @@ -143,12 +160,15 @@ github.com/ttacon/libphonenumber v1.1.0 h1:tC6kE4t8UI4OqQVQjW5q8gSWhG2wnY5moEpSE github.com/ttacon/libphonenumber v1.1.0/go.mod h1:E0TpmdVMq5dyVlQ7oenAkhsLu86OkUl+yR4OAxyEg/M= github.com/velour/velour v0.0.0-20160303155839-8e090e68d158 h1:p3rTUXxzuKsBOsHlkly7+rj9wagFBKeIsCDKkDII9sw= github.com/velour/velour v0.0.0-20160303155839-8e090e68d158/go.mod h1:Ojy3BTOiOTwpHpw7/HNi+TVTFppao191PQs+Qc3sqpE= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -163,12 +183,15 @@ golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDA golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4 h1:DZshvxDdVoeKIbudAdFEKi+f70l51luSy/7b76ibTY0= golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -182,15 +205,20 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/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-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210301091718-77cc2087c03b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20211117180635-dee7805ff2e1 h1:kwrAHlwJ0DUBZwQ238v+Uod/3eZ8B2K5rYsUHBQvzmI= golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -199,8 +227,14 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78 h1:M8tBwCtWD/cZV9DZpFYRUgaymAYAr+aIUTWzDaM3uPs= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 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-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= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.6.0 h1:DJy6UzXbahnGUf1ujUNkh/NEtK14qMo2nvlBPs4U5yw= gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= @@ -219,4 +253,126 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +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 h1:rMZhRcWrba0y3nVmdiQ7kxAgOOSq2m2f2VzjHLgEs6U= +modernc.org/cc/v3 v3.35.18/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 h1:Ym2JG2G3P4IyZqjTTojHTl7qO0RysXeGSYPSoKPSBxc= +modernc.org/ccgo/v3 v3.12.95/go.mod h1:ZcLyvtocXYi8uF+9Ebm3G8EF8HNY5hGomBqthDp4eC8= +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 h1:gxoa5b3HPo7OzD4tKZjgnwXk/w//u1oovvjSMP3Q96Q= +modernc.org/libc v1.11.104/go.mod h1:2MH3DaF/gCU8i/UBiVE1VFRos4o523M7zipmwH8SIgQ= +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/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/plugins/admin/admin.go b/plugins/admin/admin.go index c1f4989..13ea420 100644 --- a/plugins/admin/admin.go +++ b/plugins/admin/admin.go @@ -366,16 +366,18 @@ func (p *AdminPlugin) addBlacklist(channel, plugin string) error { return fmt.Errorf("you cannot disable the admin plugin") } defer p.bot.RefreshPluginBlacklist() - return p.store.Upsert(channel+plugin, bot.BlacklistItem{ + it := bot.BlacklistItem{ Channel: channel, Name: plugin, - }) + } + return p.store.Upsert(it.Key(), it) } func (p *AdminPlugin) rmBlacklist(channel, plugin string) error { defer p.bot.RefreshPluginBlacklist() - return p.store.Delete(channel+plugin, bot.BlacklistItem{ + it := bot.BlacklistItem{ Channel: channel, Name: plugin, - }) + } + return p.store.Delete(it.Key(), bot.BlacklistItem{}) } diff --git a/plugins/admin/web.go b/plugins/admin/web.go index 85d815f..9493a26 100644 --- a/plugins/admin/web.go +++ b/plugins/admin/web.go @@ -43,7 +43,7 @@ type PassEntry struct { // Should be null unless inserting a new entry Pass string `json:"pass"` - encodedPass []byte `json:"encodedPass"` + EncodedPass []byte `db:"encoded_pass" json:"encodedPass"` Cost int `json:"cost"` } @@ -52,11 +52,11 @@ func (p *PassEntry) EncodePass() { if err != nil { log.Error().Err(err).Msg("could not hash password") } - p.encodedPass = encoded + p.EncodedPass = encoded } func (p *PassEntry) Compare(pass string) bool { - if err := bcrypt.CompareHashAndPassword(p.encodedPass, []byte(pass)); err != nil { + if err := bcrypt.CompareHashAndPassword(p.EncodedPass, []byte(pass)); err != nil { log.Error().Err(err).Msg("failure to match password") return false } @@ -111,18 +111,18 @@ func (p *AdminPlugin) handleAppPassAPI(w http.ResponseWriter, r *http.Request) { req.PassEntry.EncodePass() - check := bcrypt.CompareHashAndPassword(req.PassEntry.encodedPass, []byte(req.PassEntry.Pass)) + check := bcrypt.CompareHashAndPassword(req.PassEntry.EncodedPass, []byte(req.PassEntry.Pass)) entry := PassEntry{ Secret: req.PassEntry.Secret, - encodedPass: req.PassEntry.encodedPass, + EncodedPass: req.PassEntry.EncodedPass, Cost: req.PassEntry.Cost, Pass: "", } log.Debug(). Str("secret", req.PassEntry.Secret). - Str("encoded", string(req.PassEntry.encodedPass)). + Str("encoded", string(req.PassEntry.EncodedPass)). Str("password", string(req.PassEntry.Pass)). Interface("check", check). Msg("debug pass creation") diff --git a/plugins/counter/counter.go b/plugins/counter/counter.go index e94efa7..8c760be 100644 --- a/plugins/counter/counter.go +++ b/plugins/counter/counter.go @@ -36,13 +36,13 @@ type Item struct { UserID string } -type alias struct { +type Alias struct { store *bh.Store created bool ID uint64 `boltholdKey:"ID"` Item string - PointsTo string `db:"PointsTo"` + PointsTo string `db:"points_to"` } // GetItems returns all counters @@ -110,17 +110,17 @@ func Leader(store *bh.Store, itemName string) ([]Item, error) { } func RmAlias(store *bh.Store, aliasName string) error { - a := &alias{} + a := &Alias{} if err := store.FindOne(a, bh.Where("Item").Eq(aliasName)); err != nil { return err } - return store.Delete(a.ID, alias{}) + return store.Delete(a.ID, Alias{}) } -func MkAlias(store *bh.Store, aliasName, pointsTo string) (*alias, error) { +func MkAlias(store *bh.Store, aliasName, pointsTo string) (*Alias, error) { aliasName = strings.ToLower(aliasName) pointsTo = strings.ToLower(pointsTo) - alias := &alias{ + alias := &Alias{ store: store, Item: aliasName, PointsTo: pointsTo, @@ -134,7 +134,7 @@ func MkAlias(store *bh.Store, aliasName, pointsTo string) (*alias, error) { func GetItem(store *bh.Store, itemName string) ([]Item, error) { itemName = trimUnicode(itemName) var items []Item - var a alias + var a Alias if err := store.FindOne(&a, bh.Where("Item").Eq(itemName)); err == nil { itemName = a.PointsTo } else { @@ -162,7 +162,7 @@ func GetUserItem(store *bh.Store, nick, id, itemName string) (*Item, error) { item.Nick = nick item.Item = itemName item.UserID = id - var a alias + var a Alias err := store.FindOne(&a, bh.Where("Item").Eq(itemName)) if err == nil { log.Debug().Msgf("itemName now is %s", a.PointsTo) diff --git a/plugins/goals/goals.go b/plugins/goals/goals.go index 5cf9f72..9672493 100644 --- a/plugins/goals/goals.go +++ b/plugins/goals/goals.go @@ -236,7 +236,7 @@ func parseCmd(r *regexp.Regexp, body string) cmd { return out } -type goal struct { +type Goal struct { ID uint64 `boltholdKey:"ID"` Kind string Who string @@ -246,8 +246,8 @@ type goal struct { gp *GoalsPlugin } -func (p *GoalsPlugin) newGoal(kind, who, what string, amount int) *goal { - return &goal{ +func (p *GoalsPlugin) newGoal(kind, who, what string, amount int) *Goal { + return &Goal{ ID: 0, Kind: kind, Who: who, @@ -257,8 +257,8 @@ func (p *GoalsPlugin) newGoal(kind, who, what string, amount int) *goal { } } -func (p *GoalsPlugin) getGoal(who, what string) ([]*goal, error) { - gs := []*goal{} +func (p *GoalsPlugin) getGoal(who, what string) ([]*Goal, error) { + gs := []*Goal{} err := p.store.Find(&gs, bh.Where("Who").Eq(who).And("What").Eq(what)) if err != nil { return nil, err @@ -269,8 +269,8 @@ func (p *GoalsPlugin) getGoal(who, what string) ([]*goal, error) { return gs, nil } -func (p *GoalsPlugin) getGoalKind(kind, who, what string) (*goal, error) { - g := &goal{gp: p} +func (p *GoalsPlugin) getGoalKind(kind, who, what string) (*Goal, error) { + g := &Goal{gp: p} err := p.store.FindOne(g, bh.Where("Kind").Eq(kind).And("Who").Eq(who).And("What").Eq(what)) if err != nil { return nil, err @@ -278,7 +278,7 @@ func (p *GoalsPlugin) getGoalKind(kind, who, what string) (*goal, error) { return g, nil } -func (g *goal) Save() error { +func (g *Goal) Save() error { err := g.gp.store.Insert(bh.NextSequence(), g) if err != nil { return err @@ -286,11 +286,11 @@ func (g *goal) Save() error { return nil } -func (g goal) Delete() error { +func (g Goal) Delete() error { if g.ID == 0 { return nil } - err := g.gp.store.Delete(goal{}, g.ID) + err := g.gp.store.Delete(Goal{}, g.ID) return err } @@ -313,7 +313,7 @@ func (p *GoalsPlugin) update(r bot.Request, u counter.Update) { var now = time.Now -func (p *GoalsPlugin) calculateRemaining(i *counter.Item, g *goal) int { +func (p *GoalsPlugin) calculateRemaining(i *counter.Item, g *Goal) int { today := float64(now().YearDay()) thisYear := time.Date(now().Year(), 0, 0, 0, 0, 0, 0, time.UTC) nextYear := time.Date(now().Year()+1, 0, 0, 0, 0, 0, 0, time.UTC) @@ -328,7 +328,7 @@ func (p *GoalsPlugin) calculateRemaining(i *counter.Item, g *goal) int { return diff } -func (p *GoalsPlugin) remainingText(i *counter.Item, g *goal) string { +func (p *GoalsPlugin) remainingText(i *counter.Item, g *Goal) string { remaining := p.calculateRemaining(i, g) txt := "" if remaining < 0 { diff --git a/plugins/goals/goals_test.go b/plugins/goals/goals_test.go index e53c83d..5f1ca6a 100644 --- a/plugins/goals/goals_test.go +++ b/plugins/goals/goals_test.go @@ -61,7 +61,7 @@ func TestRemainingSomeToGo(t *testing.T) { Count: 190, } - g := goal{ + g := Goal{ ID: 0, Kind: "", Who: "", @@ -92,7 +92,7 @@ func TestRemainingAheadOfCurve(t *testing.T) { Count: 200, } - g := goal{ + g := Goal{ ID: 0, Kind: "", Who: "", diff --git a/plugins/inventory/inventory.go b/plugins/inventory/inventory.go index 397bfc7..7ad79bc 100644 --- a/plugins/inventory/inventory.go +++ b/plugins/inventory/inventory.go @@ -44,7 +44,7 @@ func New(b bot.Bot) *InventoryPlugin { } type Item struct { - Name string `boltholdKey:"Name"` + Name string `db:"item" boltholdKey:"Name"` } func (p *InventoryPlugin) giveItemFilter(input string) string { diff --git a/plugins/last/last.go b/plugins/last/last.go index 0c01729..15c8e43 100644 --- a/plugins/last/last.go +++ b/plugins/last/last.go @@ -39,13 +39,13 @@ func (p *LastPlugin) register() { { Kind: bot.Message, IsCmd: true, Regex: regexp.MustCompile(`(?i)^who killed the channel\??$`), - HelpText: "Find out who had last yesterday", + HelpText: "Find out who had Last yesterday", Handler: p.whoKilled, }, { Kind: bot.Message, IsCmd: true, Regex: regexp.MustCompile(`(?i)^who killed #?(?P\S+)\??$`), - HelpText: "Find out who had last yesterday in a channel", + HelpText: "Find out who had Last yesterday in a channel", Handler: p.whoKilledChannel, }, { @@ -59,7 +59,7 @@ func (p *LastPlugin) register() { } func (p *LastPlugin) enabled_channel(r bot.Request) bool { - chs := p.c.GetArray("last.channels", []string{}) + chs := p.c.GetArray("Last.channels", []string{}) for _, ch := range chs { if r.Msg.Channel == ch { return true @@ -103,14 +103,14 @@ func (p *LastPlugin) recordLast(r bot.Request) bool { return false } - invalidUsers := p.c.GetArray("last.invalidUsers", []string{"unknown"}) + invalidUsers := p.c.GetArray("Last.invalidUsers", []string{"unknown"}) for _, u := range invalidUsers { if who == u { return false } } - l := &last{ + l := &Last{ Day: day.Unix(), TS: time.Now().Unix(), Channel: ch, @@ -118,26 +118,27 @@ func (p *LastPlugin) recordLast(r bot.Request) bool { Message: r.Msg.Body, } - // todo: I think last might depend on a key being something more real + // todo: I think Last might depend on a key being something more real return p.store.Insert(bh.NextSequence(), l) == nil } -type last struct { +type Last struct { + ID uint64 `boltholdKey:"ID"` Day int64 - TS int64 - Channel string - Who string - Message string + TS int64 `db:"ts"` + Channel string `db:"channel"` + Who string `db:"who"` + Message string `db:"message"` } -func (p *LastPlugin) yesterdaysLast(ch string) (last, error) { - l := last{} +func (p *LastPlugin) yesterdaysLast(ch string) (Last, error) { + l := Last{} midnight := first.Midnight(time.Now()) - q := `select * from last where channel = ? and day < ? and day >= ? order by day limit 1` + q := `select * from Last where channel = ? and day < ? and day >= ? order by day limit 1` log.Debug().Str("q", q).Msgf("yesterdaysLast: %d to %d", midnight.Unix(), midnight.Add(-24*time.Hour).Unix()) err := p.store.FindOne(&l, bh.Where("Channel").Eq(ch).And("Day").Lt(midnight.Unix()).And("Day").Ge(midnight.Add(-24*time.Hour).Unix())) if err != nil { - return last{}, err + return Last{}, err } return l, nil } @@ -163,12 +164,12 @@ func (p *LastPlugin) whoKilledChannel(r bot.Request) bool { func (p *LastPlugin) sayLast(c bot.Connector, chFrom, chTo string, force bool) { l, err := p.yesterdaysLast(chFrom) if err != nil || l.Day == 0 { - log.Error().Err(err).Interface("last", l).Msgf("Couldn't find last") + log.Error().Err(err).Interface("Last", l).Msgf("Couldn't find Last") if force { - p.b.Send(c, bot.Message, chTo, "I couldn't find a last.") + p.b.Send(c, bot.Message, chTo, "I couldn't find a Last.") } return } - msg := fmt.Sprintf(`%s killed the channel last night by saying "%s"`, l.Who, l.Message) + msg := fmt.Sprintf(`%s killed the channel Last night by saying "%s"`, l.Who, l.Message) p.b.Send(c, bot.Message, chTo, msg) } diff --git a/plugins/newsbid/webshit/webshit.go b/plugins/newsbid/webshit/webshit.go index 96f867f..9d53427 100644 --- a/plugins/newsbid/webshit/webshit.go +++ b/plugins/newsbid/webshit/webshit.go @@ -38,7 +38,7 @@ type Bid struct { PlacedScore int `db:"placed_score"` ProcessedScore int `db:"processed_score"` Placed time.Time - Processed bool + Processed time.Time } type Balance struct { @@ -108,7 +108,7 @@ func (w *Webshit) Check(last int64) ([]WeeklyResult, int64, error) { // Delete all those bids if err = w.store.UpdateMatching(Bid{}, bh.Where("Processed").Eq(false), func(record interface{}) error { r := record.(*Bid) - r.Processed = true + r.Processed = time.Now() return w.store.Update(r.ID, r) }); err != nil { return nil, 0, err diff --git a/plugins/reminder/reminder.go b/plugins/reminder/reminder.go index a725e81..542ec8f 100644 --- a/plugins/reminder/reminder.go +++ b/plugins/reminder/reminder.go @@ -38,10 +38,10 @@ type ReminderPlugin struct { type Reminder struct { ID uint64 `boltholdKey:"ID"` - From string - Who string + From string `db:"fromWho"` + Who string `db:"toWho"` What string - When time.Time + When time.Time `db:"remindWhen"` Channel string } diff --git a/plugins/rest/rest.go b/plugins/rest/rest.go index 628b4f8..9f373c0 100644 --- a/plugins/rest/rest.go +++ b/plugins/rest/rest.go @@ -63,8 +63,8 @@ func (p *RestPlugin) register() { HelpText: "Lists all REST functions", Handler: p.listWires}, bot.HandlerSpec{Kind: bot.Message, IsCmd: true, - Regex: regexp.MustCompile(`(?i)^rm wire (?P\d+)$`), - HelpText: "Removes a wire by ID (use list to view)", + Regex: regexp.MustCompile(`(?i)^rm Wire (?P\d+)$`), + HelpText: "Removes a Wire by ID (use list to view)", Handler: p.rmWire}, bot.HandlerSpec{Kind: bot.Message, IsCmd: true, Regex: regexp.MustCompile("(?i)^testwire `(?P[^`]+)` to (?P\\S+) `(?P[^`]+)` => (?P.*)$"), @@ -75,7 +75,7 @@ func (p *RestPlugin) register() { HelpText: "Tests a new REST function", Handler: p.handleTestWire}, bot.HandlerSpec{Kind: bot.Message, IsCmd: true, - Regex: regexp.MustCompile("(?i)^wire `(?P[^`]+)` to (?P\\S+) `(?P[^`]+)`$"), + Regex: regexp.MustCompile("(?i)^Wire `(?P[^`]+)` to (?P\\S+) `(?P[^`]+)`$"), HelpText: "Registers a new REST function", Handler: p.handleWire}, bot.HandlerSpec{Kind: bot.Message, IsCmd: true, @@ -89,7 +89,7 @@ func (p *RestPlugin) register() { panic(err) } for _, w := range wires { - p.b.RegisterRegex(p, bot.Message, w.ParseRegex.Regexp, p.mkHandler(w)) + p.b.RegisterRegex(p, bot.Message, w.regex, p.mkHandler(w)) } p.b.RegisterRegex(p, bot.Help, regexp.MustCompile(`.*`), func(r bot.Request) bool { out := "Rest commands:\n" @@ -142,20 +142,21 @@ func (s *ScanableURL) Scan(src interface{}) error { return nil } -type wire struct { +type Wire struct { // ID ID int64 `boltholdIndex:"ID"` // The URL to make a request to URL ScanableURL // The regex which will trigger this REST action - ParseRegex ScanableRegexp `db:"parse_regex"` + ParseRegex string `db:"parse_regex"` + regex *regexp.Regexp // The JSON field that will contain the REST return value ReturnField string `db:"return_field"` // Body parse for POST Body string `db:"body"` } -func (w wire) String() string { +func (w Wire) String() string { msg := "Wire:" msg += fmt.Sprintf("\nURL: %s", w.URL) msg += fmt.Sprintf("\nParsing to trigger: `%s`", w.ParseRegex) @@ -163,18 +164,18 @@ func (w wire) String() string { return msg } -func (p *RestPlugin) getWires() ([]wire, error) { - wires := []wire{} +func (p *RestPlugin) getWires() ([]Wire, error) { + wires := []Wire{} err := p.store.Find(&wires, &bh.Query{}) return wires, err } func (p *RestPlugin) deleteWire(id int64) error { - err := p.store.Delete(id, wire{}) + err := p.store.Delete(id, Wire{}) return err } -func (w *wire) Update(store *bh.Store) error { +func (w *Wire) Update(store *bh.Store) error { if w.ID == -1 { return w.Save(store) } @@ -182,7 +183,7 @@ func (w *wire) Update(store *bh.Store) error { return err } -func (w *wire) Save(store *bh.Store) error { +func (w *Wire) Save(store *bh.Store) error { if w.ID > -1 { return w.Update(store) } @@ -209,21 +210,22 @@ func (p *RestPlugin) rmWire(r bot.Request) bool { id, _ := strconv.ParseInt(r.Values["id"], 10, 64) err := p.deleteWire(id) if err != nil { - p.b.Send(r.Conn, bot.Message, r.Msg.Channel, "Could not delete wire: "+err.Error()) + p.b.Send(r.Conn, bot.Message, r.Msg.Channel, "Could not delete Wire: "+err.Error()) return true } - p.b.Send(r.Conn, bot.Message, r.Msg.Channel, fmt.Sprintf("Deleted wire: %d", id)) + p.b.Send(r.Conn, bot.Message, r.Msg.Channel, fmt.Sprintf("Deleted Wire: %d", id)) return true } -func (p *RestPlugin) mkWire(r bot.Request) (wire, error) { - var w wire +func (p *RestPlugin) mkWire(r bot.Request) (Wire, error) { + var w Wire var err error // if it's not a POST, this will be empty (and indicate we will use GET) w.Body = r.Values["body"] - w.ParseRegex.Regexp, err = regexp.Compile(r.Values["parse"]) + w.ParseRegex = r.Values["parse"] + w.regex, err = regexp.Compile(r.Values["parse"]) if err != nil { return w, err } @@ -239,7 +241,7 @@ func (p *RestPlugin) mkWire(r bot.Request) (wire, error) { } func (p *RestPlugin) handleWire(r bot.Request) bool { - var w wire + var w Wire var msg string var err error w, err = p.mkWire(r) @@ -252,7 +254,7 @@ func (p *RestPlugin) handleWire(r bot.Request) bool { msg = err.Error() goto SEND } - p.b.RegisterRegex(p, bot.Message, w.ParseRegex.Regexp, p.mkHandler(w)) + p.b.RegisterRegex(p, bot.Message, w.regex, p.mkHandler(w)) msg = fmt.Sprintf("Saved %s", w) SEND: p.b.Send(r.Conn, bot.Message, r.Msg.Channel, msg) @@ -267,11 +269,11 @@ func (p *RestPlugin) handleTestWire(r bot.Request) bool { return true } h := p.mkHandler(w) - r.Values = bot.ParseValues(w.ParseRegex.Regexp, text) + r.Values = bot.ParseValues(w.regex, text) return h(r) } -func (p *RestPlugin) mkHandler(w wire) bot.ResponseHandler { +func (p *RestPlugin) mkHandler(w Wire) bot.ResponseHandler { return func(r bot.Request) bool { if r.Msg.User.Name == p.b.Config().GetString("nick", "") { return false @@ -309,7 +311,7 @@ func (p *RestPlugin) mkHandler(w wire) bot.ResponseHandler { if p.handleErr(err, r) { return true } - // Note, we will expect this is formatted good enough to send over the wire (?) + // Note, we will expect this is formatted good enough to send over the Wire (?) log.Debug(). Interface("values", values). Str("URL", newURL.String()). diff --git a/plugins/tell/tell.go b/plugins/tell/tell.go index d0e0738..63f2b10 100644 --- a/plugins/tell/tell.go +++ b/plugins/tell/tell.go @@ -24,35 +24,35 @@ func New(b bot.Bot) *TellPlugin { return tp } -type tell struct { +type Tell struct { ID int `boltholdIndex:"ID"` Who string What string } -func (t *TellPlugin) getTells() []tell { - result := []tell{} +func (t *TellPlugin) getTells() []Tell { + result := []Tell{} t.store.Find(&result, &bh.Query{}) return result } -func (t *TellPlugin) rmTell(entry tell) { - if err := t.store.Delete(entry.ID, tell{}); err != nil { - log.Error().Err(err).Msg("could not remove tell") +func (t *TellPlugin) rmTell(entry Tell) { + if err := t.store.Delete(entry.ID, Tell{}); err != nil { + log.Error().Err(err).Msg("could not remove Tell") } } func (t *TellPlugin) addTell(who, what string) error { - tell := tell{Who: who, What: what} + tell := Tell{Who: who, What: what} err := t.store.Insert(bh.NextSequence(), tell) if err != nil { - log.Error().Err(err).Msg("could not add tell") + log.Error().Err(err).Msg("could not add Tell") } return err } -func (t *TellPlugin) check(who string) []tell { - result := []tell{} +func (t *TellPlugin) check(who string) []Tell { + result := []Tell{} tells := t.getTells() for _, e := range tells { if e.Who == who { @@ -79,7 +79,7 @@ func (t *TellPlugin) checkValidTarget(ch, target string) bool { } func (t *TellPlugin) troll(who string) bool { - targets := t.b.Config().GetArray("tell.troll", []string{}) + targets := t.b.Config().GetArray("Tell.troll", []string{}) for _, target := range targets { if who == target { return true @@ -89,13 +89,13 @@ func (t *TellPlugin) troll(who string) bool { } func (t *TellPlugin) message(c bot.Connector, kind bot.Kind, message msg.Message, args ...interface{}) bool { - if strings.HasPrefix(strings.ToLower(message.Body), "tell ") || + if strings.HasPrefix(strings.ToLower(message.Body), "Tell ") || strings.HasPrefix(strings.ToLower(message.Body), "tellah ") { parts := strings.Split(message.Body, " ") target := strings.ToLower(parts[1]) if !t.checkValidTarget(message.Channel, target) { if t.troll(message.User.Name) { - t.b.Send(c, bot.Message, message.Channel, fmt.Sprintf("Okay. I'll tell %s.", target)) + t.b.Send(c, bot.Message, message.Channel, fmt.Sprintf("Okay. I'll Tell %s.", target)) return true } return false @@ -103,7 +103,7 @@ func (t *TellPlugin) message(c bot.Connector, kind bot.Kind, message msg.Message newMessage := strings.Join(parts[2:], " ") newMessage = fmt.Sprintf("Hey, %s. %s said: %s", target, message.User.Name, newMessage) t.addTell(target, newMessage) - t.b.Send(c, bot.Message, message.Channel, fmt.Sprintf("Okay. I'll tell %s.", target)) + t.b.Send(c, bot.Message, message.Channel, fmt.Sprintf("Okay. I'll Tell %s.", target)) return true } uname := strings.ToLower(message.User.Name) diff --git a/util/migrate/apppass.go b/util/migrate/apppass.go new file mode 100644 index 0000000..419b7da --- /dev/null +++ b/util/migrate/apppass.go @@ -0,0 +1,31 @@ +package main + +import ( + "github.com/jmoiron/sqlx" + "github.com/rs/zerolog/log" + bh "github.com/timshannon/bolthold" +) + +type PassEntry struct { + ID int64 `json:"id"` + Secret string `json:"secret"` + + // Should be null unless inserting a new entry + Pass string `json:"pass"` + EncodedPass []byte `db:"encoded_pass"` + Cost int `json:"cost"` +} + +func migrateApppass(db *sqlx.DB, store *bh.Store) error { + all := []PassEntry{} + log.Printf("Migrating %T", all) + if err := db.Select(&all, `select * from apppass`); err != nil { + return err + } + for _, i := range all { + if err := store.Insert(i.ID, i); err != nil { + return err + } + } + return nil +} diff --git a/util/migrate/awards.go b/util/migrate/awards.go new file mode 100644 index 0000000..5fdeaf2 --- /dev/null +++ b/util/migrate/awards.go @@ -0,0 +1,63 @@ +package main + +import ( + "database/sql" + "github.com/jmoiron/sqlx" + "github.com/rs/zerolog/log" + bh "github.com/timshannon/bolthold" + goals2 "github.com/velour/catbase/plugins/goals" +) + +type Trophy struct { + Emojy string + Description string + Creator string +} + +type Award struct { + ID int64 `boltholderid:"ID"` + Holder string + Emojy string + Description string + Granted sql.NullTime + Amount int64 +} + +func migrateAwards(db *sqlx.DB, store *bh.Store) error { + awards := []Award{} + log.Printf("Migrating %T", awards) + err := db.Select(&awards, `select * from awards`) + if err != nil { + return err + } + for _, a := range awards { + err := store.Insert(a.ID, a) + if err != nil { + return err + } + } + log.Printf("Migrated %d awards", len(awards)) + + trophies := []Trophy{} + err = db.Select(&trophies, `select * from trophies`) + for _, t := range trophies { + err := store.Insert(t.Emojy, t) + if err != nil { + return err + } + } + log.Printf("Migrated %d trophies", len(trophies)) + + goals := []goals2.Goal{} + log.Printf("Migrating %T", goals) + if err := db.Select(&goals, `select * from goals`); err != nil { + return err + } + for _, i := range goals { + if err := store.Insert(i.ID, i); err != nil { + return err + } + } + + return nil +} diff --git a/util/migrate/babbler.go b/util/migrate/babbler.go new file mode 100644 index 0000000..82d7d08 --- /dev/null +++ b/util/migrate/babbler.go @@ -0,0 +1,103 @@ +package main + +import ( + "database/sql" + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + "log" + "time" +) + +type Babbler struct { + BabblerID uint64 `db:"id" boltholdKey:"BabblerID"` + Name string `db:"babbler"` +} + +type BabblerWord struct { + WordID uint64 `db:"id" boltholdKey:"WordID"` + Word string `db:"word"` +} + +type BabblerNode struct { + NodeID uint64 `db:"id" boltholdKey:"NodeID"` + BabblerID uint64 `db:"babblerId"` + WordID uint64 `db:"wordId"` + Root uint64 `db:"root"` + RootFrequency int64 `db:"rootFrequency"` +} + +type BabblerArc struct { + ArcID uint64 `db:"id" boltholdKey:"ArcID"` + FromNodeID uint64 `db:"fromNodeId"` + ToNodeID uint64 `db:"toNodeId"` + Frequency int64 `db:"frequency"` +} + +func migrateBabbler(db *sqlx.DB, store *bh.Store) error { + allBabblers := []Babbler{} + err := db.Select(&allBabblers, `select * from babblers`) + if err != nil { + return err + } + t0 := time.Now() + for _, b := range allBabblers { + err := store.Insert(b.BabblerID, b) + if err != nil { + return err + } + } + log.Printf("Migrated %d babblers took %v", len(allBabblers), time.Now().Sub(t0)) + + allNodes := []BabblerNode{} + err = db.Select(&allNodes, `select * from babblerNodes`) + if err != nil && err != sql.ErrNoRows { + return err + } + if err == sql.ErrNoRows || len(allNodes) == 0 { + log.Printf("Finished all windows") + return nil + } + log.Printf("Have %d nodes to insert", len(allNodes)) + nodeMap := map[uint64]bool{} + for _, n := range allNodes { + if nodeMap[n.NodeID] { + log.Fatalf("Duplicate ID: %v: %#v", n.NodeID, n) + } + nodeMap[n.NodeID] = true + } + for _, b := range allNodes { + err := store.Insert(b.NodeID, b) + if err != nil { + log.Printf("error trying to insert node: %#v", b) + } + } + log.Printf("Migrated %d nodes", len(allNodes)) + + allWords := []BabblerWord{} + err = db.Select(&allWords, `select * from babblerWords`) + if err != nil { + return err + } + for _, b := range allWords { + err := store.Insert(b.WordID, b) + if err != nil { + return err + } + } + log.Printf("Migrated %d words", len(allWords)) + + allArcs := []BabblerArc{} + err = db.Select(&allArcs, `select * from babblerArcs`) + if err != nil { + return err + } + for _, b := range allArcs { + err := store.Insert(b.ArcID, b) + if err != nil { + return err + } + } + log.Printf("Migrated %d arcs", len(allArcs)) + + return nil +} diff --git a/util/migrate/beers.go b/util/migrate/beers.go new file mode 100644 index 0000000..f6fb946 --- /dev/null +++ b/util/migrate/beers.go @@ -0,0 +1,31 @@ +package main + +import ( + "github.com/jmoiron/sqlx" + "github.com/rs/zerolog/log" + bh "github.com/timshannon/bolthold" +) + +type untappdUser struct { + ID uint64 `db:"id"` + UntappdUser string `db:"untappdUser" boltholdKey:"UntappdUser"` + Channel string `db:"channel"` + LastCheckin int `db:"lastCheckin"` + ChanNick string `db:"chanNick"` +} + +func migrateBeers(db *sqlx.DB, store *bh.Store) error { + users := []untappdUser{} + err := db.Select(&users, `select * from untappd`) + if err != nil { + return err + } + for _, u := range users { + err = store.Insert(u.UntappdUser, u) + if err != nil { + return err + } + } + log.Printf("Migrated %d untappd users", len(users)) + return nil +} diff --git a/util/migrate/blackwhite.go b/util/migrate/blackwhite.go new file mode 100644 index 0000000..8c3d998 --- /dev/null +++ b/util/migrate/blackwhite.go @@ -0,0 +1,32 @@ +package main + +import ( + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + "github.com/velour/catbase/bot" + "log" +) + +func migrateBlackWhite(db *sqlx.DB, store *bh.Store) error { + allBlack := []bot.BlacklistItem{} + allWhite := []bot.WhitelistItem{} + log.Printf("Migrating %T", allBlack) + if err := db.Select(&allBlack, `select * from pluginBlacklist`); err != nil { + return err + } + for _, i := range allBlack { + if err := store.Insert(i.Key(), i); err != nil { + return err + } + } + log.Printf("Migrating %T", allWhite) + if err := db.Select(&allWhite, `select * from pluginWhitelist`); err != nil { + return err + } + for _, i := range allWhite { + if err := store.Insert(i.Name, i); err != nil { + return err + } + } + return nil +} diff --git a/util/migrate/config.go b/util/migrate/config.go new file mode 100644 index 0000000..280da97 --- /dev/null +++ b/util/migrate/config.go @@ -0,0 +1,61 @@ +package main + +import ( + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + "go.etcd.io/bbolt" + "log" +) + +type Value struct { + // Key is the key field of the table + Key string `db:"key" json:"key"` + // Value represents the secret that must not be shared + Value string `db:"value" json:"value"` +} + +// Secret is a separate type (for storage differentiation) +type Secret Value + +func migrateConfig(db *sqlx.DB, store *bh.Store) error { + allValues := []Value{} + err := db.Select(&allValues, `select * from config`) + if err != nil { + return err + } + for _, v := range allValues { + err = store.Insert(v.Key, v) + if err != nil { + return err + } + } + + log.Printf("Migrated %d values", len(allValues)) + + allSecrets := []Secret{} + err = db.Select(&allSecrets, `select * from secrets`) + if err != nil { + return err + } + for _, v := range allSecrets { + err = store.Insert(v.Key, v) + if err != nil { + return err + } + } + + log.Printf("Migrated %d secrets", len(allSecrets)) + + return nil +} + +func rmConfig(store *bh.Store) { + store.Bolt().Batch(func(tx *bbolt.Tx) error { + tx.DeleteBucket([]byte("variables")) + return nil + }) + store.Bolt().Batch(func(tx *bbolt.Tx) error { + tx.DeleteBucket([]byte("secrets")) + return nil + }) +} diff --git a/util/migrate/counter.go b/util/migrate/counter.go new file mode 100644 index 0000000..dcc6ea2 --- /dev/null +++ b/util/migrate/counter.go @@ -0,0 +1,44 @@ +package main + +import ( + "database/sql" + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + counter2 "github.com/velour/catbase/plugins/counter" + "log" +) + +type ItemSQL struct { + counter2.Item + + UserID sql.NullString +} + +func migrateCounter(db *sqlx.DB, store *bh.Store) error { + all := []ItemSQL{} + log.Printf("Migrating %T", all) + if err := db.Select(&all, `select * from counter`); err != nil { + return err + } + for _, i := range all { + it := i.Item + if i.UserID.Valid { + it.UserID = i.UserID.String + } + if err := store.Insert(i.ID, it); err != nil { + return err + } + } + + aliases := []counter2.Alias{} + log.Printf("Migrating %T", aliases) + if err := db.Select(&aliases, `select * from counter_alias`); err != nil { + return err + } + for _, i := range all { + if err := store.Insert(i.ID, i); err != nil { + return err + } + } + return nil +} diff --git a/util/migrate/fact.go b/util/migrate/fact.go new file mode 100644 index 0000000..1b8ac44 --- /dev/null +++ b/util/migrate/fact.go @@ -0,0 +1,69 @@ +package main + +import ( + "github.com/rs/zerolog/log" + bh "github.com/timshannon/bolthold" + _ "modernc.org/sqlite" + "time" + + "github.com/jmoiron/sqlx" +) + +type SQLFactoid struct { + Factoid + + Created int64 + Accessed int64 +} + +type Factoid struct { + ID uint64 `boltholdKey:"ID"` + Fact string + Tidbit string + Verb string + Owner string + Created time.Time + Accessed time.Time + Count int +} + +type Alias struct { + Fact string + Next string +} + +func migrateFacts(db *sqlx.DB, store *bh.Store) error { + q := `select * from factoid` + allFacts := []SQLFactoid{} + if err := db.Select(&allFacts, q); err != nil { + return err + } + + for _, sqlf := range allFacts { + f := sqlf.Factoid + f.Accessed = time.Unix(sqlf.Accessed, 0) + f.Created = time.Unix(sqlf.Created, 0) + if err := store.Insert(f.ID, f); err != nil { + return err + } + } + + log.Printf("Migrated %d facts", len(allFacts)) + + q = `select * from factoid_alias` + allAliases := []Alias{} + + if err := db.Select(&allAliases, q); err != nil { + return err + } + + for _, f := range allAliases { + if err := store.Insert(bh.NextSequence(), &f); err != nil { + return err + } + } + + log.Printf("Migrated %d aliases", len(allAliases)) + + return nil +} diff --git a/util/migrate/first.go b/util/migrate/first.go new file mode 100644 index 0000000..b874fe7 --- /dev/null +++ b/util/migrate/first.go @@ -0,0 +1,33 @@ +package main + +import ( + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + first2 "github.com/velour/catbase/plugins/first" + "log" + "time" +) + +type FirstEntrySQL struct { + first2.FirstEntry + + Day int64 + Time int64 +} + +func migrateFirst(db *sqlx.DB, store *bh.Store) error { + all := []FirstEntrySQL{} + log.Printf("Migrating %T", all) + if err := db.Select(&all, `select * from first`); err != nil { + return err + } + for _, i := range all { + fe := i.FirstEntry + fe.Day = time.Unix(i.Day, 0) + fe.Time = time.Unix(i.Time, 0) + if err := store.Insert(i.ID, fe); err != nil { + return err + } + } + return nil +} diff --git a/util/migrate/inventory.go b/util/migrate/inventory.go new file mode 100644 index 0000000..b698f45 --- /dev/null +++ b/util/migrate/inventory.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + inventory2 "github.com/velour/catbase/plugins/inventory" + "log" +) + +func migrateInventory(db *sqlx.DB, store *bh.Store) error { + allItems := []inventory2.Item{} + log.Printf("Migrating %T", allItems) + if err := db.Select(&allItems, `select * from inventory`); err != nil { + return err + } + for _, i := range allItems { + if err := store.Insert(i.Name, i); err != nil { + return err + } + } + return nil +} diff --git a/util/migrate/last.go b/util/migrate/last.go new file mode 100644 index 0000000..8ebbbc1 --- /dev/null +++ b/util/migrate/last.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + last2 "github.com/velour/catbase/plugins/last" + "log" +) + +func migrateLast(db *sqlx.DB, store *bh.Store) error { + allLast := []last2.Last{} + log.Printf("Migrating %T", allLast) + if err := db.Select(&allLast, `select * from last`); err != nil { + return err + } + for _, i := range allLast { + if err := store.Insert(bh.NextSequence(), &i); err != nil { + return err + } + } + return nil +} diff --git a/util/migrate/main.go b/util/migrate/main.go new file mode 100644 index 0000000..d5f3a5f --- /dev/null +++ b/util/migrate/main.go @@ -0,0 +1,156 @@ +package main + +import ( + "flag" + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + "go.etcd.io/bbolt" + "log" +) + +var ( + dbPath = flag.String("db", "catbase.db", "path to sqlite db") + storePath = flag.String("store", "catbase.store", "path to bolthold store") + + fact = flag.Bool("fact", false, "migrate facts") + config = flag.Bool("config", false, "migrate config") + babbler = flag.Bool("babbler", false, "migrate babbler") + beers = flag.Bool("beers", false, "migrate beers") + awards = flag.Bool("awards", false, "migrate awards") + webshit = flag.Bool("webshit", false, "migrate webshit") + wire = flag.Bool("wire", false, "migrate wires") + tell = flag.Bool("tell", false, "migrate tell") + sms = flag.Bool("sms", false, "migrate sms") + reminders = flag.Bool("reminders", false, "migrate reminders") + blackWhiteLists = flag.Bool("blackWhite", false, "migrate black and white lists") + last = flag.Bool("last", false, "migrate last") + inventory = flag.Bool("inventory", false, "migrate inventory") + first = flag.Bool("first", false, "migrate first") + counter = flag.Bool("counter", false, "migrate counter") + apppass = flag.Bool("apppass", false, "migrate apppass") + nobabbler = flag.Bool("nobabbler", true, "don't migrate the babbler") + rmconfig = flag.Bool("rmconfig", false, "remove config") + + all = flag.Bool("all", false, "migrate all") +) + +func main() { + flag.Parse() + + db, err := sqlx.Open("sqlite", *dbPath) + if err != nil { + log.Fatal(err) + } + + store, err := bh.Open(*storePath, 0666, &bh.Options{ + Options: &bbolt.Options{ + NoFreelistSync: true, + FreelistType: "hashmap", + NoSync: true, + }, + }) + if err != nil { + log.Fatal(err) + } + + if *rmconfig { + rmConfig(store) + return + } + + if *fact || *all { + if err := migrateFacts(db, store); err != nil { + log.Fatal(err) + } + } + + if *config { + if err := migrateConfig(db, store); err != nil { + log.Fatal(err) + } + } + + if *babbler || *all && !*nobabbler { + if err := migrateBabbler(db, store); err != nil { + log.Fatal(err) + } + } + + if *beers || *all { + if err := migrateBeers(db, store); err != nil { + log.Fatal(err) + } + } + + if *awards || *all { + if err := migrateAwards(db, store); err != nil { + log.Fatal(err) + } + } + + if *webshit || *all { + if err := migrateWebshit(db, store); err != nil { + log.Fatal(err) + } + } + + if *wire || *all { + if err := migrateWires(db, store); err != nil { + log.Fatal(err) + } + } + + if *tell || *all { + if err := migrateTell(db, store); err != nil { + log.Fatal(err) + } + } + + if *sms || *all { + if err := migrateSMS(db, store); err != nil { + log.Fatal(err) + } + } + + if *reminders || *all { + if err := migrateReminders(db, store); err != nil { + log.Fatal(err) + } + } + + if *blackWhiteLists || *all { + if err := migrateBlackWhite(db, store); err != nil { + log.Fatal(err) + } + } + + if *last || *all { + if err := migrateLast(db, store); err != nil { + log.Fatal(err) + } + } + + if *inventory || *all { + if err := migrateInventory(db, store); err != nil { + log.Fatal(err) + } + } + + if *first || *all { + if err := migrateFirst(db, store); err != nil { + log.Fatal(err) + } + } + + if *counter || *all { + if err := migrateCounter(db, store); err != nil { + log.Fatal(err) + } + } + + if *apppass || *all { + if err := migrateApppass(db, store); err != nil { + log.Fatal(err) + } + } +} diff --git a/util/migrate/reminders.go b/util/migrate/reminders.go new file mode 100644 index 0000000..51ae8c7 --- /dev/null +++ b/util/migrate/reminders.go @@ -0,0 +1,31 @@ +package main + +import ( + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + "github.com/velour/catbase/plugins/reminder" + "log" + "time" +) + +type ReminderSQL struct { + reminder.Reminder + + When string `db:"remindWhen"` +} + +func migrateReminders(db *sqlx.DB, store *bh.Store) error { + allReminders := []ReminderSQL{} + log.Printf("Migrating %T", allReminders) + if err := db.Select(&allReminders, `select * from reminders`); err != nil { + return err + } + for _, r := range allReminders { + rem := r.Reminder + rem.When, _ = time.Parse("2006-01-02 15:04:05", r.When) + if err := store.Insert(r.ID, rem); err != nil { + return err + } + } + return nil +} diff --git a/util/migrate/sms.go b/util/migrate/sms.go new file mode 100644 index 0000000..21c7d42 --- /dev/null +++ b/util/migrate/sms.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + sms2 "github.com/velour/catbase/plugins/sms" + "log" +) + +func migrateSMS(db *sqlx.DB, store *bh.Store) error { + smses := []sms2.Person{} + log.Printf("Migrating %T", smses) + if err := db.Select(&smses, `select * from sms`); err != nil { + return err + } + for _, s := range smses { + if err := store.Insert(s.Who, s); err != nil { + return err + } + } + return nil +} diff --git a/util/migrate/tell.go b/util/migrate/tell.go new file mode 100644 index 0000000..43346d5 --- /dev/null +++ b/util/migrate/tell.go @@ -0,0 +1,24 @@ +package main + +import ( + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + tell2 "github.com/velour/catbase/plugins/tell" + "log" +) + +func migrateTell(db *sqlx.DB, store *bh.Store) error { + tells := []tell2.Tell{} + log.Printf("Migrating %T", tells) + if err := db.Select(&tells, `select * from tell`); err != nil { + return err + } + + for _, t := range tells { + if err := store.Insert(t.ID, t); err != nil { + return err + } + } + + return nil +} diff --git a/util/migrate/webshit.go b/util/migrate/webshit.go new file mode 100644 index 0000000..3f51794 --- /dev/null +++ b/util/migrate/webshit.go @@ -0,0 +1,48 @@ +package main + +import ( + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + webshit2 "github.com/velour/catbase/plugins/newsbid/webshit" + "log" + "time" +) + +type BidSQL struct { + webshit2.Bid + + Placed int64 + Processed int64 +} + +func migrateWebshit(db *sqlx.DB, store *bh.Store) error { + balances := []webshit2.Balance{} + bids := []BidSQL{} + log.Printf("Migrating %T", balances) + + if err := db.Select(&balances, `select * from webshit_balances`); err != nil { + return err + } + + for _, b := range balances { + if err := store.Insert(b.User, b); err != nil { + return err + } + } + + log.Printf("Migrating %T", bids) + if err := db.Select(&bids, `select * from webshit_bids`); err != nil { + return err + } + + for _, b := range bids { + bid := b.Bid + bid.Placed = time.Unix(b.Placed, 0) + bid.Processed = time.Unix(b.Processed, 0) + if err := store.Insert(b.ID, bid); err != nil { + return err + } + } + + return nil +} diff --git a/util/migrate/wires.go b/util/migrate/wires.go new file mode 100644 index 0000000..1d308b8 --- /dev/null +++ b/util/migrate/wires.go @@ -0,0 +1,33 @@ +package main + +import ( + "github.com/jmoiron/sqlx" + bh "github.com/timshannon/bolthold" + "github.com/velour/catbase/plugins/rest" + "log" + "net/url" +) + +type WireSQL struct { + rest.Wire + + // The URL to make a request to + URL string +} + +func migrateWires(db *sqlx.DB, store *bh.Store) error { + wires := []WireSQL{} + log.Printf("Migrating %T", wires) + if err := db.Select(&wires, `select * from wires`); err != nil { + return err + } + for _, w := range wires { + wire := w.Wire + u, _ := url.Parse(w.URL) + wire.URL = rest.ScanableURL{u} + if err := store.Insert(w.ID, wire); err != nil { + return err + } + } + return nil +}