Skip to content

Commit

Permalink
update python and packages, skip redis when not available and fix ser…
Browse files Browse the repository at this point in the history
…ver count
  • Loading branch information
zefanjajobse committed Nov 8, 2024
1 parent b4b730c commit 4b2e8f0
Show file tree
Hide file tree
Showing 13 changed files with 780 additions and 511 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.12
FROM python:3.13

WORKDIR /usr/src/app

Expand Down
8 changes: 5 additions & 3 deletions bot.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"""discord api connection"""

import os
import asyncio
import discord
from discord.ext import commands
import discordlists
from cogs.api.redis import redis_connect
from cogs.api.redis import RedisClient
import healthcheck

TOKEN = os.getenv("TOKEN", "")
Expand Down Expand Up @@ -32,7 +33,8 @@ async def on_ready():
print("bot started \n")
print(f"Connected on {len(bot.guilds)} server(s)")

await redis_connect()
redis_client = RedisClient()
await redis_client.redis_connect()

# sync /sync
await bot.tree.sync(guild=discord.Object(770746735533228083))
Expand All @@ -48,7 +50,7 @@ async def on_ready():
while True:
try:
await bot.change_presence(
activity=discord.Game(f"Is in {bot.guilds} servers")
activity=discord.Game(f"in {len(bot.guilds)} servers")
)
await asyncio.sleep(900)
except Exception as e:
Expand Down
1 change: 1 addition & 0 deletions cogs/admin_only.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Admin-only commands"""

import discord
from discord.ext import commands
from discord import app_commands
Expand Down
7 changes: 7 additions & 0 deletions cogs/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Singleton(type):
_instances = {}

def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
11 changes: 11 additions & 0 deletions cogs/api/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import os

REDIS_HOST = os.getenv("redishost", "")
REDIS_PORT = int(os.getenv("redisport", 6379))
REDIS_PASS = os.getenv("redispass", "")

CACHE_TTL_DEFAULT = os.getenv("CACHE_TTL_DEFAULT", 600)
CACHE_TTL_SERVERS = os.getenv("CACHE_TTL_SERVERS", 10)

CACHE_MAX_AGE_DEFAULT = os.getenv("CACHE_MAX_AGE_DEFAULT", 600)
CACHE_MAX_AGE_SERVERS = os.getenv("CACHE_MAX_AGE_SERVERS", 10)
96 changes: 49 additions & 47 deletions cogs/api/redis.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Redis functions"""
import os

import sys
import logging
from datetime import timedelta
from typing import Any

Expand All @@ -9,55 +10,56 @@
import redis.asyncio.cluster
import redis

REDIS_HOST = os.getenv("redishost", "")
REDIS_PORT = int(os.getenv("redisport", 6379))
REDIS_PASS = os.getenv("redispass", "")

CACHE_TTL_DEFAULT = os.getenv("CACHE_TTL_DEFAULT", 600)
CACHE_TTL_SERVERS = os.getenv("CACHE_TTL_SERVERS", 10)

CACHE_MAX_AGE_DEFAULT = os.getenv("CACHE_MAX_AGE_DEFAULT", 600)
CACHE_MAX_AGE_SERVERS = os.getenv("CACHE_MAX_AGE_SERVERS", 10)


async def redis_connect() -> redis.asyncio.client.Redis:
"""Connect to db"""
try:
global client
client = redis.asyncio.cluster.RedisCluster(
host=str(REDIS_HOST),
port=int(REDIS_PORT),
password=str(REDIS_PASS),
socket_timeout=5,
)
ping = await client.ping()
if ping is True:
return
except redis.AuthenticationError:
print("AuthenticationError")
sys.exit(1)
except redis.exceptions.RedisClusterException:
client = redis.asyncio.Redis(
host=str(REDIS_HOST),
port=int(REDIS_PORT),
password=str(REDIS_PASS),
db=0,
socket_timeout=5,
)
ping = await client.ping()
if ping is True:
return
from . import Singleton
from . import config


async def get_from_cache(key: str) -> Any:
"""Data from redis."""
class RedisClient(metaclass=Singleton):
client: redis.asyncio.Redis

val = await client.get(key)
return val
def __init__(self):
self.logger = logging.getLogger("redis")

async def redis_connect(self):
"""Connect to the redis host"""
try:
self.client = redis.asyncio.Redis(
host=str(config.REDIS_HOST),
port=int(config.REDIS_PORT),
password=str(config.REDIS_PASS),
socket_timeout=5,
)
ping = await self.client.ping()
if ping is True:
return
except redis.AuthenticationError:
self.logger.error("Redis authentication error!")
sys.exit(1)
except redis.exceptions.ConnectionError:
self.logger.error("Redis ping error, will retry on use.")
return
except redis.exceptions.TimeoutError:
self.logger.error("Redis timeout error, will retry on use.")
return

async def set_to_cache(key: str, value: str, ttl: int = CACHE_TTL_DEFAULT) -> bool:
"""Data to redis."""
async def get_from_cache(self, key: str) -> Any:
"""Data from redis."""
val = None
try:
val = await self.client.get(key)
except Exception as e:
self.logger.error("failed to get cache! %s", e)
return val

state = await client.setex(key, timedelta(seconds=ttl), value=value)
return state
async def set_to_cache(
self, key: str, value: str, ttl: int = config.CACHE_TTL_DEFAULT
) -> bool:
"""Data to redis."""
if ttl is None:
return True
try:
state = await self.client.setex(key, timedelta(seconds=ttl), value=value)
return state
except Exception as e:
self.logger.error("failed to set cache! %s", e)
return False
1 change: 1 addition & 0 deletions cogs/beamng_mp.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Beamng-mp cog"""

import re
from typing import List
import discord
Expand Down
10 changes: 6 additions & 4 deletions cogs/commands/beamng.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import pycountry
import discord

from ..api.redis import get_from_cache, set_to_cache, CACHE_MAX_AGE_SERVERS
from ..api.redis import RedisClient
from ..api import config


async def sizeof_fmt(num, suffix="B"):
Expand All @@ -18,7 +19,8 @@ async def sizeof_fmt(num, suffix="B"):

async def read_api():
"""Read the beamng API"""
data = await get_from_cache("beamMp:servers")
redis_client = RedisClient()
data = await redis_client.get_from_cache("beamMp:servers")
if data is not None:
# To not spam their api
result = json.loads(data)
Expand All @@ -28,10 +30,10 @@ async def read_api():
async with session.get(url) as r:
result = await r.json()
data = json.dumps(result)
await set_to_cache(
await redis_client.set_to_cache(
"beamMp:servers",
data,
CACHE_MAX_AGE_SERVERS,
config.CACHE_MAX_AGE_SERVERS,
)
return result

Expand Down
1 change: 1 addition & 0 deletions cogs/other.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Help cog"""

import discord
from discord.ext import commands
from discord.ext.commands import AutoShardedBot
Expand Down
1 change: 1 addition & 0 deletions cogs/sync.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Discord command syncing"""

from typing import Literal, Optional
from pprint import pprint
import discord
Expand Down
1 change: 1 addition & 0 deletions healthcheck.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Discord.py healthcheck"""

import asyncio
import discord

Expand Down
Loading

0 comments on commit 4b2e8f0

Please sign in to comment.