Compare commits
92
Commits
v0.0.42
...
bd5e58d8f4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd5e58d8f4
|
||
|
|
8c73f3b464
|
||
|
|
dc5429b697
|
||
|
|
205a3832d9 | ||
|
|
969b30c0e0 | ||
|
|
dfcd250892 | ||
|
|
0944afa940 | ||
|
|
96f80ab358 | ||
|
|
b9440de296 | ||
|
|
77bd46d0e1 | ||
|
|
303f2a2ee0 | ||
|
|
61747d60cb | ||
|
|
a1924236ee | ||
|
|
ebdfcd0f92 | ||
|
|
e0b98f54c9 | ||
|
|
5ddc67f9e0 | ||
|
|
41d72c2e05 | ||
|
|
b29fb01e84 | ||
|
|
52c59282c3 | ||
|
|
085bec0d69 | ||
|
|
ecc384017b | ||
|
|
9c5b5e8873 | ||
|
|
1bb6564669 | ||
|
|
7c9d6599e0 | ||
|
|
77dd0c3e42 | ||
|
|
5bfc22f471 | ||
|
|
30f658ad41 | ||
|
|
c85ad5c91f | ||
|
|
5c773ff149 | ||
|
|
03bd0cba72 | ||
|
|
a5b0e99c80 | ||
|
|
7e6f3dd89f | ||
|
|
f48b530914 | ||
|
|
2c71273199 | ||
|
|
5bbef73a05 | ||
|
|
24e684ef31 | ||
|
|
6f30cf6668 | ||
|
|
f1c541bdc6 | ||
|
|
4fbe9196cb | ||
|
|
cfce631155 | ||
|
|
8c9a64b060 | ||
|
|
72375a9389 | ||
|
|
0f97a11a19 | ||
|
|
8f704eca28 | ||
|
|
2469a4f7ba | ||
|
|
4a9cb0afaa | ||
|
|
2b0ed3e229 | ||
|
|
b09dd20f7b | ||
|
|
de10dab45a | ||
|
|
3d281c7891 | ||
|
|
8784ef8ef8 | ||
|
|
a5e7b79a82 | ||
|
|
e6d0e1aa09 | ||
|
|
134af6b013 | ||
|
|
96b9c3825c | ||
|
|
3f59bf2697 | ||
|
|
6efbb4a0be | ||
|
|
fc0f1b0ed3 | ||
|
|
a4b3fc5a21 | ||
|
|
3efca50194 | ||
|
|
5413c257ab | ||
|
|
48abbb0cde | ||
|
|
ece695ffe2 | ||
|
|
4bac801c6f | ||
|
|
6583e48284 | ||
|
|
a586763e81 | ||
|
|
100f52bfee | ||
|
|
81bc385253 | ||
|
|
bf4a9f906e | ||
|
|
77f932e992 | ||
|
|
1c1d212e5e | ||
|
|
f17d110dfd | ||
|
|
d780ef6725 | ||
|
|
069cec2465 | ||
|
|
e629f48333 | ||
|
|
e931ec5cf9 | ||
|
|
f03bc7b9ed | ||
|
|
7272c47c29 | ||
|
|
abe0230f95 | ||
|
|
19d173af0a | ||
|
|
85e35e0f2c | ||
|
|
68379c3562 | ||
|
|
3d44258370 | ||
|
|
e9adc05536 | ||
|
|
b8ee6a1505 | ||
|
|
ac46753546 | ||
|
|
d16521e5e3 | ||
|
|
4955f4bf88 | ||
|
|
c3d2073b2b | ||
|
|
1ddc4d4c36 | ||
|
|
d66a25a525 | ||
|
|
6c05518146 |
@@ -0,0 +1,5 @@
|
||||
# Service release contract
|
||||
|
||||
Butler resolves this repository's protected source revision to verified immutable images. The platform updates only image references in the existing production Compose file and restarts only the already running application services. It preserves current environment, storage, routes, and provider configuration. It retains previous application images and restores them if readiness fails.
|
||||
|
||||
Migration and maintenance images are pinned when declared, but this release operation does not run database migrations or maintenance jobs. A release requiring a schema change needs the corresponding explicit platform migration first. No homelab image-pin commit is required for an ordinary compatible application release.
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 1,
|
||||
"deployment": "goff-release",
|
||||
"environment": "production",
|
||||
"images": {
|
||||
"goff_release_goff_image": {
|
||||
"name": "goff",
|
||||
"tag": "sha-{revision}"
|
||||
}
|
||||
},
|
||||
"revision_variable": "goff_release_revision"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
.git
|
||||
.github
|
||||
.gitea
|
||||
.env
|
||||
.idea
|
||||
goff
|
||||
@@ -0,0 +1,158 @@
|
||||
name: Build and Push Container
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch: null
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number
|
||||
|| github.run_id }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: butler-ci
|
||||
env:
|
||||
REGISTRY: gitea.wayfinderak.com
|
||||
IMAGE_NAME: gitea.wayfinderak.com/wayfinderak/goff
|
||||
container:
|
||||
options: --dns 172.16.30.10
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Select relevant delivery work
|
||||
id: delivery
|
||||
env:
|
||||
DELIVERY_EVENT: ${{ github.event_name }}
|
||||
DELIVERY_REF: ${{ github.ref }}
|
||||
DELIVERY_SHA: ${{ github.sha }}
|
||||
DELIVERY_BASE: ${{ github.event.pull_request.base.sha || github.event.before }}
|
||||
run: |
|
||||
cd .
|
||||
bash scripts/ci-select.sh
|
||||
- name: Install Go and Docker CLI if needed
|
||||
if: ${{ steps.delivery.outputs.run == 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
need_apt=0
|
||||
need_apk=0
|
||||
if ! command -v go >/dev/null 2>&1 || ! command -v docker >/dev/null 2>&1; then
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
need_apt=1
|
||||
elif command -v apk >/dev/null 2>&1; then
|
||||
need_apk=1
|
||||
else
|
||||
echo "No supported package manager found" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$need_apt" -eq 1 ]; then
|
||||
apt-get update
|
||||
if ! command -v go >/dev/null 2>&1; then
|
||||
apt-get install -y golang-go
|
||||
fi
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
apt-get install -y docker.io curl dnsutils iputils-ping
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$need_apk" -eq 1 ]; then
|
||||
if ! command -v go >/dev/null 2>&1; then
|
||||
apk add --no-cache go
|
||||
fi
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
apk add --no-cache docker-cli curl bind-tools iputils
|
||||
fi
|
||||
fi
|
||||
|
||||
go version
|
||||
docker version
|
||||
|
||||
- name: Run tests
|
||||
if: ${{ steps.delivery.outputs.run == 'true' }}
|
||||
run: go test ./...
|
||||
|
||||
- name: Log in to Gitea Container Registry
|
||||
if: ${{ (steps.delivery.outputs.run == 'true') && github.event_name != 'pull_request' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
for attempt in 1 2 3; do
|
||||
echo "docker login attempt $attempt"
|
||||
if echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login "$REGISTRY" -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin; then
|
||||
exit 0
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
echo "docker login failed after 3 attempts" >&2
|
||||
exit 1
|
||||
|
||||
- name: Determine image tags
|
||||
if: ${{ steps.delivery.outputs.run == 'true' }}
|
||||
id: meta
|
||||
shell: bash
|
||||
env:
|
||||
REF: ${{ gitea.ref }}
|
||||
REF_NAME: ${{ gitea.ref_name }}
|
||||
SHA: ${{ gitea.sha }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tags=("$IMAGE_NAME:sha-$SHA")
|
||||
|
||||
if [[ "$REF" == refs/tags/* ]]; then
|
||||
version="$REF_NAME"
|
||||
tags+=("$IMAGE_NAME:$version")
|
||||
tags+=("$IMAGE_NAME:latest")
|
||||
else
|
||||
branch="$REF_NAME"
|
||||
branch_safe="$(echo "$branch" | tr '/_' '--')"
|
||||
sha_short="$(echo "$SHA" | cut -c1-7)"
|
||||
tags+=("$IMAGE_NAME:$branch_safe")
|
||||
tags+=("$IMAGE_NAME:$branch_safe-$sha_short")
|
||||
if [[ "$branch" == "main" || "$branch" == "master" ]]; then
|
||||
tags+=("$IMAGE_NAME:latest")
|
||||
fi
|
||||
fi
|
||||
|
||||
printf 'tags<<EOF\n' >> "$GITHUB_OUTPUT"
|
||||
printf '%s\n' "${tags[@]}" >> "$GITHUB_OUTPUT"
|
||||
printf 'EOF\n' >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Build image
|
||||
if: ${{ steps.delivery.outputs.run == 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mapfile -t tags <<'EOF'
|
||||
${{ steps.meta.outputs.tags }}
|
||||
EOF
|
||||
|
||||
build_args=()
|
||||
for tag in "${tags[@]}"; do
|
||||
build_args+=(--tag "$tag")
|
||||
done
|
||||
|
||||
docker build --label "org.opencontainers.image.revision=$GITHUB_SHA" "${build_args[@]}" .
|
||||
|
||||
- name: Push image
|
||||
if: ${{ (steps.delivery.outputs.run == 'true') && github.event_name != 'pull_request' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
while IFS= read -r tag; do
|
||||
[ -n "$tag" ] || continue
|
||||
docker push "$tag"
|
||||
done <<'EOF'
|
||||
${{ steps.meta.outputs.tags }}
|
||||
EOF
|
||||
@@ -0,0 +1,64 @@
|
||||
name: Build and Push Container
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: gitea.wayfinderak.com
|
||||
IMAGE_NAME: wayfinderak/goff
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Gitea registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Prepare image tags
|
||||
id: prep
|
||||
shell: bash
|
||||
run: |
|
||||
short_sha="${GITHUB_SHA::7}"
|
||||
tags="${REGISTRY}/${IMAGE_NAME}:sha-${short_sha}"
|
||||
|
||||
if [[ "${GITHUB_REF_TYPE}" == "branch" && ("${GITHUB_REF_NAME}" == "master" || "${GITHUB_REF_NAME}" == "main") ]]; then
|
||||
tags+=$'\n'"${REGISTRY}/${IMAGE_NAME}:latest"
|
||||
fi
|
||||
|
||||
if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
|
||||
version="${GITHUB_REF_NAME#v}"
|
||||
tags+=$'\n'"${REGISTRY}/${IMAGE_NAME}:${version}"
|
||||
fi
|
||||
|
||||
{
|
||||
echo 'tags<<EOF'
|
||||
echo "$tags"
|
||||
echo 'EOF'
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Build and push image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ${{ steps.prep.outputs.tags }}
|
||||
@@ -1,2 +1,4 @@
|
||||
.env
|
||||
.idea
|
||||
|
||||
portainer-app.env
|
||||
|
||||
+13
-8
@@ -1,13 +1,18 @@
|
||||
FROM golang:1.14-alpine
|
||||
FROM golang:1.22-alpine AS builder
|
||||
|
||||
WORKDIR /go/src/Goff
|
||||
COPY ./go.mod .
|
||||
WORKDIR /src
|
||||
RUN apk add --no-cache ca-certificates git tzdata
|
||||
|
||||
RUN apk add --no-cache git
|
||||
|
||||
RUN go get -d -v ./...
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
COPY . .
|
||||
RUN go install -v ./...
|
||||
ARG TARGETARCH=amd64
|
||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -o /out/goff ./cmd/goff
|
||||
|
||||
ENTRYPOINT /go/bin/goff
|
||||
FROM alpine:3.20
|
||||
RUN apk add --no-cache ca-certificates tzdata
|
||||
|
||||
COPY --from=builder /out/goff /usr/local/bin/goff
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/goff"]
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# Portainer deployment notes
|
||||
|
||||
Generated from the current Kubernetes deployment in namespace `discord-bots`. Secret values are in the local `portainer-*.env` files.
|
||||
|
||||
## Kubernetes source
|
||||
|
||||
- Deployment: `goff`
|
||||
- Replicas: `1`
|
||||
- Rolling update: maxSurge `1`, maxUnavailable `1`
|
||||
- minReadySeconds: `120`
|
||||
- Labels/selectors: `app=goff`
|
||||
- Image pull secrets: `none required for Portainer stack`
|
||||
|
||||
## Containers
|
||||
|
||||
- `pgbouncer`: image `timoha/pgbouncer:1.15.0`; env: DATABASE_URL, SERVER_TLS_SSLMODE, AUTH_TYPE; ports: 5432; requests: {'cpu': '500m', 'memory': '256Mi'}; limits: {'cpu': '1', 'memory': '512Mi'}
|
||||
- `goff`: image `gitea.wayfinderak.com/wayfinderak/goff:latest`; env: DATABASE_URL, DISCORDGO_TOKEN, GOFF_EMAIL_USERNAME, GOFF_EMAIL_PASSWORD; ports: none; requests: {'cpu': '1', 'memory': '512Mi'}; limits: {'cpu': '2', 'memory': '1Gi'}
|
||||
|
||||
## Portainer files
|
||||
|
||||
- `portainer-stack.yml` - Docker Compose stack to paste/use in Portainer.
|
||||
- `portainer-app.env` - bot runtime secrets/env.
|
||||
|
||||
## Portainer database connection
|
||||
|
||||
This Portainer stack does not include pgbouncer. `DATABASE_URL` in `portainer-app.env` points directly at the external PostgreSQL service copied from the Kubernetes pgbouncer upstream URL.
|
||||
Binary file not shown.
@@ -4,9 +4,14 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"djpianalto.com/goff/djpianalto.com/goff/events"
|
||||
"djpianalto.com/goff/djpianalto.com/goff/exts"
|
||||
"djpianalto.com/goff/djpianalto.com/goff/utils"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/guild_management"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/logging"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/tasks"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/user_management"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/postgres"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/services"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/pkg/email"
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
|
||||
//"github.com/MikeModder/anpan"
|
||||
@@ -34,11 +39,20 @@ func main() {
|
||||
return
|
||||
}
|
||||
dg.State.MaxMessageCount = 100
|
||||
dg.StateEnabled = true
|
||||
|
||||
utils.ConnectDatabase(os.Getenv("DATABASE_URL"))
|
||||
utils.InitializeDatabase()
|
||||
dg.Identify = discordgo.Identify{
|
||||
Intents: discordgo.MakeIntent(discordgo.IntentsAll),
|
||||
}
|
||||
|
||||
postgres.ConnectDatabase(os.Getenv("DATABASE_URL"))
|
||||
postgres.InitializeDatabase()
|
||||
//utils.LoadTestData()
|
||||
|
||||
us := &postgres.UserService{DB: postgres.DB}
|
||||
gs := &postgres.GuildService{DB: postgres.DB}
|
||||
rs := &postgres.RoleService{DB: postgres.DB}
|
||||
|
||||
//prefixes := []string{
|
||||
// "Go.",
|
||||
//}
|
||||
@@ -46,12 +60,7 @@ func main() {
|
||||
"351794468870946827",
|
||||
}
|
||||
|
||||
// Arguments are:
|
||||
// prefixes - []string
|
||||
// owner ids - []string
|
||||
// ignore bots - bool
|
||||
// check perms - bool
|
||||
handler := disgoman.CommandManager{
|
||||
manager := disgoman.CommandManager{
|
||||
Prefixes: getPrefixes,
|
||||
Owners: owners,
|
||||
StatusManager: disgoman.GetDefaultStatusManager(),
|
||||
@@ -62,18 +71,22 @@ func main() {
|
||||
}
|
||||
|
||||
// Add Command Handlers
|
||||
exts.AddCommandHandlers(&handler)
|
||||
exts.AddCommandHandlers(&manager)
|
||||
services.InitalizeServices(us, gs, rs)
|
||||
|
||||
//if _, ok := handler.Commands["help"]; !ok {
|
||||
// handler.AddDefaultHelpCommand()
|
||||
//}
|
||||
|
||||
dg.AddHandler(handler.OnMessage)
|
||||
dg.AddHandler(handler.StatusManager.OnReady)
|
||||
dg.AddHandler(events.OnMessageUpdate)
|
||||
dg.AddHandler(events.OnMessageDelete)
|
||||
dg.AddHandler(events.OnGuildMemberAddLogging)
|
||||
dg.AddHandler(events.OnGuildMemberRemoveLogging)
|
||||
dg.AddHandler(manager.OnMessage)
|
||||
dg.AddHandler(manager.StatusManager.OnReady)
|
||||
dg.AddHandler(guild_management.OnMessageUpdate)
|
||||
dg.AddHandler(guild_management.OnMessageDelete)
|
||||
dg.AddHandler(user_management.OnGuildMemberAddLogging)
|
||||
dg.AddHandler(user_management.OnGuildMemberAdd)
|
||||
dg.AddHandler(user_management.OnGuildMemberRemoveLogging)
|
||||
dg.AddHandler(user_management.OnGuildMemberRemove)
|
||||
dg.AddHandler(user_management.OnGuildMemberUpdate)
|
||||
|
||||
err = dg.Open()
|
||||
if err != nil {
|
||||
@@ -82,15 +95,15 @@ func main() {
|
||||
}
|
||||
|
||||
// Start the Error handler in a goroutine
|
||||
go ErrorHandler(handler.ErrorChannel)
|
||||
go ErrorHandler(manager.ErrorChannel)
|
||||
|
||||
// Start the Logging handler in a goroutine
|
||||
go utils.LoggingHandler(utils.LoggingChannel)
|
||||
go logging.LoggingHandler(logging.LoggingChannel)
|
||||
|
||||
// Start the task handler in a goroutine
|
||||
go utils.ProcessTasks(dg, 1)
|
||||
go tasks.ProcessTasks(dg, 1)
|
||||
|
||||
go utils.RecieveEmail(dg)
|
||||
go email.RecieveEmail(dg)
|
||||
|
||||
fmt.Println("The Bot is now running.")
|
||||
sc := make(chan os.Signal, 1)
|
||||
@@ -106,11 +119,12 @@ func main() {
|
||||
|
||||
func getPrefixes(guildID string) []string {
|
||||
queryString := "Select prefix from prefixes p, x_guilds_prefixes xgp where xgp.guild_id = $1 and xgp.prefix_id = p.id"
|
||||
rows, err := utils.Database.Query(queryString, guildID)
|
||||
rows, err := postgres.DB.Query(queryString, guildID)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return []string{"Go.", "go."}
|
||||
}
|
||||
defer rows.Close()
|
||||
var prefixes []string
|
||||
for rows.Next() {
|
||||
var prefix string
|
||||
@@ -121,6 +135,9 @@ func getPrefixes(guildID string) []string {
|
||||
}
|
||||
prefixes = append(prefixes, prefix)
|
||||
}
|
||||
if len(prefixes) == 0 {
|
||||
prefixes = append(prefixes, "Go.", "go.")
|
||||
}
|
||||
return prefixes
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: goff
|
||||
namespace: discord-bots
|
||||
labels:
|
||||
app: goff
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: goff
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 1
|
||||
minReadySeconds: 120
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: goff
|
||||
spec:
|
||||
containers:
|
||||
- name: pgbouncer
|
||||
image: timoha/pgbouncer:1.15.0
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "0.5"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "1"
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: goff
|
||||
key: pgbouncer_url
|
||||
- name: SERVER_TLS_SSLMODE
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: goff
|
||||
key: pgbouncer_ssl
|
||||
- name: AUTH_TYPE
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: goff
|
||||
key: pgbouncer_auth
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
- name: goff
|
||||
image: <IMAGE>
|
||||
resources:
|
||||
requests:
|
||||
memory: "512Mi"
|
||||
cpu: "1"
|
||||
limits:
|
||||
memory: "1Gi"
|
||||
cpu: "2"
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: goff
|
||||
key: database_url
|
||||
- name: DISCORDGO_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: goff
|
||||
key: discord_token
|
||||
- name: GOFF_EMAIL_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: goff
|
||||
key: email_username
|
||||
- name: GOFF_EMAIL_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: goff
|
||||
key: email_password
|
||||
imagePullSecrets:
|
||||
- name: registry-1
|
||||
@@ -1,49 +0,0 @@
|
||||
package exts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func interleave(ctx disgoman.Context, args []string) {
|
||||
if len(args) == 2 {
|
||||
x, err := strconv.ParseInt(args[0], 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
y, err := strconv.ParseInt(args[1], 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var z = int64(0)
|
||||
for i := 0; i < 64; i++ {
|
||||
x_masked_i := x & (1 << i)
|
||||
y_masked_i := y & (1 << i)
|
||||
|
||||
z |= x_masked_i << i
|
||||
z |= y_masked_i << (i + 1)
|
||||
}
|
||||
ctx.Send(fmt.Sprintf("%v", z))
|
||||
}
|
||||
}
|
||||
|
||||
func deinterleave(ctx disgoman.Context, args []string) {
|
||||
if len(args) == 1 {
|
||||
z, err := strconv.ParseInt(args[0], 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var x = int64(0)
|
||||
var y = int64(0)
|
||||
i := 0
|
||||
for z > 0 {
|
||||
x |= (z & 1) << i
|
||||
z >>= 1
|
||||
y |= (z & 1) << i
|
||||
z >>= 1
|
||||
i++
|
||||
}
|
||||
ctx.Send(fmt.Sprintf("(%v, %v)", x, y))
|
||||
}
|
||||
}
|
||||
@@ -1,290 +0,0 @@
|
||||
package exts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"djpianalto.com/goff/djpianalto.com/goff/utils"
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
)
|
||||
|
||||
// Guild management commands
|
||||
|
||||
func loggingChannel(ctx disgoman.Context, args []string) {
|
||||
var idString string
|
||||
if len(args) > 0 {
|
||||
idString = args[0]
|
||||
if strings.HasPrefix(idString, "<#") && strings.HasSuffix(idString, ">") {
|
||||
idString = idString[2 : len(idString)-1]
|
||||
}
|
||||
} else {
|
||||
idString = ""
|
||||
}
|
||||
fmt.Println(idString)
|
||||
if idString == "" {
|
||||
_, err := utils.Database.Exec("UPDATE guilds SET logging_channel='' WHERE id=$1;", ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Logging Channel Updated.")
|
||||
return
|
||||
}
|
||||
channel, err := ctx.Session.State.Channel(idString)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that channel.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if channel.GuildID != ctx.Guild.ID {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "The channel passed is not in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, err = utils.Database.Exec("UPDATE guilds SET logging_channel=$1 WHERE id=$2;", idString, ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Logging Channel Updated.")
|
||||
}
|
||||
|
||||
func getLoggingChannel(ctx disgoman.Context, _ []string) {
|
||||
var channelID string
|
||||
row := utils.Database.QueryRow("SELECT logging_channel FROM guilds where id=$1", ctx.Guild.ID)
|
||||
err := row.Scan(&channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error getting data from the database.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if channelID == "" {
|
||||
_, _ = ctx.Send("The logging channel is not set.")
|
||||
return
|
||||
}
|
||||
channel, err := ctx.Session.State.GuildChannel(ctx.Guild.ID, channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "I got the channel ID but it does not appear to be a valid channel in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("The logging channel is currently %s", channel.Mention()))
|
||||
return
|
||||
}
|
||||
|
||||
func welcomeChannel(ctx disgoman.Context, args []string) {
|
||||
var idString string
|
||||
if len(args) > 0 {
|
||||
idString = args[0]
|
||||
if strings.HasPrefix(idString, "<#") && strings.HasSuffix(idString, ">") {
|
||||
idString = idString[2 : len(idString)-1]
|
||||
}
|
||||
} else {
|
||||
idString = ""
|
||||
}
|
||||
fmt.Println(idString)
|
||||
if idString == "" {
|
||||
_, err := utils.Database.Exec("UPDATE guilds SET welcome_channel='' WHERE id=$1;", ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Welcomer Disabled.")
|
||||
return
|
||||
}
|
||||
channel, err := ctx.Session.State.Channel(idString)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that channel.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if channel.GuildID != ctx.Guild.ID {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "The channel passed is not in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, err = utils.Database.Exec("UPDATE guilds SET welcome_channel=$1 WHERE id=$2;", idString, ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Welcome Channel Updated.")
|
||||
return
|
||||
}
|
||||
|
||||
func getWelcomeChannel(ctx disgoman.Context, _ []string) {
|
||||
var channelID string
|
||||
row := utils.Database.QueryRow("SELECT welcome_channel FROM guilds where id=$1", ctx.Guild.ID)
|
||||
err := row.Scan(&channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error getting data from the database.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if channelID == "" {
|
||||
_, _ = ctx.Send("The welcomer is disabled.")
|
||||
return
|
||||
}
|
||||
channel, err := ctx.Session.State.GuildChannel(ctx.Guild.ID, channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "I got the channel ID but it does not appear to be a valid channel in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("The welcome channel is currently %s", channel.Mention()))
|
||||
}
|
||||
|
||||
func addGuildCommand(ctx disgoman.Context, args []string) {
|
||||
var guildID string
|
||||
row := utils.Database.QueryRow("SELECT id FROM guilds where id=$1", ctx.Guild.ID)
|
||||
err := row.Scan(&guildID)
|
||||
if err == nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "This guild is already in my database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
_, err = utils.Database.Query("INSERT INTO guilds (id) VALUES ($1)", ctx.Guild.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "There was a problem inserting this guild into the database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("This guild has been added.")
|
||||
|
||||
}
|
||||
|
||||
func puzzleChannel(ctx disgoman.Context, args []string) {
|
||||
var idString string
|
||||
if len(args) > 0 {
|
||||
idString = args[0]
|
||||
if strings.HasPrefix(idString, "<#") && strings.HasSuffix(idString, ">") {
|
||||
idString = idString[2 : len(idString)-1]
|
||||
}
|
||||
} else {
|
||||
idString = ""
|
||||
}
|
||||
fmt.Println(idString)
|
||||
if idString == "" {
|
||||
_, err := utils.Database.Exec("UPDATE guilds SET puzzle_channel='' WHERE id=$1;", ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Puzzle Channel Updated.")
|
||||
return
|
||||
}
|
||||
channel, err := ctx.Session.State.Channel(idString)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that channel.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if channel.GuildID != ctx.Guild.ID {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "The channel passed is not in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, err = utils.Database.Exec("UPDATE guilds SET puzzle_channel=$1 WHERE id=$2;", idString, ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Puzzle Channel Updated.")
|
||||
}
|
||||
|
||||
func getPuzzleChannel(ctx disgoman.Context, _ []string) {
|
||||
var channelID string
|
||||
row := utils.Database.QueryRow("SELECT puzzle_channel FROM guilds where id=$1", ctx.Guild.ID)
|
||||
err := row.Scan(&channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error getting data from the database.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if channelID == "" {
|
||||
_, _ = ctx.Send("The puzzle channel is not set.")
|
||||
return
|
||||
}
|
||||
channel, err := ctx.Session.State.GuildChannel(ctx.Guild.ID, channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "I got the channel ID but it does not appear to be a valid channel in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("The puzzle channel is currently %s", channel.Mention()))
|
||||
return
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
package exts
|
||||
|
||||
import (
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
)
|
||||
|
||||
func AddCommandHandlers(h *disgoman.CommandManager) {
|
||||
// Arguments:
|
||||
// name - command name - string
|
||||
// desc - command description - string
|
||||
// owneronly - only allow owners to run - bool
|
||||
// hidden - hide command from non-owners - bool
|
||||
// perms - permissisions required - anpan.Permission (int)
|
||||
// type - command type, sets where the command is available
|
||||
// run - function to run - func(anpan.Context, []string) / CommandRunFunc
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "ping",
|
||||
Aliases: nil,
|
||||
Description: "Check the bot's ping",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: pingCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "say",
|
||||
Aliases: nil,
|
||||
Description: "Repeat a message",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
SanitizeEveryone: true,
|
||||
Invoke: sayCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "user",
|
||||
Aliases: nil,
|
||||
Description: "Get user info",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: userCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "git",
|
||||
Aliases: nil,
|
||||
Description: "Show my github link",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: gitCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "tag",
|
||||
Aliases: nil,
|
||||
Description: "Get a tag",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: tagCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "addtag",
|
||||
Aliases: nil,
|
||||
Description: "Add a tag",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
SanitizeEveryone: true,
|
||||
Invoke: addTagCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "invite",
|
||||
Aliases: nil,
|
||||
Description: "Get the invite link for this bot or others",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: inviteCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "P",
|
||||
Aliases: nil,
|
||||
Description: "Interpret a P\" program and return the results",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: pCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "set-logging-channel",
|
||||
Aliases: []string{"slc"},
|
||||
Description: "Set the channel logging messages will be sent to.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: loggingChannel,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "get-logging-channel",
|
||||
Aliases: []string{"glc"},
|
||||
Description: "Gets the channel logging messages will be sent to.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: getLoggingChannel,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "set-welcome-channel",
|
||||
Aliases: []string{"swc"},
|
||||
Description: "Set the channel welcome messages will be sent to.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: welcomeChannel,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "get-welcome-channel",
|
||||
Aliases: []string{"gwc"},
|
||||
Description: "Gets the channel welcome messages will be sent to.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: getWelcomeChannel,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "kick",
|
||||
Aliases: nil,
|
||||
Description: "Kicks the given user with the given reason",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionKickMembers,
|
||||
Invoke: kickUserCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "addGuild",
|
||||
Aliases: nil,
|
||||
Description: "Adds the current guild to the database",
|
||||
OwnerOnly: true,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: addGuildCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "ban",
|
||||
Aliases: []string{"ban-no-delete"},
|
||||
Description: "Bans the given user with the given reason",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionBanMembers,
|
||||
Invoke: banUserCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "unban",
|
||||
Aliases: nil,
|
||||
Description: "Unbans the given user",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionBanMembers,
|
||||
Invoke: unbanUserCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "remind",
|
||||
Aliases: nil,
|
||||
Description: "Remind me at a later time",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: addReminderCommand,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "encode",
|
||||
Aliases: []string{"e"},
|
||||
Description: "Encode 2 numbers",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: interleave,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "decode",
|
||||
Aliases: []string{"d"},
|
||||
Description: "Decode 1 number into 2",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: deinterleave,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "set-puzzle-channel",
|
||||
Aliases: []string{"spc"},
|
||||
Description: "Set the channel puzzle messages will be sent to.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: puzzleChannel,
|
||||
})
|
||||
_ = h.AddCommand(&disgoman.Command{
|
||||
Name: "get-puzzle-channel",
|
||||
Aliases: []string{"gpc"},
|
||||
Description: "Gets the channel puzzle messages will be sent to.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: getPuzzleChannel,
|
||||
})
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package utils
|
||||
|
||||
import "log"
|
||||
|
||||
type postfix struct {
|
||||
Name string
|
||||
Invoke func(bool) error
|
||||
}
|
||||
|
||||
var postfixes = []postfix{
|
||||
postfix{
|
||||
Name: "1_Update_Guild_for_Puzzle",
|
||||
Invoke: updateGuildForPuzzle,
|
||||
},
|
||||
postfix{
|
||||
Name: "1_Update_X_Guild_Prefixes_to_add_ID",
|
||||
Invoke: updateXGuildPrefixesToAddID,
|
||||
},
|
||||
}
|
||||
|
||||
func RunPostfixes() {
|
||||
for _, postfix := range postfixes {
|
||||
queryString := "SELECT * from postfixes where name = $1"
|
||||
rows, err := Database.Query(queryString, postfix.Name)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
if rows.Next() {
|
||||
continue
|
||||
} else {
|
||||
err := postfix.Invoke(false)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
_, err = Database.Exec("INSERT INTO postfixes (name) VALUES ($1)", postfix.Name)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateGuildForPuzzle(revert bool) error {
|
||||
var queryString string
|
||||
if !revert {
|
||||
queryString = `ALTER TABLE guilds
|
||||
ADD COLUMN puzzle_channel varchar(30) not null default ''`
|
||||
} else {
|
||||
queryString = `ALTER TABLE guilds
|
||||
DROP COLUMN puzzleChat`
|
||||
}
|
||||
_, err := Database.Exec(queryString)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateXGuildPrefixesToAddID(revert bool) error {
|
||||
var queryString string
|
||||
if !revert {
|
||||
queryString = `ALTER TABLE x_guilds_prefixes
|
||||
ADD COLUMN id serial primary key`
|
||||
} else {
|
||||
queryString = `ALTER TABLE x_guilds_prefixes
|
||||
DROP COLUMN id`
|
||||
}
|
||||
_, err := Database.Exec(queryString)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package utils
|
||||
|
||||
type Guild struct {
|
||||
ID string
|
||||
WelcomeMessage string
|
||||
GoodbyeMessage string
|
||||
LoggingChannel string
|
||||
WelcomeChannel string
|
||||
PuzzleChannel string
|
||||
}
|
||||
+7
-29
@@ -1,32 +1,10 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
# goff-db:
|
||||
# image: postgres
|
||||
# ports:
|
||||
# - "5432:5432"
|
||||
# volumes:
|
||||
# - "${PWD}/postgres.conf:/etc/postgresql/postgresql.conf"
|
||||
# - "goff-db:/var/lib/postgresql/data:rw"
|
||||
# env_file: ${PWD}/.env
|
||||
|
||||
goff:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: "${PWD}/Dockerfile"
|
||||
env_file: ${PWD}/.env
|
||||
logging:
|
||||
driver: awslogs
|
||||
options:
|
||||
awslogs-region: us-east-1
|
||||
awslogs-group: "/docker/goff/production"
|
||||
# depends_on:
|
||||
# - goff-db
|
||||
image: ${IMAGE:-gitea.wayfinderak.com/wayfinderak/goff:${IMAGE_TAG:-latest}}
|
||||
container_name: goff
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=disable
|
||||
# links:
|
||||
# - goff-db:goff.db
|
||||
|
||||
#volumes:
|
||||
# goff-db:
|
||||
# external: true
|
||||
DATABASE_URL: ${DATABASE_URL}
|
||||
DISCORDGO_TOKEN: ${DISCORDGO_TOKEN}
|
||||
GOFF_EMAIL_USERNAME: ${GOFF_EMAIL_USERNAME}
|
||||
GOFF_EMAIL_PASSWORD: ${GOFF_EMAIL_PASSWORD}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
# goff-db:
|
||||
# image: postgres
|
||||
# ports:
|
||||
# - "5432:5432"
|
||||
# volumes:
|
||||
# - "${PWD}/postgres.conf:/etc/postgresql/postgresql.conf"
|
||||
# - "goff-db:/var/lib/postgresql/data:rw"
|
||||
# env_file: ${PWD}/.env
|
||||
|
||||
goff:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: "${PWD}/Dockerfile"
|
||||
env_file: ${PWD}/.env
|
||||
# logging:
|
||||
# driver: awslogs
|
||||
# options:
|
||||
# awslogs-region: us-east-1
|
||||
# awslogs-group: "/docker/goff/production"
|
||||
# depends_on:
|
||||
# - goff-db
|
||||
environment:
|
||||
- DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=disable
|
||||
# links:
|
||||
# - goff-db:goff.db
|
||||
|
||||
#volumes:
|
||||
# goff-db:
|
||||
# external: true
|
||||
@@ -1,13 +1,20 @@
|
||||
module djpianalto.com/goff
|
||||
module gitea.wayfinderak.com/wayfinderak/goff
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/bwmarrin/discordgo v0.20.3-0.20200525154655-ca64123b05de
|
||||
github.com/dustinpianalto/disgoman v0.0.10
|
||||
github.com/emersion/go-imap v1.0.5
|
||||
github.com/emersion/go-message v0.12.0
|
||||
github.com/AlekSi/pointer v1.1.0 // indirect
|
||||
github.com/bwmarrin/discordgo v0.23.2
|
||||
github.com/dustinpianalto/disgoman v0.0.21
|
||||
github.com/dustinpianalto/rpnparse v1.0.1
|
||||
github.com/emersion/go-imap v1.1.0
|
||||
github.com/emersion/go-message v0.15.0
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||
github.com/lib/pq v1.3.0
|
||||
github.com/lib/pq v1.10.2
|
||||
github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
|
||||
golang.org/x/sys v0.0.0-20210818153620-00dd8d7831e7 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
)
|
||||
|
||||
@@ -1,35 +1,68 @@
|
||||
github.com/AlekSi/pointer v1.0.0 h1:KWCWzsvFxNLcmM5XmiqHsGTTsuwZMsLFwWF9Y+//bNE=
|
||||
github.com/AlekSi/pointer v1.0.0/go.mod h1:1kjywbfcPFCmncIxtk6fIEub6LKrfMz3gc5QKVOSOA8=
|
||||
github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI=
|
||||
github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE=
|
||||
github.com/bwmarrin/discordgo v0.20.2 h1:nA7jiTtqUA9lT93WL2jPjUp8ZTEInRujBdx1C9gkr20=
|
||||
github.com/bwmarrin/discordgo v0.20.2/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
|
||||
github.com/bwmarrin/discordgo v0.20.3-0.20200525154655-ca64123b05de h1:0TOVVwGrmv0PA+/vuekQIRY9jJ9rcHYnicIaph3/4S4=
|
||||
github.com/bwmarrin/discordgo v0.20.3-0.20200525154655-ca64123b05de/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M=
|
||||
github.com/bwmarrin/discordgo v0.22.0 h1:uBxY1HmlVCsW1IuaPjpCGT6A2DBwRn0nvOguQIxDdFM=
|
||||
github.com/bwmarrin/discordgo v0.22.0/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M=
|
||||
github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt2fH4=
|
||||
github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dustinpianalto/disgoman v0.0.10 h1:UzmvMpOi4peF59tXGaNfVU+ePHs1hILa6gQbjxjWQ9g=
|
||||
github.com/dustinpianalto/disgoman v0.0.10/go.mod h1:v3FM6n+4dH9XlvO+IDx6MN3DUnGq6YVDBvy1A1k202g=
|
||||
github.com/dustinpianalto/disgoman v0.0.12 h1:dLptU2ZTUZJaLBOKeE6qjuL8gqdAr6ehHSOtfHmUpL8=
|
||||
github.com/dustinpianalto/disgoman v0.0.12/go.mod h1:v3FM6n+4dH9XlvO+IDx6MN3DUnGq6YVDBvy1A1k202g=
|
||||
github.com/dustinpianalto/disgoman v0.0.14 h1:hsk56JATBE5eH5GPCDGeiTdYxok4m+edSYiYz5Uj8uo=
|
||||
github.com/dustinpianalto/disgoman v0.0.14/go.mod h1:v3FM6n+4dH9XlvO+IDx6MN3DUnGq6YVDBvy1A1k202g=
|
||||
github.com/dustinpianalto/disgoman v0.0.15 h1:kdIw6jhC82WBut7+4BarqxBw06dozU+Hu47LQzkkoGM=
|
||||
github.com/dustinpianalto/disgoman v0.0.15/go.mod h1:v3FM6n+4dH9XlvO+IDx6MN3DUnGq6YVDBvy1A1k202g=
|
||||
github.com/dustinpianalto/disgoman v0.0.21 h1:GfT149ymB/7BAJaKn4DNB66zBAbSB1tdn3E26NGok0o=
|
||||
github.com/dustinpianalto/disgoman v0.0.21/go.mod h1:v3FM6n+4dH9XlvO+IDx6MN3DUnGq6YVDBvy1A1k202g=
|
||||
github.com/dustinpianalto/rpnparse v1.0.1 h1:ZvH1/RIe5hh3RGSAXOgtngEDHNPTF+DMh88XFWpQjzY=
|
||||
github.com/dustinpianalto/rpnparse v1.0.1/go.mod h1:SzFbQb+Eed5gYCtDu/SYEXXwdPtWkDg9oaL1xQtN1BY=
|
||||
github.com/emersion/go-imap v1.0.5 h1:8xg/d2wo2BBP3AEP5AOaM/6i8887RGyVW2st/IVHWUw=
|
||||
github.com/emersion/go-imap v1.0.5/go.mod h1:yKASt+C3ZiDAiCSssxg9caIckWF/JG7ZQTO7GAmvicU=
|
||||
github.com/emersion/go-imap v1.1.0 h1:hAW8Dbi/AwiVO5Wi40FTVuCzVrTmwtEK6De9GSoOy+Y=
|
||||
github.com/emersion/go-imap v1.1.0/go.mod h1:0hCeak4mA2z9hICM20jeqN6fyV0Oad0lZTyeeAyUS6o=
|
||||
github.com/emersion/go-message v0.11.1/go.mod h1:C4jnca5HOTo4bGN9YdqNQM9sITuT3Y0K6bSUw9RklvY=
|
||||
github.com/emersion/go-message v0.12.0 h1:mZnv35eZ6lB6EftTQBgYXspOH0FQdhpFhSUhA9i6/Zg=
|
||||
github.com/emersion/go-message v0.12.0/go.mod h1:C4jnca5HOTo4bGN9YdqNQM9sITuT3Y0K6bSUw9RklvY=
|
||||
github.com/emersion/go-message v0.14.1/go.mod h1:N1JWdZQ2WRUalmdHAX308CWBq747VJ8oUorFI3VCBwU=
|
||||
github.com/emersion/go-message v0.15.0 h1:urgKGqt2JAc9NFJcgncQcohHdiYb803YTH9OQwHBHIY=
|
||||
github.com/emersion/go-message v0.15.0/go.mod h1:wQUEfE+38+7EW8p8aZ96ptg6bAb1iwdgej19uXASlE4=
|
||||
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b h1:uhWtEWBHgop1rqEk2klKaxPAkVDCXexai6hSuRQ7Nvs=
|
||||
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b/go.mod h1:G/dpzLu16WtQpBfQ/z3LYiYJn3ZhKSGWn83fyoyQe/k=
|
||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
|
||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
||||
github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe h1:40SWqY0zE3qCi6ZrtTf5OUdNm5lDnGnjRSq9GgmeTrg=
|
||||
github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U=
|
||||
github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594 h1:IbFBtwoTQyw0fIM5xv1HF+Y+3ZijDR839WMulgxCcUY=
|
||||
github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
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/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
|
||||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/martinlindhe/base36 v1.0.0 h1:eYsumTah144C0A8P1T/AVSUk5ZoLnhfYFM3OGQxB52A=
|
||||
github.com/martinlindhe/base36 v1.0.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8=
|
||||
github.com/martinlindhe/base36 v1.1.0 h1:cIwvvwYse/0+1CkUPYH5ZvVIYG3JrILmQEIbLuar02Y=
|
||||
github.com/martinlindhe/base36 v1.1.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8=
|
||||
github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254 h1:JYoQR67E1vv1WGoeW8DkdFs7vrIEe/5wP+qJItd5tUE=
|
||||
github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254/go.mod h1:DPucAeQGDPUzYUt+NaWw6qsF5SFapWWToxEiVDh2aV0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@@ -37,6 +70,20 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 h1:y6ce7gCWtnH+m3dCjzQ1PCuwl28DDIc3VNnvY29DlIA=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210818153620-00dd8d7831e7 h1:/bmDWM82ZX7TawqxuI8kVjKI0TXHdSY6pHJArewwHtU=
|
||||
golang.org/x/sys v0.0.0-20210818153620-00dd8d7831e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
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.5-0.20201125200606-c27b9fd57aec/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package goff
|
||||
|
||||
import "github.com/dustinpianalto/disgoman"
|
||||
|
||||
type CommandManager struct {
|
||||
UserService UserService
|
||||
GuildService GuildService
|
||||
disgoman.CommandManager
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package goff
|
||||
|
||||
import "database/sql"
|
||||
|
||||
type Guild struct {
|
||||
ID string
|
||||
WelcomeMessage string
|
||||
GoodbyeMessage string
|
||||
LoggingChannel string
|
||||
WelcomeChannel string
|
||||
PuzzleChannel string
|
||||
PuzzleRole sql.NullString
|
||||
Prefixes []string
|
||||
}
|
||||
|
||||
type GuildService interface {
|
||||
Guild(id string) (*Guild, error)
|
||||
CreateGuild(g *Guild) error
|
||||
DeleteGuild(g *Guild) error
|
||||
GuildUsers(g *Guild) ([]*User, error)
|
||||
UpdateGuild(g *Guild) error
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package utils
|
||||
package discord_utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -32,7 +32,7 @@ func ParseDateString(inTime time.Time) string {
|
||||
} else {
|
||||
dateString = "Now"
|
||||
}
|
||||
stamp := inTime.Format("2006-01-02 15:04:05")
|
||||
stamp := inTime.Format("2006-01-02 15:04:05.000")
|
||||
return fmt.Sprintf("%v\n%v", dateString, stamp)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package utils
|
||||
package discord_utils
|
||||
|
||||
import "time"
|
||||
|
||||
@@ -19,7 +19,10 @@ func ParseSnowflake(s int64) Snowflake {
|
||||
PROCESS_ID_MASK = 0x1F000
|
||||
INCREMENT_MASK = 0xFFF
|
||||
)
|
||||
creationTime := time.Unix(((s>>TIME_BITS_LOC)+DISCORD_EPOCH)/1000.0, 0)
|
||||
t := (s >> TIME_BITS_LOC) + DISCORD_EPOCH
|
||||
sec := t / 1000.0
|
||||
nano := t % 1000.0 * 1000000.0
|
||||
creationTime := time.Unix(sec, nano)
|
||||
workerID := (s & WORKER_ID_MASK) >> WORKER_ID_LOC
|
||||
processID := (s & PROCESS_ID_MASK) >> PROCESS_ID_LOC
|
||||
increment := s & INCREMENT_MASK
|
||||
@@ -0,0 +1,134 @@
|
||||
package fun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
"github.com/dustinpianalto/rpnparse"
|
||||
)
|
||||
|
||||
var InterleaveCommand = &disgoman.Command{
|
||||
Name: "encode",
|
||||
Aliases: []string{"e"},
|
||||
Description: "Encode 2 numbers",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: interleaveFunc,
|
||||
}
|
||||
|
||||
func interleaveFunc(ctx disgoman.Context, args []string) {
|
||||
if len(args) == 2 {
|
||||
x, err := strconv.ParseInt(args[0], 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
y, err := strconv.ParseInt(args[1], 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var z = int64(0)
|
||||
for i := 0; i < 64; i++ {
|
||||
x_masked_i := x & (1 << i)
|
||||
y_masked_i := y & (1 << i)
|
||||
|
||||
z |= x_masked_i << i
|
||||
z |= y_masked_i << (i + 1)
|
||||
}
|
||||
ctx.Send(fmt.Sprintf("%v", z))
|
||||
}
|
||||
}
|
||||
|
||||
var DeinterleaveCommand = &disgoman.Command{
|
||||
Name: "decode",
|
||||
Aliases: []string{"d"},
|
||||
Description: "Decode 1 number into 2",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: deinterleaveFunc,
|
||||
}
|
||||
|
||||
func deinterleaveFunc(ctx disgoman.Context, args []string) {
|
||||
if len(args) == 1 {
|
||||
z, err := strconv.ParseInt(args[0], 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var x = int64(0)
|
||||
var y = int64(0)
|
||||
i := 0
|
||||
for z > 0 {
|
||||
x |= (z & 1) << i
|
||||
z >>= 1
|
||||
y |= (z & 1) << i
|
||||
z >>= 1
|
||||
i++
|
||||
}
|
||||
ctx.Send(fmt.Sprintf("(%v, %v)", x, y))
|
||||
}
|
||||
}
|
||||
|
||||
var GenerateRPNCommand = &disgoman.Command{
|
||||
Name: "RPN",
|
||||
Aliases: []string{"rpn"},
|
||||
Description: "Convert infix to rpn",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: generateRPNFunc,
|
||||
}
|
||||
|
||||
func generateRPNFunc(ctx disgoman.Context, args []string) {
|
||||
rpn, err := rpnparse.GenerateRPN(args)
|
||||
if err != nil {
|
||||
ctx.Send(err.Error())
|
||||
return
|
||||
}
|
||||
ctx.Send(rpn)
|
||||
}
|
||||
|
||||
var ParseRPNCommand = &disgoman.Command{
|
||||
Name: "ParseRPN",
|
||||
Aliases: []string{"PRPN", "prpn"},
|
||||
Description: "Parse RPN string and return the result",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: parseRPNFunc,
|
||||
}
|
||||
|
||||
func parseRPNFunc(ctx disgoman.Context, args []string) {
|
||||
res, err := rpnparse.ParseRPN(args)
|
||||
if err != nil {
|
||||
ctx.Send(err.Error())
|
||||
return
|
||||
}
|
||||
ctx.Send(fmt.Sprintf("The result is: %v", res))
|
||||
}
|
||||
|
||||
var SolveCommand = &disgoman.Command{
|
||||
Name: "solve",
|
||||
Aliases: []string{"math", "infix"},
|
||||
Description: "Solve infix equation and return the result",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: solveFunc,
|
||||
}
|
||||
|
||||
func solveFunc(ctx disgoman.Context, args []string) {
|
||||
rpn, err := rpnparse.GenerateRPN(args)
|
||||
if err != nil {
|
||||
ctx.Send(err.Error())
|
||||
return
|
||||
}
|
||||
res, err := rpnparse.ParseRPN(strings.Split(rpn, " "))
|
||||
if err != nil {
|
||||
ctx.Send(err.Error())
|
||||
return
|
||||
}
|
||||
ctx.Send(fmt.Sprintf("The result is: %v", res))
|
||||
}
|
||||
@@ -0,0 +1,476 @@
|
||||
package guild_management
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/postgres"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/services"
|
||||
)
|
||||
|
||||
// Guild management commands
|
||||
var SetLoggingChannelCommand = &disgoman.Command{
|
||||
Name: "set-logging-channel",
|
||||
Aliases: []string{"slc"},
|
||||
Description: "Set the channel logging messages will be sent to.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: setLoggingChannelFunc,
|
||||
}
|
||||
|
||||
func setLoggingChannelFunc(ctx disgoman.Context, args []string) {
|
||||
var idString string
|
||||
if len(args) > 0 {
|
||||
idString = args[0]
|
||||
if strings.HasPrefix(idString, "<#") && strings.HasSuffix(idString, ">") {
|
||||
idString = idString[2 : len(idString)-1]
|
||||
}
|
||||
} else {
|
||||
idString = ""
|
||||
}
|
||||
guild, err := services.GuildService.Guild(ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if idString == "" {
|
||||
guild.LoggingChannel = idString
|
||||
err = services.GuildService.UpdateGuild(guild)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Logging Channel Updated.")
|
||||
return
|
||||
}
|
||||
channel, err := ctx.Session.State.Channel(idString)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that channel.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if channel.GuildID != ctx.Guild.ID {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "The channel passed is not in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
guild.LoggingChannel = channel.ID
|
||||
err = services.GuildService.UpdateGuild(guild)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Logging Channel Updated.")
|
||||
}
|
||||
|
||||
var GetLoggingChannelCommand = &disgoman.Command{
|
||||
Name: "get-logging-channel",
|
||||
Aliases: []string{"glc"},
|
||||
Description: "Gets the channel logging messages will be sent to.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: getLoggingChannelFunc,
|
||||
}
|
||||
|
||||
func getLoggingChannelFunc(ctx disgoman.Context, _ []string) {
|
||||
var channelID string
|
||||
row := postgres.DB.QueryRow("SELECT logging_channel FROM guilds where id=$1", ctx.Guild.ID)
|
||||
err := row.Scan(&channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error getting data from the database.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if channelID == "" {
|
||||
_, _ = ctx.Send("The logging channel is not set.")
|
||||
return
|
||||
}
|
||||
channel, err := ctx.Session.State.GuildChannel(ctx.Guild.ID, channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "I got the channel ID but it does not appear to be a valid channel in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("The logging channel is currently %s", channel.Mention()))
|
||||
return
|
||||
}
|
||||
|
||||
var SetWelcomeChannelCommand = &disgoman.Command{
|
||||
Name: "set-welcome-channel",
|
||||
Aliases: []string{"swc"},
|
||||
Description: "Set the channel welcome messages will be sent to.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: setWelcomeChannelFunc,
|
||||
}
|
||||
|
||||
func setWelcomeChannelFunc(ctx disgoman.Context, args []string) {
|
||||
var idString string
|
||||
if len(args) > 0 {
|
||||
idString = args[0]
|
||||
if strings.HasPrefix(idString, "<#") && strings.HasSuffix(idString, ">") {
|
||||
idString = idString[2 : len(idString)-1]
|
||||
}
|
||||
} else {
|
||||
idString = ""
|
||||
}
|
||||
fmt.Println(idString)
|
||||
if idString == "" {
|
||||
_, err := postgres.DB.Exec("UPDATE guilds SET welcome_channel='' WHERE id=$1;", ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Welcomer Disabled.")
|
||||
return
|
||||
}
|
||||
channel, err := ctx.Session.State.Channel(idString)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that channel.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if channel.GuildID != ctx.Guild.ID {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "The channel passed is not in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, err = postgres.DB.Exec("UPDATE guilds SET welcome_channel=$1 WHERE id=$2;", idString, ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Welcome Channel Updated.")
|
||||
return
|
||||
}
|
||||
|
||||
var GetWelcomeChannelCommand = &disgoman.Command{
|
||||
Name: "get-welcome-channel",
|
||||
Aliases: []string{"gwc"},
|
||||
Description: "Gets the channel welcome messages will be sent to.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: getWelcomeChannelFunc,
|
||||
}
|
||||
|
||||
func getWelcomeChannelFunc(ctx disgoman.Context, _ []string) {
|
||||
var channelID string
|
||||
row := postgres.DB.QueryRow("SELECT welcome_channel FROM guilds where id=$1", ctx.Guild.ID)
|
||||
err := row.Scan(&channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error getting data from the database.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if channelID == "" {
|
||||
_, _ = ctx.Send("The welcomer is disabled.")
|
||||
return
|
||||
}
|
||||
channel, err := ctx.Session.State.GuildChannel(ctx.Guild.ID, channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "I got the channel ID but it does not appear to be a valid channel in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("The welcome channel is currently %s", channel.Mention()))
|
||||
}
|
||||
|
||||
var AddGuildCommand = &disgoman.Command{
|
||||
Name: "addGuild",
|
||||
Aliases: nil,
|
||||
Description: "Adds the current guild to the database",
|
||||
OwnerOnly: true,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: addGuildCommandFunc,
|
||||
}
|
||||
|
||||
func addGuildCommandFunc(ctx disgoman.Context, args []string) {
|
||||
var guildID string
|
||||
row := postgres.DB.QueryRow("SELECT id FROM guilds where id=$1", ctx.Guild.ID)
|
||||
err := row.Scan(&guildID)
|
||||
if err == nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "This guild is already in my database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
_, err = postgres.DB.Query("INSERT INTO guilds (id) VALUES ($1)", ctx.Guild.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "There was a problem inserting this guild into the database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("This guild has been added.")
|
||||
|
||||
}
|
||||
|
||||
var SetPuzzleChannelCommand = &disgoman.Command{
|
||||
Name: "set-puzzle-channel",
|
||||
Aliases: []string{"spc"},
|
||||
Description: "Set the channel puzzle messages will be sent to.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: setPuzzleChannelFunc,
|
||||
}
|
||||
|
||||
func setPuzzleChannelFunc(ctx disgoman.Context, args []string) {
|
||||
var idString string
|
||||
if len(args) > 0 {
|
||||
idString = args[0]
|
||||
if strings.HasPrefix(idString, "<#") && strings.HasSuffix(idString, ">") {
|
||||
idString = idString[2 : len(idString)-1]
|
||||
}
|
||||
} else {
|
||||
idString = ""
|
||||
}
|
||||
fmt.Println(idString)
|
||||
if idString == "" {
|
||||
_, err := postgres.DB.Exec("UPDATE guilds SET puzzle_channel='' WHERE id=$1;", ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Puzzle Channel Updated.")
|
||||
return
|
||||
}
|
||||
channel, err := ctx.Session.State.Channel(idString)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that channel.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if channel.GuildID != ctx.Guild.ID {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "The channel passed is not in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, err = postgres.DB.Exec("UPDATE guilds SET puzzle_channel=$1 WHERE id=$2;", idString, ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Puzzle Channel Updated.")
|
||||
}
|
||||
|
||||
var GetPuzzleChannelCommand = &disgoman.Command{
|
||||
Name: "get-puzzle-channel",
|
||||
Aliases: []string{"gpc"},
|
||||
Description: "Gets the channel puzzle messages will be sent to.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: getPuzzleChannelFunc,
|
||||
}
|
||||
|
||||
func getPuzzleChannelFunc(ctx disgoman.Context, _ []string) {
|
||||
var channelID string
|
||||
row := postgres.DB.QueryRow("SELECT puzzle_channel FROM guilds where id=$1", ctx.Guild.ID)
|
||||
err := row.Scan(&channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error getting data from the database.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if channelID == "" {
|
||||
_, _ = ctx.Send("The puzzle channel is not set.")
|
||||
return
|
||||
}
|
||||
channel, err := ctx.Session.State.GuildChannel(ctx.Guild.ID, channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "I got the channel ID but it does not appear to be a valid channel in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("The puzzle channel is currently %s", channel.Mention()))
|
||||
return
|
||||
}
|
||||
|
||||
var SetPuzzleRoleCommand = &disgoman.Command{
|
||||
Name: "set-puzzle-role",
|
||||
Aliases: []string{"spr"},
|
||||
Description: "Set the role to be pinged when there is a new puzzle",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: setPuzzleRoleFunc,
|
||||
}
|
||||
|
||||
func setPuzzleRoleFunc(ctx disgoman.Context, args []string) {
|
||||
var idString string
|
||||
if len(args) > 0 {
|
||||
idString = args[0]
|
||||
if strings.HasPrefix(idString, "<@&") && strings.HasSuffix(idString, ">") {
|
||||
idString = idString[3 : len(idString)-1]
|
||||
}
|
||||
} else {
|
||||
idString = ""
|
||||
}
|
||||
fmt.Println(idString)
|
||||
if idString == "" {
|
||||
_, err := postgres.DB.Exec("UPDATE guilds SET puzzle_role=NULL WHERE id=$1;", ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Puzzle Role Cleared.")
|
||||
return
|
||||
}
|
||||
role, err := ctx.Session.State.Role(ctx.Guild.ID, idString)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that Role.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, err = postgres.DB.Exec("INSERT INTO roles (id, guild_id) VALUES ($1, $2) ON CONFLICT DO NOTHING", role.ID, ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, err = postgres.DB.Exec("UPDATE guilds SET puzzle_role=$1 WHERE id=$2;", role.ID, ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send("Puzzle Role Updated.")
|
||||
}
|
||||
|
||||
var GetPuzzleRoleCommand = &disgoman.Command{
|
||||
Name: "get-puzzle-role",
|
||||
Aliases: []string{"gpr"},
|
||||
Description: "Get the role that will be pinged when there is a new puzzle",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: getPuzzleRoleFunc,
|
||||
}
|
||||
|
||||
func getPuzzleRoleFunc(ctx disgoman.Context, _ []string) {
|
||||
var roleID sql.NullString
|
||||
row := postgres.DB.QueryRow("SELECT puzzle_role FROM guilds where id=$1", ctx.Guild.ID)
|
||||
err := row.Scan(&roleID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error getting data from the database.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if !roleID.Valid {
|
||||
_, _ = ctx.Send("The puzzle role is not set.")
|
||||
return
|
||||
}
|
||||
role, err := ctx.Session.State.Role(ctx.Guild.ID, roleID.String)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "I got the role ID but it does not appear to be a valid role in this guild.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("The puzzle role is currently %s", role.Mention()))
|
||||
return
|
||||
}
|
||||
+7
-4
@@ -1,11 +1,11 @@
|
||||
package events
|
||||
package guild_management
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"djpianalto.com/goff/djpianalto.com/goff/utils"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/postgres"
|
||||
)
|
||||
|
||||
func OnMessageUpdate(session *discordgo.Session, m *discordgo.MessageUpdate) {
|
||||
@@ -19,7 +19,7 @@ func OnMessageUpdate(session *discordgo.Session, m *discordgo.MessageUpdate) {
|
||||
return
|
||||
}
|
||||
var channelID string
|
||||
row := utils.Database.QueryRow("SELECT logging_channel FROM guilds where id=$1", msg.GuildID)
|
||||
row := postgres.DB.QueryRow("SELECT logging_channel FROM guilds where id=$1", msg.GuildID)
|
||||
err := row.Scan(&channelID)
|
||||
if err != nil || channelID == "" {
|
||||
return
|
||||
@@ -29,6 +29,9 @@ func OnMessageUpdate(session *discordgo.Session, m *discordgo.MessageUpdate) {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
if m.Content == "" {
|
||||
return
|
||||
}
|
||||
embed := &discordgo.MessageEmbed{
|
||||
Title: fmt.Sprintf("Message Edited: %v", msg.ID),
|
||||
Description: fmt.Sprintf("**Before:** %v\n**After:** %v\nIn Channel: %v", msg.Content, m.Content, channel.Mention()),
|
||||
@@ -56,7 +59,7 @@ func OnMessageDelete(session *discordgo.Session, m *discordgo.MessageDelete) {
|
||||
return
|
||||
}
|
||||
var channelID string
|
||||
row := utils.Database.QueryRow("SELECT logging_channel FROM guilds where id=$1", msg.GuildID)
|
||||
row := postgres.DB.QueryRow("SELECT logging_channel FROM guilds where id=$1", msg.GuildID)
|
||||
err := row.Scan(&channelID)
|
||||
if err != nil || channelID == "" {
|
||||
return
|
||||
@@ -0,0 +1,59 @@
|
||||
package exts
|
||||
|
||||
import (
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/fun"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/guild_management"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/roles"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/tags"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/tasks"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/user_management"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/utils"
|
||||
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/p_interpreter"
|
||||
)
|
||||
|
||||
func AddCommandHandlers(h *disgoman.CommandManager) {
|
||||
// Arguments:
|
||||
// name - command name - string
|
||||
// desc - command description - string
|
||||
// owneronly - only allow owners to run - bool
|
||||
// hidden - hide command from non-owners - bool
|
||||
// perms - permissisions required - anpan.Permission (int)
|
||||
// type - command type, sets where the command is available
|
||||
// run - function to run - func(anpan.Context, []string) / CommandRunFunc
|
||||
_ = h.AddCommand(utils.UserCommand)
|
||||
_ = h.AddCommand(utils.SayCommand)
|
||||
_ = h.AddCommand(utils.GitCommand)
|
||||
_ = h.AddCommand(utils.InviteCommand)
|
||||
_ = h.AddCommand(utils.PingCommand)
|
||||
_ = h.AddCommand(utils.SnowflakeCommand)
|
||||
_ = h.AddCommand(tasks.AddReminderCommand)
|
||||
_ = h.AddCommand(tags.AddTagCommand)
|
||||
_ = h.AddCommand(tags.TagCommand)
|
||||
_ = h.AddCommand(roles.MakeRoleSelfAssignableCommand)
|
||||
_ = h.AddCommand(roles.RemoveSelfAssignableCommand)
|
||||
_ = h.AddCommand(roles.SelfAssignRoleCommand)
|
||||
_ = h.AddCommand(roles.UnAssignRoleCommand)
|
||||
_ = h.AddCommand(roles.MakeAutoRoleCommand)
|
||||
_ = h.AddCommand(roles.RemoveAutoRoleCommand)
|
||||
_ = h.AddCommand(p_interpreter.PCommand)
|
||||
_ = h.AddCommand(fun.InterleaveCommand)
|
||||
_ = h.AddCommand(fun.DeinterleaveCommand)
|
||||
_ = h.AddCommand(fun.GenerateRPNCommand)
|
||||
_ = h.AddCommand(fun.ParseRPNCommand)
|
||||
_ = h.AddCommand(fun.SolveCommand)
|
||||
_ = h.AddCommand(user_management.KickUserCommand)
|
||||
_ = h.AddCommand(user_management.BanUserCommand)
|
||||
_ = h.AddCommand(user_management.UnbanUserCommand)
|
||||
_ = h.AddCommand(guild_management.SetLoggingChannelCommand)
|
||||
_ = h.AddCommand(guild_management.GetLoggingChannelCommand)
|
||||
_ = h.AddCommand(guild_management.SetWelcomeChannelCommand)
|
||||
_ = h.AddCommand(guild_management.GetWelcomeChannelCommand)
|
||||
_ = h.AddCommand(guild_management.AddGuildCommand)
|
||||
_ = h.AddCommand(guild_management.SetPuzzleChannelCommand)
|
||||
_ = h.AddCommand(guild_management.GetPuzzleChannelCommand)
|
||||
_ = h.AddCommand(guild_management.SetPuzzleRoleCommand)
|
||||
_ = h.AddCommand(guild_management.GetPuzzleRoleCommand)
|
||||
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package utils
|
||||
package logging
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/postgres"
|
||||
)
|
||||
|
||||
var LoggingChannel = make(chan *LogEvent, 10)
|
||||
@@ -19,7 +21,7 @@ type LogEvent struct {
|
||||
func LoggingHandler(lc chan *LogEvent) {
|
||||
for event := range lc {
|
||||
var channelID string
|
||||
row := Database.QueryRow("SELECT logging_channel FROM guilds where id=$1", event.GuildID)
|
||||
row := postgres.DB.QueryRow("SELECT logging_channel FROM guilds where id=$1", event.GuildID)
|
||||
err := row.Scan(&channelID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
+16
-5
@@ -1,13 +1,24 @@
|
||||
package exts
|
||||
package p_interpreter
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
"strings"
|
||||
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
)
|
||||
|
||||
func pCommand(ctx disgoman.Context, args []string) {
|
||||
var PCommand = &disgoman.Command{
|
||||
Name: "P",
|
||||
Aliases: nil,
|
||||
Description: "Interpret a P\" program and return the results",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: pCommandFunc,
|
||||
}
|
||||
|
||||
func pCommandFunc(ctx disgoman.Context, args []string) {
|
||||
input := strings.Join(args, "")
|
||||
const LENGTH = 1999
|
||||
var mem [LENGTH]byte
|
||||
@@ -57,7 +68,7 @@ func pCommand(ctx disgoman.Context, args []string) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: fmt.Sprintf("Invalid Character: %v", input[i]),
|
||||
Error: errors.New("invalid character"),
|
||||
@@ -73,7 +84,7 @@ func pCommand(ctx disgoman.Context, args []string) {
|
||||
}
|
||||
_, err := ctx.Send(string(out))
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Couldn't send results",
|
||||
Error: err,
|
||||
@@ -0,0 +1,389 @@
|
||||
package roles
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/postgres"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/services"
|
||||
)
|
||||
|
||||
var MakeRoleSelfAssignableCommand = &disgoman.Command{
|
||||
Name: "make-role-self-assignable",
|
||||
Aliases: []string{"makesar"},
|
||||
Description: "Makes the passed in role self assignable by anyone",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: makeRoleSelfAssignableCommandFunc,
|
||||
}
|
||||
|
||||
func makeRoleSelfAssignableCommandFunc(ctx disgoman.Context, args []string) {
|
||||
var roleString string
|
||||
var roleID string
|
||||
if len(args) > 0 {
|
||||
roleString = strings.Join(args, " ")
|
||||
if strings.HasPrefix(roleString, "<@&") && strings.HasSuffix(roleString, ">") {
|
||||
roleID = roleString[3 : len(roleString)-1]
|
||||
} else if _, err := strconv.Atoi(roleString); err == nil {
|
||||
roleID = roleString
|
||||
} else {
|
||||
for _, role := range ctx.Guild.Roles {
|
||||
if roleString == role.Name {
|
||||
roleID = role.ID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(roleID)
|
||||
var role *discordgo.Role
|
||||
var err error
|
||||
if role, err = ctx.Session.State.Role(ctx.Guild.ID, roleID); err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that Role.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, err = postgres.DB.Exec("INSERT INTO roles (id, guild_id, self_assignable) VALUES ($1, $2, true) ON CONFLICT (id) DO UPDATE SET self_assignable=true", role.ID, ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("%s is now self assignable", role.Name))
|
||||
}
|
||||
|
||||
var RemoveSelfAssignableCommand = &disgoman.Command{
|
||||
Name: "remove-self-assignable-role",
|
||||
Aliases: []string{"removesar"},
|
||||
Description: "Makes a role that was previously self assignable not so",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: removeSelfAssignableRoleCommandFunc,
|
||||
}
|
||||
|
||||
func removeSelfAssignableRoleCommandFunc(ctx disgoman.Context, args []string) {
|
||||
var roleString string
|
||||
var roleID string
|
||||
if len(args) > 0 {
|
||||
roleString = strings.Join(args, " ")
|
||||
if strings.HasPrefix(roleString, "<@&") && strings.HasSuffix(roleString, ">") {
|
||||
roleID = roleString[3 : len(roleString)-1]
|
||||
} else if _, err := strconv.Atoi(roleString); err == nil {
|
||||
roleID = roleString
|
||||
} else {
|
||||
for _, role := range ctx.Guild.Roles {
|
||||
if roleString == role.Name {
|
||||
roleID = role.ID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(roleID)
|
||||
var err error
|
||||
var role *discordgo.Role
|
||||
if role, err = ctx.Session.State.Role(ctx.Guild.ID, roleID); err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that Role.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, err = postgres.DB.Exec("INSERT INTO roles (id, guild_id, self_assignable) VALUES ($1, $2, false) ON CONFLICT (id) DO UPDATE SET self_assignable=false", role.ID, ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("%s's self assignability has been removed.", role.Name))
|
||||
}
|
||||
|
||||
var SelfAssignRoleCommand = &disgoman.Command{
|
||||
Name: "giverole",
|
||||
Aliases: []string{"iwant", "givetome"},
|
||||
Description: "Assigns a person the passed in role if it is self assignable",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: selfAssignRoleCommandFunc,
|
||||
}
|
||||
|
||||
func selfAssignRoleCommandFunc(ctx disgoman.Context, args []string) {
|
||||
var roleString string
|
||||
var roleID string
|
||||
if len(args) > 0 {
|
||||
roleString = strings.Join(args, " ")
|
||||
if strings.HasPrefix(roleString, "<@&") && strings.HasSuffix(roleString, ">") {
|
||||
roleID = roleString[3 : len(roleString)-1]
|
||||
} else if _, err := strconv.Atoi(roleString); err == nil {
|
||||
roleID = roleString
|
||||
} else {
|
||||
for _, role := range ctx.Guild.Roles {
|
||||
if roleString == role.Name {
|
||||
roleID = role.ID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(roleID)
|
||||
var role *discordgo.Role
|
||||
var err error
|
||||
if role, err = ctx.Session.State.Role(ctx.Guild.ID, roleID); err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that Role.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if memberHasRole(ctx.Member, role.ID) {
|
||||
_, _ = ctx.Send(fmt.Sprintf("You already have the %s role silly...", role.Name))
|
||||
return
|
||||
}
|
||||
var selfAssignable bool
|
||||
err = postgres.DB.QueryRow("SELECT self_assignable FROM roles where id=$1", role.ID).Scan(&selfAssignable)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if !selfAssignable {
|
||||
_, _ = ctx.Send(fmt.Sprintf("You aren't allowed to assign yourself the %s role", role.Name))
|
||||
return
|
||||
}
|
||||
err = ctx.Session.GuildMemberRoleAdd(ctx.Guild.ID, ctx.User.ID, role.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "There was a problem adding that role to you.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("Congratulations! The %s role has been added to your... Ummm... Thing.", role.Name))
|
||||
}
|
||||
|
||||
var UnAssignRoleCommand = &disgoman.Command{
|
||||
Name: "removerole",
|
||||
Aliases: []string{"idon'twant"},
|
||||
Description: "Removes a role from a person if the role is self assignable",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: unAssignRoleCommandFunc,
|
||||
}
|
||||
|
||||
func unAssignRoleCommandFunc(ctx disgoman.Context, args []string) {
|
||||
var roleString string
|
||||
var roleID string
|
||||
if len(args) > 0 {
|
||||
roleString = strings.Join(args, " ")
|
||||
if strings.HasPrefix(roleString, "<@&") && strings.HasSuffix(roleString, ">") {
|
||||
roleID = roleString[3 : len(roleString)-1]
|
||||
} else if _, err := strconv.Atoi(roleString); err == nil {
|
||||
roleID = roleString
|
||||
} else {
|
||||
for _, role := range ctx.Guild.Roles {
|
||||
if roleString == role.Name {
|
||||
roleID = role.ID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(roleID)
|
||||
var role *discordgo.Role
|
||||
var err error
|
||||
if role, err = ctx.Session.State.Role(ctx.Guild.ID, roleID); err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that Role.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if !memberHasRole(ctx.Member, role.ID) {
|
||||
_, _ = ctx.Send(fmt.Sprintf("I can't remove the %s role from you because you don't have it...", role.Name))
|
||||
return
|
||||
}
|
||||
var selfAssignable bool
|
||||
err = postgres.DB.QueryRow("SELECT self_assignable FROM roles where id=$1", role.ID).Scan(&selfAssignable)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error Updating Database",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if !selfAssignable {
|
||||
_, _ = ctx.Send(fmt.Sprintf("You aren't allowed to remove the %s role from yourself", role.Name))
|
||||
return
|
||||
}
|
||||
err = ctx.Session.GuildMemberRoleRemove(ctx.Guild.ID, ctx.User.ID, role.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "There was a problem removing that role from you.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("Sad to see you go... but the %s role has been removed.", role.Name))
|
||||
}
|
||||
|
||||
func memberHasRole(m *discordgo.Member, id string) bool {
|
||||
for _, r := range m.Roles {
|
||||
if r == id {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var MakeAutoRoleCommand = &disgoman.Command{
|
||||
Name: "make-auto-role",
|
||||
Aliases: []string{"makear"},
|
||||
Description: "Marks the passed in role to auto add to new members.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: makeAutoRoleCommandFunc,
|
||||
}
|
||||
|
||||
func makeAutoRoleCommandFunc(ctx disgoman.Context, args []string) {
|
||||
var roleString string
|
||||
var roleID string
|
||||
if len(args) > 0 {
|
||||
roleString = strings.Join(args, " ")
|
||||
if strings.HasPrefix(roleString, "<@&") && strings.HasSuffix(roleString, ">") {
|
||||
roleID = roleString[3 : len(roleString)-1]
|
||||
} else if _, err := strconv.Atoi(roleString); err == nil {
|
||||
roleID = roleString
|
||||
} else {
|
||||
for _, role := range ctx.Guild.Roles {
|
||||
if roleString == role.Name {
|
||||
roleID = role.ID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(roleID)
|
||||
var r *discordgo.Role
|
||||
var err error
|
||||
if r, err = ctx.Session.State.Role(ctx.Guild.ID, roleID); err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that Role.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
role, err := services.RoleService.Role(r.ID)
|
||||
if err != nil {
|
||||
role = &goff.Role{
|
||||
ID: r.ID,
|
||||
IsModerator: false,
|
||||
IsAdmin: false,
|
||||
SelfAssignable: false,
|
||||
AutoRole: true,
|
||||
Guild: ctx.Guild.ID,
|
||||
}
|
||||
role, err = services.RoleService.AddRole(role)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error making an Auto Role",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
err = services.RoleService.MakeAutoRole(role)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error making an Auto Role",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("%s will be added to all new memebers.", r.Name))
|
||||
}
|
||||
|
||||
var RemoveAutoRoleCommand = &disgoman.Command{
|
||||
Name: "remove-auto-role",
|
||||
Aliases: []string{"removear"},
|
||||
Description: "Remove role from those added to new members.",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionManageServer,
|
||||
Invoke: removeAutoRoleCommandFunc,
|
||||
}
|
||||
|
||||
func removeAutoRoleCommandFunc(ctx disgoman.Context, args []string) {
|
||||
var roleString string
|
||||
var roleID string
|
||||
if len(args) > 0 {
|
||||
roleString = strings.Join(args, " ")
|
||||
if strings.HasPrefix(roleString, "<@&") && strings.HasSuffix(roleString, ">") {
|
||||
roleID = roleString[3 : len(roleString)-1]
|
||||
} else if _, err := strconv.Atoi(roleString); err == nil {
|
||||
roleID = roleString
|
||||
} else {
|
||||
for _, role := range ctx.Guild.Roles {
|
||||
if roleString == role.Name {
|
||||
roleID = role.ID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(roleID)
|
||||
var r *discordgo.Role
|
||||
var err error
|
||||
if r, err = ctx.Session.State.Role(ctx.Guild.ID, roleID); err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Can't find that Role.",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
role, err := services.RoleService.Role(r.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Role was not configured as an Auto Role",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
} else {
|
||||
err = services.RoleService.RemoveAutoRole(role)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error removing Auto Role",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
_, _ = ctx.Send(fmt.Sprintf("%s will no longer be added to all new memebers.", r.Name))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package exts
|
||||
package tags
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -6,63 +6,65 @@ import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"djpianalto.com/goff/djpianalto.com/goff/utils"
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
"github.com/kballard/go-shellquote"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/postgres"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/services"
|
||||
)
|
||||
|
||||
func addTagCommand(ctx disgoman.Context, input []string) {
|
||||
var AddTagCommand = &disgoman.Command{
|
||||
Name: "addtag",
|
||||
Aliases: nil,
|
||||
Description: "Add a tag",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
SanitizeEveryone: true,
|
||||
Invoke: addTagCommandFunc,
|
||||
}
|
||||
|
||||
func addTagCommandFunc(ctx disgoman.Context, input []string) {
|
||||
if len(input) >= 1 {
|
||||
args, err := shellquote.Split(strings.Join(input, " "))
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "Unterminated") {
|
||||
args = strings.SplitN(strings.Join(args, " "), " ", 2)
|
||||
} else {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
queryString := `SELECT tags.id, tags.tag, tags.content from tags
|
||||
WHERE tags.guild_id = $1
|
||||
AND tags.tag = $2;`
|
||||
row := utils.Database.QueryRow(queryString, ctx.Guild.ID, args[0])
|
||||
row := postgres.DB.QueryRow(queryString, ctx.Guild.ID, input[0])
|
||||
var dest string
|
||||
if err := row.Scan(&dest); err != nil {
|
||||
tag := args[0]
|
||||
tag := input[0]
|
||||
if tag == "" {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "That is not a valid tag name",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(args) <= 1 {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
if len(input) <= 1 {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "I got a name but no value",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
value := args[1]
|
||||
value := strings.Join(input[1:], " ")
|
||||
if value == "" {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "You have to include a content for the tag",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
queryString = `INSERT INTO tags (tag, content, creator, guild_id) VALUES ($1, $2, $3, $4);`
|
||||
_, err := utils.Database.Exec(queryString, tag, value, ctx.Message.Author.ID, ctx.Guild.ID)
|
||||
err = services.UserService.CreateUser(&goff.User{ID: ctx.User.ID}, ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.Send(err.Error())
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
log.Printf("Error creating user %s: %s", ctx.User.ID, err.Error())
|
||||
}
|
||||
queryString = `INSERT INTO tags (tag, content, creator, guild_id) VALUES ($1, $2, $3, $4);`
|
||||
_, err := postgres.DB.Exec(queryString, tag, value, ctx.Message.Author.ID, ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "",
|
||||
Error: err,
|
||||
@@ -72,7 +74,7 @@ func addTagCommand(ctx disgoman.Context, input []string) {
|
||||
ctx.Send(fmt.Sprintf("Tag %v added successfully.", tag))
|
||||
return
|
||||
} else {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "That tag already exists",
|
||||
Error: err,
|
||||
@@ -81,7 +83,7 @@ func addTagCommand(ctx disgoman.Context, input []string) {
|
||||
}
|
||||
} else {
|
||||
ctx.Send("You need to tell me what tag you want to add...")
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "You need to tell me what tag you want to add...",
|
||||
Error: errors.New("nothing to do"),
|
||||
@@ -90,14 +92,24 @@ func addTagCommand(ctx disgoman.Context, input []string) {
|
||||
}
|
||||
}
|
||||
|
||||
func tagCommand(ctx disgoman.Context, args []string) {
|
||||
var TagCommand = &disgoman.Command{
|
||||
Name: "tag",
|
||||
Aliases: nil,
|
||||
Description: "Get a tag",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: tagCommandFunc,
|
||||
}
|
||||
|
||||
func tagCommandFunc(ctx disgoman.Context, args []string) {
|
||||
if len(args) >= 1 {
|
||||
tagString := strings.Join(args, " ")
|
||||
queryString := `SELECT tags.id, tags.tag, tags.content from tags
|
||||
WHERE tags.guild_id = $1;`
|
||||
rows, err := utils.Database.Query(queryString, ctx.Guild.ID)
|
||||
rows, err := postgres.DB.Query(queryString, ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "",
|
||||
Error: err,
|
||||
@@ -111,14 +123,14 @@ func tagCommand(ctx disgoman.Context, args []string) {
|
||||
content string
|
||||
)
|
||||
if err := rows.Scan(&id, &tag, &content); err != nil {
|
||||
log.Fatal(err)
|
||||
log.Println(err)
|
||||
}
|
||||
if tagString == tag {
|
||||
ctx.Send(content)
|
||||
return
|
||||
}
|
||||
}
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: fmt.Sprintf("Tag %v not found", args[0]),
|
||||
Error: err,
|
||||
@@ -127,7 +139,7 @@ func tagCommand(ctx disgoman.Context, args []string) {
|
||||
}
|
||||
} else {
|
||||
ctx.Send("I need a tag to fetch...")
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "I need a tag to fetch...",
|
||||
Error: errors.New("nothing to do"),
|
||||
@@ -1,10 +1,12 @@
|
||||
package utils
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/postgres"
|
||||
)
|
||||
|
||||
type Task struct {
|
||||
@@ -20,7 +22,7 @@ type Task struct {
|
||||
|
||||
func processTask(task *Task, s *discordgo.Session) {
|
||||
query := "SELECT completed, processing from tasks where id = $1"
|
||||
res, err := Database.Query(query, task.ID)
|
||||
res, err := postgres.DB.Query(query, task.ID)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
@@ -38,8 +40,8 @@ func processTask(task *Task, s *discordgo.Session) {
|
||||
}
|
||||
closeQuery := "Update tasks set completed = true where id = $1"
|
||||
processQuery := "UPDATE tasks SET processing = true WHERE id = $1"
|
||||
defer Database.Exec(closeQuery, task.ID)
|
||||
_, err = Database.Exec(processQuery, task.ID)
|
||||
defer postgres.DB.Exec(closeQuery, task.ID)
|
||||
_, err = postgres.DB.Exec(processQuery, task.ID)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
@@ -85,7 +87,7 @@ func processTask(task *Task, s *discordgo.Session) {
|
||||
}
|
||||
}
|
||||
processQuery = "UPDATE tasks SET processing = false WHERE id = $1"
|
||||
_, err = Database.Exec(processQuery, task.ID)
|
||||
_, err = postgres.DB.Exec(processQuery, task.ID)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
@@ -95,9 +97,10 @@ func processTask(task *Task, s *discordgo.Session) {
|
||||
func getTasksToRun() []Task {
|
||||
query := "SELECT id, type, content, guild_id, channel_id, user_id, creation_time, trigger_time " +
|
||||
"from tasks where completed is false and processing is false and trigger_time < $1"
|
||||
res, err := Database.Query(query, time.Now())
|
||||
res, err := postgres.DB.Query(query, time.Now())
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return nil
|
||||
}
|
||||
var tasks []Task
|
||||
for res.Next() {
|
||||
@@ -1,18 +1,29 @@
|
||||
package exts
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"djpianalto.com/goff/djpianalto.com/goff/utils"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/postgres"
|
||||
"github.com/olebedev/when"
|
||||
"github.com/olebedev/when/rules/common"
|
||||
"github.com/olebedev/when/rules/en"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func addReminderCommand(ctx disgoman.Context, args []string) {
|
||||
var AddReminderCommand = &disgoman.Command{
|
||||
Name: "remind",
|
||||
Aliases: nil,
|
||||
Description: "Remind me at a later time",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: addReminderFunc,
|
||||
}
|
||||
|
||||
func addReminderFunc(ctx disgoman.Context, args []string) {
|
||||
w := when.New(nil)
|
||||
w.Add(en.All...)
|
||||
w.Add(common.All...)
|
||||
@@ -20,7 +31,7 @@ func addReminderCommand(ctx disgoman.Context, args []string) {
|
||||
text := strings.Join(args, " ")
|
||||
r, err := w.Parse(text, time.Now())
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error parsing time",
|
||||
Error: err,
|
||||
@@ -28,7 +39,7 @@ func addReminderCommand(ctx disgoman.Context, args []string) {
|
||||
return
|
||||
}
|
||||
if r == nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "You need to include a valid time",
|
||||
Error: errors.New("no time found"),
|
||||
@@ -38,9 +49,9 @@ func addReminderCommand(ctx disgoman.Context, args []string) {
|
||||
content := strings.Replace(text, r.Text+" ", "", 1)
|
||||
query := "INSERT INTO tasks (type, content, guild_id, channel_id, user_id, trigger_time) " +
|
||||
"VALUES ('Reminder', $1, $2, $3, $4, $5)"
|
||||
_, err = utils.Database.Exec(query, content, ctx.Guild.ID, ctx.Channel.ID, ctx.User.ID, r.Time)
|
||||
_, err = postgres.DB.Exec(query, content, ctx.Guild.ID, ctx.Channel.ID, ctx.User.ID, r.Time)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error adding task to database",
|
||||
Error: err,
|
||||
@@ -0,0 +1,119 @@
|
||||
package user_management
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/services"
|
||||
)
|
||||
|
||||
func OnGuildMemberAdd(s *discordgo.Session, member *discordgo.GuildMemberAdd) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Println("Recovered from panic in OnGuildMemberAdd", r)
|
||||
}
|
||||
}()
|
||||
user, err := services.UserService.User(member.User.ID)
|
||||
if err != nil {
|
||||
log.Println("Error getting user from database: ", err)
|
||||
user = &goff.User{
|
||||
ID: member.User.ID,
|
||||
Banned: false,
|
||||
Logging: true,
|
||||
IsActive: true,
|
||||
IsStaff: false,
|
||||
IsAdmin: false,
|
||||
}
|
||||
err := services.UserService.CreateUser(user, member.GuildID)
|
||||
if err != nil {
|
||||
log.Println("Error adding user to database: ", err)
|
||||
}
|
||||
}
|
||||
if !user.IsActive {
|
||||
user.IsActive = true
|
||||
err = services.UserService.UpdateUser(user)
|
||||
if err != nil {
|
||||
log.Println("Error marking user as active: ", err)
|
||||
}
|
||||
}
|
||||
err = services.UserService.AddUserToGuild(user, &goff.Guild{ID: member.GuildID})
|
||||
if err != nil {
|
||||
log.Println("Error adding user to guild: ", err)
|
||||
}
|
||||
if !member.Member.Pending {
|
||||
roles, err := services.RoleService.GetAutoRoles(member.GuildID)
|
||||
if err != nil {
|
||||
log.Println("Error getting Auto Join Roles: ", err)
|
||||
}
|
||||
log.Println(roles)
|
||||
for _, r := range roles {
|
||||
role, err := s.State.Role(member.GuildID, r.ID)
|
||||
if err != nil {
|
||||
log.Println("Error getting role: ", err)
|
||||
continue
|
||||
}
|
||||
err = s.GuildMemberRoleAdd(member.GuildID, member.User.ID, role.ID)
|
||||
if err != nil {
|
||||
log.Println("Error adding Role to member: ", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func OnGuildMemberRemove(s *discordgo.Session, member *discordgo.GuildMemberRemove) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Println("Recovered from panic in OnGuildMemberRemove: ", r)
|
||||
}
|
||||
}()
|
||||
user, err := services.UserService.User(member.User.ID)
|
||||
if err != nil {
|
||||
log.Println("Error getting user from database: ", err)
|
||||
return
|
||||
}
|
||||
err = services.UserService.RemoveUserFromGuild(user, &goff.Guild{ID: member.GuildID})
|
||||
if err != nil {
|
||||
log.Println("Error removing user from guild: ", err)
|
||||
}
|
||||
for i, g := range user.Guilds {
|
||||
if g == member.GuildID {
|
||||
user.Guilds[len(user.Guilds)-1], user.Guilds[i] = user.Guilds[i], user.Guilds[len(user.Guilds)-1]
|
||||
user.Guilds = user.Guilds[:len(user.Guilds)-1]
|
||||
}
|
||||
}
|
||||
if len(user.Guilds) == 0 {
|
||||
err = services.UserService.MarkUserInactive(user)
|
||||
if err != nil {
|
||||
log.Println("Error marking user as inactive: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func OnGuildMemberUpdate(s *discordgo.Session, member *discordgo.GuildMemberUpdate) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Println("Recovered from panic in OnGuildMemberUpdate: ", r)
|
||||
}
|
||||
}()
|
||||
if !member.Member.Pending {
|
||||
roles, err := services.RoleService.GetAutoRoles(member.GuildID)
|
||||
if err != nil {
|
||||
log.Println("Error getting Auto Join Roles: ", err)
|
||||
}
|
||||
log.Println(roles)
|
||||
for _, r := range roles {
|
||||
role, err := s.State.Role(member.GuildID, r.ID)
|
||||
if err != nil {
|
||||
log.Println("Error getting role: ", err)
|
||||
continue
|
||||
}
|
||||
err = s.GuildMemberRoleAdd(member.GuildID, member.User.ID, role.ID)
|
||||
if err != nil {
|
||||
log.Println("Error adding Role to member: ", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+40
-8
@@ -1,12 +1,14 @@
|
||||
package events
|
||||
package user_management
|
||||
|
||||
import (
|
||||
"djpianalto.com/goff/djpianalto.com/goff/utils"
|
||||
"fmt"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"log"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/discord_utils"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/postgres"
|
||||
)
|
||||
|
||||
func OnGuildMemberAddLogging(s *discordgo.Session, member *discordgo.GuildMemberAdd) {
|
||||
@@ -16,7 +18,7 @@ func OnGuildMemberAddLogging(s *discordgo.Session, member *discordgo.GuildMember
|
||||
}
|
||||
}()
|
||||
var channelID string
|
||||
row := utils.Database.QueryRow("SELECT logging_channel FROM guilds where id=$1", member.GuildID)
|
||||
row := postgres.DB.QueryRow("SELECT logging_channel FROM guilds where id=$1", member.GuildID)
|
||||
err := row.Scan(&channelID)
|
||||
if err != nil || channelID == "" {
|
||||
return
|
||||
@@ -39,11 +41,11 @@ func OnGuildMemberAddLogging(s *discordgo.Session, member *discordgo.GuildMember
|
||||
}
|
||||
|
||||
int64ID, _ := strconv.ParseInt(member.User.ID, 10, 64)
|
||||
snow := utils.ParseSnowflake(int64ID)
|
||||
snow := discord_utils.ParseSnowflake(int64ID)
|
||||
|
||||
field := &discordgo.MessageEmbedField{
|
||||
Name: "User was created:",
|
||||
Value: utils.ParseDateString(snow.CreationTime),
|
||||
Value: discord_utils.ParseDateString(snow.CreationTime),
|
||||
Inline: false,
|
||||
}
|
||||
|
||||
@@ -72,7 +74,7 @@ func OnGuildMemberRemoveLogging(s *discordgo.Session, member *discordgo.GuildMem
|
||||
}()
|
||||
timeNow := time.Now()
|
||||
var channelID string
|
||||
row := utils.Database.QueryRow("SELECT logging_channel FROM guilds where id=$1", member.GuildID)
|
||||
row := postgres.DB.QueryRow("SELECT logging_channel FROM guilds where id=$1", member.GuildID)
|
||||
err := row.Scan(&channelID)
|
||||
if err != nil || channelID == "" {
|
||||
return
|
||||
@@ -102,7 +104,7 @@ func OnGuildMemberRemoveLogging(s *discordgo.Session, member *discordgo.GuildMem
|
||||
for _, log := range al.AuditLogEntries {
|
||||
if log.TargetID == member.User.ID {
|
||||
int64ID, _ := strconv.ParseInt(log.ID, 10, 64)
|
||||
logSnow := utils.ParseSnowflake(int64ID)
|
||||
logSnow := discord_utils.ParseSnowflake(int64ID)
|
||||
if timeNow.Sub(logSnow.CreationTime).Seconds() <= 10 {
|
||||
user, err := s.User(log.UserID)
|
||||
if err == nil {
|
||||
@@ -132,3 +134,33 @@ func OnGuildMemberRemoveLogging(s *discordgo.Session, member *discordgo.GuildMem
|
||||
}
|
||||
s.ChannelMessageSendEmbed(channelID, embed)
|
||||
}
|
||||
|
||||
func AddMemberToDatabase(s *discordgo.Session, m *discordgo.GuildMemberAdd) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Println("Recovered from panic in AddMemberToDatabase", r)
|
||||
}
|
||||
}()
|
||||
queryString := `INSERT INTO users (id, banned, logging, is_active, is_staff, is_admin)
|
||||
VALUES ($1, false, false, true, false, false)`
|
||||
_, err := postgres.DB.Exec(queryString, m.User.ID)
|
||||
if err != nil {
|
||||
log.Println(fmt.Errorf("error inserting %s into database: %w", m.User.ID, err))
|
||||
return
|
||||
}
|
||||
log.Printf("New User: %s\n", m.User.ID)
|
||||
}
|
||||
|
||||
func MarkMemberInactive(s *discordgo.Session, m *discordgo.GuildMemberRemove) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Println("Recovered from panic in MarkMemberInactive")
|
||||
}
|
||||
}()
|
||||
queryString := `UPDATE users SET is_active = false WHERE id = $1`
|
||||
_, err := postgres.DB.Exec(queryString, m.User.ID)
|
||||
if err != nil {
|
||||
log.Println(fmt.Errorf("error marking %s as inactive: %w", m.User.ID, err))
|
||||
return
|
||||
}
|
||||
}
|
||||
+57
-26
@@ -1,16 +1,27 @@
|
||||
package exts
|
||||
package user_management
|
||||
|
||||
import (
|
||||
"djpianalto.com/goff/djpianalto.com/goff/utils"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/exts/logging"
|
||||
)
|
||||
|
||||
func kickUserCommand(ctx disgoman.Context, args []string) {
|
||||
var KickUserCommand = &disgoman.Command{
|
||||
Name: "kick",
|
||||
Aliases: nil,
|
||||
Description: "Kicks the given user with the given reason",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionKickMembers,
|
||||
Invoke: kickUserFunc,
|
||||
}
|
||||
|
||||
func kickUserFunc(ctx disgoman.Context, args []string) {
|
||||
var member *discordgo.Member
|
||||
var err error
|
||||
if len(ctx.Message.Mentions) > 0 {
|
||||
@@ -25,7 +36,7 @@ func kickUserCommand(ctx disgoman.Context, args []string) {
|
||||
err = errors.New("that is not a valid id")
|
||||
}
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Couldn't get that member",
|
||||
Error: err,
|
||||
@@ -34,7 +45,7 @@ func kickUserCommand(ctx disgoman.Context, args []string) {
|
||||
}
|
||||
|
||||
if higher, _ := disgoman.HasHigherRole(ctx.Session, ctx.Guild.ID, ctx.Message.Author.ID, member.User.ID); !higher {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "You must have a higher role than the person you are trying to kick",
|
||||
Error: errors.New("need higher role"),
|
||||
@@ -43,7 +54,7 @@ func kickUserCommand(ctx disgoman.Context, args []string) {
|
||||
}
|
||||
|
||||
if higher, _ := disgoman.HasHigherRole(ctx.Session, ctx.Guild.ID, ctx.Session.State.User.ID, member.User.ID); !higher {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "I don't have a high enough role to kick that person",
|
||||
Error: errors.New("need higher role"),
|
||||
@@ -61,7 +72,7 @@ func kickUserCommand(ctx disgoman.Context, args []string) {
|
||||
err = ctx.Session.GuildMemberDeleteWithReason(ctx.Guild.ID, member.User.ID, auditReason)
|
||||
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: fmt.Sprintf("Something went wrong kicking %v", member.User.Username),
|
||||
Error: err,
|
||||
@@ -69,7 +80,7 @@ func kickUserCommand(ctx disgoman.Context, args []string) {
|
||||
return
|
||||
}
|
||||
|
||||
event := &utils.LogEvent{
|
||||
event := &logging.LogEvent{
|
||||
Embed: discordgo.MessageEmbed{
|
||||
Title: "User Kicked",
|
||||
Description: fmt.Sprintf(
|
||||
@@ -84,11 +95,21 @@ func kickUserCommand(ctx disgoman.Context, args []string) {
|
||||
GuildID: ctx.Guild.ID,
|
||||
Session: ctx.Session,
|
||||
}
|
||||
utils.LoggingChannel <- event
|
||||
logging.LoggingChannel <- event
|
||||
_, _ = ctx.Send(fmt.Sprintf("User %v#%v has been kicked.", member.User.Username, member.User.Discriminator))
|
||||
}
|
||||
|
||||
func banUserCommand(ctx disgoman.Context, args []string) {
|
||||
var BanUserCommand = &disgoman.Command{
|
||||
Name: "ban",
|
||||
Aliases: []string{"ban-no-delete"},
|
||||
Description: "Bans the given user with the given reason",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionBanMembers,
|
||||
Invoke: banUserFunc,
|
||||
}
|
||||
|
||||
func banUserFunc(ctx disgoman.Context, args []string) {
|
||||
var user *discordgo.User
|
||||
var err error
|
||||
if len(ctx.Message.Mentions) > 0 {
|
||||
@@ -103,7 +124,7 @@ func banUserCommand(ctx disgoman.Context, args []string) {
|
||||
err = errors.New("that is not a valid id")
|
||||
}
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Couldn't get that user",
|
||||
Error: err,
|
||||
@@ -113,7 +134,7 @@ func banUserCommand(ctx disgoman.Context, args []string) {
|
||||
|
||||
if higher, err := disgoman.HasHigherRole(ctx.Session, ctx.Guild.ID, ctx.Message.Author.ID, user.ID); err != nil {
|
||||
if err.Error() == "can't find caller member" {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Who are you?",
|
||||
Error: err,
|
||||
@@ -121,7 +142,7 @@ func banUserCommand(ctx disgoman.Context, args []string) {
|
||||
return
|
||||
}
|
||||
} else if !higher {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "You must have a higher role than the person you are trying to ban",
|
||||
Error: errors.New("need higher role"),
|
||||
@@ -131,7 +152,7 @@ func banUserCommand(ctx disgoman.Context, args []string) {
|
||||
|
||||
if higher, err := disgoman.HasHigherRole(ctx.Session, ctx.Guild.ID, ctx.Session.State.User.ID, user.ID); err != nil {
|
||||
if err.Error() == "can't find caller member" {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Who am I?",
|
||||
Error: err,
|
||||
@@ -139,7 +160,7 @@ func banUserCommand(ctx disgoman.Context, args []string) {
|
||||
return
|
||||
}
|
||||
} else if !higher {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "I don't have a high enough role to ban that person",
|
||||
Error: errors.New("need higher role"),
|
||||
@@ -161,7 +182,7 @@ func banUserCommand(ctx disgoman.Context, args []string) {
|
||||
err = ctx.Session.GuildBanCreateWithReason(ctx.Guild.ID, user.ID, auditReason, days)
|
||||
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: fmt.Sprintf("Something went wrong banning %v", user.Username),
|
||||
Error: err,
|
||||
@@ -169,7 +190,7 @@ func banUserCommand(ctx disgoman.Context, args []string) {
|
||||
return
|
||||
}
|
||||
|
||||
event := &utils.LogEvent{
|
||||
event := &logging.LogEvent{
|
||||
Embed: discordgo.MessageEmbed{
|
||||
Title: "User Banned",
|
||||
Description: fmt.Sprintf(
|
||||
@@ -184,11 +205,21 @@ func banUserCommand(ctx disgoman.Context, args []string) {
|
||||
GuildID: ctx.Guild.ID,
|
||||
Session: ctx.Session,
|
||||
}
|
||||
utils.LoggingChannel <- event
|
||||
logging.LoggingChannel <- event
|
||||
_, _ = ctx.Send(fmt.Sprintf("User %v#%v has been banned.", user.Username, user.Discriminator))
|
||||
}
|
||||
|
||||
func unbanUserCommand(ctx disgoman.Context, args []string) {
|
||||
var UnbanUserCommand = &disgoman.Command{
|
||||
Name: "unban",
|
||||
Aliases: nil,
|
||||
Description: "Unbans the given user",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: disgoman.PermissionBanMembers,
|
||||
Invoke: unbanUserFunc,
|
||||
}
|
||||
|
||||
func unbanUserFunc(ctx disgoman.Context, args []string) {
|
||||
var user *discordgo.User
|
||||
var err error
|
||||
if len(ctx.Message.Mentions) > 0 {
|
||||
@@ -203,7 +234,7 @@ func unbanUserCommand(ctx disgoman.Context, args []string) {
|
||||
err = errors.New("that is not a valid id")
|
||||
}
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Couldn't get that user",
|
||||
Error: err,
|
||||
@@ -213,7 +244,7 @@ func unbanUserCommand(ctx disgoman.Context, args []string) {
|
||||
|
||||
bans, err := ctx.Session.GuildBans(ctx.Guild.ID)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Error processing current bans",
|
||||
Error: err,
|
||||
@@ -224,14 +255,14 @@ func unbanUserCommand(ctx disgoman.Context, args []string) {
|
||||
if ban.User.ID == user.ID {
|
||||
err = ctx.Session.GuildBanDelete(ctx.Guild.ID, user.ID)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: fmt.Sprintf("Something went wrong unbanning %v", user.Username),
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
event := &utils.LogEvent{
|
||||
event := &logging.LogEvent{
|
||||
Embed: discordgo.MessageEmbed{
|
||||
Title: "User Banned",
|
||||
Description: fmt.Sprintf(
|
||||
@@ -246,7 +277,7 @@ func unbanUserCommand(ctx disgoman.Context, args []string) {
|
||||
GuildID: ctx.Guild.ID,
|
||||
Session: ctx.Session,
|
||||
}
|
||||
utils.LoggingChannel <- event
|
||||
logging.LoggingChannel <- event
|
||||
_, _ = ctx.Send(fmt.Sprintf("User %v#%v has been unbanned.", user.Username, user.Discriminator))
|
||||
return
|
||||
}
|
||||
@@ -1,23 +1,34 @@
|
||||
package exts
|
||||
package utils
|
||||
|
||||
import (
|
||||
"djpianalto.com/goff/djpianalto.com/goff/utils"
|
||||
"fmt"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/dustinpianalto/disgoman"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/discord_utils"
|
||||
)
|
||||
|
||||
func pingCommand(ctx disgoman.Context, _ []string) {
|
||||
var PingCommand = &disgoman.Command{
|
||||
Name: "ping",
|
||||
Aliases: []string{" "},
|
||||
Description: "Check the bot's ping",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: pingCommandFunc,
|
||||
}
|
||||
|
||||
func pingCommandFunc(ctx disgoman.Context, _ []string) {
|
||||
timeBefore := time.Now()
|
||||
msg, _ := ctx.Send("Pong!")
|
||||
took := time.Now().Sub(timeBefore)
|
||||
_, err := ctx.Session.ChannelMessageEdit(ctx.Message.ChannelID, msg.ID, fmt.Sprintf("Pong!\nPing Took **%s**", took.String()))
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Ping Failed",
|
||||
Error: err,
|
||||
@@ -25,7 +36,17 @@ func pingCommand(ctx disgoman.Context, _ []string) {
|
||||
}
|
||||
}
|
||||
|
||||
func inviteCommand(ctx disgoman.Context, args []string) {
|
||||
var InviteCommand = &disgoman.Command{
|
||||
Name: "invite",
|
||||
Aliases: nil,
|
||||
Description: "Get the invite link for this bot or others",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: inviteCommandFunc,
|
||||
}
|
||||
|
||||
func inviteCommandFunc(ctx disgoman.Context, args []string) {
|
||||
var ids []string
|
||||
if len(args) == 0 {
|
||||
ids = []string{ctx.Session.State.User.ID}
|
||||
@@ -38,7 +59,7 @@ func inviteCommand(ctx disgoman.Context, args []string) {
|
||||
url := fmt.Sprintf("<https://discordapp.com/oauth2/authorize?client_id=%v&scope=bot>", id)
|
||||
_, err := ctx.Send(url)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Couldn't send the invite link.",
|
||||
Error: err,
|
||||
@@ -47,15 +68,25 @@ func inviteCommand(ctx disgoman.Context, args []string) {
|
||||
}
|
||||
}
|
||||
|
||||
func gitCommand(ctx disgoman.Context, _ []string) {
|
||||
var GitCommand = &disgoman.Command{
|
||||
Name: "git",
|
||||
Aliases: nil,
|
||||
Description: "Show my github link",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: gitCommandFunc,
|
||||
}
|
||||
|
||||
func gitCommandFunc(ctx disgoman.Context, _ []string) {
|
||||
embed := &discordgo.MessageEmbed{
|
||||
Title: "Hi there, My code is on Github",
|
||||
Title: "Hi there, my code is on Gitea",
|
||||
Color: 0,
|
||||
URL: "https://github.com/dustinpianalto/Goff",
|
||||
URL: "https://gitea.wayfinderak.com/wayfinderak/goff",
|
||||
}
|
||||
_, err := ctx.Session.ChannelMessageSendEmbed(ctx.Channel.ID, embed)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Git failed",
|
||||
Error: err,
|
||||
@@ -63,13 +94,24 @@ func gitCommand(ctx disgoman.Context, _ []string) {
|
||||
}
|
||||
}
|
||||
|
||||
func sayCommand(ctx disgoman.Context, args []string) {
|
||||
var SayCommand = &disgoman.Command{
|
||||
Name: "say",
|
||||
Aliases: nil,
|
||||
Description: "Repeat a message",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
SanitizeEveryone: true,
|
||||
Invoke: sayCommandFunc,
|
||||
}
|
||||
|
||||
func sayCommandFunc(ctx disgoman.Context, args []string) {
|
||||
resp := strings.Join(args, " ")
|
||||
resp = strings.ReplaceAll(resp, "@everyone", "@\ufff0everyone")
|
||||
resp = strings.ReplaceAll(resp, "@here", "@\ufff0here")
|
||||
_, err := ctx.Session.ChannelMessageSend(ctx.Message.ChannelID, resp)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Say Failed",
|
||||
Error: err,
|
||||
@@ -77,7 +119,17 @@ func sayCommand(ctx disgoman.Context, args []string) {
|
||||
}
|
||||
}
|
||||
|
||||
func userCommand(ctx disgoman.Context, args []string) {
|
||||
var UserCommand = &disgoman.Command{
|
||||
Name: "user",
|
||||
Aliases: nil,
|
||||
Description: "Get user info",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
Invoke: userCommandFunc,
|
||||
}
|
||||
|
||||
func userCommandFunc(ctx disgoman.Context, args []string) {
|
||||
var member *discordgo.Member
|
||||
if len(args) == 0 {
|
||||
member, _ = ctx.Session.GuildMember(ctx.Guild.ID, ctx.Message.Author.ID)
|
||||
@@ -89,7 +141,7 @@ func userCommand(ctx disgoman.Context, args []string) {
|
||||
member, err = ctx.Session.GuildMember(ctx.Guild.ID, args[0])
|
||||
}
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Couldn't get that member",
|
||||
Error: err,
|
||||
@@ -134,15 +186,15 @@ func userCommand(ctx disgoman.Context, args []string) {
|
||||
guildJoinTime, _ := member.JoinedAt.Parse()
|
||||
guildJoinedField := &discordgo.MessageEmbedField{
|
||||
Name: "Joined Guild:",
|
||||
Value: utils.ParseDateString(guildJoinTime),
|
||||
Value: discord_utils.ParseDateString(guildJoinTime),
|
||||
Inline: false,
|
||||
}
|
||||
|
||||
int64ID, _ := strconv.ParseInt(member.User.ID, 10, 64)
|
||||
s := utils.ParseSnowflake(int64ID)
|
||||
s := discord_utils.ParseSnowflake(int64ID)
|
||||
discordJoinedField := &discordgo.MessageEmbedField{
|
||||
Name: "Joined Discord:",
|
||||
Value: utils.ParseDateString(s.CreationTime),
|
||||
Value: discord_utils.ParseDateString(s.CreationTime),
|
||||
Inline: false,
|
||||
}
|
||||
|
||||
@@ -159,10 +211,39 @@ func userCommand(ctx disgoman.Context, args []string) {
|
||||
}
|
||||
_, err := ctx.Session.ChannelMessageSendEmbed(ctx.Channel.ID, embed)
|
||||
if err != nil {
|
||||
ctx.ErrorChannel <- disgoman.CommandError{
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Couldn't send the user embed",
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var SnowflakeCommand = &disgoman.Command{
|
||||
Name: "s",
|
||||
Aliases: nil,
|
||||
Description: "Return the parts of a snowflake",
|
||||
OwnerOnly: false,
|
||||
Hidden: false,
|
||||
RequiredPermissions: 0,
|
||||
SanitizeEveryone: true,
|
||||
Invoke: snowflakeCommandFunc,
|
||||
}
|
||||
|
||||
func snowflakeCommandFunc(ctx disgoman.Context, args []string) {
|
||||
int64ID, err := strconv.ParseInt(args[0], 10, 64)
|
||||
if err != nil {
|
||||
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
|
||||
Context: ctx,
|
||||
Message: "Not a valid ID",
|
||||
Error: err,
|
||||
}
|
||||
return
|
||||
}
|
||||
s := discord_utils.ParseSnowflake(int64ID)
|
||||
embed := &discordgo.MessageEmbed{
|
||||
Title: args[0],
|
||||
Description: fmt.Sprintf("Created: %s\nWorker: %d\nProcess: %d\nCounter: %d", discord_utils.ParseDateString(s.CreationTime), s.WorkerID, s.ProcessID, s.Increment),
|
||||
}
|
||||
_, _ = ctx.Session.ChannelMessageSendEmbed(ctx.Channel.ID, embed)
|
||||
}
|
||||
@@ -1,29 +1,39 @@
|
||||
package utils
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
var (
|
||||
Database *sql.DB
|
||||
DB *sql.DB
|
||||
)
|
||||
|
||||
func ConnectDatabase(dbConnString string) {
|
||||
db, err := sql.Open("postgres", dbConnString)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Can't connect to the database. %v", err))
|
||||
} else {
|
||||
fmt.Println("Database Connected.")
|
||||
}
|
||||
Database = db
|
||||
|
||||
db.SetMaxOpenConns(5)
|
||||
db.SetMaxIdleConns(2)
|
||||
db.SetConnMaxLifetime(30 * time.Minute)
|
||||
db.SetConnMaxIdleTime(5 * time.Minute)
|
||||
|
||||
if err = db.Ping(); err != nil {
|
||||
panic(fmt.Sprintf("Can't ping the database. %v", err))
|
||||
}
|
||||
|
||||
fmt.Println("Database Connected.")
|
||||
DB = db
|
||||
}
|
||||
|
||||
func InitializeDatabase() {
|
||||
_, err := Database.Query("CREATE TABLE IF NOT EXISTS users(" +
|
||||
_, err := DB.Exec("CREATE TABLE IF NOT EXISTS users(" +
|
||||
"id varchar(30) primary key," +
|
||||
"banned bool not null default false," +
|
||||
"logging bool not null default true," +
|
||||
@@ -35,7 +45,7 @@ func InitializeDatabase() {
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = Database.Query("CREATE TABLE IF NOT EXISTS guilds(" +
|
||||
_, err = DB.Exec("CREATE TABLE IF NOT EXISTS guilds(" +
|
||||
"id varchar(30) primary key," +
|
||||
"welcome_message varchar(1000) NOT NULL DEFAULT ''," +
|
||||
"goodbye_message varchar(1000) NOT NULL DEFAULT ''," +
|
||||
@@ -45,14 +55,14 @@ func InitializeDatabase() {
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = Database.Query("CREATE TABLE IF NOT EXISTS prefixes(" +
|
||||
_, err = DB.Exec("CREATE TABLE IF NOT EXISTS prefixes(" +
|
||||
"id serial primary key," +
|
||||
"prefix varchar(10) not null unique default 'Go.'" +
|
||||
")")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = Database.Query("CREATE TABLE IF NOT EXISTS tags(" +
|
||||
_, err = DB.Exec("CREATE TABLE IF NOT EXISTS tags(" +
|
||||
"id serial primary key," +
|
||||
"tag varchar(100) not null unique," +
|
||||
"content varchar(1000) not null," +
|
||||
@@ -63,21 +73,21 @@ func InitializeDatabase() {
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = Database.Query("CREATE TABLE IF NOT EXISTS x_users_guilds(" +
|
||||
_, err = DB.Exec("CREATE TABLE IF NOT EXISTS x_users_guilds(" +
|
||||
"guild_id varchar(30) not null references guilds(id)," +
|
||||
"user_id varchar(30) not null references users(id)" +
|
||||
")")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = Database.Query("CREATE TABLE IF NOT EXISTS x_guilds_prefixes(" +
|
||||
_, err = DB.Exec("CREATE TABLE IF NOT EXISTS x_guilds_prefixes(" +
|
||||
"guild_id varchar(30) not null references guilds(id)," +
|
||||
"prefix_id int not null references prefixes(id)" +
|
||||
")")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = Database.Query("CREATE TABLE IF NOT EXISTS tasks(" +
|
||||
_, err = DB.Exec("CREATE TABLE IF NOT EXISTS tasks(" +
|
||||
"id serial primary key," +
|
||||
"type varchar(10) not null," +
|
||||
"content text not null," +
|
||||
@@ -91,14 +101,14 @@ func InitializeDatabase() {
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = Database.Query(`CREATE TABLE IF NOT EXISTS postfixes(
|
||||
_, err = DB.Exec(`CREATE TABLE IF NOT EXISTS postfixes(
|
||||
id serial primary key,
|
||||
name varchar(100) not null,
|
||||
time timestamp not null default NOW())`)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
_, err = Database.Exec(`CREATE TABLE IF NOT EXISTS puzzles(
|
||||
_, err = DB.Exec(`CREATE TABLE IF NOT EXISTS puzzles(
|
||||
id serial primary key,
|
||||
text text not null,
|
||||
time timestamp not null
|
||||
@@ -106,7 +116,7 @@ func InitializeDatabase() {
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
_, err = Database.Exec(`CREATE TABLE IF NOT EXISTS x_guilds_puzzles(
|
||||
_, err = DB.Exec(`CREATE TABLE IF NOT EXISTS x_guilds_puzzles(
|
||||
id serial primary key,
|
||||
guild_id varchar(30) not null references guilds(id),
|
||||
puzzle_id int not null references puzzles(id),
|
||||
@@ -116,37 +126,37 @@ func InitializeDatabase() {
|
||||
}
|
||||
|
||||
func LoadTestData() {
|
||||
_, err := Database.Query("INSERT INTO users (id, banned, logging, steam_id, is_active, is_staff, is_admin) values " +
|
||||
_, err := DB.Exec("INSERT INTO users (id, banned, logging, steam_id, is_active, is_staff, is_admin) values " +
|
||||
"('351794468870946827', false, true, '76561198024193239', true, true, true)," +
|
||||
"('692908139506434065', false, true, '', true, false, false)," +
|
||||
"('396588996706304010', false, true, '', true, true, false)")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = Database.Query("INSERT INTO guilds (id, welcome_message, goodbye_message) VALUES " +
|
||||
_, err = DB.Exec("INSERT INTO guilds (id, welcome_message, goodbye_message) VALUES " +
|
||||
"('265828729970753537', 'Hey there is someone new here.', 'Well fine then... Just leave without saying goodbye')")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = Database.Query("INSERT INTO prefixes (prefix) VALUES ('Godev.'), ('godev.'), ('godev,')")
|
||||
_, err = DB.Exec("INSERT INTO prefixes (prefix) VALUES ('Godev.'), ('godev.'), ('godev,')")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = Database.Query("INSERT INTO x_users_guilds (guild_id, user_id) VALUES " +
|
||||
_, err = DB.Exec("INSERT INTO x_users_guilds (guild_id, user_id) VALUES " +
|
||||
"('265828729970753537', '351794468870946827')," +
|
||||
"('265828729970753537', '692908139506434065')," +
|
||||
"('265828729970753537', '396588996706304010')")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = Database.Query("INSERT INTO x_guilds_prefixes (guild_id, prefix_id) VALUES " +
|
||||
_, err = DB.Exec("INSERT INTO x_guilds_prefixes (guild_id, prefix_id) VALUES " +
|
||||
"('265828729970753537', 1)," +
|
||||
"('265828729970753537', 2)," +
|
||||
"('265828729970753537', 3)")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = Database.Query("INSERT INTO tags (tag, content, creator, guild_id) VALUES " +
|
||||
_, err = DB.Exec("INSERT INTO tags (tag, content, creator, guild_id) VALUES " +
|
||||
"('test', 'This is a test of the tag system', '351794468870946827', '265828729970753537')")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@@ -0,0 +1,127 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
|
||||
"gitea.wayfinderak.com/wayfinderak/goff"
|
||||
)
|
||||
|
||||
type GuildService struct {
|
||||
DB *sql.DB
|
||||
}
|
||||
|
||||
func (s *GuildService) Guild(id string) (*goff.Guild, error) {
|
||||
var g goff.Guild
|
||||
queryString := `SELECT id, welcome_message, goodbye_message,
|
||||
logging_channel, welcome_channel, puzzle_channel, puzzle_role
|
||||
FROM guilds
|
||||
WHERE id = $1`
|
||||
row := s.DB.QueryRow(queryString, id)
|
||||
err := row.Scan(
|
||||
&g.ID,
|
||||
&g.WelcomeMessage,
|
||||
&g.GoodbyeMessage,
|
||||
&g.LoggingChannel,
|
||||
&g.WelcomeChannel,
|
||||
&g.PuzzleChannel,
|
||||
&g.PuzzleRole,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var prefixes []string
|
||||
queryString = `SELECT p.prefix
|
||||
FROM prefixes p, x_guilds_prefixes xgp
|
||||
WHERE p.id = xgp.prefix_id AND xgp.guild_id = $1`
|
||||
rows, err := s.DB.Query(queryString, id)
|
||||
if err == nil {
|
||||
for rows.Next() {
|
||||
var prefix string
|
||||
err = rows.Scan(&prefix)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
prefixes = append(prefixes, prefix)
|
||||
}
|
||||
}
|
||||
g.Prefixes = prefixes
|
||||
return &g, nil
|
||||
}
|
||||
|
||||
func (s *GuildService) CreateGuild(g *goff.Guild) error {
|
||||
queryString := `INSERT INTO guilds (id,
|
||||
welcome_message,
|
||||
goodbye_message,
|
||||
logging_channel,
|
||||
welcome_channel,
|
||||
puzzle_channel,
|
||||
puzzle_role)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)`
|
||||
_, err := s.DB.Exec(queryString,
|
||||
g.ID,
|
||||
g.WelcomeMessage,
|
||||
g.GoodbyeMessage,
|
||||
g.LoggingChannel,
|
||||
g.WelcomeChannel,
|
||||
g.PuzzleChannel,
|
||||
g.PuzzleRole,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *GuildService) DeleteGuild(g *goff.Guild) error {
|
||||
queryString := `DELETE CASCADE FROM guilds WHERE id = $1`
|
||||
_, err := s.DB.Exec(queryString, g.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *GuildService) GuildUsers(g *goff.Guild) ([]*goff.User, error) {
|
||||
var users []*goff.User
|
||||
queryString := `SELECT u.id, u.banned, u.logging, u.steam_id, u.is_active, u.is_staff, u.is_admin
|
||||
FROM users u, x_users_guilds xug
|
||||
WHERE xug.guild_id = $1
|
||||
AND xug.user_id = u.id`
|
||||
rows, err := s.DB.Query(queryString, g.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
var user goff.User
|
||||
err := rows.Scan(&user.ID,
|
||||
&user.Banned,
|
||||
&user.Logging,
|
||||
&user.SteamID,
|
||||
&user.IsActive,
|
||||
&user.IsStaff,
|
||||
&user.IsAdmin,
|
||||
)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
users = append(users, &user)
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (s *GuildService) UpdateGuild(g *goff.Guild) error {
|
||||
queryString := `UPDATE guilds SET
|
||||
welcome_message = $1,
|
||||
goodbye_message = $2,
|
||||
logging_channel = $3,
|
||||
welcome_channel = $4,
|
||||
puzzle_channel = $5,
|
||||
puzzle_role = $6
|
||||
WHERE id = $7`
|
||||
_, err := s.DB.Exec(queryString,
|
||||
g.WelcomeMessage,
|
||||
g.GoodbyeMessage,
|
||||
g.LoggingChannel,
|
||||
g.WelcomeChannel,
|
||||
g.PuzzleChannel,
|
||||
g.PuzzleRole,
|
||||
g.ID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package postgres
|
||||
|
||||
import "log"
|
||||
|
||||
type postfix struct {
|
||||
Name string
|
||||
Invoke func(bool) error
|
||||
}
|
||||
|
||||
var postfixes = []postfix{
|
||||
postfix{
|
||||
Name: "1_Update_Guild_for_Puzzle",
|
||||
Invoke: updateGuildForPuzzle,
|
||||
},
|
||||
postfix{
|
||||
Name: "1_Update_X_Guild_Prefixes_to_add_ID",
|
||||
Invoke: updateXGuildPrefixesToAddID,
|
||||
},
|
||||
postfix{
|
||||
Name: "1_Update_Tags_Content_Length",
|
||||
Invoke: updateTagsContentLength,
|
||||
},
|
||||
postfix{
|
||||
Name: "2_Add_Table_Roles",
|
||||
Invoke: addTableRoles,
|
||||
},
|
||||
postfix{
|
||||
Name: "3_Update_Guild_Add_Puzzle_Role",
|
||||
Invoke: updateGuildsAddPuzzleRole,
|
||||
},
|
||||
postfix{
|
||||
Name: "4_Add_Multi_Column_Unique_XUsersGuilds",
|
||||
Invoke: addMultiColumnUniqueXUsersGuilds,
|
||||
},
|
||||
postfix{
|
||||
Name: "5_Add_Auto_Role_To_Roles_Table",
|
||||
Invoke: addAutoRoleToRoles,
|
||||
},
|
||||
}
|
||||
|
||||
func RunPostfixes() {
|
||||
for _, postfix := range postfixes {
|
||||
queryString := "SELECT * from postfixes where name = $1"
|
||||
rows, err := DB.Query(queryString, postfix.Name)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
if rows.Next() {
|
||||
rows.Close()
|
||||
continue
|
||||
} else {
|
||||
rows.Close()
|
||||
err := postfix.Invoke(false)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
_, err = DB.Exec("INSERT INTO postfixes (name) VALUES ($1)", postfix.Name)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateGuildForPuzzle(revert bool) error {
|
||||
var queryString string
|
||||
if !revert {
|
||||
queryString = `ALTER TABLE guilds
|
||||
ADD COLUMN puzzle_channel varchar(30) not null default ''`
|
||||
} else {
|
||||
queryString = `ALTER TABLE guilds
|
||||
DROP COLUMN puzzleChat`
|
||||
}
|
||||
_, err := DB.Exec(queryString)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateXGuildPrefixesToAddID(revert bool) error {
|
||||
var queryString string
|
||||
if !revert {
|
||||
queryString = `ALTER TABLE x_guilds_prefixes
|
||||
ADD COLUMN id serial primary key`
|
||||
} else {
|
||||
queryString = `ALTER TABLE x_guilds_prefixes
|
||||
DROP COLUMN id`
|
||||
}
|
||||
_, err := DB.Exec(queryString)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateTagsContentLength(revert bool) error {
|
||||
var queryString string
|
||||
if !revert {
|
||||
queryString = `ALTER TABLE tags
|
||||
ALTER COLUMN content TYPE varchar(2000)`
|
||||
} else {
|
||||
queryString = `ALTER TABLE tags
|
||||
ALTER COLUMN content TYPE varchar(1000)`
|
||||
}
|
||||
_, err := DB.Exec(queryString)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addTableRoles(revert bool) error {
|
||||
var queryString string
|
||||
if !revert {
|
||||
queryString = `CREATE TABLE roles(
|
||||
id varchar(30) primary key,
|
||||
guild_id varchar(30) not null references guilds(id),
|
||||
self_assignable bool not null default false,
|
||||
admin bool not null default false,
|
||||
moderator bool not null default false
|
||||
)`
|
||||
} else {
|
||||
queryString = `DROP TABLE roles`
|
||||
}
|
||||
_, err := DB.Exec(queryString)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateGuildsAddPuzzleRole(revert bool) error {
|
||||
var queryString string
|
||||
if !revert {
|
||||
queryString = `ALTER TABLE guilds
|
||||
ADD COLUMN puzzle_role varchar(30) references roles(id)`
|
||||
} else {
|
||||
queryString = `ALTER TABLE guilds
|
||||
DROP COLUMN puzzle_role`
|
||||
}
|
||||
_, err := DB.Exec(queryString)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addMultiColumnUniqueXUsersGuilds(revert bool) error {
|
||||
var queryString string
|
||||
if !revert {
|
||||
queryString = `ALTER TABLE x_users_guilds
|
||||
ADD CONSTRAINT u_user_guild UNIQUE(user_id, guild_id)`
|
||||
} else {
|
||||
queryString = `ALTER TABLE DROP CONSTRAINT u_user_guild IF EXISTS`
|
||||
}
|
||||
_, err := DB.Exec(queryString)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addAutoRoleToRoles(revert bool) error {
|
||||
var queryString string
|
||||
if !revert {
|
||||
queryString = `ALTER TABLE roles
|
||||
ADD COLUMN auto_role bool DEFAULT false`
|
||||
} else {
|
||||
queryString = `ALTER TABLE roles
|
||||
DROP COLUMN auto_role`
|
||||
}
|
||||
_, err := DB.Exec(queryString)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
|
||||
"gitea.wayfinderak.com/wayfinderak/goff"
|
||||
)
|
||||
|
||||
type RoleService struct {
|
||||
DB *sql.DB
|
||||
}
|
||||
|
||||
func (s *RoleService) Role(id string) (*goff.Role, error) {
|
||||
var r goff.Role
|
||||
queryString := `SELECT id, moderator, admin, self_assignable, guild_id FROM roles WHERE id = $1`
|
||||
row := s.DB.QueryRow(queryString, id)
|
||||
if err := row.Scan(&r.ID, &r.IsModerator, &r.IsAdmin, &r.SelfAssignable, &r.Guild); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
func (s *RoleService) AddRole(r *goff.Role) (*goff.Role, error) {
|
||||
queryString := `INSERT INTO roles (id, moderator, admin, self_assignable, auto_role, guild_id)
|
||||
VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT DO NOTHING`
|
||||
_, err := s.DB.Exec(queryString, r.ID, r.IsModerator, r.IsAdmin, r.SelfAssignable, r.AutoRole, r.Guild)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (s *RoleService) DeleteRole(r *goff.Role) error {
|
||||
queryString := `DELETE FROM roles WHERE id = $1`
|
||||
_, err := s.DB.Exec(queryString, r.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *RoleService) MakeSelfAssignable(r *goff.Role) error {
|
||||
queryString := `UPDATE roles SET self_assignable = true WHERE id = $1`
|
||||
_, err := s.DB.Exec(queryString, r.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *RoleService) RemoveSelfAssignable(r *goff.Role) error {
|
||||
queryString := `UPDATE roles SET self_assignable = false WHERE id = $1`
|
||||
_, err := s.DB.Exec(queryString, r.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *RoleService) MakeAutoRole(r *goff.Role) error {
|
||||
queryString := `UPDATE roles SET auto_role = true WHERE id = $1`
|
||||
_, err := s.DB.Exec(queryString, r.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *RoleService) RemoveAutoRole(r *goff.Role) error {
|
||||
queryString := `UPDATE roles SET auto_role = false WHERE id = $1`
|
||||
_, err := s.DB.Exec(queryString, r.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *RoleService) GetAutoRoles(gID string) ([]*goff.Role, error) {
|
||||
var roles []*goff.Role
|
||||
queryString := `SELECT id FROM roles WHERE guild_id = $1 AND auto_role = true`
|
||||
rows, err := s.DB.Query(queryString, gID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
var id string
|
||||
err := rows.Scan(&id)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
role, err := s.Role(id)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
roles = append(roles, role)
|
||||
}
|
||||
return roles, nil
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"gitea.wayfinderak.com/wayfinderak/goff"
|
||||
)
|
||||
|
||||
type UserService struct {
|
||||
DB *sql.DB
|
||||
}
|
||||
|
||||
func (s *UserService) User(id string) (*goff.User, error) {
|
||||
var u goff.User
|
||||
queryString := `SELECT id, banned, logging, steam_id, is_active, is_staff, is_admin
|
||||
FROM users WHERE id=$1`
|
||||
row := s.DB.QueryRow(queryString, id)
|
||||
if err := row.Scan(&u.ID, &u.Banned, &u.Logging, &u.SteamID, &u.IsActive, &u.IsStaff, &u.IsAdmin); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var guilds []string
|
||||
queryString = `SELECT guild_id from x_users_guilds WHERE user_id=$1`
|
||||
rows, err := s.DB.Query(queryString, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
var guildID string
|
||||
err = rows.Scan(&guildID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
guilds = append(guilds, guildID)
|
||||
}
|
||||
u.Guilds = guilds
|
||||
return &u, nil
|
||||
}
|
||||
|
||||
func (s *UserService) CreateUser(u *goff.User, gid string) error {
|
||||
queryString := `INSERT INTO users (id, banned, logging, steam_id, is_active, is_staff, is_admin)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT DO NOTHING`
|
||||
_, err := s.DB.Exec(queryString, u.ID, u.Banned, u.Logging, u.SteamID, u.IsActive, u.IsStaff, u.IsAdmin)
|
||||
if err == nil {
|
||||
err = s.AddUserToGuild(u, &goff.Guild{ID: gid})
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *UserService) DeleteUser(u *goff.User) error {
|
||||
queryString := `DELETE CASCADE FROM x_users_guilds WHERE user_id = $1; DELETE FROM users WHERE id = $1`
|
||||
_, err := s.DB.Exec(queryString, u.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *UserService) MarkUserInactive(u *goff.User) error {
|
||||
queryString := `UPDATE users SET is_active = false WHERE id = $1`
|
||||
_, err := s.DB.Exec(queryString, u.ID)
|
||||
if err == nil {
|
||||
u.IsActive = false
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *UserService) AddUserToGuild(u *goff.User, g *goff.Guild) error {
|
||||
queryString := `INSERT INTO x_users_guilds (user_id, guild_id) VALUES ($1, $2) ON CONFLICT DO NOTHING`
|
||||
_, err := s.DB.Exec(queryString, u.ID, g.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *UserService) RemoveUserFromGuild(u *goff.User, g *goff.Guild) error {
|
||||
queryString := `DELETE FROM x_users_guilds WHERE user_id = $1 AND guild_id = $2`
|
||||
_, err := s.DB.Exec(queryString, u.ID, g.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *UserService) UpdateUser(u *goff.User) error {
|
||||
queryString := `UPDATE users SET
|
||||
banned = $1,
|
||||
logging = $2,
|
||||
steam_id = $3,
|
||||
is_active = $4,
|
||||
is_staff = $5,
|
||||
is_admin = $6
|
||||
WHERE id = $7`
|
||||
_, err := s.DB.Exec(queryString, u.Banned, u.Logging, u.SteamID, u.IsActive, u.IsStaff, u.IsAdmin)
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package services
|
||||
|
||||
import "gitea.wayfinderak.com/wayfinderak/goff"
|
||||
|
||||
var UserService goff.UserService
|
||||
var GuildService goff.GuildService
|
||||
var RoleService goff.RoleService
|
||||
|
||||
func InitalizeServices(us goff.UserService, gs goff.GuildService, rs goff.RoleService) {
|
||||
UserService = us
|
||||
GuildService = gs
|
||||
RoleService = rs
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package utils
|
||||
package email
|
||||
|
||||
import (
|
||||
"io"
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/pkg/puzzles"
|
||||
imap "github.com/emersion/go-imap"
|
||||
"github.com/emersion/go-imap/client"
|
||||
"github.com/emersion/go-message/mail"
|
||||
@@ -117,7 +118,7 @@ func processEmail(r io.Reader, dg *discordgo.Session, wg *sync.WaitGroup) {
|
||||
if addressIn(from, puzzleAddress) &&
|
||||
strings.Contains(subject, "Daily Coding Problem:") {
|
||||
log.Println("Processing Puzzle")
|
||||
ProcessPuzzleEmail(mr, dg)
|
||||
puzzles.ProcessPuzzleEmail(mr, dg)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package utils
|
||||
package puzzles
|
||||
|
||||
import (
|
||||
"io"
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff"
|
||||
"gitea.wayfinderak.com/wayfinderak/goff/internal/postgres"
|
||||
"github.com/emersion/go-message/mail"
|
||||
)
|
||||
|
||||
@@ -48,15 +50,15 @@ func ProcessPuzzleEmail(mr *mail.Reader, dg *discordgo.Session) {
|
||||
Text: "Daily Coding Problem",
|
||||
},
|
||||
}
|
||||
var guilds []Guild
|
||||
queryString := `SELECT id, puzzle_channel from guilds`
|
||||
rows, err := Database.Query(queryString)
|
||||
var guilds []goff.Guild
|
||||
queryString := `SELECT id, puzzle_channel, puzzle_role from guilds`
|
||||
rows, err := postgres.DB.Query(queryString)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
for rows.Next() {
|
||||
var guild Guild
|
||||
err := rows.Scan(&guild.ID, &guild.PuzzleChannel)
|
||||
var guild goff.Guild
|
||||
err := rows.Scan(&guild.ID, &guild.PuzzleChannel, &guild.PuzzleRole)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
@@ -65,7 +67,7 @@ func ProcessPuzzleEmail(mr *mail.Reader, dg *discordgo.Session) {
|
||||
}
|
||||
var puzzleID int64
|
||||
queryString = "INSERT INTO puzzles (text, time) VALUES ($1, $2) RETURNING id"
|
||||
err = Database.QueryRow(queryString, puzzle, date).Scan(&puzzleID)
|
||||
err = postgres.DB.QueryRow(queryString, puzzle, date).Scan(&puzzleID)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
@@ -74,15 +76,24 @@ func ProcessPuzzleEmail(mr *mail.Reader, dg *discordgo.Session) {
|
||||
if g.PuzzleChannel == "" {
|
||||
continue
|
||||
}
|
||||
msg := discordgo.MessageSend{
|
||||
Embed: &e,
|
||||
var msg discordgo.MessageSend
|
||||
role, err := dg.State.Role(g.ID, g.PuzzleRole.String)
|
||||
if err != nil {
|
||||
msg = discordgo.MessageSend{
|
||||
Embed: &e,
|
||||
}
|
||||
} else {
|
||||
msg = discordgo.MessageSend{
|
||||
Content: role.Mention(),
|
||||
Embed: &e,
|
||||
}
|
||||
}
|
||||
m, err := dg.ChannelMessageSendComplex(g.PuzzleChannel, &msg)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
queryString = "INSERT INTO x_guilds_puzzles (guild_id, puzzle_id, message_id) VALUES ($1, $2, $3)"
|
||||
_, err = Database.Exec(queryString, g.ID, puzzleID, m.ID)
|
||||
_, err = postgres.DB.Exec(queryString, g.ID, puzzleID, m.ID)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
@@ -0,0 +1,4 @@
|
||||
DATABASE_URL=postgresql://USER:PASSWORD@HOST:5432/goff?sslmode=disable
|
||||
DISCORDGO_TOKEN=replace-me
|
||||
GOFF_EMAIL_USERNAME=replace-me
|
||||
GOFF_EMAIL_PASSWORD=replace-me
|
||||
@@ -0,0 +1,9 @@
|
||||
services:
|
||||
goff:
|
||||
image: gitea.wayfinderak.com/wayfinderak/goff:latest
|
||||
container_name: goff
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- ./portainer-app.env
|
||||
mem_limit: 1g
|
||||
cpus: "2.0"
|
||||
@@ -0,0 +1,21 @@
|
||||
package goff
|
||||
|
||||
type Role struct {
|
||||
ID string
|
||||
IsModerator bool
|
||||
IsAdmin bool
|
||||
SelfAssignable bool
|
||||
AutoRole bool
|
||||
Guild string
|
||||
}
|
||||
|
||||
type RoleService interface {
|
||||
Role(id string) (*Role, error)
|
||||
AddRole(r *Role) (*Role, error)
|
||||
DeleteRole(r *Role) error
|
||||
MakeSelfAssignable(r *Role) error
|
||||
RemoveSelfAssignable(r *Role) error
|
||||
MakeAutoRole(r *Role) error
|
||||
RemoveAutoRole(r *Role) error
|
||||
GetAutoRoles(gID string) ([]*Role, error)
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bash
|
||||
# Keep required jobs alive; only skip reviewed non-runtime documentation paths.
|
||||
set -euo pipefail
|
||||
base="${DELIVERY_BASE:-}"
|
||||
head="$(git rev-parse HEAD)"
|
||||
run=true
|
||||
if [[ "${DELIVERY_REF:-}" != refs/tags/* && "$head" == "${DELIVERY_SHA:-}" && "${DELIVERY_EVENT:-}" =~ ^(push|pull_request)$ && "$base" =~ ^[0-9a-f]{40}$ && "$base" != 0000000000000000000000000000000000000000 ]]; then
|
||||
if ! git cat-file -e "$base^{commit}" 2>/dev/null; then
|
||||
if [[ -n "${DELIVERY_FETCH_TOKEN:-}" ]]; then
|
||||
git -c "http.extraHeader=Authorization: token ${DELIVERY_FETCH_TOKEN}" fetch --quiet --depth=1 origin "$base" >/dev/null 2>&1 || true
|
||||
else
|
||||
git fetch --quiet --depth=1 origin "$base" >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
if git cat-file -e "$base^{commit}" 2>/dev/null; then
|
||||
paths="$(mktemp)"
|
||||
trap 'rm -f -- "$paths"' EXIT
|
||||
# Snapshot comparison is conservative when main advanced during a PR.
|
||||
# Both rename sides remain visible, including names containing newlines.
|
||||
if git diff --no-renames --name-only -z "$base" "$head" > "$paths"; then
|
||||
run=false
|
||||
while IFS= read -r -d '' path; do
|
||||
case "$path" in
|
||||
README.md|CHANGELOG.md|LICENSE|LICENSE.md) ;;
|
||||
*) run=true; break ;;
|
||||
esac
|
||||
done < "$paths"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [[ "$run" == false ]]; then
|
||||
echo 'Only reviewed non-runtime documentation changed; build and validation are not applicable.'
|
||||
else
|
||||
echo 'Runtime, unknown inputs, or unavailable event history: run required validation.'
|
||||
fi
|
||||
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
|
||||
echo "run=$run" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
printf '%s\n' "$run"
|
||||
@@ -0,0 +1,134 @@
|
||||
{
|
||||
"ipcMode": null,
|
||||
"executionRoleArn": "arn:aws:iam::005692590034:role/goff_ecs_rds+cw+ecr",
|
||||
"containerDefinitions": [
|
||||
{
|
||||
"dnsSearchDomains": null,
|
||||
"environmentFiles": null,
|
||||
"logConfiguration": {
|
||||
"logDriver": "awslogs",
|
||||
"secretOptions": null,
|
||||
"options": {
|
||||
"awslogs-group": "/ecs/goff",
|
||||
"awslogs-region": "us-east-1",
|
||||
"awslogs-stream-prefix": "ecs"
|
||||
}
|
||||
},
|
||||
"entryPoint": null,
|
||||
"portMappings": [],
|
||||
"command": null,
|
||||
"linuxParameters": null,
|
||||
"cpu": 0,
|
||||
"environment": [],
|
||||
"resourceRequirements": null,
|
||||
"ulimits": null,
|
||||
"dnsServers": null,
|
||||
"mountPoints": [],
|
||||
"workingDirectory": null,
|
||||
"secrets": [
|
||||
{
|
||||
"valueFrom": "goff_database_uri",
|
||||
"name": "DATABASE_URL"
|
||||
},
|
||||
{
|
||||
"valueFrom": "goff_discord_token",
|
||||
"name": "DISCORDGO_TOKEN"
|
||||
},
|
||||
{
|
||||
"valueFrom": "goff_email_password",
|
||||
"name": "GOFF_EMAIL_PASSWORD"
|
||||
},
|
||||
{
|
||||
"valueFrom": "goff_email_username",
|
||||
"name": "GOFF_EMAIL_USERNAME"
|
||||
}
|
||||
],
|
||||
"dockerSecurityOptions": null,
|
||||
"memory": 512,
|
||||
"memoryReservation": null,
|
||||
"volumesFrom": [],
|
||||
"stopTimeout": null,
|
||||
"image": "005692590034.dkr.ecr.us-east-1.amazonaws.com/goff:latest",
|
||||
"startTimeout": null,
|
||||
"firelensConfiguration": null,
|
||||
"dependsOn": null,
|
||||
"disableNetworking": null,
|
||||
"interactive": null,
|
||||
"healthCheck": null,
|
||||
"essential": true,
|
||||
"links": null,
|
||||
"hostname": null,
|
||||
"extraHosts": null,
|
||||
"pseudoTerminal": null,
|
||||
"user": null,
|
||||
"readonlyRootFilesystem": null,
|
||||
"dockerLabels": null,
|
||||
"systemControls": null,
|
||||
"privileged": null,
|
||||
"name": "goff"
|
||||
}
|
||||
],
|
||||
"placementConstraints": [],
|
||||
"memory": "512",
|
||||
"taskRoleArn": "arn:aws:iam::005692590034:role/goff_ecs_rds+cw+ecr",
|
||||
"compatibilities": [
|
||||
"EC2"
|
||||
],
|
||||
"taskDefinitionArn": "arn:aws:ecs:us-east-1:005692590034:task-definition/goff:2",
|
||||
"family": "goff",
|
||||
"requiresAttributes": [
|
||||
{
|
||||
"targetId": null,
|
||||
"targetType": null,
|
||||
"value": null,
|
||||
"name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
|
||||
},
|
||||
{
|
||||
"targetId": null,
|
||||
"targetType": null,
|
||||
"value": null,
|
||||
"name": "ecs.capability.execution-role-awslogs"
|
||||
},
|
||||
{
|
||||
"targetId": null,
|
||||
"targetType": null,
|
||||
"value": null,
|
||||
"name": "com.amazonaws.ecs.capability.ecr-auth"
|
||||
},
|
||||
{
|
||||
"targetId": null,
|
||||
"targetType": null,
|
||||
"value": null,
|
||||
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
|
||||
},
|
||||
{
|
||||
"targetId": null,
|
||||
"targetType": null,
|
||||
"value": null,
|
||||
"name": "com.amazonaws.ecs.capability.task-iam-role"
|
||||
},
|
||||
{
|
||||
"targetId": null,
|
||||
"targetType": null,
|
||||
"value": null,
|
||||
"name": "ecs.capability.execution-role-ecr-pull"
|
||||
},
|
||||
{
|
||||
"targetId": null,
|
||||
"targetType": null,
|
||||
"value": null,
|
||||
"name": "ecs.capability.secrets.ssm.environment-variables"
|
||||
}
|
||||
],
|
||||
"pidMode": null,
|
||||
"requiresCompatibilities": [
|
||||
"EC2"
|
||||
],
|
||||
"networkMode": null,
|
||||
"cpu": "1024",
|
||||
"revision": 2,
|
||||
"status": "ACTIVE",
|
||||
"inferenceAccelerators": null,
|
||||
"proxyConfiguration": null,
|
||||
"volumes": []
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
/usr/local/bin/docker-compose build || exit
|
||||
/usr/local/bin/docker-compose up -d
|
||||
@@ -0,0 +1,22 @@
|
||||
package goff
|
||||
|
||||
type User struct {
|
||||
ID string
|
||||
Banned bool
|
||||
Logging bool
|
||||
SteamID string
|
||||
IsActive bool
|
||||
IsStaff bool
|
||||
IsAdmin bool
|
||||
Guilds []string
|
||||
}
|
||||
|
||||
type UserService interface {
|
||||
User(id string) (*User, error)
|
||||
CreateUser(u *User, gid string) error
|
||||
DeleteUser(u *User) error
|
||||
MarkUserInactive(u *User) error
|
||||
AddUserToGuild(u *User, g *Guild) error
|
||||
RemoveUserFromGuild(u *User, g *Guild) error
|
||||
UpdateUser(u *User) error
|
||||
}
|
||||
Reference in New Issue
Block a user