REFACTOR: Use connection pooling

Signed-off-by: baalajimaestro <me@baalajimaestro.me>
This commit is contained in:
baalajimaestro 2022-11-12 13:35:24 +05:30
parent f0954bdcbc
commit 20f397135b
Signed by: baalajimaestro
GPG key ID: F93C394FE9BBAFD5

View file

@ -12,14 +12,13 @@ import std/[asyncdispatch,
options, options,
strutils, strutils,
random, random,
with,
os, os,
tables, tables,
times, times,
sequtils, sequtils,
json] json]
import norm/[model, sqlite] import norm/[model, sqlite, pool]
# Logging Level # Logging Level
var L = newConsoleLogger(levelThreshold=lvlError, fmtStr="$levelname, [$time] ") var L = newConsoleLogger(levelThreshold=lvlError, fmtStr="$levelname, [$time] ")
@ -49,6 +48,7 @@ var GroupMedia = initTable[int, string]()
let AdminID = getEnv("ADMIN_ID").split(",") let AdminID = getEnv("ADMIN_ID").split(",")
let dbConn* = getDb() let dbConn* = getDb()
var connPool = newPool[DbConn](15)
# Functions to assist adding/deleting entries from tables # Functions to assist adding/deleting entries from tables
func NewCensoredData*(ftype = ""; fhash = ""; fileid = ""; time = 0.0; caption = ""): func NewCensoredData*(ftype = ""; fhash = ""; fileid = ""; time = 0.0; caption = ""):
@ -58,8 +58,9 @@ func NewBannedUsers*(userid = int64(0), bantime = 0.0, bantype = ""):
BannedUsers = BannedUsers(userid: userid, bantime: bantime, bantype: bantype) BannedUsers = BannedUsers(userid: userid, bantime: bantime, bantype: bantype)
# Create tables if they dont exist # Create tables if they dont exist
dbConn.createTables(NewCensoredData()) withDb(connPool):
dbConn.createTables(NewBannedUsers()) db.createTables(NewCensoredData())
db.createTables(NewBannedUsers())
# Ratelimits a user if there is more than 30 timestamps within 60 secs. # Ratelimits a user if there is more than 30 timestamps within 60 secs.
# Resets their ratelimit counter if 60s has passed since first timestamp # Resets their ratelimit counter if 60s has passed since first timestamp
@ -70,24 +71,26 @@ proc ManageRateLimit(): void=
elif len(RateLimiter[i]) >= 30: elif len(RateLimiter[i]) >= 30:
var BannedUser = NewBannedUsers(i, epochTime(), "auto") var BannedUser = NewBannedUsers(i, epochTime(), "auto")
RateLimiter.del(i) RateLimiter.del(i)
with dbConn: withDb(connPool):
insert BannedUser db.insert(BannedUser)
if dbConn.exists(BannedUsers, "bantype = ? and ? - bantime >= 1800", "auto", epochTime()): withDb(connPool):
if db.exists(BannedUsers, "bantype = ? and ? - bantime >= 1800", "auto", epochTime()):
var TempData = @[NewBannedUsers()] var TempData = @[NewBannedUsers()]
dbConn.select(TempData, "bantype = ? and ? - bantime >= 1800", "auto", epochTime()) db.select(TempData, "bantype = ? and ? - bantime >= 1800", "auto", epochTime())
for i in TempData: for i in TempData:
var e = i var e = i
dbConn.delete(e) db.delete(e)
# Cleanup old data to save space # Cleanup old data to save space
# Deletes old data after 6 months of entry # Deletes old data after 6 months of entry
proc OldDataCleanup(): void= proc OldDataCleanup(): void=
if dbConn.exists(CensoredData, "? - time >= 15780000", epochTime()): withDb(connPool):
if db.exists(CensoredData, "? - time >= 15780000", epochTime()):
var TempData = @[NewCensoredData()] var TempData = @[NewCensoredData()]
dbConn.select(TempData, "? - time >= 15780000", epochTime()) db.select(TempData, "? - time >= 15780000", epochTime())
for i in TempData: for i in TempData:
var e = i var e = i
dbConn.delete(e) db.delete(e)
# Generates a 6-character magic that will be used to identify the file # Generates a 6-character magic that will be used to identify the file
proc generate_hash(): string= proc generate_hash(): string=
@ -101,7 +104,8 @@ proc generate_hash(): string=
proc startHandler(b: Telebot, c: Command): Future[bool] {.gcsafe, async.} = proc startHandler(b: Telebot, c: Command): Future[bool] {.gcsafe, async.} =
let param = c.params let param = c.params
ManageRateLimit() ManageRateLimit()
if not dbConn.exists(BannedUsers, "userid = ?", c.message.chat.id): withDb(connPool):
if not db.exists(BannedUsers, "userid = ?", c.message.chat.id):
# Update rate-limit counter # Update rate-limit counter
if not AdminID.contains($c.message.chat.id): if not AdminID.contains($c.message.chat.id):
if RateLimiter.contains(c.message.chat.id): if RateLimiter.contains(c.message.chat.id):
@ -113,12 +117,12 @@ proc startHandler(b: Telebot, c: Command): Future[bool] {.gcsafe, async.} =
"Hey, To create a censored post, you can share any album, video, photo, gif, sticker, etc. " & "Hey, To create a censored post, you can share any album, video, photo, gif, sticker, etc. " &
"The response of the bot can be used to share the media with other chats.") "The response of the bot can be used to share the media with other chats.")
else: else:
if not dbConn.exists(CensoredData, "fhash = ?", param): if not db.exists(CensoredData, "fhash = ?", param):
discard await b.sendMessage(c.message.chat.id, discard await b.sendMessage(c.message.chat.id,
"Media does not exist on database, ask the sender to censor this again!") "Media does not exist on database, ask the sender to censor this again!")
else: else:
var TempData = @[NewCensoredData()] var TempData = @[NewCensoredData()]
dbConn.select(TempData, "fhash = ?", param) db.select(TempData, "fhash = ?", param)
if len(TempData) > 1: if len(TempData) > 1:
var inputmedia = newSeq[InputMediaPhoto]() var inputmedia = newSeq[InputMediaPhoto]()
for i in TempData: for i in TempData:
@ -144,7 +148,8 @@ proc startHandler(b: Telebot, c: Command): Future[bool] {.gcsafe, async.} =
# Give them source url # Give them source url
proc sourceHandler(b: Telebot, c: Command): Future[bool] {.gcsafe, async.} = proc sourceHandler(b: Telebot, c: Command): Future[bool] {.gcsafe, async.} =
ManageRateLimit() ManageRateLimit()
if not dbConn.exists(BannedUsers, "userid = ?", c.message.chat.id): withDb(connPool):
if not db.exists(BannedUsers, "userid = ?", c.message.chat.id):
# Update rate-limit counter # Update rate-limit counter
if not AdminID.contains($c.message.chat.id): if not AdminID.contains($c.message.chat.id):
if RateLimiter.contains(c.message.chat.id): if RateLimiter.contains(c.message.chat.id):
@ -162,12 +167,13 @@ proc sourceHandler(b: Telebot, c: Command): Future[bool] {.gcsafe, async.} =
proc unbanHandler(b: Telebot, c: Command): Future[bool] {.gcsafe, async.} = proc unbanHandler(b: Telebot, c: Command): Future[bool] {.gcsafe, async.} =
if $c.message.chat.id in AdminID: if $c.message.chat.id in AdminID:
let user = c.params let user = c.params
if dbConn.exists(BannedUsers, "userid = ?", int64(parseInt(user))): withDb(connPool):
if db.exists(BannedUsers, "userid = ?", int64(parseInt(user))):
var TempData = @[NewBannedUsers()] var TempData = @[NewBannedUsers()]
dbConn.select(TempData, "userid = ?", int64(parseInt(user))) db.select(TempData, "userid = ?", int64(parseInt(user)))
for i in TempData: for i in TempData:
var e = i var e = i
dbConn.delete(e) db.delete(e)
discard await b.sendMessage(c.message.chat.id, "Unbanned!") discard await b.sendMessage(c.message.chat.id, "Unbanned!")
# ban Handler # ban Handler
@ -175,12 +181,12 @@ proc banHandler(b: Telebot, c: Command): Future[bool] {.gcsafe, async.} =
if $c.message.chat.id in AdminID: if $c.message.chat.id in AdminID:
let user = c.params let user = c.params
var BannedUser = NewBannedUsers(int64(parseInt(user)), epochTime(), "permanent") var BannedUser = NewBannedUsers(int64(parseInt(user)), epochTime(), "permanent")
with dbConn: withDb(connPool):
insert BannedUser db.insert(BannedUser)
discard await b.sendMessage(c.message.chat.id, "Banned!") discard await b.sendMessage(c.message.chat.id, "Banned!")
# Inline share handler # Inline share handler
proc inlineHandler(b: Telebot, u: InlineQuery): Future[bool]{.async.} = proc inlineHandler(b: Telebot, u: InlineQuery): Future[bool]{.gcsafe, async.} =
var TempData = @[NewCensoredData()] var TempData = @[NewCensoredData()]
var ftype = "" var ftype = ""
var res: InlineQueryResultArticle var res: InlineQueryResultArticle
@ -188,12 +194,13 @@ proc inlineHandler(b: Telebot, u: InlineQuery): Future[bool]{.async.} =
res.kind = "article" res.kind = "article"
res.id = "1" res.id = "1"
if u.query != "": if u.query != "":
if not dbConn.exists(CensoredData, "fhash = ?",u.query): withDb(connPool):
if not db.exists(CensoredData, "fhash = ?",u.query):
res.title = "Media Not Found" res.title = "Media Not Found"
res.inputMessageContent = InputTextMessageContent( res.inputMessageContent = InputTextMessageContent(
"Media does not exist on database, ask the sender to censor this again!").some "Media does not exist on database, ask the sender to censor this again!").some
else: else:
dbConn.select(TempData, "fhash = ?", u.query) db.select(TempData, "fhash = ?", u.query)
if len(TempData) > 1: if len(TempData) > 1:
ftype = "Album" ftype = "Album"
elif len(TempData) == 1: elif len(TempData) == 1:
@ -220,8 +227,9 @@ proc updateHandler(b: Telebot, u: Update): Future[bool] {.async, gcsafe.} =
let response = u.message.get let response = u.message.get
# Refresh rate-limits # Refresh rate-limits
ManageRateLimit() ManageRateLimit()
withDb(connPool):
# Dont bother about rate-limited/banned users # Dont bother about rate-limited/banned users
if not dbConn.exists(BannedUsers, "userid = ?", response.chat.id): if not db.exists(BannedUsers, "userid = ?", response.chat.id):
# Update rate-limit counter # Update rate-limit counter
if not AdminID.contains($response.chat.id): if not AdminID.contains($response.chat.id):
if RateLimiter.contains(response.chat.id): if RateLimiter.contains(response.chat.id):
@ -259,8 +267,8 @@ proc updateHandler(b: Telebot, u: Update): Future[bool] {.async, gcsafe.} =
let filehash = generate_hash() let filehash = generate_hash()
GroupMedia[parseInt(response.mediaGroupId.get)] = filehash GroupMedia[parseInt(response.mediaGroupId.get)] = filehash
var CensoredRow = NewCensoredData(ftype, filehash, fileid, epochTime(), fcaption) var CensoredRow = NewCensoredData(ftype, filehash, fileid, epochTime(), fcaption)
with dbConn: withDb(connPool):
insert CensoredRow db.insert(CensoredRow)
var replybutton = InlineKeyboardButton(text: "Share", switchInlineQuery: some(filehash)) var replybutton = InlineKeyboardButton(text: "Share", switchInlineQuery: some(filehash))
let replymark = newInlineKeyboardMarkup(@[replybutton]) let replymark = newInlineKeyboardMarkup(@[replybutton])
discard await b.sendMessage(response.chat.id, discard await b.sendMessage(response.chat.id,
@ -276,14 +284,14 @@ proc updateHandler(b: Telebot, u: Update): Future[bool] {.async, gcsafe.} =
else: else:
let filehash = GroupMedia[parseInt(response.mediaGroupId.get)] let filehash = GroupMedia[parseInt(response.mediaGroupId.get)]
var CensoredRow = NewCensoredData(ftype, filehash, fileid, epochTime(), fcaption) var CensoredRow = NewCensoredData(ftype, filehash, fileid, epochTime(), fcaption)
with dbConn: withDb(connPool):
insert CensoredRow db.insert(CensoredRow)
else: else:
let filehash = generate_hash() let filehash = generate_hash()
var CensoredRow = NewCensoredData(ftype, filehash, fileid, epochTime(), fcaption) var CensoredRow = NewCensoredData(ftype, filehash, fileid, epochTime(), fcaption)
with dbConn: withDb(connPool):
insert CensoredRow db.insert(CensoredRow)
var replybutton = InlineKeyboardButton(text: "Share", switchInlineQuery: some(filehash)) var replybutton = InlineKeyboardButton(text: "Share", switchInlineQuery: some(filehash))
let replymark = newInlineKeyboardMarkup(@[replybutton]) let replymark = newInlineKeyboardMarkup(@[replybutton])
discard await b.sendMessage(response.chat.id, discard await b.sendMessage(response.chat.id,