From f14f426ae6bcf48c18386966b69ad625d183e2aa Mon Sep 17 00:00:00 2001 From: Jack Merrill Date: Sat, 19 Aug 2023 17:36:17 -0500 Subject: [PATCH] feat: idk but theres a lot here --- go.mod | 2 + go.sum | 30 ++ internal/commands/studentlife/abbreviation.go | 125 ++++++++ .../commands/studentlife/laundry-notify.go | 281 ++++++++++++++++++ internal/commands/studentlife/laundry.go | 4 +- internal/commands/studentlife/pvta.go | 16 +- internal/utils/config/config.go | 16 +- main.go | 12 + 8 files changed, 477 insertions(+), 9 deletions(-) create mode 100644 internal/commands/studentlife/abbreviation.go create mode 100644 internal/commands/studentlife/laundry-notify.go diff --git a/go.mod b/go.mod index a06aa97..f3a5aa5 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( github.com/gorilla/websocket v1.5.0 // indirect github.com/jackmerrill/hamp-api v0.0.0-20230818235104-8d222c9674c9 // indirect github.com/jackmerrill/pvta-go v0.0.0-20220912020258-36dee8883b6e // indirect + github.com/klauspost/compress v1.10.3 // indirect github.com/labstack/echo/v4 v4.9.1 // indirect github.com/labstack/gommon v0.4.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect @@ -42,4 +43,5 @@ require ( golang.org/x/net v0.14.0 // indirect golang.org/x/sys v0.11.0 // indirect golang.org/x/text v0.12.0 // indirect + nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/go.sum b/go.sum index b994823..ed4566a 100644 --- a/go.sum +++ b/go.sum @@ -26,17 +26,28 @@ github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-redis/redis/v8 v8.10.0/go.mod h1:vXLTvigok0VtUX0znvbcEW1SOt4OA9CU1ZfnOtKOaiM= github.com/go-redis/redis/v8 v8.11.0 h1:O1Td0mQ8UFChQ3N9zFQqo6kTU2cJ+/it88gDB+zg0wo= github.com/go-redis/redis/v8 v8.11.0/go.mod h1:DLomh7y2e3ggQXQLd1YgmvIfecPJoFl7WU5SOQ/r06M= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/geo v0.0.0-20230421003525-6adc56603217 h1:HKlyj6in2JV6wVkmQ4XmG/EIm+SCYlPZ+V4GWit7Z+I= github.com/golang/geo v0.0.0-20230421003525-6adc56603217/go.mod h1:8wI0hitZ3a1IxZfeH3/5I97CI8i5cLGsYe7xNhQGs9U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -48,7 +59,9 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/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/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= @@ -61,6 +74,9 @@ github.com/jackmerrill/pvta-go v0.0.0-20220912020258-36dee8883b6e/go.mod h1:olGz github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/joeshaw/gengen v0.0.0-20190604015154-c77d87825f5a/go.mod h1:v2qvRL8Xwk4OlARK6gPlf2JreZXzv0dYp/8+kUJ0y7Q= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -68,16 +84,20 @@ github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+ github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= @@ -100,10 +120,13 @@ github.com/sashabaranov/go-openai v1.14.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adO github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tkrajina/gpxgo v1.1.2/go.mod h1:795sjVRFo5wWyN6oOZp0RYienGGBJjpAlgOz2nCngA0= github.com/tkrajina/gpxgo v1.3.0 h1:rXqIey0Mc6wOvEoKHEnhZG6Kgxq/vQsOUs7/AME128Q= github.com/tkrajina/gpxgo v1.3.0/go.mod h1:795sjVRFo5wWyN6oOZp0RYienGGBJjpAlgOz2nCngA0= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= @@ -170,6 +193,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/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= @@ -193,6 +217,7 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 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/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -200,6 +225,7 @@ golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190603231351-8aaa1484dc10/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -220,7 +246,11 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= diff --git a/internal/commands/studentlife/abbreviation.go b/internal/commands/studentlife/abbreviation.go new file mode 100644 index 0000000..1da19b6 --- /dev/null +++ b/internal/commands/studentlife/abbreviation.go @@ -0,0 +1,125 @@ +package studentlife + +import ( + "fmt" + "strings" + + "github.com/bwmarrin/discordgo" + "github.com/jackmerrill/hampbot/internal/utils/config" + "github.com/jackmerrill/hampbot/internal/utils/embed" + "github.com/zekroTJA/shireikan" +) + +type Abbreviation struct { +} + +func (c *Abbreviation) GetInvokes() []string { + return []string{"abbreviation", "abbrev", "abbr"} +} + +func (c *Abbreviation) GetDescription() string { + return "WHAT DOES IT MEAN???" +} + +func (c *Abbreviation) GetHelp() string { + return "`abbreviation [acronym]` - Returns the meaning of a Hampshire College acronym" +} + +func (c *Abbreviation) GetGroup() string { + return config.GroupStudentLife +} + +func (c *Abbreviation) GetDomainName() string { + return "hamp.studentlife.abbreviation" +} + +func (c *Abbreviation) GetSubPermissionRules() []shireikan.SubPermission { + return nil +} +func (c *Abbreviation) IsExecutableInDMChannels() bool { + return true +} + +var Abbreviations = map[string]string{ + "APL": "Airport Lounge", + "ASH": "Adele Simmons Hall", + "BOT": "Board of Trustees", + "CAPES": "Community Advocacy, Prevention and Education, Safety", + "CASA": "Center for Academic Support and Advising", + "CC": "Cultural Center (short for Lebrón-Wiggins-Pran Cultural Center)", + "CFF": "Center for Feminisms", + "CMC": "Collaborative Modeling Center", + "CoCo": "Community Commons (located in the library—off of the Airport Lounge, and formerly called the Knowledge Commons)", + "CRB": "Community Review Board", + "CTL": "Center for Teaching and Learning in Cole Science Center on the 1st Floor", + "DLR": "Dakin Living Room (inside Dakin Student Life Center)", + "DSLC": "Dakin Student Life Center", + "EDH": "Emily Dickinson Hall", + "ELC": "Early Learning Center", + "ELH": "East Lecture Hall (room in Franklin Patterson Hall)", + "CEPC": "Curriculum and Educational Policy Committee", + "ESSP": "Environmental Studies and Sustainability Program", + "FPH": "Franklin Patterson Hall", + "FPV": "Film, Photography, and Video Program", + "G": "Greenwich and Enfield Houses (one shared office)", + "E": "Greenwich and Enfield Houses (one shared office)", + "GEO": "Global Education Office", + "HCFC": "Hampshire College Farm Center", + "HCSU": "Hampshire College Student Union", + "HLP": "Holistic Learning Program", + "IDBM": "Identity-Based Mod/Hall", + "IDBH": "Identity-Based Hall", + "RLSE": "Residence Life and Student Engagement", + "HR": "Human Resources", + "HRP": "Hampshire Research Project", + "ISS": "International Student Services", + "IT": "Information Technology", + "JEA": "Justice, Equity, and Antiracism", + "JLC": "Jerome Liebling Center for Film, Photography, and Video", + "KERN": "The R.W. Kern Center", + "LC": "Learning Collaborative", + "MDB": "Music and Dance Building", + "MLR": "Merrill Living Room (inside Merrill Student Life Center)", + "NSE": "New Student Experience", + "OARS": "Office of Accessibility Resources and Services", + "OPRA": "Outdoor Programs, Recreation, and Athletics", + "PAWSS": "Peace and World Security Studies", + "QCAC": "Queer Community Alliance Center", + "RCC": "Robert Crown Center", + "SAC": "Staff Advocacy Committee", + "SOURCE": "Students of Under-Represented Cultures and Ethnicities", + "SPARC": "Supporting Your Purpose through Action, Resources, and Connections (formerly CORC = Career Options Resource Center)", + "WLH": "West Lecture Hall (room in Franklin Patterson Hall)", +} + +func (c *Abbreviation) Exec(ctx shireikan.Context) error { + acronym := ctx.GetArgs().Get(0).AsString() + + if acronym == "" { + ctx.GetSession().ChannelMessageSendComplex(ctx.GetChannel().ID, &discordgo.MessageSend{ + Embed: embed.NewErrorEmbed(ctx).SetDescription("Please specify an acronym to get the meaning of.\n\n**Usage:** `abbreviation [acronym]`").MessageEmbed, + Reference: ctx.GetMessage().Reference(), + }) + return nil + } + + acronym = strings.ToUpper(acronym) + + if meaning, ok := Abbreviations[acronym]; ok { + ctx.GetSession().ChannelMessageSendComplex(ctx.GetChannel().ID, &discordgo.MessageSend{ + Embed: embed.NewEmbed(). + SetTitle("Hampshire College Acronym"). + SetDescription(fmt.Sprintf("**%s**\n\n%s", acronym, meaning)). + SetColor(0x00ff00). + MessageEmbed, + Reference: ctx.GetMessage().Reference(), + }) + return nil + } + + ctx.GetSession().ChannelMessageSendComplex(ctx.GetChannel().ID, &discordgo.MessageSend{ + Embed: embed.NewErrorEmbed(ctx).SetDescription("Please specify a valid acronym to get the meaning of.\n\n**Usage:** `abbreviation [acronym]`").MessageEmbed, + Reference: ctx.GetMessage().Reference(), + }) + return nil +} diff --git a/internal/commands/studentlife/laundry-notify.go b/internal/commands/studentlife/laundry-notify.go new file mode 100644 index 0000000..8c025ed --- /dev/null +++ b/internal/commands/studentlife/laundry-notify.go @@ -0,0 +1,281 @@ +package studentlife + +import ( + "encoding/json" + "fmt" + "net/url" + "strings" + + "github.com/bwmarrin/discordgo" + "github.com/charmbracelet/log" + "github.com/jackmerrill/hampbot/internal/utils/config" + "github.com/jackmerrill/hampbot/internal/utils/embed" + "github.com/zekroTJA/shireikan" + "golang.org/x/net/websocket" +) + +type LaundryNotify struct { +} + +func (c *LaundryNotify) GetInvokes() []string { + return []string{"laundrynotify", "ln"} +} + +func (c *LaundryNotify) GetDescription() string { + return "(Beta) Be notified when laundry machines are available or done" +} + +func (c *LaundryNotify) GetHelp() string { + return "`laundrynotify [building] [machine|any] `\n\n**Example:** `laundrynotify dakin 01` `ln merrill any washer`" +} + +func (c *LaundryNotify) GetGroup() string { + return config.GroupStudentLife +} + +func (c *LaundryNotify) GetDomainName() string { + return "hamp.util.laundrynotify" +} + +func (c *LaundryNotify) GetSubPermissionRules() []shireikan.SubPermission { + return nil +} +func (c *LaundryNotify) IsExecutableInDMChannels() bool { + return true +} + +type NotifiedMachine struct { + Building string + Machine string + MachineType *string + WaitingFor string // Available, Done +} + +var NotifiedMachines map[string]NotifiedMachine = make(map[string]NotifiedMachine) + +func NotifyUser(ctx *discordgo.Session, userId string, machine Machine, building string, waitingFor string) { + var machineType string + + if machine.Type == Washer { + machineType = "washer" + } else { + machineType = "dryer" + } + + if waitingFor == "Available" && machine.Status == "Available" { + ctx.ChannelMessageSendComplex(userId, &discordgo.MessageSend{ + Embed: embed.NewEmbed().SetTitle("Laundry Machine Available").SetDescription(fmt.Sprintf("The %s in %s is now available.", machineType, building)).SetColor(0x00ff00).MessageEmbed, + }) + } else if waitingFor == "Done" && machine.Status == "End of cycle" { + ctx.ChannelMessageSendComplex(userId, &discordgo.MessageSend{ + Embed: embed.NewEmbed().SetTitle("Laundry Machine Done").SetDescription(fmt.Sprintf("The %s in %s is now done.", machineType, building)).SetColor(0x00ff00).MessageEmbed, + }) + } +} + +func wsLoop(client *websocket.Conn, ctx *discordgo.Session) { + for { + msg := make([]byte, 4096) // 4kb to be safe lol + n, err := client.Read(msg) + if err != nil { + log.Error(err) + return + } + + msg = msg[:n] + + var room LaundryRoom + + err = json.Unmarshal(msg, &room) + + if err != nil { + log.Error(err) + return + } + + for _, machine := range room.Machines { + for userId, notifiedMachine := range NotifiedMachines { + if notifiedMachine.Building == room.Name { + if notifiedMachine.Machine == "any" { // requesting any machine with specific type + if notifiedMachine.MachineType != nil { + if string(machine.Type) == *notifiedMachine.MachineType { + NotifyUser(ctx, userId, machine, room.Name, notifiedMachine.WaitingFor) + } + } + } else { + if notifiedMachine.Machine == machine.Name { // doesn't matter, they're specifying a specific machine + NotifyUser(ctx, userId, machine, room.Name, notifiedMachine.WaitingFor) + } + } + } + } + } + } +} + +func InitDakin(ctx *discordgo.Session) error { + u := url.URL{Scheme: "wss", Host: config.HampAPIHost, Path: "/api/utilities/laundry/dakin/live"} + + wsClient, err := websocket.Dial(u.String(), "", "http://localhost") + + if err != nil { + log.Error(err) + return err + } + + go wsLoop(wsClient, ctx) + return nil + +} + +func InitMerrill(ctx *discordgo.Session) error { + u := url.URL{Scheme: "wss", Host: config.HampAPIHost, Path: "/api/utilities/laundry/merrill/live"} + + wsClient, err := websocket.Dial(u.String(), "", "http://localhost") + + if err != nil { + log.Error(err) + return err + } + + go wsLoop(wsClient, ctx) + return nil + +} + +func InitPrescott(ctx *discordgo.Session) error { + u := url.URL{Scheme: "wss", Host: config.HampAPIHost, Path: "/api/utilities/laundry/prescott/live"} + + wsClient, err := websocket.Dial(u.String(), "", "http://localhost") + + if err != nil { + log.Error(err) + return err + } + + go wsLoop(wsClient, ctx) + return nil + +} + +func InitEnfield(ctx *discordgo.Session) error { + u := url.URL{Scheme: "wss", Host: config.HampAPIHost, Path: "/api/utilities/laundry/enfield/live"} + + wsClient, err := websocket.Dial(u.String(), "", "http://localhost") + + if err != nil { + log.Error(err) + return err + } + + go wsLoop(wsClient, ctx) + return nil + +} + +func InitAll(ctx *discordgo.Session) error { + err := InitDakin(ctx) + + if err != nil { + return err + } + + err = InitMerrill(ctx) + + if err != nil { + return err + } + + err = InitPrescott(ctx) + + if err != nil { + return err + } + + err = InitEnfield(ctx) + + if err != nil { + return err + } + + return nil +} + +func (c *LaundryNotify) Exec(ctx shireikan.Context) error { + building := ctx.GetArgs().Get(0).AsString() + + if building == "" { + ctx.GetSession().ChannelMessageSendComplex(ctx.GetChannel().ID, &discordgo.MessageSend{ + Embed: embed.NewErrorEmbed(ctx).SetDescription("Please specify a building to get the laundry status of.\n\n**Usage:** `laundrynotify [building] [machine|any] `").MessageEmbed, + Reference: ctx.GetMessage().Reference(), + }) + return nil + } + + building = strings.ToLower(building) + + if building != "dakin" && building != "merrill" && building != "prescott" && building != "enfield" { + ctx.GetSession().ChannelMessageSendComplex(ctx.GetChannel().ID, &discordgo.MessageSend{ + Embed: embed.NewErrorEmbed(ctx).SetDescription("Please specify a valid building to get the laundry status of.\n\n**Usage:** `laundrynotify [building] [machine|any] `").MessageEmbed, + Reference: ctx.GetMessage().Reference(), + }) + return nil + } + + machine := ctx.GetArgs().Get(1).AsString() + + if machine == "" { + ctx.GetSession().ChannelMessageSendComplex(ctx.GetChannel().ID, &discordgo.MessageSend{ + Embed: embed.NewErrorEmbed(ctx).SetDescription("Please specify a machine to get the laundry status of.\n\n**Usage:** `laundrynotify [building] [machine|any] `").MessageEmbed, + Reference: ctx.GetMessage().Reference(), + }) + return nil + } + + machine = strings.ToLower(machine) + + if machine != "any" { + if len(machine) == 1 { + machine = fmt.Sprintf("0%s", machine) + } + } + + machineType := ctx.GetArgs().Get(2).AsString() + + notifiedMachine := NotifiedMachine{ + Building: building, + Machine: machine, + } + + if machineType == "" { + if machine == "any" { + ctx.GetSession().ChannelMessageSendComplex(ctx.GetChannel().ID, &discordgo.MessageSend{ + Embed: embed.NewErrorEmbed(ctx).SetDescription("Please specify a machine type to get the laundry status of.\n\n**Usage:** `laundrynotify [building] [machine|any] `").MessageEmbed, + Reference: ctx.GetMessage().Reference(), + }) + + return nil + } else { + notifiedMachine.MachineType = nil + notifiedMachine.WaitingFor = "Done" + } + } else { + machineType = strings.ToLower(machineType) + notifiedMachine.MachineType = &machineType + } + + if machine == "any" { + notifiedMachine.WaitingFor = "Available" + machine = fmt.Sprintf("any %s", *notifiedMachine.MachineType) + } else { + notifiedMachine.WaitingFor = "Done" + } + + NotifiedMachines[ctx.GetUser().ID] = notifiedMachine + + ctx.GetSession().ChannelMessageSendComplex(ctx.GetChannel().ID, &discordgo.MessageSend{ + Embed: embed.NewSuccessEmbed(ctx).SetTitle("Laundry Notification Set").SetDescription(fmt.Sprintf("You will be notified when `%s` in %s is %s.", machine, building, notifiedMachine.WaitingFor)).MessageEmbed, + }) + + return nil +} diff --git a/internal/commands/studentlife/laundry.go b/internal/commands/studentlife/laundry.go index cc43890..1cf866f 100644 --- a/internal/commands/studentlife/laundry.go +++ b/internal/commands/studentlife/laundry.go @@ -55,7 +55,7 @@ func (c *Laundry) GetHelp() string { } func (c *Laundry) GetGroup() string { - return config.GroupUtil + return config.GroupStudentLife } func (c *Laundry) GetDomainName() string { @@ -111,6 +111,8 @@ func (c *Laundry) Exec(ctx shireikan.Context) error { embed.AddField(fmt.Sprintf("%s - %s", machine.Name, machine.Type), fmt.Sprintf(":green_circle: **Status:** %s", machine.Status), false) } else if machine.Status == "Not online" { embed.AddField(fmt.Sprintf("%s - %s", machine.Name, machine.Type), fmt.Sprintf(":red_circle: **Status:** %s", machine.Status), false) + } else if machine.Status == "End of cycle" { + embed.AddField(fmt.Sprintf("%s - %s", machine.Name, machine.Type), fmt.Sprintf(":blue_circle: **Status:** %s", machine.Status), false) } else { embed.AddField(fmt.Sprintf("%s - %s", machine.Name, machine.Type), fmt.Sprintf(":yellow_circle: **Status:** %s\n:alarm_clock: **Time Remaining:** %s", machine.Status, config.ConvertTimestampToDiscordTimestampWithFormat(*machine.EstimatedTime, "R")), false) } diff --git a/internal/commands/studentlife/pvta.go b/internal/commands/studentlife/pvta.go index d915882..bc2a8cd 100644 --- a/internal/commands/studentlife/pvta.go +++ b/internal/commands/studentlife/pvta.go @@ -34,7 +34,7 @@ func (c *PVTA) GetHelp() string { } func (c *PVTA) GetGroup() string { - return config.GroupUtil + return config.GroupStudentLife } func (c *PVTA) GetDomainName() string { @@ -62,6 +62,10 @@ func getRouteByShortName(shortName string) (*pvtago.RouteDetail, error) { if route.ShortName == shortName { return &route, nil } + + if route.RouteAbbreviation == shortName { + return &route, nil + } } return nil, nil @@ -102,12 +106,22 @@ func (c *PVTA) Exec(ctx shireikan.Context) error { return err } + if route == nil { + ctx.ReplyEmbed(embed.NewErrorEmbed(ctx).SetTitle("Error").SetDescription("The route you specified does not exist.").MessageEmbed) + return nil + } + vehicles, err := client.GetVehiclesForRoute(route.RouteID) if err != nil { return err } + if len(vehicles) == 0 { + ctx.ReplyEmbed(embed.NewErrorEmbed(ctx).SetTitle("Error").SetDescription("There are no vehicles on this route.").MessageEmbed) + return nil + } + e := embed.NewSuccessEmbed(ctx).SetTitle(":bus: PVTA Route Details").SetDescription(fmt.Sprintf("**Route:** %s\n**Name:** %s", route.ShortName, route.LongName)) tileProvider := &sm.TileProvider{ diff --git a/internal/utils/config/config.go b/internal/utils/config/config.go index d3eacaa..0d7f0c2 100644 --- a/internal/utils/config/config.go +++ b/internal/utils/config/config.go @@ -21,16 +21,18 @@ var ( BotGuild = "936651575684915201" // HampAPI is the URL to the hamp API. - // HampAPI = "https://api.hamp.sh" - HampAPI = "http://localhost:1323" + HampAPI = "https://api.hamp.sh" + HampAPIHost = "api.hamp.sh" + // HampAPIHost = "localhost:1323" + // HampAPI = "http://localhost:1323" ) var ( - GroupUtil = "Util" - GroupFun = "Fun" - GroupInfo = "Info" - GroupMod = "Moderation" - GroupDev = "Dev" + GroupUtil = "Util" + GroupFun = "Fun" + GroupInfo = "Info" + GroupMod = "Moderation" + GroupStudentLife = "Student Life" ) var Statuses = []discordgo.Activity{ diff --git a/main.go b/main.go index 5563834..6096cfe 100644 --- a/main.go +++ b/main.go @@ -76,6 +76,18 @@ func main() { handler.Register(&studentlife.PVTA{}) log.Debug("Registered PVTA command") + handler.Register(&studentlife.Abbreviation{}) + log.Debug("Registered abbreviation command") + + err = studentlife.InitAll(session) + if err != nil { + log.Error("Failed to initialize laundry notify- skipping.") + } else { + handler.Register(&studentlife.LaundryNotify{}) + + } + log.Debug("Registered laundry notify command") + log.Info("Registered all commands") log.Info("Setting up activities...")