Exemple #1
0
 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 = {}
Exemple #2
0
 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()
Exemple #3
0
    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)
Exemple #4
0
    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)
Exemple #5
0
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}'}
Exemple #6
0
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()
Exemple #7
0
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