Rewrite and refactor #1
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
config.yaml
|
||||
statedata
|
||||
config.yml
|
||||
simpbot
|
||||
|
@ -1,10 +1,10 @@
|
||||
FROM golang:1.18 as builder
|
||||
FROM golang:1.20 as builder
|
||||
WORKDIR /go/src/app
|
||||
COPY . .
|
||||
RUN apt update && apt upgrade -y
|
||||
RUN go build
|
||||
|
||||
FROM alpine:latest as final
|
||||
FROM debian:stable-slim as final
|
||||
WORKDIR /srv/
|
||||
RUN mkdir /srv/simpbot
|
||||
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
|
||||
|
53
deploy.yml
53
deploy.yml
@ -1,53 +0,0 @@
|
||||
---
|
||||
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
|
||||
- name: check simpbot version
|
||||
uri:
|
||||
url: https://git.saintnet.tech/api/v1/repos/stryan/simpbot/releases?limit=1
|
||||
return_content: true
|
||||
register: simpbot_latest
|
||||
|
||||
- name: "downloading and installing simpbot {{ simpbot_latest.json[0].tag_name }}"
|
||||
block:
|
||||
- name: create temp directory
|
||||
tempfile:
|
||||
state: directory
|
||||
suffix: dwn
|
||||
register: tempfolder_1
|
||||
|
||||
- name: download simpbot
|
||||
loop: "{{ simpbot_latest.json[0].assets }}"
|
||||
when: "'amd64.tar.gz' in item.name"
|
||||
unarchive:
|
||||
remote_src: yes
|
||||
src: "{{ item.browser_download_url }}"
|
||||
dest: "{{ tempfolder_1.path }}"
|
||||
keep_newer: yes
|
||||
|
||||
- name: installing simpbot binary
|
||||
copy:
|
||||
remote_src: yes
|
||||
src: "{{ tempfolder_1.path }}/simpbot"
|
||||
dest: /usr/local/bin/
|
||||
mode: '0755'
|
||||
register: new_binary
|
||||
|
||||
- name: installing unit file
|
||||
copy:
|
||||
remote_src: yes
|
||||
src: "{{ tempfolder_1.path }}/init/simpbot.service"
|
||||
dest: /etc/systemd/system/simpbot.service
|
||||
register: new_unit
|
||||
|
||||
- name: reload systemd with new unit
|
||||
systemd:
|
||||
daemon_reload: yes
|
||||
when: new_unit.changed or new_binary.changed
|
||||
|
||||
- name: start service
|
||||
systemd:
|
||||
name: simpbot
|
||||
state: restarted
|
||||
when: new_binary.changed
|
50
go.mod
50
go.mod
@ -1,13 +1,47 @@
|
||||
module git.saintnet.tech/stryan/simpbot
|
||||
|
||||
go 1.15
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.5.1
|
||||
github.com/spf13/viper v1.9.0
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
|
||||
golang.org/x/net v0.0.0-20211014172544-2b766c08f1c0 // indirect
|
||||
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
maunium.net/go/mautrix v0.9.29
|
||||
github.com/charmbracelet/log v0.2.1
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
github.com/spf13/viper v1.15.0
|
||||
maunium.net/go/mautrix v0.15.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/btcsuite/btcutil v1.0.2 // indirect
|
||||
github.com/charmbracelet/lipgloss v0.7.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/muesli/reflow v0.3.0 // indirect
|
||||
github.com/muesli/termenv v0.15.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.7 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/rs/zerolog v1.29.1 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/tidwall/gjson v1.14.4 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tidwall/sjson v1.2.5 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
maunium.net/go/maulogger/v2 v2.4.1 // indirect
|
||||
)
|
||||
|
108
go.sum
108
go.sum
@ -3,6 +3,7 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
@ -15,6 +16,7 @@ cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOY
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
|
||||
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
||||
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
||||
@ -41,6 +43,7 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
@ -51,6 +54,8 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
@ -64,6 +69,10 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E=
|
||||
github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c=
|
||||
github.com/charmbracelet/log v0.2.1 h1:1z7jpkk4yKyjwlmKmKMM5qnEDSpV32E7XtWhuv0mTZE=
|
||||
github.com/charmbracelet/log v0.2.1/go.mod h1:GwFfjewhcVDWLrpAbY5A0Hin9YOlEn40eWT4PNaxFT4=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
@ -74,6 +83,7 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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=
|
||||
@ -91,10 +101,14 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@ -156,6 +170,7 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
@ -166,6 +181,7 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
@ -210,16 +226,30 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
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/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
|
||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.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.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
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/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
@ -230,24 +260,44 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo=
|
||||
github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
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/modern-go/reflect2 v1.0.1/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.1 h1:UzuTb/+hhlBugQz28rpzey4ZuKcZ03MeKsoG7IJZIxs=
|
||||
github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
|
||||
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us=
|
||||
github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
|
||||
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sagikazarmark/crypt v0.1.0/go.mod h1:B/mN0msZuINBtQ1zZLEQcegFJJf9vnYIR88KRMEuODE=
|
||||
@ -255,28 +305,51 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
|
||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
|
||||
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
|
||||
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.9.0 h1:yR6EXjTp0y0cLN8OZg1CRZmOBdI88UcGkhgyJhu6nZk=
|
||||
github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4=
|
||||
github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU=
|
||||
github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/tidwall/gjson v1.6.8/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI=
|
||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
||||
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.1.5/go.mod h1:VuJzsZnTowhSxWdOgsAnb886i4AjEyTkk7tNtsL7EYE=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@ -307,9 +380,13 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -378,6 +455,7 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
@ -386,6 +464,9 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211014172544-2b766c08f1c0 h1:xNP8gGXzUFztyWFRq+TV6zyPNxOr8lXtV6x0KMrhk0o=
|
||||
golang.org/x/net v0.0.0-20211014172544-2b766c08f1c0/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -454,12 +535,14 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -468,8 +551,13 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c h1:taxlMj0D/1sOAuv/CbSD+MMDof2vbyPTqz5FNYKpXt8=
|
||||
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -482,6 +570,8 @@ golang.org/x/text v0.3.5/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=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@ -533,6 +623,7 @@ golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
@ -612,7 +703,9 @@ google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
@ -676,6 +769,8 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c=
|
||||
gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@ -685,8 +780,9 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@ -695,8 +791,12 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
maunium.net/go/maulogger/v2 v2.2.4/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
|
||||
maunium.net/go/maulogger/v2 v2.4.1 h1:N7zSdd0mZkB2m2JtFUsiGTQQAdP0YeFWT7YMc80yAL8=
|
||||
maunium.net/go/maulogger/v2 v2.4.1/go.mod h1:omPuYwYBILeVQobz8uO3XC8DIRuEb5rXYlQSuqrbCho=
|
||||
maunium.net/go/mautrix v0.9.29 h1:qJyTSZQuogkkEFrJd+oZiTuE/6Cq7ca3wxiLYadYUoM=
|
||||
maunium.net/go/mautrix v0.9.29/go.mod h1:7IzKfWvpQtN+W2Lzxc0rLvIxFM3ryKX6Ys3S/ZoWbg8=
|
||||
maunium.net/go/mautrix v0.15.1 h1:pmCtMjYRpd83+2UL+KTRFYQo5to0373yulimvLK+1k0=
|
||||
maunium.net/go/mautrix v0.15.1/go.mod h1:icQIrvz2NldkRLTuzSGzmaeuMUmw+fzO7UVycPeauN8=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
85
lazystore.go
85
lazystore.go
@ -1,85 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
|
||||
"os"
|
||||
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
type LazyMemStore struct {
|
||||
mem *mautrix.InMemoryStore
|
||||
NextBatch map[id.UserID]string
|
||||
saveFile string
|
||||
}
|
||||
|
||||
func NewLazyMemStore(fileloc string) *LazyMemStore {
|
||||
return &LazyMemStore{
|
||||
mem: mautrix.NewInMemoryStore(),
|
||||
NextBatch: make(map[id.UserID]string),
|
||||
saveFile: fileloc,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LazyMemStore) SaveFilterID(userID id.UserID, filterID string) {
|
||||
l.mem.SaveFilterID(userID, filterID)
|
||||
}
|
||||
|
||||
func (l *LazyMemStore) LoadFilterID(userID id.UserID) string {
|
||||
return l.mem.LoadFilterID(userID)
|
||||
}
|
||||
|
||||
func (l *LazyMemStore) SaveNextBatch(userID id.UserID, nextBatchToken string) {
|
||||
b := new(bytes.Buffer)
|
||||
l.NextBatch[userID] = nextBatchToken
|
||||
e := gob.NewEncoder(b)
|
||||
err := e.Encode(l.NextBatch)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := os.WriteFile(l.saveFile, b.Bytes(), 0666); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (l *LazyMemStore) LoadNextBatch(userID id.UserID) string {
|
||||
|
||||
dat, err := os.ReadFile(l.saveFile)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
b := new(bytes.Buffer)
|
||||
e := gob.NewEncoder(b)
|
||||
err := e.Encode(l.NextBatch)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := os.WriteFile(l.saveFile, b.Bytes(), 0666); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
dat, err = os.ReadFile(l.saveFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
d := gob.NewDecoder(bytes.NewBuffer(dat))
|
||||
err = d.Decode(&l.NextBatch)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return l.NextBatch[userID]
|
||||
}
|
||||
|
||||
func (l *LazyMemStore) SaveRoom(room *mautrix.Room) {
|
||||
l.mem.SaveRoom(room)
|
||||
}
|
||||
|
||||
func (l *LazyMemStore) LoadRoom(roomID id.RoomID) *mautrix.Room {
|
||||
return l.mem.LoadRoom(roomID)
|
||||
}
|
299
main.go
299
main.go
@ -2,36 +2,22 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
"sync"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/spf13/viper"
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
var Homeserver string
|
||||
var Username string
|
||||
var Password string
|
||||
var DimensionServer string
|
||||
var HomeserverDomain string
|
||||
var Token string
|
||||
var GitCommit string
|
||||
var GitTag string
|
||||
var Statefile string
|
||||
var CurrStreamCnt int
|
||||
var MostStreamCnt int
|
||||
var StartTime time.Time
|
||||
var HolodexToken string
|
||||
|
||||
func main() {
|
||||
simp := newSimp()
|
||||
logger := log.NewWithOptions(os.Stderr, log.Options{
|
||||
ReportCaller: true,
|
||||
})
|
||||
log.SetDefault(logger)
|
||||
viper.SetConfigName("config")
|
||||
viper.AddConfigPath(".")
|
||||
viper.AddConfigPath("/etc/simpbot")
|
||||
@ -40,255 +26,62 @@ func main() {
|
||||
log.Fatalf("Fatal error config file: %v \n", err)
|
||||
}
|
||||
viper.SetConfigType("yaml")
|
||||
Homeserver = viper.GetString("homeserver")
|
||||
Homeserver := viper.GetString("homeserver")
|
||||
viper.SetDefault("domain", Homeserver)
|
||||
viper.SetDefault("statefile", "simpstate")
|
||||
Username = viper.GetString("username")
|
||||
Password = viper.GetString("password")
|
||||
Token = viper.GetString("access_token")
|
||||
HolodexToken = viper.GetString("api_token")
|
||||
DimensionServer = viper.GetString("dimension")
|
||||
HomeserverDomain = viper.GetString("domain")
|
||||
Statefile = viper.GetString("statefile")
|
||||
CurrStreamCnt = 0
|
||||
MostStreamCnt = 0
|
||||
StartTime = time.Now()
|
||||
var vtubers []*Vtuber
|
||||
log.Println("Logging into", Homeserver, "as", Username)
|
||||
var client *mautrix.Client
|
||||
uid := id.NewUserID(strings.ToLower(Username), strings.ToLower(HomeserverDomain))
|
||||
if Token == "" {
|
||||
client, err = mautrix.NewClient(Homeserver, "", "")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
log.Println("using token login")
|
||||
client, err = mautrix.NewClient(Homeserver, uid, Token)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
dataFilter := &mautrix.Filter{
|
||||
AccountData: mautrix.FilterPart{
|
||||
Limit: 20,
|
||||
NotTypes: []event.Type{
|
||||
event.NewEventType("simp.batch"),
|
||||
},
|
||||
},
|
||||
}
|
||||
store := mautrix.NewAccountDataStore("simp.batch", client)
|
||||
fID, err := client.CreateFilter(dataFilter)
|
||||
store.SaveFilterID(uid, fID.FilterID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
client.Store = store
|
||||
Username := viper.GetString("username")
|
||||
Password := viper.GetString("password")
|
||||
Token := viper.GetString("access_token")
|
||||
simp.holodexToken = viper.GetString("api_token")
|
||||
HomeserverDomain := viper.GetString("domain")
|
||||
DimensionServer := viper.GetString("dimension")
|
||||
|
||||
if Token == "" {
|
||||
login_res, err := client.Login(&mautrix.ReqLogin{
|
||||
Type: "m.login.password",
|
||||
Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: Username},
|
||||
Password: Password,
|
||||
StoreCredentials: true,
|
||||
})
|
||||
log.Info("logging into matrix", "homeserver", Homeserver, "username", Username)
|
||||
err = simp.SetupMatrix(Username, Password, Token, Homeserver, HomeserverDomain, DimensionServer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
Token = login_res.AccessToken
|
||||
viper.Set("access_token", Token)
|
||||
log.Println("Login succesful, saving access_token to config file")
|
||||
err = viper.WriteConfig()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if simp.holodexToken == "" {
|
||||
log.Warn("No holodex API token provided, unlikely to be able to get streams")
|
||||
}
|
||||
} else {
|
||||
log.Println("skipping login since token provided")
|
||||
}
|
||||
if HolodexToken == "" {
|
||||
log.Println("No holodex API token provided, unlikely to be able to get streams")
|
||||
}
|
||||
syncer := client.Syncer.(*mautrix.DefaultSyncer)
|
||||
syncer.OnEventType(event.EventMessage, func(source mautrix.EventSource, evt *event.Event) {
|
||||
if evt.Sender == client.UserID {
|
||||
return //ignore events from self
|
||||
}
|
||||
fmt.Printf("<%[1]s> %[4]s (%[2]s/%[3]s)\n", evt.Sender, evt.Type.String(), evt.ID, evt.Content.AsMessage().Body)
|
||||
body := evt.Content.AsMessage().Body
|
||||
body_s := strings.Split(body, " ")
|
||||
if body_s[0] != "!simp" {
|
||||
return
|
||||
}
|
||||
if len(body_s) < 2 {
|
||||
return //nothing to parse
|
||||
}
|
||||
switch body_s[1] {
|
||||
case "info":
|
||||
// print info page
|
||||
var infomsg string
|
||||
vlist := []string{}
|
||||
for _, vt := range vtubers {
|
||||
ann := ""
|
||||
if vt.AnnounceLive {
|
||||
ann = "*"
|
||||
}
|
||||
vlist = append(vlist, fmt.Sprintf("%v%v", vt.Name, ann))
|
||||
}
|
||||
infomsg = fmt.Sprintf("Currently Simping For: \n%v", strings.Join(vlist, "\n"))
|
||||
client.SendText(evt.RoomID, infomsg)
|
||||
case "stats":
|
||||
var statmsg string
|
||||
vlist := []string{}
|
||||
t := 0
|
||||
for _, vt := range vtubers {
|
||||
vlist = append(vlist, fmt.Sprintf("%v Total:%v", vt.Name, vt.TotalStreams))
|
||||
t = t + vt.TotalStreams
|
||||
}
|
||||
statmsg = fmt.Sprintf("Current Stats Since %v:\n%v\n\nTotal Streams: %v\nMost Concurrent: %v/%v\n", StartTime, strings.Join(vlist, "\n"), t, MostStreamCnt, len(vtubers))
|
||||
client.SendText(evt.RoomID, statmsg)
|
||||
case "version":
|
||||
// print version
|
||||
if GitTag != "" {
|
||||
client.SendText(evt.RoomID, "SimpBot version "+GitTag)
|
||||
} else {
|
||||
client.SendText(evt.RoomID, "SimpBot version "+GitCommit)
|
||||
}
|
||||
case "reload":
|
||||
//reload config
|
||||
client.SendText(evt.RoomID, "Reloading config")
|
||||
fmt.Println("Reload requested,reloading vtubers")
|
||||
vtubers = LoadVtubers()
|
||||
case "subscribe":
|
||||
if len(body_s) < 3 {
|
||||
client.SendText(evt.RoomID, "Need a member to subscribe to")
|
||||
}
|
||||
vt := body_s[2]
|
||||
var subbed bool
|
||||
for _, v := range vtubers {
|
||||
if strings.ToUpper(v.Name) == strings.ToUpper(vt) {
|
||||
v.Subs[evt.Sender] = true
|
||||
subbed = true
|
||||
}
|
||||
}
|
||||
if subbed {
|
||||
client.SendText(evt.RoomID, "subbed")
|
||||
} else {
|
||||
client.SendText(evt.RoomID, "could not identify talent to subscribe to")
|
||||
}
|
||||
|
||||
case "help":
|
||||
client.SendText(evt.RoomID, "Supported commands: info,version,stats,reload,subscribe")
|
||||
default:
|
||||
//command not found
|
||||
client.SendText(evt.RoomID, "command not recognized")
|
||||
}
|
||||
})
|
||||
syncer.OnEventType(event.StateMember, func(source mautrix.EventSource, evt *event.Event) {
|
||||
fmt.Printf("<%[1]s> %[4]s (%[2]s/%[3]s)\n", evt.Sender, evt.Type.String(), evt.ID, evt.Content.AsMessage().Body)
|
||||
if evt.Content.AsMember().Membership.IsInviteOrJoin() {
|
||||
_, err = client.JoinRoomByID(evt.RoomID)
|
||||
if err != nil {
|
||||
fmt.Printf("error joining room %v", evt.RoomID)
|
||||
} else {
|
||||
fmt.Printf("joined room %v", evt.RoomID)
|
||||
}
|
||||
}
|
||||
})
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGUSR1)
|
||||
vtubers = LoadVtubers()
|
||||
simp.vtubers = loadVtubers()
|
||||
viper.WatchConfig()
|
||||
viper.OnConfigChange(func(e fsnotify.Event) {
|
||||
fmt.Println("Config file changed,reloading vtubers:", e.Name)
|
||||
vtubers = LoadVtubers()
|
||||
simp.vtubers = loadVtubers()
|
||||
})
|
||||
|
||||
var wg sync.WaitGroup
|
||||
stop := make(chan bool)
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(30 * time.Second)
|
||||
roomResp, err := client.JoinedRooms()
|
||||
if err != nil {
|
||||
log.Println("error getting joined rooms")
|
||||
log.Println(err)
|
||||
log.Println("Skipping iteration")
|
||||
continue
|
||||
}
|
||||
rooms := roomResp.JoinedRooms
|
||||
// We're going to assume they're only stream one video at a time
|
||||
for _, v := range vtubers {
|
||||
err = v.Update(HolodexToken)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if v.IsLive() {
|
||||
|
||||
for _, room := range rooms {
|
||||
//check to see if already embeded
|
||||
var content YoutubeWidget
|
||||
err = client.StateEvent(room, event.NewEventType("im.vector.modular.widgets"), "dimension-m.video-simp-"+v.Name, &content)
|
||||
if err != nil {
|
||||
log.Printf("error getting state event in room %v: %v", room, err)
|
||||
continue
|
||||
}
|
||||
if content.ID == "" {
|
||||
if v.AnnounceLive {
|
||||
client.SendText(room, v.LiveMsg)
|
||||
} else {
|
||||
if isValidUrl(v.LiveMsg) {
|
||||
client.SendNotice(room, fmt.Sprintf("%v has gone live", v.Name))
|
||||
} else {
|
||||
client.SendNotice(room, v.LiveMsg)
|
||||
}
|
||||
}
|
||||
client.SendNotice(room, fmt.Sprintf("%v's Title: %v", v.Name, v.CurrentStreamTitle))
|
||||
var subs string
|
||||
for k := range v.Subs {
|
||||
subs += k.String() + " "
|
||||
}
|
||||
if len(v.Subs) > 0 {
|
||||
client.SendText(room, fmt.Sprintf("Pinging %v", subs))
|
||||
}
|
||||
resp, err := client.SendStateEvent(room, event.NewEventType("im.vector.modular.widgets"), "dimension-m.video-simp-"+v.Name, NewYT(v.Name+"'s stream", v.CurrentStream, string(room)))
|
||||
if err != nil {
|
||||
log.Println("error embeding video")
|
||||
log.Println(err)
|
||||
}
|
||||
v.TotalStreams = v.TotalStreams + 1
|
||||
CurrStreamCnt = CurrStreamCnt + 1
|
||||
if CurrStreamCnt > MostStreamCnt {
|
||||
MostStreamCnt = CurrStreamCnt
|
||||
}
|
||||
log.Printf("Embed stream %v for %v ", resp, v.Name)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Not live, check to see if there's any embeds and remove them
|
||||
for _, room := range rooms {
|
||||
var content YoutubeWidget
|
||||
err = client.StateEvent(room, event.NewEventType("im.vector.modular.widgets"), "dimension-m.video-simp-"+v.Name, &content)
|
||||
if err == nil && content.ID != "" {
|
||||
//event found, kill it
|
||||
resp, err := client.SendStateEvent(room, event.NewEventType("im.vector.modular.widgets"), "dimension-m.video-simp-"+v.Name, struct{}{})
|
||||
if err != nil {
|
||||
log.Println("error removing video embed")
|
||||
log.Println(err)
|
||||
}
|
||||
CurrStreamCnt = CurrStreamCnt - 1
|
||||
log.Printf("Embed stream %v removed %v", resp, v.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
<-c
|
||||
log.Info("trying to shutdown cleanly")
|
||||
simp.Stop()
|
||||
stop <- true
|
||||
}()
|
||||
|
||||
err = client.Sync()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
err = simp.client.Sync()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Error(err)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
simp.Run()
|
||||
wg.Done()
|
||||
log.Info("simpbot shutdown")
|
||||
}()
|
||||
log.Info("simpbot running")
|
||||
wg.Wait()
|
||||
log.Info("shutting down")
|
||||
}
|
||||
|
||||
func isValidUrl(toTest string) bool {
|
||||
func isValidURL(toTest string) bool {
|
||||
_, err := url.ParseRequestURI(toTest)
|
||||
if err != nil {
|
||||
return false
|
||||
|
297
simp.go
Normal file
297
simp.go
Normal file
@ -0,0 +1,297 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/spf13/viper"
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
type simp struct {
|
||||
client *mautrix.Client
|
||||
dimensionServer string
|
||||
holodexToken string
|
||||
startTime time.Time
|
||||
currStream int
|
||||
maxStream int
|
||||
vtubers []*Vtuber
|
||||
stop chan bool
|
||||
rooms []id.RoomID
|
||||
}
|
||||
|
||||
func newSimp() *simp {
|
||||
return &simp{
|
||||
startTime: time.Now(),
|
||||
stop: make(chan bool),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *simp) Run() {
|
||||
ticker := time.NewTicker(time.Second * 45)
|
||||
roomResp, err := s.client.JoinedRooms()
|
||||
if err != nil {
|
||||
log.Errorf("error getting joined rooms: %v", err)
|
||||
return
|
||||
}
|
||||
s.rooms = roomResp.JoinedRooms
|
||||
for {
|
||||
select {
|
||||
case <-s.stop:
|
||||
return
|
||||
case <-ticker.C:
|
||||
// We're going to assume they're only stream one video at a time
|
||||
for _, v := range s.vtubers {
|
||||
err = v.Update(s.holodexToken)
|
||||
if err != nil {
|
||||
log.Error("error pinging holodex", "error", err)
|
||||
}
|
||||
for _, room := range s.rooms {
|
||||
if v.IsLive() {
|
||||
// check to see if already embeded
|
||||
var content YoutubeWidget
|
||||
err = s.client.StateEvent(
|
||||
room,
|
||||
event.NewEventType("im.vector.modular.widgets"),
|
||||
"dimension-m.video-simp-"+v.Name,
|
||||
&content,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("error getting state event in room %v: %v", room, err)
|
||||
}
|
||||
if content.ID == "" {
|
||||
if v.AnnounceLive {
|
||||
s.client.SendText(room, v.LiveMsg)
|
||||
} else {
|
||||
if isValidURL(v.LiveMsg) {
|
||||
s.client.SendNotice(room, fmt.Sprintf("%v has gone live", v.Name))
|
||||
} else {
|
||||
s.client.SendNotice(room, v.LiveMsg)
|
||||
}
|
||||
}
|
||||
s.client.SendNotice(room, fmt.Sprintf("%v's Title: %v", v.Name, v.CurrentStreamTitle))
|
||||
var subs string
|
||||
for k := range v.Subs {
|
||||
subs += k.String() + " "
|
||||
}
|
||||
if len(v.Subs) > 0 {
|
||||
s.client.SendText(room, fmt.Sprintf("Pinging %v", subs))
|
||||
}
|
||||
resp, err := s.client.SendStateEvent(
|
||||
room,
|
||||
event.NewEventType("im.vector.modular.widgets"),
|
||||
"dimension-m.video-simp-"+v.Name,
|
||||
s.NewYT(v.Name+"'s stream", v.CurrentStream, string(room)),
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("error embeding video: %v", err)
|
||||
}
|
||||
v.TotalStreams = v.TotalStreams + 1
|
||||
s.currStream++
|
||||
if s.currStream > s.maxStream {
|
||||
s.maxStream = s.currStream
|
||||
}
|
||||
log.Info("Embed stream added", "event", resp, "vtuber", v.Name)
|
||||
}
|
||||
} else {
|
||||
var content YoutubeWidget
|
||||
err = s.client.StateEvent(room, event.NewEventType("im.vector.modular.widgets"), "dimension-m.video-simp-"+v.Name, &content)
|
||||
if err == nil && content.ID != "" {
|
||||
// event found, kill it
|
||||
resp, err := s.client.SendStateEvent(room, event.NewEventType("im.vector.modular.widgets"), "dimension-m.video-simp-"+v.Name, struct{}{})
|
||||
if err != nil {
|
||||
log.Errorf("error removing embed: %v", err)
|
||||
}
|
||||
s.currStream--
|
||||
log.Info("Embed stream removed", "event", resp, "vtuber", v.Name)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *simp) SetupMatrix(uname, pass, token, hs, domain, dserver string) error {
|
||||
uid := id.NewUserID(strings.ToLower(uname), strings.ToLower(domain))
|
||||
if token == "" {
|
||||
client, err := mautrix.NewClient(hs, "", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.client = client
|
||||
} else {
|
||||
log.Info("using token login")
|
||||
client, err := mautrix.NewClient(hs, uid, token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.client = client
|
||||
}
|
||||
dataFilter := &mautrix.Filter{
|
||||
AccountData: mautrix.FilterPart{
|
||||
Limit: 20,
|
||||
NotTypes: []event.Type{
|
||||
event.NewEventType("s.batch"),
|
||||
},
|
||||
},
|
||||
}
|
||||
store := mautrix.NewAccountDataStore("simp.batch", s.client)
|
||||
fID, err := s.client.CreateFilter(dataFilter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
store.SaveFilterID(uid, fID.FilterID)
|
||||
s.client.Store = store
|
||||
|
||||
if token == "" {
|
||||
loginRes, err := s.client.Login(&mautrix.ReqLogin{
|
||||
Type: "m.login.password",
|
||||
Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: uname},
|
||||
Password: pass,
|
||||
StoreCredentials: true,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
token = loginRes.AccessToken
|
||||
viper.Set("access_token", token)
|
||||
log.Info("Login succesful, saving access_token to config file")
|
||||
err = viper.WriteConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
log.Info("skipping login since token provided")
|
||||
}
|
||||
syncer := s.client.Syncer.(*mautrix.DefaultSyncer)
|
||||
syncer.OnEventType(event.EventMessage, func(source mautrix.EventSource, evt *event.Event) {
|
||||
if evt.Sender == s.client.UserID {
|
||||
return // ignore events from self
|
||||
}
|
||||
log.Debugf("<%[1]s> %[4]s (%[2]s/%[3]s)\n", evt.Sender, evt.Type.String(), evt.ID, evt.Content.AsMessage().Body)
|
||||
body := evt.Content.AsMessage().Body
|
||||
bodyS := strings.Split(body, " ")
|
||||
if bodyS[0] != "!simp" {
|
||||
return
|
||||
}
|
||||
if len(bodyS) < 2 {
|
||||
return // nothing to parse
|
||||
}
|
||||
switch bodyS[1] {
|
||||
case "info":
|
||||
// print info page
|
||||
var infomsg string
|
||||
vlist := []string{}
|
||||
for _, vt := range s.vtubers {
|
||||
ann := ""
|
||||
if vt.AnnounceLive {
|
||||
ann = "*"
|
||||
}
|
||||
vlist = append(vlist, fmt.Sprintf("%v%v", vt.Name, ann))
|
||||
}
|
||||
infomsg = fmt.Sprintf("Currently Simping For: \n%v", strings.Join(vlist, "\n"))
|
||||
s.client.SendText(evt.RoomID, infomsg)
|
||||
case "stats":
|
||||
var statmsg string
|
||||
vlist := []string{}
|
||||
t := 0
|
||||
for _, vt := range s.vtubers {
|
||||
vlist = append(vlist, fmt.Sprintf("%v Total:%v", vt.Name, vt.TotalStreams))
|
||||
t = t + vt.TotalStreams
|
||||
}
|
||||
statmsg = fmt.Sprintf(
|
||||
"Current Stats Since %v:\n%v\n\nTotal Streams: %v\nMost Concurrent: %v/%v\n",
|
||||
s.startTime,
|
||||
strings.Join(vlist, "\n"),
|
||||
t,
|
||||
s.maxStream,
|
||||
len(s.vtubers),
|
||||
)
|
||||
s.client.SendText(evt.RoomID, statmsg)
|
||||
case "version":
|
||||
s.client.SendText(evt.RoomID, "not implemented")
|
||||
|
||||
case "reload":
|
||||
// reload config
|
||||
s.client.SendText(evt.RoomID, "Reloading config")
|
||||
log.Info("Reload requested,reloading vtubers")
|
||||
s.vtubers = loadVtubers()
|
||||
case "subscribe":
|
||||
if len(bodyS) < 3 {
|
||||
s.client.SendText(evt.RoomID, "Need a member to subscribe to")
|
||||
}
|
||||
vt := bodyS[2]
|
||||
var subbed bool
|
||||
for _, v := range s.vtubers {
|
||||
if strings.ToUpper(v.Name) == strings.ToUpper(vt) {
|
||||
v.Subs[evt.Sender] = true
|
||||
subbed = true
|
||||
}
|
||||
}
|
||||
if subbed {
|
||||
s.client.SendText(evt.RoomID, "subbed")
|
||||
} else {
|
||||
s.client.SendText(evt.RoomID, "could not identify talent to subscribe to")
|
||||
}
|
||||
|
||||
case "help":
|
||||
s.client.SendText(evt.RoomID, "Supported commands: info,version,stats,reload,subscribe")
|
||||
default:
|
||||
// command not found
|
||||
s.client.SendText(evt.RoomID, "command not recognized")
|
||||
}
|
||||
})
|
||||
syncer.OnEventType(event.StateMember, func(source mautrix.EventSource, evt *event.Event) {
|
||||
log.Infof("<%[1]s> %[4]s (%[2]s/%[3]s)\n", evt.Sender, evt.Type.String(), evt.ID, evt.Content.AsMessage().Body)
|
||||
if evt.Content.AsMember().Membership.IsInviteOrJoin() {
|
||||
_, err = s.client.JoinRoomByID(evt.RoomID)
|
||||
if err != nil {
|
||||
log.Errorf("error joining room %v", evt.RoomID)
|
||||
} else {
|
||||
log.Infof("joined room %v", evt.RoomID)
|
||||
s.rooms = append(s.rooms, evt.RoomID)
|
||||
}
|
||||
}
|
||||
})
|
||||
s.dimensionServer = dserver
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *simp) Stop() {
|
||||
s.stop <- true
|
||||
s.client.StopSync()
|
||||
}
|
||||
|
||||
func (s *simp) NewYT(videoName, videoID, roomID string) *YoutubeWidget {
|
||||
encodedVod := url.QueryEscape("https://youtube.com/embed/" + videoID)
|
||||
return &YoutubeWidget{
|
||||
Type: "im.vector.modular.widgets",
|
||||
URL: "https://" + s.dimensionServer + "/widgets/video?url=" + encodedVod,
|
||||
Name: videoName,
|
||||
Data: VideoData{
|
||||
VideoURL: "https://www.youtube.com/watch?v=" + videoID,
|
||||
URL: "https://youtube.com/embed/" + videoID,
|
||||
DimensionAppMetadata: DimensionAppMetadata{
|
||||
InRoomID: roomID,
|
||||
WrapperURLBase: "https://" + s.dimensionServer + "/widgets/video?url=",
|
||||
WrapperID: "video",
|
||||
ScalarWrapperID: "youtube",
|
||||
Integration: Integration{
|
||||
Category: "widget",
|
||||
Type: "youtube",
|
||||
},
|
||||
LastUpdatedTs: time.Now().UnixNano() / int64(time.Millisecond),
|
||||
},
|
||||
},
|
||||
CreatorUserID: string(s.client.UserID),
|
||||
ID: "dimension-m.video-simp",
|
||||
}
|
||||
}
|
41
vtuber.go
41
vtuber.go
@ -4,20 +4,21 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/spf13/viper"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
type VtuberConfig struct {
|
||||
type vtuberConfig struct {
|
||||
Name string `mapstructure:"name"`
|
||||
ChannelID string `mapstructure:"channelid"`
|
||||
LiveMsg string `mapstructure:"msg"`
|
||||
Announce bool `mapstructure:"Announce"`
|
||||
}
|
||||
|
||||
// Vtuber represents a vtuber
|
||||
type Vtuber struct {
|
||||
Name string
|
||||
ChannelID string
|
||||
@ -29,7 +30,7 @@ type Vtuber struct {
|
||||
Subs map[id.UserID]bool
|
||||
}
|
||||
|
||||
func NewVtuber(name, channelID, liveMsg string, announce bool) *Vtuber {
|
||||
func newVtuber(name, channelID, liveMsg string, announce bool) *Vtuber {
|
||||
return &Vtuber{
|
||||
Name: name,
|
||||
ChannelID: channelID,
|
||||
@ -42,42 +43,52 @@ func NewVtuber(name, channelID, liveMsg string, announce bool) *Vtuber {
|
||||
}
|
||||
}
|
||||
|
||||
func LoadVtubers() []*Vtuber {
|
||||
var vtubersRaw []VtuberConfig
|
||||
func loadVtubers() []*Vtuber {
|
||||
var vtubersRaw []vtuberConfig
|
||||
var vtubers []*Vtuber
|
||||
err := viper.UnmarshalKey("vtubers", &vtubersRaw)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, vt := range vtubersRaw {
|
||||
log.Printf("adding vtuber %v", vt)
|
||||
vtubers = append(vtubers, NewVtuber(vt.Name, vt.ChannelID, vt.LiveMsg, vt.Announce))
|
||||
log.Infof("adding vtuber %v", vt)
|
||||
vtubers = append(vtubers, newVtuber(vt.Name, vt.ChannelID, vt.LiveMsg, vt.Announce))
|
||||
}
|
||||
return vtubers
|
||||
}
|
||||
|
||||
// IsLive returns whether the specified Vtuber is live
|
||||
func (v *Vtuber) IsLive() bool {
|
||||
return v.CurrentStream != ""
|
||||
}
|
||||
|
||||
func (v *Vtuber) Update(api_key string) error {
|
||||
url := fmt.Sprintf("https://holodex.net/api/v2/live?channel_id=%s&lang=all&sort=available_at&order=desc&limit=25&offset=0&paginated=%%3Cempty%%3E", v.ChannelID)
|
||||
// Update takes an apiKey and updates the vtuber struct
|
||||
func (v *Vtuber) Update(apiKey string) error {
|
||||
url := fmt.Sprintf(
|
||||
"https://holodex.net/api/v2/live?channel_id=%s&lang=all&sort=available_at&order=desc&limit=25&offset=0&paginated=%%3Cempty%%3E",
|
||||
v.ChannelID,
|
||||
)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
req.Header.Set("X-APIKEY", api_key)
|
||||
req.Header.Set("X-APIKEY", apiKey)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("error creating GET %w", err)
|
||||
}
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("error sending request %w", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
jsonBody, _ := ioutil.ReadAll(res.Body)
|
||||
if res.StatusCode != 200 {
|
||||
return fmt.Errorf("bad status code %v", res.StatusCode)
|
||||
}
|
||||
jsonBody, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading response: %w", err)
|
||||
}
|
||||
var sl StreamList
|
||||
err = json.Unmarshal(jsonBody, &sl)
|
||||
if err != nil {
|
||||
log.Printf("error parsing json for vtuber %v:%v", v.Name, err)
|
||||
return err
|
||||
return fmt.Errorf("error marshalling vtuber: %w %v", err, string(jsonBody))
|
||||
}
|
||||
found := false
|
||||
for _, s := range sl.Streams {
|
||||
|
37
youtube.go
37
youtube.go
@ -1,10 +1,5 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Integration struct {
|
||||
Category string `json:"category"`
|
||||
Type string `json:"type"`
|
||||
@ -17,7 +12,7 @@ type DimensionAppMetadata struct {
|
||||
Integration Integration `json:"integration"`
|
||||
LastUpdatedTs int64 `json:"lastUpdatedTs"`
|
||||
}
|
||||
type Data struct {
|
||||
type VideoData struct {
|
||||
VideoURL string `json:"videoUrl"`
|
||||
URL string `json:"url"`
|
||||
DimensionAppMetadata DimensionAppMetadata `json:"dimension:app:metadata"`
|
||||
@ -26,38 +21,12 @@ type YoutubeWidget struct {
|
||||
Type string `json:"type"`
|
||||
URL string `json:"url"`
|
||||
Name string `json:"name"`
|
||||
Data Data `json:"data"`
|
||||
Data VideoData `json:"data"`
|
||||
CreatorUserID string `json:"creatorUserId"`
|
||||
ID string `json:"id"`
|
||||
RoomID string `json:"roomId"`
|
||||
EventID string `json:"eventId"`
|
||||
}
|
||||
type Unsigned struct {
|
||||
type unsignedAge struct {
|
||||
Age int `json:"age"`
|
||||
}
|
||||
|
||||
func NewYT(videoName, videoID, roomID string) *YoutubeWidget {
|
||||
encodedVod := url.QueryEscape("https://youtube.com/embed/" + videoID)
|
||||
return &YoutubeWidget{
|
||||
Type: "im.vector.modular.widgets",
|
||||
URL: "https://" + DimensionServer + "/widgets/video?url=" + encodedVod,
|
||||
Name: videoName,
|
||||
Data: Data{
|
||||
VideoURL: "https://www.youtube.com/watch?v=" + videoID,
|
||||
URL: "https://youtube.com/embed/" + videoID,
|
||||
DimensionAppMetadata: DimensionAppMetadata{
|
||||
InRoomID: roomID,
|
||||
WrapperURLBase: "https://" + DimensionServer + "/widgets/video?url=",
|
||||
WrapperID: "video",
|
||||
ScalarWrapperID: "youtube",
|
||||
Integration: Integration{
|
||||
Category: "widget",
|
||||
Type: "youtube",
|
||||
},
|
||||
LastUpdatedTs: time.Now().UnixNano() / int64(time.Millisecond),
|
||||
},
|
||||
},
|
||||
CreatorUserID: "@" + Username + ":" + HomeserverDomain,
|
||||
ID: "dimension-m.video-simp",
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user