From 6375fe5af1c3bac9bd0c2772827c9b354a5e66d0 Mon Sep 17 00:00:00 2001 From: watn3y Date: Fri, 29 Dec 2023 05:15:23 +0100 Subject: [PATCH] A bunch of Changes Docker is broken as of now, will fix later --- .gitignore | 4 +- TODO.md | 2 +- bot.go | 36 ++++++++----- botIO/authenticate.go | 2 +- commands/commands.go | 28 +++++++--- commands/download/download.go | 15 +++--- commands/gaypoints/gaypoints.go | 12 +++-- commands/gaypoints/sql.go | 6 +-- commands/notify/notify.go | 4 +- commands/notify/sql.go | 5 +- config/config.go | 14 ++--- data/204.jpg | Bin 0 -> 22819 bytes bloater.webp => data/bloater.webp | Bin .../config.toml.example | 0 data/db/placeholder | 0 data/nenefoot/placeholder | 0 data/videos/placeholder | 0 docker-compose.yaml | 3 +- go.mod | 21 +++++++- go.sum | 48 ++++++++++++++++++ inline/nenefoot/nenefoot.go | 29 +++++++++++ inline/nenefoot/sql.go | 47 +++++++++++++++++ main.go | 9 ++-- text/balonlyl/balonlyl.go | 5 +- text/matcher.go | 10 ++-- videos/index.html | 13 ----- webserver/webserver.go | 26 ++++++++-- 27 files changed, 258 insertions(+), 81 deletions(-) create mode 100644 data/204.jpg rename bloater.webp => data/bloater.webp (100%) rename config.toml.example => data/config.toml.example (100%) create mode 100644 data/db/placeholder create mode 100644 data/nenefoot/placeholder create mode 100644 data/videos/placeholder create mode 100644 inline/nenefoot/nenefoot.go create mode 100644 inline/nenefoot/sql.go delete mode 100644 videos/index.html diff --git a/.gitignore b/.gitignore index ce7987f..172b195 100644 --- a/.gitignore +++ b/.gitignore @@ -108,6 +108,4 @@ fabric.properties # CUSTOM -config.toml -bloater.db - +data/ diff --git a/TODO.md b/TODO.md index c9af091..6b2ab7b 100644 --- a/TODO.md +++ b/TODO.md @@ -1,4 +1,4 @@ -## ;todolist +//TODO - Improve logging - differentiate between debug and non-debug logs diff --git a/bot.go b/bot.go index 9c46354..9f61d7b 100644 --- a/bot.go +++ b/bot.go @@ -2,30 +2,42 @@ package main import ( "time" - "watn3y/bloaterbot/botIO" - "watn3y/bloaterbot/commands" - "watn3y/bloaterbot/commands/notify" - "watn3y/bloaterbot/text" + "github.com/rs/zerolog/log" + "watn3y.de/bloaterbot/botIO" + "watn3y.de/bloaterbot/commands" + "watn3y.de/bloaterbot/commands/notify" + "watn3y.de/bloaterbot/inline/nenefoot" + "watn3y.de/bloaterbot/text" ) func bot() { updates, bot := botIO.Authenticate() + go notify.NotifyHandler(bot) - now := time.Now().UTC() + for update := range updates { - if update.Message == nil || update.Message.Time().UTC().Unix() < now.UTC().Unix() { + log.Debug().Interface("update", update).Msg("Recieved update") + + if update.InlineQuery != nil && update.Message == nil { + nenefoot.Nenefoot(update, bot) continue } - log.Info().Int64("user", update.Message.From.ID).Int64("chat", update.Message.Chat.ID).Str("msg", update.Message.Text).Msg("Recieved update:") - log.Debug().Interface("update", update).Msg("") + if update.Message != nil { + if update.Message.Time().UTC().Unix() < time.Now().UTC().Unix() { + continue + } + if update.Message.IsCommand() { + commands.Commands(update, bot) + } else { + text.Matcher(update, bot) + continue + } - if update.Message.IsCommand() { - commands.Commands(update, bot) - } else { - text.Matcher(update, bot) } + log.Info().Interface("update", update).Msg("Unable to parse update") + } } diff --git a/botIO/authenticate.go b/botIO/authenticate.go index 80db0bc..eb502b8 100644 --- a/botIO/authenticate.go +++ b/botIO/authenticate.go @@ -1,9 +1,9 @@ package botIO import ( - "watn3y/bloaterbot/config" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "github.com/rs/zerolog/log" + "watn3y.de/bloaterbot/config" ) func Authenticate() (tgbotapi.UpdatesChannel, *tgbotapi.BotAPI) { diff --git a/commands/commands.go b/commands/commands.go index 727d12e..0e25ce0 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -5,11 +5,12 @@ import ( "strconv" "strings" "time" - "watn3y/bloaterbot/botIO" - "watn3y/bloaterbot/commands/download" - "watn3y/bloaterbot/commands/gaypoints" - "watn3y/bloaterbot/commands/notify" - "watn3y/bloaterbot/config" + + "watn3y.de/bloaterbot/botIO" + "watn3y.de/bloaterbot/commands/download" + "watn3y.de/bloaterbot/commands/gaypoints" + "watn3y.de/bloaterbot/commands/notify" + "watn3y.de/bloaterbot/config" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "github.com/rs/zerolog/log" @@ -25,25 +26,35 @@ func Commands(update tgbotapi.Update, bot *tgbotapi.BotAPI) { switch cmd { case "shutup": - shutup(update, bot) + go shutup(update, bot) + break case "shut": - shutup(update, bot) + go shutup(update, bot) + break case "gp": gaypoints.GetGP(update, bot) + break case "addgp": gaypoints.SetGP(update, bot) + break case "subtractgp": gaypoints.SetGP(update, bot) + break case "remindme": notify.Reminder(update, bot) + break case "download": go download.Download(update, bot) + break case "dl": go download.Download(update, bot) + break case "help": help(update, bot) + break case "info": info(update, bot) + break } } @@ -82,7 +93,8 @@ func info(update tgbotapi.Update, bot *tgbotapi.BotAPI) { if commit == "" { commit = "not available" } - info, _ := os.Stat("./bloater.db") + //TODO calculate total size + info, _ := os.Stat("data/db/gaypoints.db") dbSizeInKiloBytes := info.Size() / 1000 textInfo := "" + me.FirstName + "" + "\n\n" + diff --git a/commands/download/download.go b/commands/download/download.go index 453815f..290e603 100644 --- a/commands/download/download.go +++ b/commands/download/download.go @@ -14,9 +14,10 @@ import ( "strconv" "strings" "time" - "watn3y/bloaterbot/botIO" - "watn3y/bloaterbot/commonlogic" - "watn3y/bloaterbot/config" + + "watn3y.de/bloaterbot/botIO" + "watn3y.de/bloaterbot/commonlogic" + "watn3y.de/bloaterbot/config" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "github.com/rs/zerolog/log" @@ -61,7 +62,7 @@ func Download(update tgbotapi.Update, bot *tgbotapi.BotAPI) { return } - files, err := os.ReadDir("./videos/" + downloadTarget) + files, err := os.ReadDir("data/videos/" + downloadTarget) if err != nil { log.Error().Err(err).Msg("failed to download. unable to read target directory") @@ -112,7 +113,7 @@ func randomString(n int) string { func runYTDL(URL string, targetDir string) (success bool) { - cmd := exec.Command("yt-dlp", "-f", "bv*[ext=mp4]+ba[ext=m4a] / bv*+ba/b", "--no-playlist", "-o", "videos/"+targetDir+"/"+"%(title)s.%(ext)s", "--write-thumbnail", "--convert-thumbnails", "jpg", "-o", "thumbnail:videos/"+targetDir+"thumb"+"/"+"%(title)s.%(ext)s", URL) + cmd := exec.Command("yt-dlp", "-f", "bv*[ext=mp4]+ba[ext=m4a] / bv*+ba/b", "--no-playlist", "-o", "data/videos/"+targetDir+"/"+"%(title)s.%(ext)s", "--write-thumbnail", "--convert-thumbnails", "jpg", "-o", "thumbnail:data/videos/"+targetDir+"thumb"+"/"+"%(title)s.%(ext)s", URL) out, err := cmd.CombinedOutput() var ( @@ -181,8 +182,8 @@ func shortURL(URL string) (shorturl string) { } func serveMedia(update tgbotapi.Update, bot *tgbotapi.BotAPI, randomNoise string, file string) { - fsPath := "./videos/" + randomNoise + "/" + file - fsThumbPath := "./videos/" + randomNoise + "thumb" + "/" + strings.TrimSuffix(file, "mp4") + "jpg" + fsPath := "data/videos/" + randomNoise + "/" + file + fsThumbPath := "data/videos/" + randomNoise + "thumb" + "/" + strings.TrimSuffix(file, "mp4") + "jpg" fExt := filepath.Ext(fsPath) imageTypes := []string{".jpg", ".jpeg", ".png"} diff --git a/commands/gaypoints/gaypoints.go b/commands/gaypoints/gaypoints.go index e67c126..0737acd 100644 --- a/commands/gaypoints/gaypoints.go +++ b/commands/gaypoints/gaypoints.go @@ -3,14 +3,16 @@ package gaypoints import ( "strconv" "strings" - "watn3y/bloaterbot/botIO" - "watn3y/bloaterbot/commonlogic" - "watn3y/bloaterbot/config" + + "watn3y.de/bloaterbot/botIO" + "watn3y.de/bloaterbot/commonlogic" + "watn3y.de/bloaterbot/config" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "github.com/rs/zerolog/log" ) -//TODO logging + +// TODO logging func GetGP(update tgbotapi.Update, bot *tgbotapi.BotAPI) { log.Debug().Int64("chat", update.Message.Chat.ID).Int64("user", update.Message.From.ID).Msg("getting gaypoints") @@ -97,7 +99,7 @@ func SetGP(update tgbotapi.Update, bot *tgbotapi.BotAPI) { log.Debug().Int64("chat", update.Message.Chat.ID).Ints64("enabledChats", config.BotConfig.GayPoints.ModifyUsers).Msg("not setting gaypoints, user not authorised") sticker := tgbotapi.StickerConfig{BaseFile: tgbotapi.BaseFile{ BaseChat: tgbotapi.BaseChat{ChatID: update.Message.Chat.ID, ReplyToMessageID: update.Message.MessageID}, - File: tgbotapi.FilePath("bloater.webp"), + File: tgbotapi.FilePath("data/bloater.webp"), }} botIO.SendSticker(sticker, bot) diff --git a/commands/gaypoints/sql.go b/commands/gaypoints/sql.go index e86aee5..74c2747 100644 --- a/commands/gaypoints/sql.go +++ b/commands/gaypoints/sql.go @@ -2,7 +2,7 @@ package gaypoints import ( "database/sql" - _ "github.com/mattn/go-sqlite3" + _ "modernc.org/sqlite" "github.com/rs/zerolog/log" ) @@ -68,9 +68,9 @@ func sqlSetGP(chatid int64, userid int64, gaypoints int64) { } func InitDB() { - const dbPath string = "./bloater.db" + const dbPath string = "data/db/gaypoints.db" log.Info().Str("dbpath", dbPath).Msg("init database") - db, err := sql.Open("sqlite3", dbPath) + db, err := sql.Open("sqlite", dbPath) if err != nil { log.Panic().Err(err).Msg("failed to open sqlite database") } diff --git a/commands/notify/notify.go b/commands/notify/notify.go index 1240385..37de4dd 100644 --- a/commands/notify/notify.go +++ b/commands/notify/notify.go @@ -5,11 +5,13 @@ import ( "strconv" "strings" "time" - "watn3y/bloaterbot/botIO" + + "watn3y.de/bloaterbot/botIO" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "github.com/rs/zerolog/log" ) + //TODO logging func Reminder(update tgbotapi.Update, bot *tgbotapi.BotAPI) { diff --git a/commands/notify/sql.go b/commands/notify/sql.go index 707a162..5b5100e 100644 --- a/commands/notify/sql.go +++ b/commands/notify/sql.go @@ -3,6 +3,7 @@ package notify import ( "database/sql" "github.com/rs/zerolog/log" + _ "modernc.org/sqlite" ) var notifySetReminder *sql.Stmt @@ -12,9 +13,9 @@ var notifyDeleteReminder *sql.Stmt //TODO logging //TODO switch to SQL func InitDB() { - const dbPath string = "./bloater.db" + const dbPath string = "data/db/notify.db" log.Info().Str("dbpath", dbPath).Msg("init database") - db, err := sql.Open("sqlite3", dbPath) + db, err := sql.Open("sqlite", dbPath) if err != nil { log.Panic().Err(err).Msg("failed to open sqlite database") } diff --git a/config/config.go b/config/config.go index 1a996be..034d3bd 100644 --- a/config/config.go +++ b/config/config.go @@ -38,14 +38,14 @@ var BotConfig config func LoadConfig() { - configFile, err := os.ReadFile("config.toml") + configFile, err := os.ReadFile("data/config.toml") if err != nil { - log.Panic().Err(err).Msg("error opening config file") + log.Panic().Err(err).Msg("error opening data/config.toml") } _, err = toml.Decode(string(configFile), &BotConfig) if err != nil { - log.Panic().Err(err).Msg("error decoding config file") + log.Panic().Err(err).Msg("error decoding data/config.toml") } BotConfig.Shutup = make(map[int64]time.Time) @@ -102,18 +102,18 @@ func EncodeToml() { }, } - f, err := os.Create("config.toml.example") + f, err := os.Create("data/config.toml.example") if err != nil { - log.Panic().Err(err).Msg("error encoding config file. Cannot open config.toml.example") + log.Panic().Err(err).Msg("error encoding config file. Cannot open data/config.toml.example") } if err := toml.NewEncoder(f).Encode(exampleConfig); err != nil { log.Panic().Err(err).Msg("error encoding config file") } if err := f.Close(); err != nil { - log.Panic().Err(err).Msg("error encoding config file. Cannot close config.toml.example") + log.Panic().Err(err).Msg("error encoding config file. Cannot close data/config.toml.example") } - log.Info().Msg("Wrote example config to config.toml.example. Bye Bye") + log.Info().Msg("Wrote example config to data/config.toml.example. Bye Bye") } diff --git a/data/204.jpg b/data/204.jpg new file mode 100644 index 0000000000000000000000000000000000000000..424deb5595ca80f34365261b0c7762549ccfdcf9 GIT binary patch literal 22819 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�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 literal 0 HcmV?d00001 diff --git a/bloater.webp b/data/bloater.webp similarity index 100% rename from bloater.webp rename to data/bloater.webp diff --git a/config.toml.example b/data/config.toml.example similarity index 100% rename from config.toml.example rename to data/config.toml.example diff --git a/data/db/placeholder b/data/db/placeholder new file mode 100644 index 0000000..e69de29 diff --git a/data/nenefoot/placeholder b/data/nenefoot/placeholder new file mode 100644 index 0000000..e69de29 diff --git a/data/videos/placeholder b/data/videos/placeholder new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose.yaml b/docker-compose.yaml index 63fb407..9dcd8eb 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -5,8 +5,7 @@ services: container_name: bloaterbot restart: unless-stopped volumes: - - /opt/bloaterbot/config.toml:/app/config.toml - - /opt/bloaterbot/bloater.db:/app/bloater.db + - /opt/bloaterbot/data:/app/data networks: - expose networks: diff --git a/go.mod b/go.mod index a58c5b6..7865c7e 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,33 @@ -module watn3y/bloaterbot +module watn3y.de/bloaterbot go 1.21 require ( github.com/BurntSushi/toml v1.3.2 github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 - github.com/mattn/go-sqlite3 v1.14.19 github.com/rs/zerolog v1.31.0 + modernc.org/sqlite v1.28.0 ) +require github.com/mattn/go-sqlite3 v1.14.19 // indirect + require ( + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/google/uuid v1.5.0 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + golang.org/x/mod v0.14.0 // indirect golang.org/x/sys v0.15.0 // indirect + golang.org/x/tools v0.16.1 // indirect + lukechampine.com/uint128 v1.3.0 // indirect + modernc.org/cc/v3 v3.41.0 // indirect + modernc.org/ccgo/v3 v3.16.15 // indirect + modernc.org/libc v1.38.0 // indirect + modernc.org/mathutil v1.6.0 // indirect + modernc.org/memory v1.7.2 // indirect + modernc.org/opt v0.1.3 // indirect + modernc.org/strutil v1.2.0 // indirect + modernc.org/token v1.1.0 // indirect ) diff --git a/go.sum b/go.sum index 6b041ee..8773c6e 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,19 @@ github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -13,11 +23,49 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= +lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= +modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= +modernc.org/ccgo/v3 v3.16.15 h1:KbDR3ZAVU+wiLyMESPtbtE/Add4elztFyfsWoNTgxS0= +modernc.org/ccgo/v3 v3.16.15/go.mod h1:yT7B+/E2m43tmMOT51GMoM98/MtHIcQQSleGnddkUNI= +modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v1.38.0 h1:o4Lpk0zNDSdsjfEXnF1FGXWQ9PDi1NOdWcLP5n13FGo= +modernc.org/libc v1.38.0/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= +modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ= +modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY= +modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY= +modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE= diff --git a/inline/nenefoot/nenefoot.go b/inline/nenefoot/nenefoot.go new file mode 100644 index 0000000..3e3ce20 --- /dev/null +++ b/inline/nenefoot/nenefoot.go @@ -0,0 +1,29 @@ +package nenefoot + +import ( + //"watn3y.de/bloaterbot/botIO" + //"watn3y.de/bloaterbot/config" + "fmt" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + //"github.com/rs/zerolog/log" +) + +func Nenefoot(update tgbotapi.Update, bot *tgbotapi.BotAPI) { + + msg3 := tgbotapi.NewInlineQueryResultVideo("hihi", "https://bloater.watn3y.de/5r5NJELyDKYSdPsX6fzK/7000%20Dollars%20for%20this%20car%2C%20but%20i%20got%20a%20slight%20dent.mp4") + msg3.MimeType = "video/mp4" + msg3.Title = "Rat Pencilcase" + msg3.ThumbURL = "https://i.imgur.com/XjCWMco.jpeg" + + inline := tgbotapi.InlineConfig{ + InlineQueryID: update.InlineQuery.ID, + Results: []interface{}{msg3}, + CacheTime: 0, + } + + if _, err := bot.Request(inline); err != nil { + fmt.Println(err) + } + +} diff --git a/inline/nenefoot/sql.go b/inline/nenefoot/sql.go new file mode 100644 index 0000000..9105cb7 --- /dev/null +++ b/inline/nenefoot/sql.go @@ -0,0 +1,47 @@ +package nenefoot + +import ( + "database/sql" + _ "modernc.org/sqlite" + "github.com/rs/zerolog/log" +) + +var gpSelectUser *sql.Stmt + +var gpSelectChat *sql.Stmt + +var gpSet *sql.Stmt + +func InitDB() { + const dbPath string = "data/db/nenefoot.db" + log.Info().Str("dbpath", dbPath).Msg("init database") + db, err := sql.Open("sqlite", dbPath) + if err != nil { + log.Panic().Err(err).Msg("failed to open sqlite database") + } + + _, err = db.Exec("CREATE TABLE IF NOT EXISTS nenefoot (title string, type string, ID string, URL string, UNIQUE(title), UNIQUE(ID), UNIQUE(URL))") + if err != nil { + log.Panic().Err(err).Msg("failed to create table") + } + + gpSelectUser, err = db.Prepare("SELECT gaypoints FROM gaypoints WHERE chatid = ? AND userid = ?") + + if err != nil { + log.Panic().Err(err).Msg("failed to create sql statement") + } + + gpSelectChat, err = db.Prepare("SELECT userid,gaypoints FROM gaypoints WHERE chatid = ? ORDER BY gaypoints DESC") + + if err != nil { + log.Panic().Err(err).Msg("failed to create sql statement") + } + + gpSet, err = db.Prepare("INSERT OR REPLACE INTO gaypoints (chatid, userid, gaypoints) values (?,?,?)") + + if err != nil { + log.Panic().Err(err).Msg("failed to create sql statement") + } + + log.Info().Msg("init database: done") +} diff --git a/main.go b/main.go index 5ffb58c..a18e1a5 100644 --- a/main.go +++ b/main.go @@ -5,10 +5,11 @@ import ( "fmt" "os" "time" - "watn3y/bloaterbot/commands/gaypoints" - "watn3y/bloaterbot/commands/notify" - "watn3y/bloaterbot/config" - "watn3y/bloaterbot/webserver" + + "watn3y.de/bloaterbot/commands/gaypoints" + "watn3y.de/bloaterbot/commands/notify" + "watn3y.de/bloaterbot/config" + "watn3y.de/bloaterbot/webserver" "github.com/rs/zerolog" "github.com/rs/zerolog/log" diff --git a/text/balonlyl/balonlyl.go b/text/balonlyl/balonlyl.go index b13cd83..862a2ba 100644 --- a/text/balonlyl/balonlyl.go +++ b/text/balonlyl/balonlyl.go @@ -1,11 +1,12 @@ package balonlyl import ( - "watn3y/bloaterbot/botIO" - "watn3y/bloaterbot/config" + "watn3y.de/bloaterbot/botIO" + "watn3y.de/bloaterbot/config" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" ) + //TODO logging func Balonlyl(update tgbotapi.Update, bot *tgbotapi.BotAPI) { diff --git a/text/matcher.go b/text/matcher.go index baea18c..29f1644 100644 --- a/text/matcher.go +++ b/text/matcher.go @@ -3,14 +3,16 @@ package text import ( "strings" "time" - "watn3y/bloaterbot/commonlogic" - "watn3y/bloaterbot/config" - "watn3y/bloaterbot/text/balonlyl" + + "watn3y.de/bloaterbot/commonlogic" + "watn3y.de/bloaterbot/config" + "watn3y.de/bloaterbot/text/balonlyl" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "github.com/rs/zerolog/log" ) -//TODO logging + +// TODO logging func Matcher(update tgbotapi.Update, bot *tgbotapi.BotAPI) { log.Debug().Str("text", update.Message.Text).Int64("chat", update.Message.Chat.ID).Msg("Starting text matcher") diff --git a/videos/index.html b/videos/index.html deleted file mode 100644 index c7060ad..0000000 --- a/videos/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - bloaterbot - - - - -

NO.

- - diff --git a/webserver/webserver.go b/webserver/webserver.go index 24424d3..7a7029c 100644 --- a/webserver/webserver.go +++ b/webserver/webserver.go @@ -2,16 +2,21 @@ package webserver import ( "net/http" - "watn3y/bloaterbot/config" + "watn3y.de/bloaterbot/config" "github.com/rs/zerolog/log" ) func RunServer() { - fs := http.FileServer(http.Dir("./videos")) - http.Handle("/", fs) + //http.HandleFunc("/", handle204) - log.Info().Str("port", config.BotConfig.Webserver.Port).Str("path", "./videos").Msg("Starting webserver") + videos := http.FileServer(http.Dir("data/videos")) + nenefoot := http.FileServer(http.Dir("data/nenefoot")) + + http.Handle("/", videos) + http.Handle("/nenefoot/", nenefoot) + + log.Info().Str("port", config.BotConfig.Webserver.Port).Msg("Starting webserver") err := http.ListenAndServe(":"+config.BotConfig.Webserver.Port, nil) @@ -20,3 +25,16 @@ func RunServer() { } } + +/*func handle204(w http.ResponseWriter, r *http.Request) { + + buf, err := os.ReadFile("data/204.jpg") + if err != nil { + log.Err(err).Msg("failed to open data/204.jpg") + } + w.Header().Set("Content-Type", "image/jpeg") + w.Write(buf) + return + +} +*/ \ No newline at end of file