def __init__(self, total_shards): logger.info(f"Number of shards: {total_shards}") self.hoarfrost_gen = HoarFrostGenerator() self.total_shards = total_shards self.registered = [False for _ in range(total_shards)] self.last_checkin = {} self.store = {}
def __init__(self, total_shards): """ Instantiates a new manager server that handles some number of shards. """ logger.info(f"Number of shards: {total_shards}") self.hoarfrost_gen = HoarFrostGenerator() self.total_shards = total_shards self.registered = [False for _ in range(total_shards)] self.last_checkin = dict() self.store = dict()
def __init__(self, **kwargs): self.session = get_session() self.asyncpg_wrapper = AsyncConnWrapper() self.deletable_messages = [] self.hoarfrost_gen = HoarFrostGenerator() logger.debug("registering with manager...") manager_client = grpc_client.get_blocking_client('manager:50051') while True: try: shard_info = manager_client.register(message.RegisterRequest()) break except Exception: logger.info("Trying to get shard id from manager") time.sleep(3) self.shard_id = shard_info.shard_id shard_dict = { 'shard_id': shard_info.shard_id, 'shard_count': shard_info.shard_count } logger.info(f"Got shard_id {self.shard_id}") kwargs.update(shard_dict) super().__init__(**kwargs)
def __init__(self, **kwargs): self.user_commands = {} self.session = get_session() self.deletable_messages = [] self.hoarfrost_gen = HoarFrostGenerator() manager_client = blocking_rpc_client.shardRPC() # wait for manager to come up; this is scuffed import time time.sleep(2) logger.debug("asking for shard id") shard_info, sc = manager_client.register(routing_key='manager_rpc') self.shard_id = shard_info['shard_id'] logger.info(f"Got shard_id {self.shard_id}") kwargs.update(shard_info) super().__init__(**kwargs)
class Manager: """Manages shards. assigns shard nodes their ids and checks if they are alive""" def __init__(self, total_shards): logger.info(f"Number of shards: {total_shards}") self.hoarfrost_gen = HoarFrostGenerator() self.total_shards = total_shards self.registered = [False for _ in range(total_shards)] self.last_checkin = {} self.store = {} async def handle_task(self, method, *args, **kwargs): try: return (await (getattr(self, method)(*args, **kwargs)), 200) except Exception as e: logger.exception(f"caught: '{e}' while executing '{method}'") return {'message': f"caught: '{e}' while executing '{method}'"} async def health_check(self): while True: await asyncio.sleep(1) for shard, last_checkin in self.last_checkin.items(): if last_checkin is not None and last_checkin < datetime.now() - timedelta(seconds=5): logger.error(f"--- SHARD {shard} MISSED ITS HEARTBEAT, DEREGISTERING... ---") self.registered[shard] = False self.last_checkin[shard] = None async def register(self): """Returns the next shard id that needs to be filled as well as the total shards""" if all(self.registered): raise Exception("Shard trying to register even though we're full") i = next(i for i in range(self.total_shards) if not self.registered[i]) logger.info(f'Shard requested id, assigning {i + 1}/{self.total_shards}...') self.store[i] = {'shard_id': i} self.registered[i] = True return {'shard_id': i, 'shard_count': self.total_shards} async def all_guilds(self): """Return information about all guilds that the bot is in, including their admins""" guilds = [] for shard, shard_store in self.store.items(): guilds += shard_store.get('guilds', ()) return guilds async def guild_count(self): """Return guild and user count information""" guild_count = 0 user_count = 0 for shard, shard_store in self.store.items(): guilds = shard_store.get('guilds', ()) guild_count += len(guilds) for guild in guilds: user_count += guild['member_count'] return {'guild_count': guild_count, 'user_count': user_count} async def guild_update(self, shard_id, guilds): """Update the manager with the latest information about a shard's guilds""" logger.debug(f"someone sent guild list containing {len(guilds)} guilds") self.store[int(shard_id)]['guilds'] = guilds return {"message": "thanks"} async def checkin(self, shard_id): self.last_checkin[shard_id] = datetime.now() self.registered[shard_id] = True return "nice" async def publish_file(self, location: str = 'assets', name: str = '', filetype: str = 'png', data: str = ''): assert data != '' if name == '': name = str(self.hoarfrost_gen.generate()) directory = f'/var/www/{location}' if not os.path.exists(directory): os.makedirs(directory) with open(f'{directory}/{name}.{filetype}', 'wb') as f: logger.info(f'writing {directory}/{name}.{filetype}') f.write(base64.b64decode(data)) return {'url': f'https://cdn.{domain_name}/{location}/{name}.{filetype}'}
class Manager(manager_grpc.ManagerServicer): """ Implements a server for the Manager gRPC protocol. """ def __init__(self, total_shards): """ Instantiates a new manager server that handles some number of shards. """ logger.info(f"Number of shards: {total_shards}") self.hoarfrost_gen = HoarFrostGenerator() self.total_shards = total_shards self.registered = [False for _ in range(total_shards)] self.last_checkin = dict() self.store = dict() def health_check(self): while True: time.sleep(5) for shard, last_checkin in self.last_checkin.items(): if last_checkin is not None and last_checkin < datetime.now( ) - timedelta(seconds=5): logger.error( f"--- SHARD {shard} MISSED ITS HEARTBEAT, DEREGISTERING... ---" ) self.registered[shard] = False self.last_checkin[shard] = None def register(self, request, context): """Returns the next shard id that needs to be filled as well as the total shards""" if all(self.registered): raise Exception("Shard trying to register even though we're full") i = next(i for i in range(self.total_shards) if not self.registered[i]) logger.info( f"Shard requested id, assigning {i + 1}/{self.total_shards}...") self.registered[i] = True return message.ShardInfo(shard_id=i, shard_count=self.total_shards) def guild_count(self, request, context): """Return guild and user count information""" gc = 0 uc = 0 for guilds in self.store.values(): gc += len(guilds) for guild in guilds: uc += guild.member_count return message.GuildInfo(guild_count=gc, user_count=uc) def checkin(self, request, context): self.last_checkin[request.shard_id] = datetime.now() self.registered[request.shard_id] = True return message.CheckInResponse() def publish_file(self, request_iterator, context): """Missing associated documentation comment in .proto file""" first = next(request_iterator) filetype = "png" if first.filetype == "" else first.filetype name = first.name if name == "": name = str(self.hoarfrost_gen.generate()) location = first.location if location == "": location = "assets" directory = f"/var/www/{location}" if not os.path.exists(directory): os.makedirs(directory) with open(f"{directory}/{name}.{filetype}", "wb") as f: logger.info(f"Writing {directory}/{name}.{filetype}") f.write(first.file) for datum in request_iterator: f.write(datum.file) return message.Url( url=f"https://cdn.{domain_name}/{location}/{name}.{filetype}") def all_guilds(self, request, context): """Return information about all guilds that the bot is in, including their admins""" for guilds in self.store.values(): for guild in guilds: yield guild def guild_update(self, request_iterator, context): """Update the manager with the latest information about a shard's guilds""" guilds = [] for guild in request_iterator: guilds.append(guild) if len(guilds) == 0: return message.UpdateResponse() logger.debug( f"Received guild list from shard {guilds[0].shard_id + 1} of {len(guilds)} guilds" ) self.store[guilds[0].shard_id] = guilds return message.UpdateResponse()
from discord import Emoji from PIL import ImageChops, Image from lib.hoar_frost import HoarFrostGenerator from src.utils import download_emoji from lib.config import logger hoarfrost_gen = HoarFrostGenerator() class ArchitusEmoji: @classmethod async def from_discord(cls, emoji: Emoji): '''creates an architus emoji from a discord emoji''' im = Image.open(await download_emoji(emoji)) return cls(im, emoji.name, None, emoji.id, emoji.user.id if emoji.user is not None else None) def __init__(self, im: Image, name: str, id: int = None, discord_id: int = None, author_id: int = None, num_uses: int = 0, priority: float = 0.0): self.im = im self.name = name if id is None:
import os import string import time from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine import json from collections import defaultdict from lib.models import Command, AutoResponse, Settings from lib.hoar_frost import HoarFrostGenerator from lib.response_grammar.response import parse from lib.reggy.reggy import Reggy from src.auto_response import ResponseMode hoarfrost_gen = HoarFrostGenerator() DB_HOST = 'postgres' DB_PORT = 5432 db_user = os.environ['db_user'] db_pass = os.environ['db_pass'] engine = create_engine(f"postgresql://{db_user}:{db_pass}@{DB_HOST}:{DB_PORT}/autbot") Session = sessionmaker(bind=engine) session = Session() command_list = session.query(Command).all() def load_settings(guild_id): settings_row = None