if recipient is None

This commit is contained in:
2025-02-15 13:57:47 -05:00
parent 9d23438b13
commit 6463ace40c
9 changed files with 617 additions and 716 deletions

View File

@@ -6,7 +6,7 @@ import traceback
import random
import datetime
import pytz
from typing import Optional, LiteralString
from typing import Any, Optional, LiteralString, Union
import regex
import aiosqlite as sqlite3
from aiohttp import ClientSession, ClientTimeout
@@ -19,7 +19,7 @@ class Util:
self.URL_URBANDICTIONARY: str = "http://api.urbandictionary.com/v0/define"
self.URL_INSULTAPI: str = "https://insult.mattbas.org/api/insult"
self.COMPLIMENT_GENERATOR = ComplimentGenerator()
self.dbs: dict[str|LiteralString] = {
self.dbs: dict[str, str|LiteralString] = {
'whisky': os.path.join("/usr/local/share",
"sqlite_dbs", "whiskey.db"),
'drinks': os.path.join("/usr/local/share",
@@ -73,50 +73,42 @@ class Util:
(mics, mils) = _t(td.microseconds, 1000)
return (td.days, h, m, s, mics, mils)
def sqlite_dict_factory(self, cursor: sqlite3.Cursor, row: sqlite3.Row) -> dict:
"""
SQLite Dict Factory for Rows Returned
Args:
cursor (sqlite3.Row)
row (sqlite3.Row)
Returns:
dict
"""
fields = [column[0] for column in cursor.description]
return { key: value for key, value in zip(fields, row) }
async def get_counter(self, counter: Optional[str] = None) -> dict:
async def get_counter(self, counter: Optional[str] = None) -> Optional[dict]:
"""
Get Counter
Args:
counter (Optional[str])
Returns:
dict
Optional[dict]
"""
async with sqlite3.connect(self.dbs.get('stats'),
stats_db: str|LiteralString = self.dbs.get('stats', '')
if not stats_db:
return None
async with sqlite3.connect(stats_db,
timeout=3) as db_conn:
db_conn.row_factory = self.sqlite_dict_factory
db_conn.row_factory = sqlite3.Row
query: str = "SELECT ? FROM stats LIMIT 1"
if not counter:
query: str = "SELECT * FROM stats LIMIT 1"
query = "SELECT * FROM stats LIMIT 1"
async with await db_conn.execute(query, (counter,) if counter else None) as db_cursor:
result: dict = await db_cursor.fetchone()
result = await db_cursor.fetchone()
return result
async def get_stats_embed(self) -> Embed:
async def get_stats_embed(self) -> Optional[Embed]:
"""
Get Stats Embed
Returns:
Embed
Optional[Embed]
"""
counters: dict = await self.get_counter()
counters: Optional[dict] = await self.get_counter()
if not counters:
return None
embed: Embed = Embed(title="Stats")
counter_message: str = ""
counters_sorted: dict = dict(sorted(counters.items(),
key=lambda item: item[1], reverse=True))
for counter, value in counters_sorted.items():
counter: str = regex.sub(r'_', ' ',
counter = regex.sub(r'_', ' ',
counter.strip()).title()
counter_message += f"- {value} {counter}\n"
embed.description = counter_message.strip()
@@ -130,7 +122,10 @@ class Util:
Returns:
bool
"""
async with sqlite3.connect(self.dbs.get('stats'),
stats_db: str|LiteralString = self.dbs.get('stats', '')
if not stats_db:
return False
async with sqlite3.connect(stats_db,
timeout=3) as db_conn:
async with await db_conn.execute(f"UPDATE stats SET {counter} = {counter} + 1") as db_cursor:
if db_cursor.rowcount < 0:
@@ -139,11 +134,11 @@ class Util:
await db_conn.commit()
return True
async def get_ud_def(self, term: Optional[str] = None) -> tuple[str, str]:
async def get_ud_def(self, term: str) -> tuple[str, str]:
"""
Get Definition from UD
Args:
term (Optional[str])
term (str)
Returns:
tuple[str, str]
"""
@@ -202,93 +197,107 @@ class Util:
return self.COMPLIMENT_GENERATOR.compliment(subject)
return self.COMPLIMENT_GENERATOR.compliment_in_language(subject, language)
async def get_whisky(self) -> tuple:
async def get_whisky(self) -> Optional[tuple]:
"""
Get Whisky
Returns:
tuple
Optional[tuple]
"""
whisky_db: str|LiteralString = self.dbs.get('whisky')
db_conn = await sqlite3.connect(database=whisky_db, timeout=2)
db_query: str = "SELECT name, category, description FROM whiskeys ORDER BY random() LIMIT 1"
db_cursor: sqlite3.Cursor = await db_conn.execute(db_query)
db_result: tuple = await db_cursor.fetchone()
(name, category, description) = db_result
name: str = regex.sub(r'(^\p{White_Space}|\r|\n)', '',
regex.sub(r'\p{White_Space}{2,}', ' ',
name.strip()))
category: str = regex.sub(r'(^\p{White_Space}|\r|\n)', '',
regex.sub(r'\p{White_Space}{2,}', ' ',
category.strip()))
description: str = regex.sub(r'(^\p{White_Space}|\r|\n)', '',
whisky_db: str|LiteralString = self.dbs.get('whisky', '')
if not whisky_db:
return None
async with sqlite3.connect(database=whisky_db,
timeout=2) as db_conn:
db_query: str = "SELECT name, category, description FROM whiskeys ORDER BY random() LIMIT 1"
async with await db_conn.execute(db_query) as db_cursor:
db_result: Optional[Union[sqlite3.Row, tuple]] = await db_cursor.fetchone()
if not db_result:
return None
(name, category, description) = db_result
name = regex.sub(r'(^\p{White_Space}|\r|\n)', '',
regex.sub(r'\p{White_Space}{2,}', ' ',
description.strip()))
return (name, category, description)
name.strip()))
category = regex.sub(r'(^\p{White_Space}|\r|\n)', '',
regex.sub(r'\p{White_Space}{2,}', ' ',
category.strip()))
description = regex.sub(r'(^\p{White_Space}|\r|\n)', '',
regex.sub(r'\p{White_Space}{2,}', ' ',
description.strip()))
return (name, category, description)
async def get_drink(self) -> tuple:
async def get_drink(self) -> Optional[tuple]:
"""
Get Drink
Returns:
tuple
Optional[tuple]
"""
drinks_db: str|LiteralString = self.dbs.get('drinks')
db_conn = await sqlite3.connect(database=drinks_db, timeout=2)
db_query: str = "SELECT name, ingredients FROM cocktails ORDER BY random() LIMIT 1"
db_cursor: sqlite3.Cursor = await db_conn.execute(db_query)
db_result: tuple = await db_cursor.fetchone()
drinks_db: str|LiteralString = self.dbs.get('drinks', '')
if not drinks_db:
return None
async with sqlite3.connect(database=drinks_db,
timeout=2) as db_conn:
db_query: str = "SELECT name, ingredients FROM cocktails ORDER BY random() LIMIT 1"
async with await db_conn.execute(db_query) as db_cursor:
db_result: tuple = await db_cursor.fetchone()
(name, ingredients) = db_result
name = regex.sub(r'(^\p{White_Space}|\r|\n)', '', regex.sub(r'\p{White_Space}{2,}', ' ', name.strip()))
ingredients = regex.sub(r'(^\p{White_Space}|\r|\n)', '', regex.sub(r'\p{White_Space}{2,}', ' ', ingredients.strip()))
ingredients = regex.sub(r'\*', '\u2731', ingredients.strip())
return (name, ingredients)
(name, ingredients) = db_result
name = regex.sub(r'(^\p{White_Space}|\r|\n)', '', regex.sub(r'\p{White_Space}{2,}', ' ', name.strip()))
ingredients = regex.sub(r'(^\p{White_Space}|\r|\n)', '', regex.sub(r'\p{White_Space}{2,}', ' ', ingredients.strip()))
ingredients = regex.sub(r'\*', '\u2731', ingredients.strip())
return (name, ingredients)
async def get_strain(self, strain: Optional[str] = None) -> tuple:
async def get_strain(self, strain: Optional[str] = None) -> Optional[tuple]:
"""
Get Strain
Args:
strain (Optional[str])
Returns:
tuple
Optional[tuple]
"""
strains_db: str|LiteralString = self.dbs.get('strains')
db_conn = await sqlite3.connect(database=strains_db, timeout=2)
db_params: Optional[tuple] = None
if not strain:
db_query: str = "SELECT name, description FROM strains_w_desc ORDER BY random() LIMIT 1"
else:
db_query: str = "SELECT name, description FROM strains_w_desc WHERE name LIKE ?"
db_params: tuple = (f"%{strain.strip()}%",)
db_cursor: sqlite3.Cursor = await db_conn.execute(db_query, db_params)
db_result: tuple = await db_cursor.fetchone()
strains_db: str|LiteralString = self.dbs.get('strains', '')
if not strains_db:
return None
async with sqlite3.connect(database=strains_db,
timeout=2) as db_conn:
db_params: Optional[tuple] = None
if not strain:
db_query: str = "SELECT name, description FROM strains_w_desc ORDER BY random() LIMIT 1"
else:
db_query = "SELECT name, description FROM strains_w_desc WHERE name LIKE ?"
db_params = (f"%{strain.strip()}%",)
async with await db_conn.execute(db_query, db_params) as db_cursor:
db_result: Optional[tuple] = await db_cursor.fetchone()
return db_result
return db_result
async def get_qajoke(self) -> tuple:
async def get_qajoke(self) -> Optional[tuple]:
"""
Get QA Joke
Returns:
tuple
Optional[tuple]
"""
qajoke_db: str|LiteralString = self.dbs.get('qajoke')
async with sqlite3.connect(database=qajoke_db, timeout=2) as db:
async with await db.execute('SELECT question, answer FROM jokes ORDER BY RANDOM() LIMIT 1') as cursor:
qajoke_db: str|LiteralString = self.dbs.get('qajoke', '')
if not qajoke_db:
return None
async with sqlite3.connect(database=qajoke_db,
timeout=2) as db_conn:
db_query: str = "SELECT question, answer FROM jokes ORDER BY RANDOM() LIMIT 1"
async with await db_conn.execute(db_query) as cursor:
(question, answer) = await cursor.fetchone()
return (question, answer)
return None
async def get_rjoke(self) -> tuple:
async def get_rjoke(self) -> Optional[tuple]:
"""
Get r/joke Joke
Returns:
tuple
Optional[tuple]
"""
rjokes_db: str|LiteralString = self.dbs.get('rjokes')
async with sqlite3.connect(database=rjokes_db, timeout=2) as db:
async with await db.execute('SELECT title, body, score FROM jokes WHERE score >= 100 ORDER BY RANDOM() LIMIT 1') as cursor:
rjokes_db: str|LiteralString = self.dbs.get('rjokes', '')
if not rjokes_db:
return None
async with sqlite3.connect(database=rjokes_db, timeout=2) as db_conn:
db_query: str = "SELECT title, body, score FROM jokes WHERE score >= 100 ORDER BY RANDOM() LIMIT 1'"
async with await db_conn.execute(db_query) as cursor:
(title, body, score) = await cursor.fetchone()
return (title, body, score)
return None
@@ -307,29 +316,34 @@ class Util:
try:
async with await client.get(facts_api_url,
timeout=ClientTimeout(connect=5, sock_read=5)) as request:
json: dict = await request.json()
fact: str = json.get('text')
_json: dict = await request.json()
fact: str = _json.get('text', None)
if not fact:
raise BaseException("RandFact Src 1 Failed")
return fact
except:
async with await client.get(facts_backup_url,
timeout=ClientTimeout(connect=5, sock_read=5)) as request:
json: dict = await request.json()
fact: str = json.get('fact')
_json = await request.json()
fact = _json.get('fact', None)
return fact
except Exception as e:
traceback.print_exc()
return f"Failed to get a random fact :( [{str(e)}]"
async def get_cookie(self) -> dict:
async def get_cookie(self) -> Optional[dict]:
"""
Get Cookie
Returns:
dict
Optional[dict]
"""
async with sqlite3.connect(self.dbs.get('cookies'), timeout=2) as db_conn:
async with await db_conn.execute("SELECT name, origin, image_url FROM cookies ORDER BY RANDOM() LIMIT 1") as db_cursor:
cookies_db = self.dbs.get('cookies', '')
if not cookies_db:
return None
async with sqlite3.connect(cookies_db,
timeout=2) as db_conn:
db_query: str = "SELECT name, origin, image_url FROM cookies ORDER BY RANDOM() LIMIT 1"
async with await db_conn.execute(db_query) as db_cursor:
(name, origin, image_url) = await db_cursor.fetchone()
return {
'name': name,
@@ -338,7 +352,7 @@ class Util:
}
def get_coffee(self) -> str:
def get_coffee(self) -> Optional[str]:
"""
Get Coffee
Returns:
@@ -354,16 +368,16 @@ class Util:
return randomCoffee
except:
traceback.print_exc()
return False
return None
def get_days_to_xmas(self) -> tuple[int|float]:
def get_days_to_xmas(self) -> Optional[tuple]:
"""
Get # of Days until Xmas
Returns:
tuple[int|float]
Optional[tuple]
"""
today: datetime = datetime.datetime.now(tz=pytz.UTC)
xmas: datetime = datetime.datetime(
today: datetime.datetime = datetime.datetime.now(tz=pytz.UTC)
xmas: datetime.datetime = datetime.datetime(
year=today.year,
month=12,
day=25,
@@ -374,15 +388,18 @@ class Util:
return (days, hours, minutes, seconds, ms, us)
async def get_randmsg(self) -> str:
async def get_randmsg(self) -> Optional[str]:
"""
Get Random Message from randmsg.db
Returns:
str
Optional[str]
"""
randmsg_db = self.dbs.get('randmsg')
randmsg_db: str|LiteralString = self.dbs.get('randmsg', '')
if not randmsg_db:
return None
async with sqlite3.connect(database=randmsg_db,
timeout=2) as db_conn:
async with await db_conn.execute("SELECT msg FROM msgs ORDER BY RANDOM() LIMIT 1") as db_cursor:
db_query: str = "SELECT msg FROM msgs ORDER BY RANDOM() LIMIT 1"
async with await db_conn.execute(db_query) as db_cursor:
(result,) = await db_cursor.fetchone()
return result