import random import re # discord.py has a different name # noinspection PyPackageRequirements import discord # noinspection PyPackageRequirements import discord.opus # noinspection PyPackageRequirements import discord.voice_client import functools import sys import db import youtube_dl import concurrent.futures import typing import os import asyncio import configparser import async_timeout import raven import logging import datetime import sqlalchemy.exc import coloredlogs import errors import math import enum import requests logging.getLogger().disabled = True logger = logging.getLogger(__name__) os.environ["COLOREDLOGS_LOG_FORMAT"] = "%(asctime)s %(levelname)s %(name)s %(message)s" coloredlogs.install(level="DEBUG", logger=logger) # Number emojis from zero (now playing) to ten number_emojis = [":arrow_forward:", ":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:", ":nine:", ":keycap_ten:"] # Init the event loop loop = asyncio.get_event_loop() # FFmpeg settings ffmpeg_settings = {} # Init the executor executor = concurrent.futures.ThreadPoolExecutor(max_workers=3) class Succ: """All calls to this class return itself.""" def __bool__(self): return False def __getattr__(self, attr): return Succ() def __call__(self, *args, **kwargs): return Succ() def __str__(self): return "succ" def __repr__(self): return "" class Video: def __init__(self, enqueuer: typing.Optional[discord.Member] = None): self.is_ready = False self.name = None self.enqueuer = enqueuer self.audio_source = None self.suggestion = None def __str__(self): if self.name is None: return "_Untitled_" return self.name def plain_text(self): """Title without formatting to be printed on terminals.""" if self.name is None: return "Untitled" return self.name def database_text(self): """The text to be stored in the database for the stats. Usually the same as plain_text().""" if self.name is None: raise errors.VideoHasNoName() return self.name def __repr__(self): return f"