def go(): _, srv, url = yield from self.create_server(None, '/', None) client = ClientSession(loop=self.loop) resp = yield from client.get(url) self.assertEqual(404, resp.status) yield from resp.release() client.close()
def github_action(action, plugin, config, sort_by='updated'): url = API_URL.format( api=API_URL, user=config['user'], repo=config['repository'], action=action, ) query = { 'sort': sort_by, 'direction': 'desc', 'sha': config.get('branch', 'master') } headers = {'Accept': 'application/vnd.github.v3+json'} etag = plugin.temp.get(action) if etag is not None: headers['If-None-Match'] = etag session = ClientSession() try: resp = yield from asyncio.wait_for( session.get(url, params=query, headers=headers), timeout=5 ) try: plugin.temp[action] = resp.headers.get('etag') if resp.status != 200 or etag is None: # etag must be cached first raise NothingChangeException(etag) data = yield from resp.json() finally: resp.close() finally: session.close() return data[0]
def go(): _, srv, url = yield from self.create_server('GET', '/', handler) client = ClientSession(loop=self.loop) resp = yield from client.get(url) self.assertEqual(200, resp.status) data = yield from resp.read() self.assertEqual(b'xyz', data) yield from resp.release() client.close()
def go(): _, srv, url = yield from self.create_server('GET', '/', handler) client = ClientSession(loop=self.loop) resp = yield from client.get(url) self.assertEqual(200, resp.status) data = yield from resp.read() self.assertEqual(b'mydata', data) self.assertEqual(resp.headers.get('CONTENT-ENCODING'), 'deflate') yield from resp.release() client.close()
def get_html(url): session = ClientSession() try: resp = yield from session.get(url) try: raw_data = yield from resp.read() data = raw_data.decode('utf-8', errors='xmlcharrefreplace') return fromstring_to_html(data) finally: resp.close() finally: session.close()
class RestClient(): def __init__(self): self.client = ClientSession() def close(self): self.client.close() @asyncio.coroutine def post(self, url, headers={}): if 'content-type' not in headers: headers['content-type'] = 'application/json' resp = yield from self.client.post(url, headers=headers) data = yield from resp.read() yield from resp.release() return data.decode('utf-8') @asyncio.coroutine def get(self, url, headers={}, to_json=False): resp = yield from self.client.post(url) data = yield from resp.read() yield from resp.release() if to_json: data = json.loads(data.decode('utf-8')) return data @asyncio.coroutine def put(self, url, headers={}): resp = yield from self.client.post(url) data = yield from resp.read() yield from resp.release() return json.loads(data) @asyncio.coroutine def delete(self, url): resp = yield from self.client.post(url) data = yield from resp.read() yield from resp.release() return json.loads(data) @asyncio.coroutine def patch(self, url): resp = yield from self.client.post(url) data = yield from resp.read() yield from resp.release() return json.loads(data)
class Bot: '''Base class of your bot. You should implement the ``on_message`` function. Text may be parsed using ``parse`` ''' def __init__(self): self.conversations = {} self.history = [] self._client = ClientSession() def __enter__(self): return self def __exit__(self, ex_type, ex_value, ex_tb): self._client.close() def close(self): self._client.close() async def parse(self, text): async with self._client.post( LUIS_ENDPOINT, text.encode('utf-8'), ) as resp: data = await resp.json() # TODO: Extract relevant information from data return data @abstractmethod async def on_message(self, conversation, text): pass async def _handler(self, request): return web.Response( b"Not implemented", ) async def _history(self, request): return web.Response( '\n'.join('<p>{!r}</p>'.format(h) for h in self.history).encode('utf-8') )
class Downloader(Actor): async def startup(self): self.session = ClientSession(loop=self.loop) @concurrent async def download_content(self, url): async with self.session.get(url) as response: content = await response.read() print('{}: {:.80}...'.format(url, content.decode())) return len(content) async def shutdown(self): self.session.close() async def __aenter__(self): return self async def __aexit__(self, exc_type, exc, tb): await self.close()
class Github: _BASE_URL = 'https://api.github.com' def __init__(self, username, password, timeout=10): self._loop = asyncio.get_event_loop() self._session = ClientSession(loop=self._loop, auth=BasicAuth(username, password)) self._timeout = timeout def close(self): self._session.close() async def fetch(self, url, params): with Timeout(self._timeout): async with self._session.get('{}{}'.format(self._BASE_URL, url), params=params) as response: return await response.json() async def search_repositories(self, language, pushed, sort, order): q = 'language:{}'.format(language) if pushed: q = '{} pushed:>={}'.format(q, pushed) params = {'q': q, 'sort': sort, 'order': order} return await self.fetch('/search/repositories', params=params)
def go(dirname, filename): ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ssl_ctx.load_cert_chain( os.path.join(dirname, 'sample.crt'), os.path.join(dirname, 'sample.key') ) app, _, url = yield from self.create_server( 'GET', '/static/' + filename, ssl_ctx=ssl_ctx ) app.router.add_static('/static', dirname) conn = TCPConnector(verify_ssl=False, loop=self.loop) session = ClientSession(connector=conn) resp = yield from session.request('GET', url) self.assertEqual(200, resp.status) txt = yield from resp.text() self.assertEqual('file content', txt.rstrip()) ct = resp.headers['CONTENT-TYPE'] self.assertEqual('application/octet-stream', ct) self.assertEqual(resp.headers.get('CONTENT-ENCODING'), None) resp.close() session.close()
class StreamingClient: filter_endpoint = "/1.1/statuses/filter.json" sample_endpoint = "/1.1/statuses/sample.json" predicates = ["follow", "locations", "track"] keys = ['language', 'delimited', 'stall_warnings'] trafaret = t.Dict({ 'api_key': t.String, 'api_secret': t.String, 'access_token': t.String, 'access_secret': t.String, 'stream': t.URL, }).ignore_extra('*') def __init__(self, config): config = self.trafaret.check(config) self.base_url = config['stream'] self.signature = HmacSha1Signature() self.session = ClientSession() self.oauth_client = oauth.Client( client_key=config['api_key'], client_secret=config['api_secret'], resource_owner_key=config['access_token'], resource_owner_secret=config['access_secret'] ) async def request(self, method, endpoint, params=None, headers=None): url = urljoin(self.base_url, endpoint) headers = (headers or {}) if method == 'POST': headers['Content-type'] = 'application/x-www-form-urlencoded' uri, signed_headers, body = self.oauth_client.sign(url, method, params, headers) logger.debug("PREPARED: %s %s %s", uri, signed_headers, body) resp = await self.session.request(method, uri, params=body, headers=signed_headers) return resp async def stream(self, queue, predicate, value, **kwargs): params = dict(((predicate, value,),)) while True: resp = await self.request('POST', self.filter_endpoint, params) while True: data = await resp.content.readline() message = data.strip() if message != b'': message = json.loads(message.decode('utf-8')) logger.debug("Got something %s", message['id']) await queue.put(message) await asyncio.sleep(10) def __del__(self): asyncio.ensure_future(self.session.close())
class HttpClientSupplier: def __init__(self): self.client = None def __getattr__(self, name): if self.client is None: session_timeout = ClientTimeout(total=None, sock_connect=None, sock_read=None) self.client = ClientSession(timeout=session_timeout) # Proxy all attribute/method accesses to self.client # Because inheriting from ClientSession is discouraged in aiohttp # return getattr(object.__getattr__(self, 'client'), name) return getattr(self.client, name) def __del__(self): self.client and asyncio.run(self.client.close())
class AsyncNexusClient(object): def __init__(self, services: list, address: tuple, timeout=None, protocol_cls=TBinaryProtocol): """Initialize AsyncNexusClient :param services: A list of thrift service module. :param address: A (host, port) tuple. :param timeout: Timeout seconds. :param protocol_cls: Thrift protocol class, default is `TBinaryProtocol`. """ self.address = address self.protocol_cls = protocol_cls self.timeout = timeout self.httpclient = ClientSession() self.services = {} for service_module in services: service = ThriftService(service_module) self.services[service.name] = _AsyncNexusClientService( service, self) def __getattr__(self, item: str): if item not in self.services: raise AttributeError(item) return self.services[item] async def __aenter__(self): return self async def __aexit__(self, exc_type, exc_val, exc_tb): await self.close() def close(self): return self.httpclient.close()
def wait_for_connection(endpoint:str): log.info(f'waiting for: {endpoint}') session = ClientSession() try: async def _wait(count: int): while count >= 0: count -= 1 try: async with session.get(endpoint): ... except ClientConnectorError: await asyncio.sleep(1) except ClientResponseError: return True except Exception as e: log.error(type(e)) #log.error(str(e)) else: return True success = loop.run_until_complete(_wait(5)) finally: loop.run_until_complete(session.close()) if not success: raise ConnectionRefusedError() print("*"*20+"\n*** connection complete ***")
async def on_message(self, message): if message.server is None: return # DM if message.author.id == self.user.id: return if str(message.author.discriminator ) == "0000": # Ignore webhooks and system messages return logger = logging.getLogger(message.server.name) user = "******".format(message.author.name, message.author.discriminator) for line in message.content.split("\n"): logger.debug("#{} / {} {}".format(message.channel.name, user, line)) chars = self.data_manager.get_server_command_chars(message.server) text = None if message.content.startswith(chars): # It's a command text = message.content[len(chars):].strip() elif message.content.startswith(self.user.mention): text = message.content[len(self.user.mention):].strip() if text: if " " in text: command, args = text.split(" ", 1) else: command = text args = "" args_string = args args = shlex.split(args) if len(args) > 0: data = args[0:] if GIST_REGEX.match(data[-1]): gist_id = data.pop(-1).split(":")[1] gist_url = GIST_URL.format(gist_id) log.debug("Grabbing gist info: {}".format(gist_id)) session = ClientSession() async with session.get(gist_url) as response: gist_json = await response.json() session.close() if "files" not in gist_json: return await self.send_message( message.channel, "{} No such gist: `{}`".format( message.author.mention, gist_id)) for filename, file in gist_json["files"].items(): log.debug("Gist file collected: {}".format(filename)) data.append(file["content"]) else: data = [] log.debug("Command: {}".format(repr(command))) log.debug("Args: {}".format(repr(args))) log.debug("Args string: {}".format(repr(args_string))) log.debug("Data: {}".format(repr(data))) if hasattr(self, "command_{}".format(command.replace("-", "_"))): await getattr(self, "command_{}".format( command.replace("-", "_")))(data, args_string, message)
class Scriptures(object): def __init__(self, sparcli: commands.Bot): self.sparcli = sparcli self.session = ClientSession(loop=sparcli.loop) self.regexMatches = { 'OriginalRequest': r'(.+[a-zA-Z0-9]+\s[0-9]+:[0-9]+(-[0-9]+)?)', 'StripAuthor': r'(.+\b)([0-9]+:)', 'GetPassages': r'([0-9]+:[0-9]+)', 'GetMax': r'(-[0-9]+)', 'QuranMatch': r'([0-9]+:[0-9]+([-0-9]+)?)' } self.biblePicture = 'http://pacificbible.com/wp/wp-content/uploads/2015/03/holy-bible.png' self.quranPicture = 'http://www.siotw.org/modules/burnaquran/images/quran.gif' def __unload(self): self.session.close() @commands.command(pass_context=True) async def bible(self, ctx, *, script: str): ''' Gives you the Christian Bible quote from a specific script ''' # Check if it's a valid request matches = match(self.regexMatches['OriginalRequest'], script) if not matches: self.sparcli.say( 'That string was malformed, and could not be processed. Please try again.' ) return else: script = matches.group() # It is - send it to the API await self.sparcli.send_typing(ctx.message.channel) # Actually do some processing script = quote(script, safe='') async with self.session.get( 'https://getbible.net/json?scrip={}'.format(script)) as r: try: apiText = await r.text() apiData = loads(apiText[1:-2]) except Exception as e: apiData = None script = unquote(script) # Just check if it's something that we can process if not apiData: await self.sparcli.say( 'I was unable to get that paricular Bible passage. Please try again.' ) # Now we do some processin' # Get the max and the min verse numbers chapterMin = int( match(self.regexMatches['GetPassages'], script).group().split(':')[1]) chapterMax = match(self.regexMatches['GetMax'], script) if chapterMax: chapterMax = int(chapterMax.group()) + 1 else: chapterMax = chapterMin + 1 # Process them into an ordered dict o = OrderedDict() passages = apiData['book'][0]['chapter'] for verse in range(chapterMin, chapterMax): o[verse] = passages[str(verse)]['verse'] # Make it into an embed author = match(self.regexMatches['StripAuthor'], script).group().title() em = makeEmbed(fields=o, author=author, author_icon=self.biblePicture) # And done c: await self.sparcli.say(embed=em) async def getQuran(self, number, mini, maxi, english=True): ''' Sends stuff off to the API to be processed, returns embed object ''' o = OrderedDict() if english: base = 'http://api.alquran.cloud/ayah/{}:{}/en.sahih' else: base = 'http://api.alquran.cloud/ayah/{}:{}' # Get the data from the API async with self.session.get(base.format(number, mini)) as r: data = await r.json() author = data['data']['surah']['englishName'] if english else data[ 'data']['surah']['name'] o['{}:{}'.format(number, mini)] = data['data']['text'] for verse in range(mini + 1, maxi): async with self.session.get(base.format(number, verse)) as r: data = await r.json() o['{}:{}'.format(number, verse)] = data['data']['text'] em = makeEmbed(fields=o, author=author, author_icon=self.quranPicture) return em @commands.command(pass_context=True) async def quran(self, ctx, *, script: str): ''' Gives you a Quran quote given a specific verse ''' # http://api.alquran.cloud/ayah/{}/en.sahih # Check if it's a valid request matches = match(self.regexMatches['QuranMatch'], script) if not matches: self.sparcli.say( 'That string was malformed, and could not be processed. Please try again.' ) return else: script = matches.group() # It is - prepare to send it to an API await self.sparcli.send_typing(ctx.message.channel) # Acutally do some processing number = int(script.split(':')[0]) minQuote = int(script.split(':')[1].split('-')[0]) try: maxQuote = int(script.split(':')[1].split('-')[1]) + 1 except IndexError as e: maxQuote = minQuote + 1 # Send it off nicely to the API to be processed em = await self.getQuran(number, minQuote, maxQuote) await self.sparcli.say(embed=em)
class AirPlayPlayerTest(AioHTTPTestCase): def setUp(self): AioHTTPTestCase.setUp(self) self.log_handler = LogOutputHandler(self) self.session = ClientSession(loop=self.loop) def tearDown(self): self.session.close() self.log_handler.tearDown() AioHTTPTestCase.tearDown(self) @asyncio.coroutine def get_application(self, loop=None): self.fake_atv = FakeAppleTV(self.loop, 0, 0, 0, self) # Import TestServer here and not globally, otherwise py.test will # complain when running: # # test_functional.py cannot collect test class 'TestServer' # because it has a __init__ constructor from aiohttp.test_utils import TestServer return TestServer(self.fake_atv) @unittest_run_loop def test_verify_invalid(self): http = HttpSession( self.session, 'http://127.0.0.1:{0}/'.format(self.app.port)) handler = srp.SRPAuthHandler() handler.initialize(INVALID_AUTH_KEY) verifier = AuthenticationVerifier(http, handler) with self.assertRaises(DeviceAuthenticationError): yield from verifier.verify_authed() @unittest_run_loop def test_verify_authenticated(self): http = HttpSession( self.session, 'http://127.0.0.1:{0}/'.format(self.app.port)) handler = srp.SRPAuthHandler() handler.initialize(binascii.unhexlify(DEVICE_AUTH_KEY)) verifier = AuthenticationVerifier(http, handler) self.assertTrue((yield from verifier.verify_authed())) @unittest_run_loop def test_auth_successful(self): http = HttpSession( self.session, 'http://127.0.0.1:{0}/'.format(self.app.port)) handler = srp.SRPAuthHandler() handler.initialize(INVALID_AUTH_KEY) auther = DeviceAuthenticator(http, handler) yield from auther.start_authentication() with self.assertRaises(DeviceAuthenticationError): yield from auther.finish_authentication( DEVICE_IDENTIFIER, DEVICE_PIN) @unittest_run_loop def test_auth_failed(self): http = HttpSession( self.session, 'http://127.0.0.1:{0}/'.format(self.app.port)) handler = srp.SRPAuthHandler() handler.initialize(binascii.unhexlify(DEVICE_AUTH_KEY)) auther = DeviceAuthenticator(http, handler) yield from auther.start_authentication() self.assertTrue((yield from auther.finish_authentication( DEVICE_IDENTIFIER, DEVICE_PIN)))
class Eventorial: """An environment for Eventories. Args: directory: Directory path to store data in. If not provided the Eventorial uses a temporary directory which will be destroyed at the end. When provided with a path, the Eventorial loads all files that already exist in the directory. loop: Loop to use for various async operations. Uses asyncio.get_event_loop() if not specified. Attributes: eventories (Dict[str, Eventory]): Dictionary containing all loaded Eventories loop (AbstractEventLoop): Loop being used aiosession (ClientSession): ClientSession used for internet access directory (str): Path to directory used to store data """ def __init__(self, directory: str = None, *, loop=None): self.eventories = {} self.loop = loop or asyncio.get_event_loop() self.aiosession = ClientSession(loop=self.loop) if directory: self.directory = directory self._load_directory() else: self._tempdir = TemporaryDirectory(prefix="Eventory_") self.directory = self._tempdir.name log.debug( f"{self} created temporary directory in {self.directory}") def __str__(self): return f"<Eventorial {len(self.eventories)} Eventory/ies loaded>" def __len__(self): return len(self.eventories) def __del__(self): self.cleanup() def __contains__(self, item): return (item in self.eventories.keys()) or bool(self.get(item)) def __delitem__(self, key): return self.remove(key) def __getitem__(self, item): return self.get(item) def __iter__(self): return iter(self.eventories) def _load_directory(self): names = os.listdir(self.directory) loaded_eventories = 0 for name in names: if name.endswith(constants.FILE_SUFFIX): with open(path.join(self.directory, name), "r") as f: self.add(load(f)) loaded_eventories += 1 log.info( f"{self} loaded {loaded_eventories} Eventory/ies from directory") def cleanup(self): """Clean the Eventorial. Closes the ClientSession and removes the temporary directory if one has been created. """ if hasattr(self, "_tempdir"): self._tempdir.cleanup() log.debug(f"{self} removed temporary directory") self.loop.create_task(asyncio.gather(self.aiosession.close(), )) log.debug("{self} cleaned up") def add(self, source: Union[Eventory, str, TextIOBase]): """Add an Eventory to this Eventorial. Args: source: Can be an Eventory to add, a string containing a serialised Eventory or an open file to load the Eventory from Raises: TODO """ if isinstance(source, Eventory): eventory = source else: eventory = load(source) sane_title = sanitise_string(eventory.title) if sane_title in self.eventories: raise EventoryAlreadyLoaded(eventory.title) self.eventories[sane_title] = eventory eventory.save(path.join(self.directory, "{filename}")) def remove(self, item: Eventory): """Remove an Eventory from the Eventorial. Args: item: Eventory to removes Raises: KeyError: If the Eventory isn't part of the Eventorial """ title = sanitise_string(item.title) self.eventories.pop(title) os.remove(path.join(self.directory, item.filename)) def get(self, title: str, default: Any = _DEFAULT) -> Eventory: """Get an Eventory from this Eventorial. Args: title: Name of the Eventory to retrieve default: Default value to return if no Eventory found Returns: Eventory Raises: KeyError: If no Eventory with that title was found and default wasn't specified. """ sane_title = sanitise_string(title) story = self.eventories.get(sane_title) if story is None: if default is _DEFAULT: raise KeyError(f"No Eventory with title \"{title}\"") else: return default else: return story async def load_data(self, source: Union[str, URL, TextIOBase], **kwargs) -> str: """Retrieve text from a source. Contrary to the get_data function this method doesn't assume that all strings are urls. It checks whether the string is a url using the URL_REGEX and if it isn't a url it treats it as the name of a file relative to the directory of the Eventorial. Args: source: Source to retrieve text from Returns: str: Retrieved text Raises: TODO """ if isinstance(source, str): if not URL_REGEX.match(source): with open(path.join(self.directory, source), "r", encoding="utf-8") as f: return await self.load_data(f, **kwargs) return await get_data(source, session=self.aiosession, **kwargs) async def load(self, source: Union[str, URL, TextIOBase], **kwargs) -> Eventory: """Load an Eventory from a source into this Eventorial. Contrary to the get_eventory function this method doesn't assume that all strings are urls. It checks whether the string is a url using the URL_REGEX and if it isn't a url it treats it as the name of a file relative to the directory of the Eventorial. Args: source: Source to load Eventory from Returns: Eventory: Eventory that was added to the Eventorial Raises: TODO """ data = await self.load_data(source, **kwargs) eventory = load(data, **kwargs) self.add(eventory) return eventory
class ApiClient: def __init__(self, api_url, loop=None): self._loop = loop or asyncio.get_event_loop() self._session = ClientSession(loop=self._loop, raise_for_status=True) self._api_url = api_url def close(self): self._loop.run_until_complete(self._session.close()) async def fetch(self, method: str = "/", verb: str = "GET", params: dict = None, payload: dict = None, headers: dict = None) -> dict: url = self._api_url + method try: async with self._session.request(verb, url, json=payload, params=params, headers=headers) as response: response = await response.json() return response except ClientResponseError as e: raise ApiClientError from e async def add_user(self, user: User) -> bool: await self.fetch(method="/user/add", verb="POST", payload={ "tg_id": user.tg_id, "first_name": user.first_name, "username": user.username, }) return True async def update_answer(self, answer: Answer) -> bool: await self.fetch(method=f"/answer/{answer.id_}", verb="PUT", payload={ "msg_id": answer.msg_id, "rating": answer.rating, }) return True async def publish_question(self, query: str, predictor: str, tg_id: int, msg_id: int, chat_id: int) -> Union[Answer, None]: resp = await self.fetch(method="/search", params={ "user_id": tg_id, "query": query, "predictor": predictor, "msg_id": msg_id, "chat_id": chat_id, }) if resp["success"] is True: return Answer(id_=resp["answer"]["id"], text=resp["answer"]["text"], predictor=predictor) else: return None async def get_all_predictors(self) -> List[str]: return (await self.fetch(method="/predictor/all", verb="GET"))["predictors"] async def add_expert_question(self, exp_q: ExpertQuestion) -> bool: await self.fetch(method="/question/add", verb="POST", payload={ "text": exp_q.question_text, "msg_id": exp_q.question_msg_id, "chat_id": exp_q.question_chat_id, "expert_chat_id": exp_q.expert_question_chat_id, "expert_msg_id": exp_q.expert_question_msg_id, }) return True async def update_expert_question( self, exp_q: ExpertQuestion) -> Union[None, ExpertQuestion]: resp = await self.fetch(method="/question/update", verb="PUT", payload={ "msg_id": exp_q.expert_answer_msg_id, "text": exp_q.expert_answer_text, "tg_id": exp_q.expert_user_fk, }, params={ "msg_id": exp_q.expert_question_msg_id, "chat_id": exp_q.expert_question_chat_id, }) if resp["success"] is True: exp_q.question_msg_id = resp["expert_question"]["question_msg_id"] exp_q.question_text = resp["expert_question"]["question_text"] exp_q.question_chat_id = resp["expert_question"][ "question_chat_id"] exp_q.id_ = resp["expert_question"]["id"] return exp_q else: return None
class HttpDispatcher(AbstractDispatcher): """ Dispatcher that proxies HTTP messages back and forth, if a backend system can be resolved from the AbstractServiceResolver """ __slots__ = ('_buf_size', '_resolver', '_session') def __init__(self, resolver_: AbstractServiceResolver, *, buf_size=128): self._resolver = resolver_ self._buf_size = buf_size self._session = ClientSession() @atexit.register def close(self): if not self._session.closed: self._session.close() async def dispatch(self, request: Request): service_addr = await self._resolver.resolve(request) print('service_addr:', service_addr) # we need the headers as a dict: headers = CIMultiDict() for k, v in request.headers: headers[k.decode()] = v.decode() # aiohttp will try to do a len on the content if there is # no content-length header. Since we aren't currently supporting # streaming incoming, we are going to just pretend that there is # no data... if headers.get('Content-Length') is None: data = None else: data = request.content try: async with self._session.request(request.method.decode(), service_addr, data=data, headers=headers) as resp: # TODO: Need to support any other versions? # TODO: Abstract to response class. request.transport.write( b'HTTP/1.1 %d %b\r\n' % (resp.status, resp.reason.encode())) # noqa # TODO: Figure out how to use raw_headers to bypass en/decode for k, v in resp.headers.items(): request.transport.write(b'%b: %b\r\n' % (k.encode(), v.encode())) request.transport.write(b'\r\n') while True: chunk = await resp.content.readany() if not chunk: break request.transport.write(chunk) request.transport.close() except ClientOSError: raise HTTPBadGatewayException('Unable to reach destination, ' 'service unreachable.')
class DaapSession(object): """This class makes it easy to perform DAAP requests. It automatically adds the required headers and also does DMAP parsing. """ def __init__(self, loop, timeout=DEFAULT_TIMEOUT): """Initialize a new DaapSession.""" self._session = ClientSession(loop=loop) self._timeout = timeout def close(self): """Close the underlying client session.""" return self._session.close() @asyncio.coroutine def get_data(self, url, should_parse=True): """Perform a GET request. Optionally parse reponse as DMAP data.""" _LOGGER.debug('GET URL: %s', url) resp = yield from self._session.get(url, headers=_DMAP_HEADERS, timeout=self._timeout) try: resp_data = yield from resp.read() extracted = self._extract_data(resp_data, should_parse) return extracted, resp.status except Exception as ex: resp.close() raise ex finally: yield from resp.release() @asyncio.coroutine def post_data(self, url, data=None, parse=True): """Perform a POST request. Optionally parse reponse as DMAP data.""" _LOGGER.debug('POST URL: %s', url) headers = copy(_DMAP_HEADERS) headers['Content-Type'] = 'application/x-www-form-urlencoded' resp = yield from self._session.post(url, headers=headers, data=data, timeout=self._timeout) try: resp_data = yield from resp.read() extracted = self._extract_data(resp_data, parse) return extracted, resp.status except Exception as ex: resp.close() raise ex finally: yield from resp.release() @staticmethod def _extract_data(data, should_parse): if _LOGGER.isEnabledFor(logging.DEBUG): output = data[0:128] _LOGGER.debug('Data[%d]: %s%s', len(data), binascii.hexlify(output), '...' if len(output) != len(data) else '') if should_parse: return dmap.parse(data, lookup_tag) else: return data
class MarshalService: """ MarshalService creates a reverse proxy server in front of actual API server, implementing the micro batching feature. It wait a short period and packed multiple requests in a single batch before sending to the API server. It applied an optimized CORK algorithm to get best efficiency. """ @inject def __init__( self, bento_bundle_path, outbound_host="localhost", outbound_port=None, outbound_workers: int = Provide[BentoMLContainer.api_server_workers], mb_max_batch_size: int = Provide[ BentoMLContainer.config.bento_server.microbatch.max_batch_size], mb_max_latency: int = Provide[ BentoMLContainer.config.bento_server.microbatch.max_latency], max_request_size: int = Provide[ BentoMLContainer.config.bento_server.max_request_size], outbound_unix_socket: str = None, enable_microbatch: bool = Provide[ BentoMLContainer.config.bento_server.microbatch.enabled], ): self._client = None self.outbound_unix_socket = outbound_unix_socket self.outbound_host = outbound_host self.outbound_port = outbound_port self.outbound_workers = outbound_workers self.mb_max_batch_size = mb_max_batch_size self.mb_max_latency = mb_max_latency self.batch_handlers = dict() self._outbound_sema = None # the semaphore to limit outbound connections self.max_request_size = max_request_size self.bento_service_metadata_pb = load_bento_service_metadata( bento_bundle_path) if enable_microbatch: self.setup_routes_from_pb(self.bento_service_metadata_pb) if psutil.POSIX: import resource self.CONNECTION_LIMIT = resource.getrlimit( resource.RLIMIT_NOFILE)[0] else: self.CONNECTION_LIMIT = 1024 logger.info( "Your system nofile limit is %d, which means each instance of microbatch " "service is able to hold this number of connections at same time. " "You can increase the number of file descriptors for the server process, " "or launch more microbatch instances to accept more concurrent connection.", self.CONNECTION_LIMIT, ) def set_outbound_port(self, outbound_port): self.outbound_port = outbound_port def fetch_sema(self): if self._outbound_sema is None: self._outbound_sema = NonBlockSema(self.outbound_workers) return self._outbound_sema def get_client(self): from aiohttp import ClientSession, DummyCookieJar, UnixConnector, TCPConnector if self._client is None: jar = DummyCookieJar() if self.outbound_unix_socket: conn = UnixConnector(path=self.outbound_unix_socket, ) else: conn = TCPConnector(limit=30) self._client = ClientSession( connector=conn, auto_decompress=False, cookie_jar=jar, ) return self._client def __del__(self): if getattr(self, '_client', None) is not None and not self._client.closed: self._client.close() def add_batch_handler(self, api_route, max_latency, max_batch_size): ''' Params: * max_latency: limit the max latency of overall request handling * max_batch_size: limit the max batch size for handler ** marshal server will give priority to meet these limits than efficiency ''' from aiohttp.web import HTTPTooManyRequests if api_route not in self.batch_handlers: _func = CorkDispatcher( max_latency, max_batch_size, shared_sema=self.fetch_sema(), fallback=HTTPTooManyRequests, )(functools.partial(self._batch_handler_template, api_route=api_route)) self.batch_handlers[api_route] = _func def setup_routes_from_pb(self, bento_service_metadata_pb): for api_pb in bento_service_metadata_pb.apis: if api_pb.batch: max_latency = (self.mb_max_latency or api_pb.mb_max_latency or DEFAULT_MAX_LATENCY) max_batch_size = (self.mb_max_batch_size or api_pb.mb_max_batch_size or DEFAULT_MAX_BATCH_SIZE) self.add_batch_handler(api_pb.route, max_latency, max_batch_size) logger.info( "Micro batch enabled for API `%s` max-latency: %s" " max-batch-size %s", api_pb.route, max_latency, max_batch_size, ) async def request_dispatcher(self, request): from aiohttp.web import HTTPInternalServerError, Response with get_tracer().async_span( service_name=self.__class__.__name__, span_name="[1]http request", is_root=True, standalone=True, sample_rate=0.001, ): api_route = request.match_info.get("path") if api_route in self.batch_handlers: req = HTTPRequest( tuple((k.decode(), v.decode()) for k, v in request.raw_headers), await request.read(), ) try: resp = await self.batch_handlers[api_route](req) except RemoteException as e: # known remote exception logger.error(traceback.format_exc()) resp = Response( status=e.payload.status, headers=e.payload.headers, body=e.payload.body, ) except Exception: # pylint: disable=broad-except logger.error(traceback.format_exc()) resp = HTTPInternalServerError() else: resp = await self.relay_handler(request) return resp async def relay_handler(self, request): from aiohttp.client_exceptions import ClientConnectionError from aiohttp.web import Response data = await request.read() url = request.url.with_host(self.outbound_host).with_port( self.outbound_port) with get_tracer().async_span( service_name=self.__class__.__name__, span_name=f"[2]{url.path} relay", request_headers=request.headers, ): try: client = self.get_client() async with client.request(request.method, url, data=data, headers=request.headers) as resp: body = await resp.read() except ClientConnectionError: return Response(status=503, body=b"Service Unavailable") return Response( status=resp.status, body=body, headers=resp.headers, ) async def _batch_handler_template(self, requests, api_route): ''' batch request handler params: * requests: list of aiohttp request * api_route: called API name raise: * RemoteException: known exceptions from model server * Exception: other exceptions ''' from aiohttp.client_exceptions import ClientConnectionError from aiohttp.web import Response headers = {MARSHAL_REQUEST_HEADER: "true"} api_url = f"http://{self.outbound_host}:{self.outbound_port}/{api_route}" with get_tracer().async_span( service_name=self.__class__.__name__, span_name=f"[2]merged {api_route}", request_headers=headers, ): reqs_s = DataLoader.merge_requests(requests) try: client = self.get_client() async with client.post(api_url, data=reqs_s, headers=headers) as resp: raw = await resp.read() except ClientConnectionError as e: raise RemoteException(e, payload=HTTPResponse( status=503, body=b"Service Unavailable")) if resp.status != 200: raise RemoteException( f"Bad response status from model server:\n{resp.status}\n{raw}", payload=HTTPResponse( status=resp.status, headers=tuple(resp.headers.items()), body=raw, ), ) merged = DataLoader.split_responses(raw) return tuple( Response( body=i.body, headers=i.headers, status=i.status or 500) for i in merged) def async_start(self, port): """ Start an micro batch server at the specific port on the instance or parameter. """ marshal_proc = multiprocessing.Process( target=self.fork_start_app, kwargs=dict(port=port), daemon=True, ) marshal_proc.start() logger.info("Running micro batch service on :%d", port) def make_app(self): from aiohttp.web import Application app = Application(client_max_size=self.max_request_size) app.router.add_view("/", self.relay_handler) app.router.add_view("/{path:.*}", self.request_dispatcher) return app @inject def fork_start_app( self, port=Provide[BentoMLContainer.config.bento_server.port], ): from aiohttp.web import run_app # Use new eventloop in the fork process to avoid problems on MacOS # ref: https://groups.google.com/forum/#!topic/python-tornado/DkXjSNPCzsI loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) app = self.make_app() run_app(app, port=port)
class Minecraft(Cog, name="Minecraft Category"): def __init__(self, bot): self.bot = bot #Define our aiohttp ClientSession #To make apis easier to access self.ses = ClientSession(loop=self.bot.loop) self.g = self.bot.get_cog("Global") with open("data/build_ideas.json", "r") as stuff: _json = json.load(stuff) self.first = _json["first"] self.pronouns = _json["prenouns"] self.nouns = _json["nouns"] self.colors = _json["colors"] self.sizes = _json["sizes"] #•----------Functions-----------•# #Run the ClientSession #Then close the session when complete def cog_unload(self): self.bot.loop.create_task(self.ses.close()) async def nice(self, ctx): com_len = len(f'{ctx.prefix}{ctx.invoked_with} ') return ctx.message.clean_content[com_len:] #Goes through message and replaces all #Instances of keys with their values in a dict async def lang_convert(self, ctx, msg, lang): keys = list(lang) #Iterate through list of 'lang' argument for k in keys: msg = msg.replace(k, lang[k]) #If user's message is too long if len(msg) > 750: e = discord.Embed( description= f"<:redmark:738415723172462723> That message is too long to convert" ) await ctx.send(embed=e) else: await ctx.send(msg) #•-----------Commands----------•# @command(name='mcping', brief="{Check Status of a MC Server}", usage="mcping <server_ip>", aliases=['serverping', 'mcstatus']) @cooldown(1, 1.5, BucketType.user) @guild_only() async def mcping(self, ctx, host, port: int = None): port_str = '' if port is not None: port_str = f':{port}' combined = f'{host}{port_str}' async with ctx.typing(): #Get the status from api res = await self.ses.get( f'https://theapi.info/mc/mcping?host={combined}') jj = await res.json() if not jj['success'] or not jj['online']: e = discord.Embed( color=0x420000, title=f'<:offline:728377784207933550> {combined} is offline') await ctx.send(embed=e) return player_list = jj.get('players_names', []) # list if player_list is None: player_list = [] players_online = jj['players_online'] # int e = discord.Embed( color=randint(0, 0xffffff), title=f'<:online:728377717090680864> {combined} is online', description=f"*Version:* {jj['version'].get('brand', 'Unknown')}") e.add_field(name='__*Latency/Ping*__', value=jj['latency']) player_list_cut = player_list[:24] if jj['version']['method'] != 'query' and len(player_list_cut) < 1: e.add_field( name= f'__*Online Players ({players_online}/{jj["players_max"]})*__', value='*Player list is not available for this server*', inline=True) else: extra = '' if len(player_list_cut) < players_online: extra = f', and {players_online - len(player_list_cut)} others...' e.add_field( name= f'__*Online Players ({players_online}/{jj["players_max"]})*__', value='`' + '`, `'.join(player_list_cut) + '`' + extra, inline=False) e.set_image( url= f'https://theapi.info/mc/mcpingimg?host={combined}&imgonly=true&v={random.random()*100000}' ) if jj['favicon'] is not None: e.set_thumbnail( url=f'https://theapi.info/mc/serverfavi?host={combined}') await ctx.send(embed=e) @command(brief="{Get a User's Skin}", usage="skin <player/uuid>", aliases=['stealskin', 'mcskin']) @cooldown(1, 2.5, BucketType.user) @guild_only() @bot_has_permissions(use_external_emojis=True, embed_links=True) async def skin(self, ctx, *, gamertag: str): #Define author to make stuff shorter mem = ctx.author redmark = "<:redmark:738415723172462723>" response = await self.ses.get( f"https://api.mojang.com/users/profiles/minecraft/{gamertag}") #If there is no player found if response.status == 204: e = discord.Embed( description= f"{redmark} __*{mem.mention}, That Player doesn't Exist*__", color=0x420000) await ctx.send(embed=e) return #Try to find the uuid of the playwer uuid = json.loads(await response.text()).get("id") #If there is no uuid if uuid is None: e = discord.Embed( color=0x420000, description= f"{redmark} __*{mem.mention}, That player doesn't exist*__") await ctx.send(embed=e) return response = await self.ses.get( f"https://sessionserver.mojang.com/session/minecraft/profile/{uuid}?unsigned=false" ) content = json.loads(await response.text()) if "error" in content: if content["error"] == "TooManyRequestsException": e = discord.Embed( description= f"{redmark} __*{mem.mention}, You have to Slow Down*__", color=0x420000) await ctx.send(embed=e) return if len(content["properties"]) == 0: e = discord.Embed( description= f"{redmark} __*{mem.mention}, This user's skin can't be stolen for some reason*__", color=0x420000) await ctx.send(embed=e) return undec = base64.b64decode(content["properties"][0]["value"]) try: #Get the download url of the skin skin_download = json.loads(undec)["textures"]["SKIN"]["url"] except Exception: e = discord.Embed( color=0x420000, description= f"{redmark} __*An error occurred while fetching that skin*__") await ctx.send(embed=e) return #Get user's uuid uuid = await self.ses.post("https://api.mojang.com/profiles/minecraft", json=[gamertag]) j = json.loads(await uuid.text()) #If uuid isn't found/doesn't exist if not j: e = discord.Embed( description=f"{redmark} __*That user couldn't be found*__", color=0x420000) await ctx.send(embed=e) return #Shows the head of the skin skin_head = f"https://minotar.net/avatar/{gamertag}/50.png" #Make embed e = discord.Embed(title=f"*Download Here*", url=skin_download, description=f"__*UUID*__ -> {j[0]['id']}") #A dict for us to choose a random response ran = [ f"{gamertag}'s Epic Skin", f"{gamertag}'s Awesome Skin", f"{gamertag}'s Sexy Skin" ] e.set_author(name=choice(ran), icon_url=skin_head) e.set_footer(text=f"Requested by {mem}") #Set embed image as skin's body e.set_image(url=f"https://mc-heads.net/body/{gamertag}/110") #Send embed await ctx.send(embed=e) @command(brief="{Get a List of Name History on MC Player}", usage="names <player/uuid>", aliases=['namehistory', 'namelist']) @guild_only() @cooldown(1, 2.5, BucketType.user) @bot_has_permissions(use_external_emojis=True) async def names(self, ctx, *, gamertag: str): #Define custom emoji as a var redmark = "<:redmark:738415723172462723>" garbage = "<:trash:734043301187158082>" #Defining author as something easier mem = ctx.author #Aiohttp session to get a player's username r = await self.ses.post(f"https://api.mojang.com/profiles/minecraft", json=[gamertag]) j = json.loads(await r.text()) #If a user with that name isn't found if not j: e = discord.Embed( color=0x420000, description= f"{redmark} __*{mem.mention}, That Player Couldn't be Found*__" ) await ctx.send(embed=e) return #Get the api for our embed res = await self.ses.get( f"https://some-random-api.ml/mc?username={gamertag}") #Storing the aiohttp session as a var mn = await res.json() #Define the dict/json we're getting data = mn #Change 'origanal' in the api #To 'original' data['name_history'][0]['changedToAt'] = "Original Name" #Change case where month is 0 data['name_history'][0]['changedToAt'] = "1/29/2017" #Store the user name history #As a variable history = data['name_history'][::-1] #Split the names into chunks of 3 #name_chunks = [history[i:i + 3] for i in range(0, len(history), 3)] #Max number of pages we can have page_max = len(history) #Start the pages (Defaults to first {1}) page = 1 #Empty list to store the embed fields later on embed_list = [] #Make a variable we will add on to later num = 0 #Reverse all the numbers num_list = list(range(len(history)))[::-1] #Iterate through the list of dicts for item in history: #Empty list of name fields nfields = [] username = item['name'] user_date = item['changedToAt'] #Check to make sure we don't count #Original name if item['changedToAt'] == "Original Name": namedate = user_date else: namedate = datetime.strptime( user_date, "%m/%d/%Y").strftime('%a/%b %d/%Y') #Add these fields to our empty list #Of name fields above nfields.append( ("•------------------•", f"**{num_list[num]+1}.** `{username}` - {namedate}", True)) e = discord.Embed(description=f"**{gamertag}'s Name History**", timestamp=datetime.utcnow()) fields = nfields #Add fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) #The skin's head as a link/png skin_head = f"https://minotar.net/avatar/{gamertag}/50.png" #Set the embed author e.set_author(name=f"Page {page}/{page_max}") e.set_footer(text=f"Ordered by Most Recent to Oldest") e.set_thumbnail(url=f"https://minotar.net/bust/{gamertag}/100.png") #Add this embed to our empty list of embeds embed_list.append(e) #Add to the number variable above num += 1 #Add to the page variable page += 1 #Default pages to first page {1} page = 1 #Send embed m = await ctx.send(embed=embed_list[page - 1]) #List of reactions to add react = ['⬅️', '➡️', '⏹'] #Add the reactions for emotes in react: await m.add_reaction(emotes) #Custom check for when checking user reactions def checkauth(reaction, user): return user == ctx.author and reaction.message.id == m.id and str( reaction.emoji) in ['⬅️', '➡️', '⏹'] while True: try: reaction, user = await self.bot.wait_for('reaction_add', timeout=180.0, check=checkauth) except asyncio.TimeoutError: e = discord.Embed( description= f"{redmark} __*{ctx.author.mention}, you took too long to react", color=0x420000) await m.edit(embed=e) await m.clear_reactions() #Break the loop break else: if str(reaction.emoji) == '➡️' and page != page_max: await m.remove_reaction(reaction, user) page += 1 #Edit the original embed with #Our list of embeds await m.edit(embed=embed_list[page - 1]) elif str(reaction.emoji) == '⬅️' and page > 1: await m.remove_reaction(reaction, user) page -= 1 #Edit original embed #With list of embeds await m.edit(embed=embed_list[page - 1]) elif str(reaction.emoji) == '⏹': await m.clear_reactions() em = discord.Embed( description= f"{garbage} __*Removing this embed in 5 seconds...*__", color=0x420000) await m.edit(embed=em, delete_after=5) else: await m.remove_reaction(reaction, user) #except KeyError: #e = discord.Embed( #description=f"{redmark} __*{mem.mention}, that isn't a Valid Player*__", #color=0x420000) #await ctx.send(embed=e) #return @command(brief="{See a Player's Cape}", usage="cape <player/uuid>") @cooldown(1, 1.5, BucketType.user) @guild_only() async def cape(self, ctx, *, gamertag: str): #Make a custom emoji a variable redmark = "<:redmark:738415723172462723>" #Define the author as something shorter mem = ctx.author async with ctx.typing(): r = await self.ses.post( "https://api.mojang.com/profiles/minecraft", json=[gamertag]) j = json.loads(await r.text()) #If a user couldn't be found if not j: e = discord.Embed( description= f"{redmark} __*{mem.mention}, that isn't a valid player*__", color=0x420000) await ctx.send(embed=e) return #Use the MojangAPI #To search for a mc user's cape user = await Client.User.createUser(gamertag) cape = await user.getProfile() print(cape) #If there isn't a cape for that player if cape.cape is None: e = discord.Embed( description= f"{redmark} __*{mem.mention}, **{gamertag}** doesn't have a cape*__", color=0x420000) await ctx.send(embed=e) return #List of random choices we want to get ran = [ f"{gamertag}'s Epic Cape", f"{gamertag}'s Awesome Cape", f"{gamertag}'s Sexy Cape" ] e = discord.Embed() #Set the author name as a random choice #From the list above e.set_author(name=choice(ran), icon_url=f"https://minotar.net/avatar/{gamertag}") #Set the image as the user's cape e.set_image(url=cape.cape) e.set_footer(text=mem) e.timestamp = datetime.utcnow() await ctx.send(embed=e) @command(name="uuid", brief="{Get a UUID with a Username}", usage="uuid <player>", aliases=['']) @cooldown(1, 1.5, BucketType.user) @guild_only() @bot_has_permissions(use_external_emojis=True) async def get_uuid(self, ctx, *, gamertag: str): redmark = "<:redmark:738415723172462723>" #Makes stuff shorter mem = ctx.author #If the user tries to use a uuid if len(gamertag) > 30: e = discord.Embed( description= f"{redmark} __*{mem.mention}, you can't use uuid's*__", color=0x420000) await ctx.send(embed=e) return try: #Get the api r = await self.ses.post( "https://api.mojang.com/profiles/minecraft", json=[gamertag]) #j[0]['id'] \/ j = json.loads(await r.text()) #If a user couldn't be found if not j: e = discord.Embed( description= f"{redmark} __*{mem.mention}, that isn't a Valid Player*__", color=0x420000) await ctx.send(embed=e) return #Make the embed to send e = discord.Embed( title="Search UUID's here", url="https://mcuuid.net", description=f"\n*UUID for **{gamertag}** -> {j[0]['id']}*\n\n") e.set_thumbnail(url=f"https://minotar.net/bust/{gamertag}/100.png") e.set_footer(text=f"Requested by {mem}") e.timestamp = datetime.utcnow() #Send embed await ctx.send(embed=e) except KeyError: e = discord.Embed( description= f"{redmark} __*{mem.mention}, that isn't a Valid Player", color=0x420000) await ctx.send(embed=e) @command(name="mcplayer", brief="{Get a Gamertag using a UUID}", usage="mcplayer <uuid>", aliases=['gamertag', 'mcuser', 'mcname']) @cooldown(1, 1.5, BucketType.user) @guild_only() @bot_has_permissions(use_external_emojis=True) async def get_gamertag(self, ctx, *, uuid): #Define our custom emoji redmark = "<:redmark:738415723172462723>" #Define author as something easier mem = ctx.author #Check if a uuid is given #uuid's are over 30 characters if len(uuid) < 30: e = discord.Embed( description= f"{redmark} __*{mem.mention}, That isn't a Valid MC UUID*__", color=0x420000) await ctx.send(embed=e) return try: #Get the api response = await self.ses.get( f"https://api.mojang.com/user/profiles/{uuid}/names") #If a player isn't valid if response.status == 204: e = discord.Embed( description= f"{redmark} __*{mem.mention}, That Player doesn't exist*__", color=0x420000) await ctx.send(embed=e) return #Get the name j = json.loads(await response.text()) name = j[len(j) - 1]["name"] #Make the embed e = discord.Embed(title="Convert UUID's to Players Here", url="https://mcuuid.net", description=f"*Name for **{uuid}** -> {name}*") #Set the thumbnail as player's skin #Just for aesthetics yk e.set_thumbnail(url=f"https://minotar.net/bust/{uuid}/100.png") e.set_footer(text=f"Requested by {mem}") e.timestamp = datetime.utcnow() #Send embed await ctx.send(embed=e) #If the uuid doesn't match a player except KeyError: e = discord.Embed( description= f"{redmark} __*{mem.mention}, that isn't a Valid Player*__", color=0x420000) await ctx.send(embed=e) @command(brief="{Converts your Text into Villager Noises}", usage="villagerspeak <text>", aliases=['vspeak']) @guild_only() @cooldown(1, 1.5, BucketType.user) async def villagerspeak(self, ctx, *, msg): #Use the function/method from above #To convert user's text await self.lang_convert(ctx, str(msg).replace("\\", "\\\\"), self.g.villagerLang) @command(brief="{Converts text into Enchantment Table Language}", usage="enchant <text>") @guild_only() @cooldown(1, 1.5, BucketType.user) async def enchant(self, ctx, *, msg): msg = str(msg).replace("```", "").replace("\\", "\\\\") await self.lang_convert(ctx, "```" + msg + "```", self.g.enchantLang) @command(brief="{Unenchant text}", usage="unenchant <enchantment_text>", aliases=['unchant']) @guild_only() @cooldown(1, 1.5, BucketType.user) async def unenchant(self, ctx, *, msg): lang = {} for key in list(self.g.enchantLang): lang[self.g.enchantLang[key]] = key await self.lang_convert(ctx, str(msg), lang) @command(brief="{Get a Random Cursed Minecraft Image}", usage="cursed", aliases=['mccursed', 'cursedmc']) @guild_only() @cooldown(1, 1.5, BucketType.user) async def cursed(self, ctx): #Get the images from 'global.py' images = self.g.cursedImages e = discord.Embed(color=randint(0, 0xffffff)) e.set_image(url="http://olimone.ddns.net/images/cursed_minecraft/" + random.choice(images)) await ctx.send(embed=e) @command(brief="{Get Sales for Minecraft Games}", usage="mcsales", aliases=['minecraftsales']) @guild_only() @cooldown(1, 1.5, BucketType.user) async def mcsales(self, ctx): dung = await DataService.Data.getStatistics(item_sold_dungeons=True) mc = await DataService.Data.getStatistics(item_sold_minecraft=True) #Make the embed e = discord.Embed(color=randint(0, 0xffffff), title="Total Sales for Minecraft") #Make our fields fields = [( "__*Total Minecraft Copies*__", f"Total: **{mc['total']}** Total Copies" + f"\nSold last **24** Hours: {mc['last24h']}" + f"\nSold per Second: **{round(mc['saleVelocityPerSeconds'], 3)}** Copies sold a Sec", True), ("__*Minecraft Dungeon Sales*__", f"Total: **{dung['total']}**" + f"\nSold Last **24** Hours: **{dung['last24h']}** Sold", True)] #Add our fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) #Send embed await ctx.send(embed=e) @command(name="randomserver", brief="{Get a Random Minecraft Server}", usage="randomserver", aliases=['mcserver']) @guild_only() @cooldown(1, 1.5, BucketType.user) @bot_has_permissions(use_external_emojis=True) async def random_mc_server(self, ctx): #Define a variable #For getting a random choice from mc server.json s = choice(self.g.mc_servers) try: #If the server's online #Use online custom emoji online = MinecraftServer.lookup(s['ip'] + ":" + str(s['port'])).status() stat = "<:online:728377717090680864>" #If the server's offline #Use an offline custom emoji except Exception: stat = "<:offline:728377784207933550>" #Make it look like the bot's typing in chat #In case it takes long to send the embed async with ctx.typing(): mark = "<:greenmark:738415677827973152>" if s[ 'verified'] is True else "<:redmark:738415723172462723>" #Make embed e = discord.Embed( timestamp=datetime.utcnow(), description=f"*Status for **{s['name']}** -> {stat}*") #Make fields fields = [("__*Server IP*__", s['ip'], True), ("__*Server Port*__", s['port'], True), ("__*Version*__", f"{s['version']}{{{s['type']}}}", True), ("__*Verified?*__", f"{mark} {s['verified']}", True)] #Add the fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) e.set_footer(text=f"Requested by {ctx.author}") e.set_thumbnail(url=s['image']) #Send embed await ctx.send(embed=e) @command(name="mcidea", brief="{Get a Random Build Idea}", usage='mcidea', aliases=['buildidea']) @guild_only() @cooldown(1, 1.5, BucketType.user) async def build_idea(self, ctx): if choice([True, False]): e = discord.Embed( description= f"*{choice(self.first)} {choice(self.pronouns)}{choice(['!', ''])}*", color=randint(0, 0xffffff)) await ctx.send(embed=e) else: e = discord.Embed( description= f"*{choice(self.first)} a {choice(self.sizes)}, {choice(self.colors)} {choice(self.nouns)}{choice(['!', ''])}*", color=randint(0, 0xffffff)) await ctx.send(embed=e) @command(name="mccolors", brief="{Colorcodes for Minecraft Text}", usage="mccolors", aliases=['mccolorcodes']) @guild_only() @cooldown(1, 2.5, BucketType.user) @bot_has_permissions(use_external_emojis=True) async def mc_color_codes(self, ctx): #Define author as something easier mem = ctx.author #Make our embed e = discord.Embed( description= "*Text in Minecraft can be formatted using different codes and using the {``§``} sign*" ) #Set the embed author e.set_author(name="Minecraft Text Color Formatting") #Make our fields fields = [ ("__*Bright Colors*__", "<:red:749067570379882496> **Red** ``§c``" + "\n<:yellow:749080901253857331> **Yellow** ``§e``" + "\n<:green:749080915082215454> **Green** ``§a``" + "\n<:aqua:749108387093938177> **Aqua** ``§b``" + "\n<:blue:749080929552695428> **Blue** ``§9``" + "\n<:light_purple:749102028046729266> **Light Purple** ``§d``\n" + "\n<:white:749101731136274502> **White** ``§f``" + "\n<:lightgray:749101578014687343> **Gray** ``§7``", True), ("__*Dark Colors*__", "<:dark_red:749101827995205642> **Dark Red** ``§4``\n" + "<:darkyellow:749102067750010884> **Gold** ``§6``\n" + "<:darkgreen:749101908911980678> **Dark Green** ``§2``\n" + "<:dark_aqua:749108577180057650> **Dark Aqua** ``§3``\n" + "<:darkblue:749101874338201601> **Dark Blue** ``§1``\n" + "<:darkpurple:749101989564121179> **Dark Purple** ``§5``\n" + "<:darkgray:749101943737155615> **Dark Gray** ``§8``\n" + "<:black:749102125224689676> **Black** ``§0``\n", True), ("__*Formatting/Markdown*__", "<:bold:749106727353581619> **Bold** ``§l``\n" + "<:emoji_21:749106924225691658> ~~Strikethrough~~ ``§m``\n" + "<:underline:749106690774794250> __Underline__ ``§n``\n" + "<:italic:749105941214920766> *Italic* ``§o``\n" + "<:obfuscated:749106114662105139> ||Obfuscated|| ``§k``\n" + "<:reset:749108115039060050> Reset ``§r``\n", True) ] #Add our fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) e.set_footer(text=f"Requested by {mem}", icon_url=mem.avatar_url) #Send the embed await ctx.send(embed=e)
class Client(TelegramClient): # pylint: disable = R0901, W0223 """Custom telethon client that has the plugin manager as attribute.""" plugin_mgr: Optional[PluginManager] = None db: Database = None kantek_version: str = '' sw: spamwatch.Client = None swo: spamwatch.Client = None sw_url: str = None aioclient: ClientSession = None config: Config _me: Optional[User] = None def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.aioclient = ClientSession(timeout=ClientTimeout(total=2)) async def respond(self, event: NewMessage.Event, msg: Union[str, KanTeXDocument], reply: bool = True, delete: Optional[str] = None, link_preview: bool = False) -> Message: """Respond to the message an event caused or to the message that was replied to Args: event: The event of the message msg: The message text reply: If it should reply to the message that was replied to delete: Seconds until the sent message should be deleted Returns: None """ msg = str(msg) if reply: if isinstance(event, ChatAction.Event): reply_to = event.action_message.id else: reply_to = (event.reply_to_msg_id or event.message.id) sent_msg: Message = await event.respond(msg, reply_to=reply_to, link_preview=link_preview) else: sent_msg: Message = await event.respond(msg, link_preview=link_preview) if delete is not None: delete_in = parsers.time(delete) # While asyncio.sleep would work it would stop the function from returning which is annoying await self.send_message( sent_msg.chat, f'{self.config.prefix}delete [Scheduled deletion]', schedule=datetime.timedelta(seconds=delete_in), reply_to=sent_msg.id, link_preview=link_preview) return sent_msg async def gban(self, uid: Union[int, str], reason: str, message: Optional[str] = None) -> Tuple[bool, str]: """Command to gban a user Args: uid: User ID reason: Ban reason Returns: True if ban was successful else false, ban reason """ # if the user account is deleted this can be None if uid is None: return False, 'Deleted account' time_to_sleep: int = randint(1, 3) await asyncio.sleep(time_to_sleep) user_wl = await self.db.whitelist.get(uid) if user_wl: return False, 'User is unbannable (┛ಠ_ಠ)┛彡┻━┻' user = await self.db.banlist.get(uid) for ban_reason in AUTOMATED_BAN_REASONS: if user and (ban_reason in user.reason.lower()): if ban_reason == 'kriminalamt': return False, 'Already banned by kriminalamt' else: return False, 'Already banned by autobahn' # Remove need to check the reason for previous count of added members since this is now done by Kommando if user: if '[SW]' not in reason: count = SPAMADD_PATTERN.search(reason) previous_count = SPAMADD_PATTERN.search(str(user.reason)) if count is not None and previous_count is not None: if previous_count + 30 < count: reason = f"spam adding {count}+ members" else: return False, 'Not added enough' data = {'id': str(uid), 'reason': reason} await self.db.banlist.upsert_multiple([data]) await self.send_message(self.config.gban_group, f'<a href="tg://user?id={uid}">{uid}</a>', parse_mode='html') await self.send_message(self.config.gban_group, f'/gban {uid} {reason}') await self.send_message(self.config.gban_group, f'/fban {uid} {reason}') if self.sw and self.sw.permission in [ Permission.Admin, Permission.Root ]: self.sw.add_ban(int(uid), reason, message) # Some bots are slow so wait a while before clearing mentions # doesnt really do much, sending a message clears unread messages anyway # await asyncio.sleep(10) # await self.send_read_acknowledge(config.gban_group, # max_id=1000000, # clear_mentions=True) return True, reason async def ungban(self, uid: Union[int, str]): """Command to gban a user Args: uid: User ID Returns: None """ await self.send_message(self.config.gban_group, f'<a href="tg://user?id={uid}">{uid}</a>', parse_mode='html') await self.send_message(self.config.gban_group, f'/ungban {uid}') await self.send_message(self.config.gban_group, f'/unfban {uid}') await self.send_message(self.config.gban_group, f'/unban {uid}') await asyncio.sleep(0.5) await self.send_read_acknowledge(self.config.gban_group, max_id=1000000, clear_mentions=True) await self.db.banlist.remove(uid) if self.sw and self.sw.permission in [ Permission.Admin, Permission.Root ]: self.sw.delete_ban(int(uid)) async def ban(self, chat, uid): """Bans a user from a chat.""" if not self.config.debug_mode: try: await self( EditBannedRequest( chat, uid, ChatBannedRights(until_date=datetime.datetime( 2038, 1, 1), view_messages=True))) except UserAdminInvalidError as err: logger.error(err) async def get_cached_entity(self, entity: hints.EntitiesLike): """Get the cached version of a entity""" try: input_entity = await self.get_input_entity(entity) return await self.get_entity(input_entity) except ValueError: return None async def resolve_url(self, url: str, base_domain: bool = True) -> str: """Follow all redirects and return the base domain Args: url: The url base_domain: Flag if any subdomains should be stripped Returns: The base comain as given by urllib.parse """ faker = Faker() headers = {'User-Agent': faker.user_agent()} old_url = url if not url.startswith('http'): url: str = f'http://{url}' try: async with self.aioclient.get(url, headers=headers) as response: url: URL = response.url except (ClientError, asyncio.TimeoutError, socket.gaierror) as err: if base_domain: return await helpers.netloc(old_url) else: raise if base_domain: # split up the result to only get the base domain # www.sitischu.com => sitischu.com url: Optional[str] = url.host _base_domain = url.split('.', maxsplit=url.count('.') - 1)[-1] if _base_domain: url: str = _base_domain return str(url) async def get_me(self, input_peer: bool = False) -> User: if self._me is None: self._me = await super().get_me() else: return self._me def disconnect(self): loop = asyncio.get_event_loop() loop.create_task(self.aioclient.close()) loop.create_task(self.db.disconnect()) return super().disconnect()
class Client(object): def __init__(self, url, dumper=None, loop=None): self.url = url self.dumper = dumper if not loop: loop = asyncio.get_event_loop() if not self.dumper: self.dumper = json.dumps self.client = ClientSession( loop=loop, headers={'content-type': 'application/json'}) def __del__(self): self.client.close() def __encode(self, method, params=None, id=None): try: data = self.dumper({ "jsonrpc": "2.0", "id": id, "method": method, "params": params }) except Exception as e: raise Exception("Can not encode: {}".format(e)) return data @asyncio.coroutine def call(self, method, params=None, id=None, schem=None): if not id: id = uuid4().hex try: resp = yield from self.client.post( self.url, data=self.__encode(method, params, id)) except Exception as err: raise Exception(err) if 200 != resp.status: raise InvalidResponse( "Error, server retunrned: {status}".format(status=resp.status)) try: data = yield from resp.json() except Exception as err: raise InvalidResponse(err) try: validate(data, ERR_JSONRPC20) return Response(**data) except ValidationError: # Passing data to validate response. # Good if does not valid to ERR_JSONRPC20 object. pass except Exception as err: raise InvalidResponse(err) try: validate(data, RSP_JSONRPC20) if id != data['id']: raise InvalidResponse( "Rsponse id {local} not equal {remote}".format( local=id, remote=data['id'])) except Exception as err: raise InvalidResponse(err) if schem: try: validate(data['result'], schem) except ValidationError as err: raise InvalidResponse(err) except Exception as err: raise InternalError(err) return Response(**data)
class HttpClient(object): DEFAULT_PORTS = {'http': 80, 'https': 443} def __init__(self, scheme: str = None, host: str = None, port: int = None, is_proxy: bool = False): self.scheme = scheme self.host = host self.port = port self.is_proxy = is_proxy self.session: ClientSession = None async def connect( self, host, port, scheme='http', timeout=None, # this parameter is deprecated is_proxy=False): """*** DEPRECATED *** Provide the values via constructor instead. """ if not self.is_closed(): await self.session.close() self.scheme = scheme self.host = host self.port = port self.is_proxy = is_proxy self.session = ClientSession(connector=aiohttp.TCPConnector()) async def request(self, url, headers=None, method='GET', body=None): parts = urllib.parse.urlsplit(url) if self.is_proxy: host = parts.netloc path = url else: if parts.scheme and parts.scheme != self.scheme: raise HttpException("URL is %s but connection is %s" % (parts.scheme, self.scheme)) host = parts.netloc if not host: host = self.host if self.port != self.DEFAULT_PORTS[self.scheme]: host += ":%s" % self.port path = parts.path if parts.query: path += '?' + parts.query async with self.session.request(method, self.scheme + '://' + host + path, headers=headers, data=body) as resp: return await HttpResponse.from_aiohttp_response(resp) def close(self): asyncio.ensure_future(self.session.close()) def is_closed(self): return self.session is None or self.session.closed @classmethod async def query(cls, url, headers=None, method='GET', body=None): async with aiohttp.request(method, url, headers=headers, data=body) as resp: monocle_resp = await HttpResponse.from_aiohttp_response(resp) return monocle_resp
import time import asyncio from aiohttp import ClientSession, TCPConnector, BasicAuth async def fetch(url, session): proxy_auth = BasicAuth('tstfmsfsfax', '0sfsf0fsf0') headers = {'connection': 'closed'} async with session.get(url=url, proxy="http://http-proxy-sg1.dobel.cn:9180", proxy_auth=proxy_auth, headers=headers) as resp: print(await resp.read()) connector = TCPConnector(limit=60) session = ClientSession(connector=connector) nums = 300 url = 'https://www.taobao.com/help/getip.php' tasks = [fetch(url, session) for x in range(nums)] begin = time.time() try: loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks)) except: pass finally: end = time.time() loop.close() session.close() print('cost', end - begin, 'speed', nums / (end - begin), 'req/s')
class TestClient: """ a test client class designed for easy testing in Sanic-based Application. """ def __init__(self, app, loop=None, host='127.0.0.1', protocol=None, ssl=None, scheme=None, **kwargs): if not isinstance(app, Sanic): raise TypeError("app should be a Sanic application.") self._app = app self._loop = loop # we should use '127.0.0.1' in most cases. self._host = host self._ssl = ssl self._scheme = scheme self._protocol = HttpProtocol if protocol is None else protocol self._closed = False self._server = TestServer(self._app, loop=self._loop, protocol=self._protocol, ssl=self._ssl, scheme=self._scheme) cookie_jar = CookieJar(unsafe=True, loop=loop) self._session = ClientSession(loop=loop, cookie_jar=cookie_jar, **kwargs) # Let's collect responses objects and websocket objects, # and clean up when test is done. self._responses = [] self._websockets = [] @property def app(self): return self._app @property def host(self): return self._server.host @property def port(self): return self._server.port @property def server(self): return self._server @property def session(self): return self._session def make_url(self, uri): return self._server.make_url(uri) async def start_server(self): """ Start a TestServer that running Sanic application. """ await self._server.start_server(loop=self._loop) async def close(self): """ Close TestClient obj, and cleanup all fixtures created by test client. """ if not self._closed: for resp in self._responses: resp.close() for ws in self._websockets: await ws.close() self._session.close() await self._server.close() self._closed = True async def _request(self, method, uri, *args, **kwargs): url = self._server.make_url(uri) response = await self._session.request(method, url, *args, **kwargs) self._responses.append(response) return response async def get(self, uri, *args, **kwargs): return await self._request(GET, uri, *args, **kwargs) async def post(self, uri, *args, **kwargs): return await self._request(POST, uri, *args, **kwargs) async def put(self, uri, *args, **kwargs): return await self._request(PUT, uri, *args, **kwargs) async def delete(self, uri, *args, **kwargs): return await self._request(DELETE, uri, *args, **kwargs) async def patch(self, uri, *args, **kwargs): return await self._request(PATCH, uri, *args, **kwargs) async def options(self, uri, *args, **kwargs): return await self._request(OPTIONS, uri, *args, **kwargs) async def head(self, uri, *args, **kwargs): return await self._request(HEAD, uri, *args, **kwargs) async def ws_connect(self, uri, *args, **kwargs): """ Create a websocket connection. a thin wrapper around aiohttp.ClientSession.ws_connect. """ url = self._server.make_url(uri) ws_conn = await self._session.ws_connect(url, *args, **kwargs) # Save it, clean up later. self._websockets.append(ws_conn) return ws_conn # Context Manager async def __aenter__(self): await self.start_server() return self async def __aexit__(self, exc_type, exc_value, traceback): await self.close()
class BotLogger(object): def __init__(self, sparcli:commands.Bot): self.sparcli = sparcli logChannel = getTokens()['BotLoggingChannel'] self.discordBotsToken = getTokens()['DiscordBotsPw']['Key'] self.logChannel = sparcli.get_channel(logChannel) self.session = ClientSession(loop=sparcli.loop) self.fserver = None def __unload(self): self.session.close() async def on_message(self, message): if self.fserver: if message.server == self.fserver: print(PrintableMessage(message)) else: print(PrintableMessage(message)) @commands.command(pass_context=True, hidden=True) @permissionChecker(check='is_owner') async def setfilter(self, ctx, *, serverName:str=None): if serverName: try: serverObj = [i for i in self.sparcli.servers if serverName in i.name][0] self.fserver = serverObj await self.sparcli.say('Done!') except IndexError: await self.sparcli.say('No can do, boss.') else: self.fserver = None await self.sparcli.say('Done!') @commands.command(pass_context=True, hidden=True) @permissionChecker(check='is_owner') async def say(self, ctx, channelName:str, *, content:str): c = [i for i in self.fserver.channels if channelName in i.name][0] await self.sparcli.send_message(c, content) async def updateDiscordBots(self, serverAmount): ''' Updates the Discord bots website ''' if not self.discordBotsToken: return data = { 'server_count': serverAmount } headers = { 'Authorization': self.discordBotsToken } v = await self.session.post( 'https://bots.discord.pw/api/bots/{}/stats'.format(self.sparcli.user.id), data=data, headers=headers ) async def on_server_join(self, server): ''' Triggered when the bot joins a server ''' botServers = len(self.sparcli.servers) # await self.updateDiscordBots(botServers) allMembers = server.members userMembers = len([i for i in allMembers if not i.bot]) botMembers = len(allMembers) - userMembers o = OrderedDict() o['Server Name'] = server.name o['Server Amount'] = botServers o['Server ID'] = server.id o['Memebrs'] = '`{}` members (`{}` users, `{}` bots)'.format( len(allMembers), userMembers, botMembers ) em = makeEmbed(author='Server Join!', fields=o, colour=0x228B22) await self.sparcli.send_message( self.logChannel, embed=em ) async def on_server_remove(self, server): ''' Triggered when the bot leaves a server ''' botServers = len(self.sparcli.servers) # await self.updateDiscordBots(botServers) allMembers = server.members userMembers = len([i for i in allMembers if not i.bot]) botMembers = len(allMembers) - userMembers o = OrderedDict() o['Server Name'] = server.name o['Server Amount'] = botServers o['Server ID'] = server.id o['Memebrs'] = '`{}` members (`{}` users, `{}` bots)'.format( len(allMembers), userMembers, botMembers ) em = makeEmbed(author='Server Leave :c', fields=o, colour=0xFF0000) await self.sparcli.send_message( self.logChannel, embed=em )
class ApiSession: def __init__(self, root_url, settings: Settings, loop=None): self.settings = settings self.loop = loop or asyncio.get_event_loop() self.session = ClientSession( loop=self.loop, json_serialize=self.encode_json, ) self.root = root_url.rstrip('/') + '/' @classmethod def encode_json(cls, data): return json.dumps(data, cls=CustomJSONEncoder) def close(self): self.session.close() async def get(self, uri, *, allowed_statuses=(200, ), **data): return await self._request(METH_GET, uri, allowed_statuses=allowed_statuses, **data) async def delete(self, uri, *, allowed_statuses=(200, ), **data): return await self._request(METH_DELETE, uri, allowed_statuses=allowed_statuses, **data) async def post(self, uri, *, allowed_statuses=(200, 201), **data): return await self._request(METH_POST, uri, allowed_statuses=allowed_statuses, **data) async def put(self, uri, *, allowed_statuses=(200, 201), **data): return await self._request(METH_PUT, uri, allowed_statuses=allowed_statuses, **data) async def _request(self, method, uri, allowed_statuses=(200, 201), **data) -> Response: method, url, data = self._modify_request( method, self.root + str(uri).lstrip('/'), data) headers = data.pop('headers_', {}) timeout = data.pop('timeout_', 300) async with self.session.request(method, url, json=data, headers=headers, timeout=timeout) as r: # always read entire response before closing the connection response_text = await r.text() if isinstance(allowed_statuses, int): allowed_statuses = allowed_statuses, if allowed_statuses != '*' and r.status not in allowed_statuses: raise ApiError(method, url, data, r, response_text) else: api_logger.debug('%s /%s -> %s', method, uri, r.status) return r def _modify_request(self, method, url, data): return method, url, data
class Misc(Cog, name="Misc Category"): """`{Miscallaneous Commands}`""" def __init__(self, bot): self.bot = bot self.ses = ClientSession(loop=self.bot.loop) def cog_unload(self): self.bot.loop.create_task(self.ses.close()) #•----------Commands----------•# #Booster Command @command(brief="{List of Boosters for the Server}", usage="boosters", aliases=['sboosters', 'boosts', 'boosterlist']) @guild_only() @cooldown(1, 1.5, BucketType.user) @bot_has_permissions(use_external_emojis=True) async def boosters(self, ctx): booster_list = [] boost = ctx.guild.premium_subscribers #If there's over 25 boosters if len(boost) > 25: #Subtract 25 length = boost - 25 #Showing the 25 members and if there's more #We show the leftover booster_list = f"{' , '.join(map(str, (member.mention for member in list(reversed(boost))[:25])))} and **{length}** more..." else: #Show all members if less than 25 booster_list = f"{' , '.join(map(str, (member.mention for member in list(reversed(boost[1:])))))}" #Make a variable to make stuff easier boosters = "No Members" if not booster_list else booster_list #Make embed e = discord.Embed( title= f"<:booster:741407205575622696> __**List of Boosters for {{{ctx.guild.name}}}**__", color=0x420000, timestamp=datetime.utcnow()) #Make fields fields = [("*Members who Boosted*", f"{boosters}", False)] #Add fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) e.set_footer(text=f"{len(boost)} Total") await ctx.send(embed=e) @command(brief="{Leave a Suggestion}", usage="suggest <suggestion>", aliases=['sugg']) @guild_only() @cooldown(1, 1.5, BucketType.user) async def suggest(self, ctx, *, sug): #If the suggestion is too long if len(sug) > 750: e = discord.Embed( description= "<:redmark:738415723172462723> __*Suggestion can't be longer than 750 Characters*__", color=0x420000) await ctx.send(embed=e) return #Look for a keyword 'sugg' in a channel channel = discord.utils.find(lambda g: 'sugg' in g.name, ctx.guild.text_channels) #If there isn't a suggestion channel if not channel: await ctx.send("I can't seem to find a Suggestion channel") return #Make embed e = discord.Embed(title="__*New Suggestion!*__", description=f"{sug}\n** **", color=0x420000) e.set_thumbnail(url=ctx.author.avatar_url) e.set_footer(text=f"Provided by {ctx.author}") e.timestamp = datetime.utcnow() #Delete author's message await ctx.message.delete() #Make the embed fields fields = [("__*React to Leave your Opinion!*__", "<:greenmark:738415677827973152> - __*Good*__" + "\n<:redmark:738415723172462723> - __*Bad*__" + "\n<:maybemark:738418156808175616> - __*Maybe/Ok*__", True)] #Add fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) #Send the embed m = await channel.send(embed=e) #List the reactions reactions = [ "<:greenmark:738415677827973152>", "<:redmark:738415723172462723>", "<:maybemark:738418156808175616>" ] #Add reactions for react in reactions: await m.add_reaction(react) @command(brief="{Bot Interactively Starts a Poll}", usage="poll") @guild_only() @cooldown(1, 2.5, BucketType.user) async def poll(self, ctx, *, question): #A list of messages to delete when we're all done messages = [ctx.message] answers = [] def check(m): return m.author == ctx.author and m.channel == ctx.channel and len( m.content) <= 100 for i in range(20): messages.append( await ctx.send(f'Say poll option or `publish` to publish poll.')) try: entry = await self.bot.wait_for('message', check=check, timeout=60.0) except asyncio.TimeoutError: break messages.append(entry) if entry.clean_content.startswith('publish'): break answers.append((to_emoji(i), entry.clean_content)) try: await ctx.channel.delete_messages(messages) except: pass # oh well answer = '\n'.join(f'{keycap}: {content}' for keycap, content in answers) embed = discord.Embed(title=f"{ctx.author} asks: {question}", description=f"\n{answer}\n", color=discord.Color.dark_gold()) actual_poll = await ctx.send(embed=embed) for emoji, _ in answers: await actual_poll.add_reaction(emoji) @command(brief="{Start a poll quickly}", usage="quickpoll <at_least_2_questions>") @cooldown(1, 2.5, BucketType.user) @guild_only() async def quickpoll(self, ctx, *questions_and_choices: str): if len(questions_and_choices) < 3: return await ctx.send('Need at least 1 question with 2 choices.', delete_after=5) elif len(questions_and_choices) > 21: return await ctx.send('You can only have up to 20 choices.', delete_after=5) perms = ctx.channel.permissions_for(ctx.me) if not (perms.read_message_history or perms.add_reactions): return await ctx.send( 'Need Read Message History and Add Reactions permissions.', delete_after=5) question = questions_and_choices[0] choices = [(to_emoji(e), v) for e, v in enumerate(questions_and_choices[1:])] try: await ctx.message.delete() except: pass body = "\n".join(f"{key}: {c}" for key, c in choices) embed = discord.Embed(title=f"{ctx.author} asks: {question}", description=f"\n{body}\n") poll = await ctx.send(embed=embed) for emoji, _ in choices: await poll.add_reaction(emoji) @command(brief="{Apply for Moderator}", usage="applymod") @cooldown(1, 3, BucketType.user) @is_owner() @guild_only() async def applymod(self, ctx, member: discord.Member = None): member = member or ctx.author def checkreact(reaction, user): return user.id == member.id and str(reaction.emoji) in ["✅", "❌"] applicationQuestions = [ "What's your Minecraft IGN + Discord Username?", "How old are you? (If you feel uncomfortable saying this, just confirm if you're at least a teenager)", "What Time Zone do you live in? (So I know when you're online, and gives me a reason if you're not too active)", "Why do you want to be Moderator? Isn't it fun to play without any responsibilites?", "What will you do for the Discord Server?", "Anything else you want to say?", ] await ctx.send("__*Application will be sent to you soon...*__") applicationAnswers = {} for question in applicationQuestions: answer = await GetMessage(self.bot, member=member, contentOne=question, timeout=500) if not answer: #They failed to provide an answer await member.send( f"You failed to answer: `{question}`\nBe quicker next time" ) return # We have a valid answer to a question, lets store it applicationAnswers[applicationQuestions.index(question)] = answer print(answer) # We finished asking questions, lets check they want to submit this before sending it off confirmation = await member.send( "Are you sure you want to submit this application?") await confirmation.add_reaction("✅") await confirmation.add_reaction("❌") reaction, user = await self.bot.wait_for("reaction_add", timeout=60.0, check=checkreact) if str(reaction.emoji) == "✅": async with member.typing(): await member.send( "Thank you for applying! Your application will be sent to the Owner soon" ) # We need to sus out whether or not to split the application into separate # embeds or not due to embed ratelimits descriptionChunks = {} description = "" for key, value in applicationAnswers.items(): addition = f"{key+1}) {applicationQuestions[key]}\n{value}\n\n" if (len(description) + len(addition)) > 1850 and len(addition) <= 1850: # This is gonna be to big for 1 embed together, but its gucci on its own # so lets split it and make 2 embeds # Lets make the bigger of the two into a descriptionChunks and the other description if len(description) > len(addition): # the current description is bigger descriptionChunks[description] = False description = addition else: # the addition is bigger descriptionChunks[addition] = False continue elif len(addition) > 1850: # This line alone is to big for one embed description if len(addition) < 2850: # It can still technically fit into 1 embed partOne = addition[:1850] partTwo = addition[1850:] descriptionChunks[partOne] = { 'multipleEmbeds': False, 'fieldValue': partTwo } else: # Technically, it has to be less then 4k words or # else we would not have been able to send ours # and vice versa so make 2 embeds partOne = addition[:1850] partTwo = addition[1850:] descriptionChunks[partOne] = False descriptionChunks[partTwo] = False continue else: # We should be safe to simply add this to our current # description and carry on as we are description += addition continue else: if description != "": descriptionChunks[description] = False for key, value in descriptionChunks.items(): applicationEmbed = discord.Embed( title="Application Answers __**{MODERATOR}**__", description=key, color=discord.Color.dark_purple(), timestamp=datetime.utcnow()) applicationEmbed.set_author( name=f"Application taken by: {member.display_name}", icon_url=f"{member.avatar_url}") applicationEmbed.set_footer(text=f"{member.display_name}") if value != False: # We need to add a field for the rest of the data applicationEmbed.add_field(name='\uFEFF', value=value['fieldValue']) channelnames = ['application'] #Checks for a channel with an Application keyword to send this to channel = discord.utils.find( lambda channel: any( map(lambda c: c in channel.name, channelnames)), ctx.guild.text_channels) #Checks if a application channel doesn't exist if not channel: otherchann = ['gener', 'chat', 'welc'] newchann = discord.utils.find( lambda newchann: any( map(lambda n: n in newchann.name, otherchann)), ctx.guild.text_channels) await newchann.send( "I can't seem to find the Application channel containing a keyword {`application`} to send everybody's applications" ) await channel.send(embed=applicationEmbed) elif str(reaction.emoji) == "❌": await member.send("Application won't be sent")
class TestClient: """ A test client implementation, for a aiohttp.web.Application. :param app: the aiohttp.web application passed to create_test_server :type app: aiohttp.web.Application :param protocol: the aiohttp.web application passed to create_test_server :type app: aiohttp.web.Application """ def __init__(self, app, protocol="http"): self._app = app self._loop = loop = app.loop self.port = unused_port() self._handler = handler = app.make_handler() self._server = loop.run_until_complete(loop.create_server( handler, '127.0.0.1', self.port )) self._session = ClientSession(loop=self._loop) self._root = "{}://127.0.0.1:{}".format( protocol, self.port ) self._closed = False def request(self, method, url, *args, **kwargs): return _RequestContextManager(self._request( method, url, *args, **kwargs )) @asyncio.coroutine def _request(self, method, url, *args, **kwargs): """ routes a request to the http server. the interface is identical to asyncio.request, except the loop kwarg is overriden by the instance used by the application. """ return (yield from self._session.request( method, self._root + url, *args, **kwargs )) def close(self): if not self._closed: loop = self._loop loop.run_until_complete(self._session.close()) loop.run_until_complete(self._handler.finish_connections()) loop.run_until_complete(self._app.finish()) self._server.close() loop.run_until_complete(self._server.wait_closed()) self._closed = True def __del__(self): self.close() def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): self.close()
class Covid(commands.AutoShardedBot, Pool): __slots__ = ("thumb", "http_session", "author_thumb", "news", "pool", "auto_update_running") def __init__(self, *args, loop=None, **kwargs): super().__init__( command_prefix=self._get_prefix, activity=discord.Game(name="c!help | Loading shards..."), status=discord.Status.dnd) super(Pool, self).__init__() self.remove_command("help") self._load_extensions() self.news = None self.http_session = None self.pool = None self.auto_update_running = False self.thumb = "https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/COVID-19_Outbreak_World_Map.svg/langfr-1000px-COVID-19_Outbreak_World_Map.svg.png?t=" self.author_thumb = "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/International_Flag_of_Planet_Earth.svg/1200px-International_Flag_of_Planet_Earth.svg.png" self.loop.create_task(self.init_async()) async def _get_prefix(self, bot, message): try: prefix = await self.getg_prefix(message.guild.id) except: if message.content[0:2] == "C!": prefix = "C!" else: prefix = "c!" return when_mentioned_or(prefix)(bot, message) def _load_extensions(self): for file in os.listdir("cogs/"): try: if file.endswith(".py"): self.load_extension(f'cogs.{file[:-3]}') logger.info(f"{file} loaded") except Exception: logger.exception(f"Fail to load {file}") def _unload_extensions(self): for file in os.listdir("cogs/"): try: if file.endswith(".py"): self.unload_extension(f'cogs.{file[:-3]}') logger.info(f"{file} unloaded") except Exception: logger.exception(f"Fail to unload {file}") async def on_command_error(self, ctx, error): if isinstance(error, commands.CommandOnCooldown): await ctx.send( '{} This command is ratelimited, please try again in {:.2f}s'. format(ctx.author.mention, error.retry_after)) else: # raise error embed = discord.Embed( title="Error", description= f"{error} Invalid command see `c!help`.\nIf you think that is a bot error, report this issue on my discord [here](https://discordapp.com/invite/wTxbQYb) thank you.", timestamp=datetime.datetime.utcnow(), color=utils.COLOR) await ctx.send(embed=embed) async def on_guild_join(self, guild: discord.Guild): await self.wait_until_ready() chan_logger = self.get_channel(692815717078270052) try: general = find(lambda x: x.name == "general", guild.text_channels) if general and general.permissions_for(guild.me).send_messages: embed = discord.Embed( description= "You can support me on <:kofi:693473314433138718>[Kofi](https://ko-fi.com/takitsu) and vote on [top.gg](https://top.gg/bot/682946560417333283/vote) for the bot. <:github:693519776022003742> [Source code](https://github.com/takitsu21/covid-19-tracker)", timestamp=utils.discord_timestamp(), color=utils.COLOR) embed.set_author(name="Coronavirus COVID-19 Tracker", icon_url=guild.me.avatar_url) embed.set_thumbnail(url=self.thumb) embed.add_field( name="Vote", value= "[Click here](https://top.gg/bot/682946560417333283/vote)") embed.add_field( name="Invite Coronavirus COVID-19", value= "[Click here](https://discordapp.com/oauth2/authorize?client_id=682946560417333283&scope=bot&permissions=313408)" ) embed.add_field( name="Discord Support", value="[Click here](https://discordapp.com/invite/wTxbQYb)" ) embed.add_field( name="Source code", value= "[Click here](https://github.com/takitsu21/covid-19-tracker)" ) embed.add_field(name="Help command", value="c!help") embed.add_field(name="Prefix", value="c!") nb_users = 0 channels = 0 for s in self.guilds: nb_users += len(s.members) channels += len(s.channels) embed.add_field( name="<:confirmed:688686089548202004> Confirmed", value=self._data["total"]["confirmed"]) embed.add_field(name="<:recov:688686059567185940> Recovered", value=self._data["total"]["recovered"]) embed.add_field(name="<:_death:688686194917244928> Deaths", value=self._data["total"]["deaths"]) embed.add_field(name="<:servers:693053697453850655> Servers", value=len(self.guilds)) embed.add_field(name="<:users:693053423494365214> Members", value=nb_users) embed.add_field(name="<:hashtag:693056105076621342> Channels", value=channels) embed.add_field( name="<:stack:693054261512110091> Shards", value=f"{ctx.guild.shard_id + 1}/{self.bot.shard_count}") embed.set_footer(text="Made by Taki#0853 (WIP) " + utils.last_update(utils.DATA_PATH), icon_url=guild.me.avatar_url) await general.send(embed=embed) except: pass embed = discord.Embed(title="Bot added to " + guild.name, timestamp=datetime.datetime.utcnow(), color=utils.COLOR) embed.add_field(name="<:users:693053423494365214> Members", value=len(guild.members)) embed.add_field(name="<:hashtag:693056105076621342> Channels", value=len(guild.channels)) embed.set_thumbnail(url=guild.icon_url) embed.set_footer(icon_url=guild.me.avatar_url) await chan_logger.send(embed=embed) async def on_guild_remove(self, guild: discord.Guild): try: await self.delete_notif(guild.id) except: pass try: await self.delete_prefix(guild.id) except: pass async def init_async(self): if self.http_session is None: self.http_session = ClientSession(loop=self.loop) if self.pool is None: try: self.pool = await aiomysql.create_pool( host=config("db_host"), port=3306, user=config("db_user"), password=config("db_token"), db=config("db_user"), minsize=5, maxsize=50, loop=self.loop, autocommit=True) logger.info("pool created") except Exception as e: logger.exception(e, exc_info=True) async def on_ready(self): await self.init_async() await self.change_presence(activity=discord.Game( name=f"c!help | coronavirus.jessicoh.com/api/")) def run(self, token, *args, **kwargs): try: super().run(token, *args, **kwargs) except KeyboardInterrupt: try: self.loop.run_until_complete(self._close()) self.loop.run_until_complete(self.http_session.close()) logger.info("Shutting down") exit(0) except Exception as e: logger.exception(e, exc_info=True) exit(1)
class AppTask(WatchTask): template_files = '.html', '.jinja', '.jinja2' def __init__(self, config: Config): self._config = config self._reloads = 0 self._session: Optional[ClientSession] = None self._runner = None assert self._config.watch_path super().__init__(self._config.watch_path) async def _run(self, live_checks: int = 20) -> None: assert self._app is not None self._session = ClientSession() try: self._start_dev_server() static_path = str(self._app['static_path']) def is_static(changes: Iterable[Tuple[object, str]]) -> bool: return all(str(c[1]).startswith(static_path) for c in changes) async for changes in self._awatch: self._reloads += 1 if any(f.endswith('.py') for _, f in changes): logger.debug('%d changes, restarting server', len(changes)) self._stop_dev_server() self._start_dev_server() await self._src_reload_when_live(live_checks) elif len(changes) == 1 and is_static(changes): # a single (static) file has changed, reload a single file. await src_reload(self._app, changes.pop()[1]) else: # reload all pages await src_reload(self._app) except Exception as exc: logger.exception(exc) await self._session.close() raise AiohttpDevException('error running dev server') async def _src_reload_when_live(self, checks: int = 20) -> None: assert self._app is not None and self._session is not None if self._app[WS]: url = 'http://localhost:{.main_port}/?_checking_alive=1'.format(self._config) logger.debug('checking app at "%s" is running before prompting reload...', url) for i in range(checks): await asyncio.sleep(0.1) try: async with self._session.get(url): pass except OSError as e: logger.debug('try %d | OSError %d app not running', i, e.errno) else: logger.debug('try %d | app running, reloading...', i) await src_reload(self._app) return def _start_dev_server(self) -> None: act = 'Start' if self._reloads == 0 else 'Restart' logger.info('%sing dev server at http://%s:%s ●', act, self._config.host, self._config.main_port) try: tty_path = os.ttyname(sys.stdin.fileno()) except OSError: # pragma: no branch # fileno() always fails with pytest tty_path = '/dev/tty' except AttributeError: # on windows, without a windows machine I've no idea what else to do here tty_path = None self._process = Process(target=serve_main_app, args=(self._config, tty_path)) self._process.start() def _stop_dev_server(self) -> None: if self._process.is_alive(): logger.debug('stopping server process...') if self._process.pid: os.kill(self._process.pid, signal.SIGINT) self._process.join(5) if self._process.exitcode is None: logger.warning('process has not terminated, sending SIGKILL') self._process.kill() self._process.join(1) else: logger.debug('process stopped') else: logger.warning('server process already dead, exit code: %s', self._process.exitcode) async def close(self, *args: object) -> None: self.stopper.set() self._stop_dev_server() if self._session is None: raise RuntimeError("Object not started correctly before calling .close()") await asyncio.gather(super().close(), self._session.close())
class OwnerCommands(object): def __init__(self, bot: CustomBot): self.bot = bot self.session = ClientSession(loop=bot.loop) def __unload(self): self.session.close() async def __local_check(self, ctx: Context): x = await is_owner(ctx) if x: return True raise NotOwner() @command() async def runsql(self, ctx: Context, *, content: str): ''' Runs a line of SQL into the sparcli database ''' async with self.bot.database() as db: x = await db(content) or 'No content.' if type(x) in [str, type(None)]: await ctx.send(x) return # Get the results into groups column_headers = list(x[0].keys()) grouped_outputs = {} for i in column_headers: grouped_outputs[i] = [] for guild_data in x: for i, o in guild_data.items(): grouped_outputs[i].append(str(o)) # Everything is now grouped super nicely # Now to get the maximum length of each column and add it as the last item for key, item_list in grouped_outputs.items(): max_len = max([len(i) for i in item_list + [key]]) grouped_outputs[key].append(max_len) # Format the outputs and add to a list key_headers = [] temp_output = [] for key, value in grouped_outputs.items(): # value is a list of unformatted strings key_headers.append(format(key, '<' + str(value[-1]))) formatted_values = [ format(i, '<' + str(value[-1])) for i in value[:-1] ] # string_value = '|'.join(formatted_values) temp_output.append(formatted_values) key_string = '|'.join(key_headers) # Rotate the list because apparently I need to output = [] for i in range(len(temp_output[0])): temp = [] for o in temp_output: temp.append(o[i]) output.append('|'.join(temp)) # Add some final values before returning to the user line = '-' * len(key_string) output = [key_string, line] + output string_output = '\n'.join(output) await ctx.send('```\n{}```'.format(string_output)) @group() async def profile(self, ctx: Context): ''' A parent group for the different profile commands ''' pass @profile.command(aliases=['username']) async def name(self, ctx: Context, *, username: str): ''' Lets you change the username of the bot ''' if len(username) > 32: await ctx.send( 'That username is too long to be compatible with Discord.') return await self.bot.user.edit(username=username) await ctx.send('Done.') @profile.command(aliases=['picture']) async def avatar(self, ctx: Context, *, url: str = None): ''' Allows you to change the avatar of the bot to a URL or attached picture ''' # Make sure a URL is passed if url == None: try: url = ctx.message.attachments[0].url except IndexError: raise MissingRequiredArgument(self.avatar.params['url']) # Get the image async with self.session.get(url) as r: content = await r.read() # Edit the profile await self.bot.user.edit(avatar=content) await ctx.send('Done.') @profile.command() async def game(self, ctx: Context, game_type: int = None, *, name: str = None): ''' Change the game that the bot is playing ''' if not name: name = self.bot.config['Game']['name'] if not game_type: game_type = self.bot.config['Game']['type'] game = Game(name=name, type=game_type) await self.bot.change_presence(activity=game) await ctx.send('Done.') @command() async def embed(self, ctx: Context, *, content: str): ''' Creates an embed from raw JSON data ''' e = Embed.from_data(eval(content)) await ctx.send(embed=e) @command() async def kill(self, ctx: Context): ''' Turns off the bot and anything related to it ''' async with self.bot.database() as db: for i in self.bot._die.values(): await db.store_die(i) await ctx.send('Turning off now.') await self.bot.logout() @command() async def ev(self, ctx: Context, *, content: str): ''' Runs some text through Python's eval function ''' try: ans = eval(content) except Exception as e: await ctx.send('```py\n' + format_exc() + '```') return if iscoroutine(ans): ans = await ans await ctx.send('```py\n' + str(ans) + '```') @command(aliases=['uld']) async def unload(self, ctx: Context, *cog_name: str): ''' Unloads a cog from the bot ''' self.bot.unload_extension('cogs.' + '_'.join([i.lower() for i in cog_name])) await ctx.send('Cog unloaded.') @command() async def load(self, ctx: Context, *cog_name: str): ''' Unloads a cog from the bot ''' self.bot.load_extension('cogs.' + '_'.join([i.lower() for i in cog_name])) await ctx.send('Cog loaded.') @command(aliases=['rld']) async def reload(self, ctx: Context, *, cog_name: str): ''' Unloads a cog from the bot ''' self.bot.unload_extension('cogs.' + cog_name.lower()) try: self.bot.load_extension('cogs.' + cog_name.lower()) except Exception as e: await ctx.send('```py\n' + format_exc() + '```') return await ctx.send('Cog reloaded.') @command() async def leaveguild(self, ctx: Context, guild_id: int): ''' Leaves a given guild ''' guild = self.bot.get_guild(guild_id) await guild.leave() await ctx.send('Done.')
class DeoWebSocket(): """description of class""" def __init__(self, IP: str): self.URL = f'ws://{IP}:8080/' self.session = ClientSession() self.ws = None self.evtLoop = asyncio.get_event_loop() self.evtLoop.run_until_complete(self.connect()) self.__receivedData = None # global logger logger = logging.getLogger(__name__) def __delete__(self): self.closeSession() self.evtLoop.close() async def connect(self): if self.ws is not None: return self.ws = await self.session.ws_connect(self.URL) async def receive(self, receiveTimeout = None): await self.connect() # set __receiveData, empty if timed out try: self.__receivedData = (await self.ws.receive(receiveTimeout)).data except asyncio.TimeoutError: self.__receivedData = '' async def getLastMsg(self, receiveTimeout:float): ''' call ws.receive() until timeout encountered, then return last msg empties buffer ''' if receiveTimeout is None: receiveTimeout = 0.5 await self.connect() bufferEmpty = False data = '' while not bufferEmpty: try: data = (await self.ws.receive(receiveTimeout)).data except asyncio.TimeoutError: bufferEmpty = True self.__receivedData = data def getWSData(self, receiveTimeout = None) -> str: ''' retrieves a msg from WS (from head of buffer) ''' self.evtLoop.run_until_complete(self.receive(receiveTimeout)) return self.__receivedData def getLatestDeoData(self) -> str: ''' retrieves last DEO msg from WS (from tail of buffer) sleeps 1s to guarantee at least 1 DEO update ''' time.sleep(1) self.evtLoop.run_until_complete(self.getLastMsg(0.5)) return self.__receivedData def getDeoContainerByName(self, jsonList, containerName:str): ''' input should be a JSON array with each object having a field 'structureName' returns new list of JSON objects filtered on the input name matching the field ''' return list(filter(lambda obj: obj[STRUCTURE_NAME]==containerName, jsonList)) def getCurrentContainerValue(self, container_value: str): ''' returns container.value input container_value parameter is assumed to be in this form ''' (container, value) = container_value.split('.') deoJson = json.loads(self.getLatestDeoData()) while DEVICE_DATA not in deoJson: deoJson = json.loads(self.getLatestDeoData()) containerJson = self.getDeoContainerByName(deoJson[DEVICE_DATA], container)[0] logger.debug(containerJson[STRUCTURE_DATA]) return containerJson[STRUCTURE_DATA][value] def getCurrentAlarm0Condition(self): ''' poll DEO to get latest update returns value found for AlarmManagerData._activeAlarmsList0 ''' return self.getCurrentContainerValue('AlarmManagerData._activeAlarmsList0') def getAlarms(self) -> list: ''' returns list of alarms ''' alarms = [] for n in range(0,10): alarm = self.getCurrentContainerValue(f'AlarmManagerData._activeAlarmsList{n}') if len(alarm) > 0: alarms.append(alarm) else: break return alarms def closeSession(self): logger.info('Closing session...') self.evtLoop.run_until_complete(self.session.close()) @staticmethod def pollDeoAlarm(netIP: str, pollTime: int) -> bool: ''' poll DEO through WebSocket to check alarm conditions return True means an alarm was seen, otherwise, no alarm happened in the polling period ''' logging.info('Connecting to DEO WebSocket, check if any alarms raised...') # try a couple of times to connect tries = 3 try: for i in range(0,tries): try: logging.info('connecting...') deoWS = DeoWebSocket(netIP) # if we get here, it means the connection succeeded, break from loop break except: if i < (tries - 1): logging.error('Connection attempt to DEO websocket failed, wait and try again...') time.sleep(10) else: logging.error(f'Unable to connect to DEO websocket after {tries} attempts, aborting') raise Exception('Cannot poll for alarms ==> unable to make websocket connnection to DEO') def isAlarm0(): alarms = deoWS.getAlarms() if len(alarms) == 0: logging.info('No alarms...') return False else: logging.info('Alarms seen: ' + str(alarms)) return True # poll for alarms for up to pollTime seconds at 30s intervals return poll_wait_until(isAlarm0, pollTime, 30) finally: deoWS.closeSession()
class Scriptures(object): def __init__(self, bot: commands.Bot): self.bot = bot self.session = ClientSession(loop=bot.loop) self.regexMatches = { 'OriginalRequest': r'(.+[a-zA-Z0-9]+\s[0-9]+:[0-9]+(-[0-9]+)?)', 'StripAuthor': r'(.+\b)([0-9]+:)', 'GetPassages': r'([0-9]+:[0-9]+)', 'GetMax': r'(-[0-9]+)', 'QuranMatch': r'([0-9]+:[0-9]+([-0-9]+)?)' } self.biblePicture = 'http://pacificbible.com/wp/wp-content/uploads/2015/03/holy-bible.png' self.quranPicture = 'http://www.siotw.org/modules/burnaquran/images/quran.gif' self.hadithPicture = 'https://sunnah.com/images/hadith_icon2_huge.png' def __unload(self): self.session.close() @commands.command(pass_context=True) @hasRoles() async def bible(self, ctx, *, script: str): ''' Gives you the Christian Bible quote from a specific script ''' # Check if it's a valid request matches = match(self.regexMatches['OriginalRequest'], script) if not matches: self.bot.say( 'That string was malformed, and could not be processed. Please try again.' ) return else: script = matches.group() # It is - send it to the API await self.bot.send_typing(ctx.message.channel) # Actually do some processing script = quote(script, safe='') async with self.session.get( 'https://getbible.net/json?scrip={}'.format(script)) as r: try: apiText = await r.text() apiData = loads(apiText[1:-2]) except Exception as e: apiData = None script = unquote(script) # Just check if it's something that we can process if not apiData: await self.bot.say( 'I was unable to get that paricular Bible passage. Please try again.' ) # Now we do some processin' # Get the max and the min verse numbers chapterMin = int( match(self.regexMatches['GetPassages'], script).group().split(':')[1]) chapterMax = match(self.regexMatches['GetMax'], script) if chapterMax: chapterMax = int(chapterMax.group()[1:]) + 1 else: chapterMax = chapterMin + 1 # Process them into an ordered dict o = OrderedDict() passages = apiData['book'][0]['chapter'] for verse in range(chapterMin, chapterMax): o[verse] = passages[str(verse)]['verse'] # Make it into an embed author = match(self.regexMatches['StripAuthor'], script).group().title() em = makeEmbed(fields=o, author=author, author_icon=self.biblePicture) # And done c: await self.bot.say(embed=em) async def getQuran(self, number, mini, maxi, english=True): ''' Sends stuff off to the API to be processed, returns embed object ''' o = OrderedDict() if english: base = 'http://api.alquran.cloud/ayah/{}:{}/en.sahih' else: base = 'http://api.alquran.cloud/ayah/{}:{}' # Get the data from the API async with self.session.get(base.format(number, mini)) as r: data = await r.json() author = data['data']['surah']['englishName'] if english else data[ 'data']['surah']['name'] o['{}:{}'.format(number, mini)] = data['data']['text'] for verse in range(mini + 1, maxi): async with self.session.get(base.format(number, verse)) as r: data = await r.json() o['{}:{}'.format(number, verse)] = data['data']['text'] em = makeEmbed(fields=o, author=author, author_icon=self.quranPicture) return em @commands.command(pass_context=True) @hasRoles() async def quran(self, ctx, *, script: str): ''' Gives you a Quran quote given a specific verse ''' # http://api.alquran.cloud/ayah/{}/en.sahih # Check if it's a valid request matches = match(self.regexMatches['QuranMatch'], script) if not matches: self.bot.say( 'That string was malformed, and could not be processed. Please try again.' ) return else: script = matches.group() # It is - prepare to send it to an API await self.bot.send_typing(ctx.message.channel) # Acutally do some processing number = int(script.split(':')[0]) minQuote = int(script.split(':')[1].split('-')[0]) try: maxQuote = int(script.split(':')[1].split('-')[1]) + 1 except IndexError as e: maxQuote = minQuote + 1 # Send it off nicely to the API to be processed em = await self.getQuran(number, minQuote, maxQuote) await self.bot.say(embed=em) @commands.command(pass_context=True) @hasRoles() async def aquran(self, ctx, *, script: str): ''' Gives you a Quran quote given a specific verse ''' # http://api.alquran.cloud/ayah/{}/en.sahih # Check if it's a valid request matches = match(self.regexMatches['QuranMatch'], script) if not matches: self.bot.say( 'That string was malformed, and could not be processed. Please try again.' ) return else: script = matches.group() # It is - prepare to send it to an API await self.bot.send_typing(ctx.message.channel) # Acutally do some processing number = int(script.split(':')[0]) minQuote = int(script.split(':')[1].split('-')[0]) try: maxQuote = int(script.split(':')[1].split('-')[1]) + 1 except IndexError as e: maxQuote = minQuote + 1 # Send it off nicely to the API to be processed em = await self.getQuran(number, minQuote, maxQuote, False) await self.bot.say(embed=em) @commands.command(pass_context=True) async def hadith(self, ctx, bookAuthor: str, bookNumber: str, hadithNumber: str = None): ''' Gets a particular hadith ''' # Get the hadith number and book numbers into the right variables if not hadithNumber: if not ':' in bookNumber: await self.bot.say( 'That is not a valid format to get a Hadith.' 'Please see this command\'s help message.') return bookNumber, hadithNumber = [ i.strip() for i in bookNumber.split(':') ] await self.bot.send_typing(ctx.message.channel) # Special case book authors are sucky bookAuthor = { 'qudsi': 'qudsi40', 'nawawi': 'nawawi40' }.get(bookAuthor.lower(), bookAuthor.lower()) # Grab the links from the site # print(f'https://sunnah.com/{bookAuthor}/{bookNumber}/{hadithNumber}') siteURL = f'https://sunnah.com/{bookAuthor}/{bookNumber}/{hadithNumber}' async with self.session.get(siteURL) as r: siteText = await r.text() # Make sure it's a valid set of text if 'You have entered an incorrect URL. Please use the menu above to navigate the website' in siteText: await self.bot.say('The URL parsed was invalid. Sorry :/') return # Parse from the site siteRaw = siteText.replace('\n', '').replace('<i>', '*').replace('</i>', '*') # Get the relevant snippet r = r'<div class=\"englishcontainer\" id=t[0-9]+><div class=\"english_hadith_full\"><div class=hadith_narrated>.+<\/div><div class=text_details>.+<\/b><\/div>' try: relevantSnippet = search(r, siteRaw).group() except Exception: await self.bot.say('The URL parsed was invalid. Sorry :/') return # Get the narrator r = r'<div class=hadith_narrated>.*<\/div><div class=text_details>' hadithNarrator = search(r, relevantSnippet).group().replace( '<p>', '').split('>')[1].split('<')[0].strip() # Get the Hadith text r = r'<div class=text_details>.*<\/b>' hadithText = search(r, relevantSnippet).group().replace( '<p>', '').split('>')[1].split('<')[0].strip() # Fix the author bookAuthor = { 'bukhari': 'Sahih Bukhari', 'muslim': 'Sahih Muslim', 'tirmidhi': 'Jami` at-Tirmidhi', 'abudawud': 'Sunan Abi Dawud', 'nasai': "Sunan an-Nasa'i", 'ibnmajah': 'Sunan Ibn Majah', 'malik': 'Muwatta Malik', 'riyadussaliheen': 'Riyad as-Salihin', 'adab': "Al-Adab Al-Mufrad", 'bulugh': 'Bulugh al-Maram', 'qudsi40': '40 Hadith Qudsi', 'nawawi40': '40 Hadith Nawawi' }.get(bookAuthor, bookAuthor) # Fix up some other stuff hadithText = hadithText.replace('<p>', '').replace('</p>', '').replace('`', '\\`') hadithNarrator = hadithNarrator.replace('<p>', '').replace('</p>', '') # Generate the embed properly author = f'{bookAuthor} {bookNumber}:{hadithNumber}'.title() em = makeEmbed(fields={hadithNarrator: hadithText}, author=author, colour=0x78c741, author_icon=self.hadithPicture, author_url=siteURL) try: await self.bot.say(embed=em) except Exception: em = makeEmbed(fields={hadithNarrator: hadithText[:500] + '...'}, author=author, colour=0x78c741, author_icon=self.hadithPicture, author_url=siteURL) await self.bot.say( 'That was too long to get fully. Here\'s the best I can do:', embed=em)
class AppTask(WatchTask): template_files = '.html', '.jinja', '.jinja2' def __init__(self, config: Config, loop: asyncio.AbstractEventLoop): self._config = config self._reloads = 0 self._session = None self._runner = None super().__init__(self._config.watch_path, loop) async def _run(self, live_checks=20): self._session = ClientSession() try: self._start_dev_server() async for changes in self._awatch: self._reloads += 1 if any(f.endswith('.py') for _, f in changes): logger.debug('%d changes, restarting server', len(changes)) self._stop_dev_server() self._start_dev_server() except Exception as exc: logger.exception(exc) await self._session.close() raise SanicDevException('error running dev server') def _start_dev_server(self): act = 'Start' if self._reloads == 0 else 'Restart' logger.info('%sing dev server at http://%s:%s ●', act, self._config.host, self._config.main_port) try: tty_path = os.ttyname(sys.stdin.fileno()) except OSError: # pragma: no branch # fileno() always fails with pytest tty_path = '/dev/tty' except AttributeError: # on windows, without a windows machine I've no idea what else to do here tty_path = None self._process = Process(target=serve_main_app, args=(self._config, tty_path)) self._process.start() def _stop_dev_server(self): if self._process.is_alive(): logger.debug('stopping server process...') os.kill(self._process.pid, signal.SIGINT) self._process.join(5) if self._process.exitcode is None: logger.warning('process has not terminated, sending SIGKILL') os.kill(self._process.pid, signal.SIGKILL) self._process.join(1) else: logger.debug('process stopped') else: logger.warning('server process already dead, exit code: %s', self._process.exitcode) async def close(self, *args): self.stopper.set() self._stop_dev_server() await asyncio.gather(super().close(), self._session.close())
class AppTask(WatchTask): template_files = '.html', '.jinja', '.jinja2' def __init__(self, config: Config, loop: asyncio.AbstractEventLoop): self._config = config self._reloads = 0 self._session = ClientSession(loop=loop) super().__init__(self._config.code_directory_str, loop) async def _run(self): await self._loop.run_in_executor(None, self._start_process) async for changes in self._awatch: self._reloads += 1 if any(f.endswith('.py') for _, f in changes): logger.debug('%d changes, restarting server', len(changes)) await self._loop.run_in_executor(None, self.stop_process) await self._loop.run_in_executor(None, self._start_process) await self._src_reload_when_live() elif len(changes) > 1 or any( f.endswith(self.template_files) for _, f in changes): self._app.src_reload() else: self._app.src_reload(changes.pop()[1]) async def _src_reload_when_live(self, checks=20): if self._app[WS]: url = 'http://localhost:{.main_port}/?_checking_alive=1'.format( self._config) logger.debug( 'checking app at "%s" is running before prompting reload...', url) for i in range(checks): await asyncio.sleep(0.1, loop=self._app.loop) try: async with self._session.get(url): pass except OSError as e: logger.debug('try %d | OSError %d app not running', i, e.errno) else: logger.debug('try %d | app running, reloading...', i) self._app.src_reload() return def _start_process(self): act = 'Start' if self._reloads == 0 else 'Restart' logger.info('%sing dev server at http://%s:%s ●', act, self._config.host, self._config.main_port) try: tty_path = os.ttyname(sys.stdin.fileno()) except OSError: # pragma: no branch # fileno() always fails with pytest tty_path = '/dev/tty' except AttributeError: # on windows, without a windows machine I've no idea what else to do here tty_path = None self._process = Process(target=serve_main_app, args=(self._config, tty_path)) self._process.start() def stop_process(self): if self._process.is_alive(): logger.debug('stopping server process...') os.kill(self._process.pid, signal.SIGINT) self._process.join(5) if self._process.exitcode is None: logger.warning('process has not terminated, sending SIGKILL') os.kill(self._process.pid, signal.SIGKILL) self._process.join(1) else: logger.debug('process stopped') else: logger.warning('server process already dead, exit code: %s', self._process.exitcode) async def close(self, *args): await self._loop.run_in_executor(None, self.stop_process) await super().close() self._session.close()
class Fun(Cog, name="Fun Category"): """`{Full List of Fun Commands}`""" def __init__(self, bot): self.bot = bot #Used to get the functions #From this cog self.gc = self.bot.get_cog('Helpdude') self.d = self.bot.emojified self.g = self.bot.get_cog('Global') self.ses = ClientSession(loop=self.bot.loop) #•----------Methods/Functions----------•# #Used to run the ClientSession #And close when complete def cog_unload(self): self.bot.loop.create_task(self.ses.close()) async def nice(self, ctx): com_len = len(f'{ctx.prefix}{ctx.invoked_with} ') return ctx.message.clean_content[com_len:] #Goes through message and replaces all #Instances of keys with their values in a dict async def lang_convert(self, ctx, msg, lang): keys = list(lang) #Iterate through list of 'lang' argument for k in keys: msg = msg.replace(k, lang[k]) #If user's message is too long if len(msg) > 750: e = discord.Embed( description= f"<:redmark:738415723172462723> That message is too long to convert" ) await ctx.send(embed=e) else: await ctx.send(msg) #•-----------Commands----------•# @command(brief="{Shows a Menu for Minecraft Commands}", usage="minecraft") @cooldown(1, 2.5, BucketType.user) @guild_only() async def minecraft(self, ctx): #Defining the author #Makes stuff shorter mem = ctx.author #Get the cog by it's class #Using a function from another file cog = self.gc.get_cog_by_class('Minecraft') #Make embed e = discord.Embed( title= f"<:grass:734647227523268668> __*{cog.qualified_name}*__\n_*() - Optional\n<> - Required*_\n\n__*Your Available Commands*__" ) #Iterate through the Subcommands for c in cog.walk_commands(): #Make fields fields = [(f"• **{c.name} :** `{ctx.prefix}{c.usage}`", c.brief, True)] #Add fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) e.set_thumbnail(url=mem.avatar_url) e.set_footer(text=mem) e.timestamp = datetime.utcnow() await ctx.send(embed=e) @command(brief="{Insult a Member}", usage="roast <member>", aliases=['bully']) @cooldown(1, 2.5, BucketType.user) @guild_only() async def roast(self, ctx, member: discord.Member): async with ctx.typing(): #Url for the api url = "https://evilinsult.com/generate_insult.php?lang=en&type=json" #Get the api r = await self.ses.get(url) #Convert into json format js = await r.text() resp = json.loads(js) #If the api is unavailable if r.status != 200: e = discord.Embed( description=f"__*{member.mention}, something went wrong*__", color=0x420000) await ctx.send(embed=e) return #Make embed e = discord.Embed( description=f"**{member.mention}, {resp['insult']}**", color=0x420000) #Send embed await ctx.send(embed=e) @command(brief="{Get a Random Meme}", usage="meme") @cooldown(1, 2.5, BucketType.user) @guild_only() async def meme(self, ctx): async with ctx.typing(): #api we want to get url = "https://apis.duncte123.me/meme" #Fetch the api r = await self.ses.get(url) #Turn the api into a json for easy access res = await r.json() #Get the meme url meme_url = f"{res['data']['url']}" #Make embed e = discord.Embed(title="Meme Link", url=meme_url, timestamp=datetime.utcnow()) #Set the embed's image #With the meme's image e.set_image(url=res['data']['image']) #Get the title #Of the meme val = f"{res['data']['title']}" e.add_field(name="__*Quality Meme 👌*__", value=val) await ctx.send(embed=e) @command(brief="{Info on a Movie}", usage="movie <movie_title>", aliases=['searchmovie']) @guild_only() @cooldown(1, 2.5, BucketType.user) @bot_has_permissions(use_external_emojis=True) async def movie(self, ctx, *, title): try: redmark = "<:redmark:738415>" #Only works if you have an api key inside the website url = f"https://api.themoviedb.org/3/search/movie?api_key=Your_api_key={title}" r = await self.ses.get(url) resp = await r.json() #If the resource isn't available if r.status == 404: e = discord.Embed( description= f"{redmark} __*{ctx.author.mention}, that movie doesn't exist*__", color=0x420000) await ctx.send(embed=e) return #Make embed e = discord.Embed( description= f"**General Info for {resp['results'][0]['title']}**") fields = [( "__*Misc Info*__", f"PG13? {resp['results'][0]['adult']}" + f"\nOriginal Language: {resp['results'][0]['original_language']}" + f"\nMovie ID: {resp['results'][0]['id']}" + f"\nGenre ID's: {resp['results'][0]['genre_ids']}" + f"\nVote Count: {resp['results'][0]['vote_count']}" + f"\nVote Average: {resp['results'][0]['vote_average']}", True), ("__*Overview*__", resp['results'][0]['overview'], True)] #Add fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) e.set_thumbnail( url= f"https://image.tmdb.org/t/p/w500/{resp['results'][0]['poster_path']}" ) #Set footer to when movie #Was released e.set_footer( text= f"{resp['results'][0]['title']} Released | {resp['results'][0]['release_date']}" ) #Send embed await ctx.send(embed=e) #If the given movie doesn't exist except Exception: e = discord.Embed( description= f"{redmark} __*{ctx.author.mention}, that isn't a movie*__", color=0x420000) await ctx.send(embed=e) return @command(brief="{See what song somebody's listening to}", usage="spotify <member>") @guild_only() @cooldown(1, 2.5, BucketType.user) async def spotify(self, ctx, user: discord.Member = None): user = user or ctx.author #Iterate through user's activities for act in user.activities: if isinstance(act, Spotify): e = discord.Embed(color=0x0F4707) e.description = f'__*{user.mention} is listening to*__ **{act.title}**' e.set_thumbnail(url=act.album_cover_url) #Display the length of the song length = f"{pendulum.duration(seconds=act.duration.total_seconds()).in_words(locale='en')}" #Make fields fields = [("*Song Name*", f"** **• {act.title}", False), ("*Song Artist*", f"** **• {act.artist}", False), ("*Song's Album*", f"** **•{act.album}", False), ("*Length*", f"** **• {length}", True)] #Add fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) #Send the embed await ctx.send(embed=e) #Break the loop #If the user isn't listening #To anything else: e = discord.Embed( description= f"__*{user.mention}, isn't listening to Spotify right now*__", color=0x420000) await ctx.send(embed=e) @command(brief="{Hack a Member}", usage="hack <member>", aliases=['hck']) @guild_only() async def hack(self, ctx, member: discord.Member = None): #If a member isn't given if not member: await ctx.send("Please mention a member") return #Fake passwords to go through passwords = [ 'imnothackedlmao', 'sendnoodles63', 'ilovenoodles', 'icantcode', 'christianmicraft', 'server', 'icantspell', 'hackedlmao', 'WOWTONIGHT', '69' ] #Fake ips to go through fakeips = [ '154.2345.24.743', '255.255. 255.0', '356.653.56', '101.12.8.6053', '255.255. 255.0' ] #Random time to wait for sec = randint(1, 3) e = discord.Embed(title=f"**Hacking: {member.mention}** 0%...", color=randint(0x000000, 0xffffff)) m = await ctx.send(embed=e) await asyncio.sleep(sec) e = discord.Embed(title=f"Searching for contacts... {{19%}}", color=randint(0x000000, 0xffffff)) await m.edit(embed=e) await asyncio.sleep(sec) e = discord.Embed( title=f"Searching for any friends if there is any {{34%}}", color=randint(0x000000, 0xffffff)) await m.edit(embed=e) await asyncio.sleep(sec) e = discord.Embed(title=f"Getting IP... {{55%}}", color=randint(0x000000, 0xffffff)) await m.edit(embed=e) await asyncio.sleep(sec) e = discord.Embed(title=f"Got IP {random.choice(fakeips)} {{69%}}", color=randint(0x000000, 0xffffff)) await m.edit(embed=e) await asyncio.sleep(sec) e = discord.Embed(title=f"Getting password... {{84%}}", color=randint(0x000000, 0xffffff)) await m.edit(embed=e) await asyncio.sleep(sec) e = discord.Embed( title=f"Got password {random.choice(passwords)} {{99%}}", color=randint(0x000000, 0xffffff)) await m.edit(embed=e) await asyncio.sleep(sec) embed = discord.Embed(title=f"**Hacking: {member}** 100%", color=randint(0x000000, 0xffffff)) await m.edit(embed=embed) await asyncio.sleep(sec) embed = discord.Embed( title=f"{member} info ", description= f"*Email `{member}@gmail.com` Password `{random.choice(passwords)}` IP `{random.choice(fakeips)}`*", color=random.randint(0x000000, 0xffffff)) embed.set_footer(text="You've totally been hacked 😏") await m.edit(embed=embed) @command(brief="{Info on an Insta Acc}", usage="insta <insta_username>", aliases=['instagram']) @cooldown(1, 1, BucketType.user) async def insta(self, ctx, *, user_name): redmark = "<:redmark:738415723172462723>" mem = ctx.author async with ctx.typing(): # Request profile information from API url = f"https://apis.duncte123.me/insta/{user_name}" r = await self.ses.get(url) #If the api's available/online if r.status == 200: #Convert api into a json #For easy access later on insta = await r.json() data = insta["user"] images = insta["images"] private = data["is_private"] verified = data["is_verified"] full_name = data["full_name"] username = data["username"] pfp = data["profile_pic_url"] followers = data["followers"]["count"] following = data["following"]["count"] uploads = data["uploads"]["count"] biography = data["biography"] #When profile isn't private, grab the information of their last post if not private: image_url = images[0]["url"] image_caption = images[0]["caption"] #Send error if no instagram profile was found with given username elif r.status == 422: e = discord.Embed( description= f"{redmark} __*{mem.mention}, that Account doesn't exist*__", color=0x420000) await ctx.send(embed=e) return elif r.status == 429: e = discord.Embed( description= f"{redmark} __*{mem.mention}, you're being **RateLimited**\nYou spammed the command too much*__", color=0x420000) await ctx.send(embed=e) return # Setting bools to ticks/cross emojis verif = "<:greenmark:738415677827973152>" if verified else redmark priv = "<:greenmark:738415677827973152>" if private else redmark biography = biography if biography else "No Bio" # Set the page url to the last post or the profile based on privacy settings page_url = images[0][ "page_url"] if not private else f"https://www.instagram.com/{username}/" desc = f"**Full Name:** {full_name}" \ f"\n**Bio:** {biography}" \ f"\n\n**Verified?:** {verif} | **Private?:** {priv}" \ f"\n**Following:** {following} | **Followers:** {followers}" \ f"\n**Upload Count:** {uploads}" e = discord.Embed(title=f"{username}'s Instagram", description=desc, url=page_url, colour=0x420000) e.set_thumbnail(url=pfp) e.set_footer(text=f"Requested By {ctx.author}", icon_url=ctx.author.avatar_url) # When profile is not private, display the last post with the caption if not private: e.add_field(name="My Latest Post", value=f"**Caption:** {image_caption}", inline=False) e.set_image(url=image_url) await ctx.send(embed=e) @command(brief="{Get a random fact}", usage="fact") @guild_only() @cooldown(1, 2.5, BucketType.user) async def fact(self, ctx): async with ctx.typing(): url = f'https://uselessfacts.jsph.pl/random.json?language=en' response = await self.ses.get(url) r = await response.json() fact = r['text'] e = discord.Embed(title=f'Random Fact', colour=randint(0x000000, 0xffffff)) #Make fields fields = [("**Fun Fact**", fact, False)] #Add fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) #Send embed await ctx.send(embed=e) @command(brief="{Get Lyrics for a Song}", usage="lyrics <song_title>", aliases=['songlyrics', 'lyric']) @guild_only() @cooldown(1, 2.5, BucketType.user) async def lyrics(self, ctx, *, title): mem = ctx.author redmark = "<:redmark:738415723172462723>" async with ctx.typing(): try: #Getting the url url = f"https://some-random-api.ml/lyrics?title={title}" r = await self.ses.get(url) #Converting into json for easy access resp = await r.json() #Making variables for the json keys song_image = resp['thumbnail']['genius'] song_artist = resp['author'] song_title = resp['title'] song_lyrics = resp['lyrics'] #If song lyrics are too long if len(song_lyrics) > 650: #Subtract 650 characters #From lyrics length = len(song_lyrics) - 650 lyrics = f"{''.join(song_lyrics[:650])} and **{length}** more words..." #Else if lyrics are less than 650 characters else: lyrics = song_lyrics lyric_link = resp['links']['genius'] #If the api's down if r.status != 200: e = discord.Embed( description= f"{redmark} __*{mem.mention}, looks like something went wrong*__", color=0x420000) await ctx.send(embed=e) #Make embed e = discord.Embed( title=f"*Direct Link to Lyrics for -> {{{song_title}}}*", url=lyric_link) #Set thumbnail as song image e.set_thumbnail(url=song_image) #Make fields fields = [("__*Lyrics*__", lyrics, True), ("__*Artist*__", song_artist, True)] e.set_footer(text=f"Requested by {mem}") #Add fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) await ctx.send(embed=e) #If the song doesn't exist except KeyError: e = discord.Embed( description= f"{redmark} __*{mem.mention}, that isn't a song*__", color=0x420000) await ctx.send(embed=e) return @command(brief="{Do Math}", usage="math <math_stuff>") @guild_only() @cooldown(1, 1.25, BucketType.user) async def math(self, ctx): redmark = "<:redmark:738415723172462723>" mem = ctx.author try: problem = str( ctx.message.clean_content.replace(f"{ctx.prefix}math", "")) #If a problem isn't given if problem == "": e = discord.Embed( description= f"{redmark} __*{mem.mention}, you need to put an actual problem", color=0x420000) await ctx.send(embed=e) return #If the user's problem is too long if len(problem) > 500: e = discord.Embed( description= f"{redmark} __*{mem.mention}, that problem's way too long", color=0x420000) await ctx.send(embed=e) return problem = problem.replace("÷", "/").replace("x", "*").replace( "•", "*").replace("=", "==").replace("π", "3.14159") #Iterate through a string of invalid #Chracters for letter in "abcdefghijklmnopqrstuvwxyz\\_@~`,<>?|'\"{}[]": #If any of those characters are in user's math if letter in problem: e = discord.Embed( description= f"{redmark} __*{mem.mention}, that math problem has invalid characters*__", color=0x420000) await ctx.send(embed=e) return #Make embed e = discord.Embed(timestamp=datetime.utcnow()) #Make fields fields = [("__*Problem Given*__", problem, True), ("__*Answer*__", f"{str(round(eval(problem), 4))}", True) ] #Add the fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) e.set_footer(text=mem, icon_url=mem.avatar_url) #Send embed await ctx.send(embed=e) #If the problem is unsolvable except Exception: e = discord.Embed( description= f"{redmark} __*{mem.mention}, looks like something went wrong*__", color=0x420000) await ctx.send(embed=e) @command(brief="{Say something in Sarcasm}", usage="sarcastic <text>", aliases=['sarcasm', 'sarc']) @guild_only() @cooldown(1, 2.5, BucketType.user) async def sarcastic(self, ctx, *, text): text = await self.nice(ctx) if len(text) > 500: await ctx.send("That message is too long to convert") return caps = True sarc = '' for letter in text: if not letter == ' ': caps = not caps if caps: sarc += letter.upper() else: sarc += letter.lower() await ctx.send(sarc) @command(brief="{Places a 👏 in between your Text}", usage="clap <text>") @guild_only() @cooldown(1, 2.5, BucketType.user) async def clap(self, ctx, *, msg): clapped = '👏' + ' 👏 '.join((await self.nice(ctx)).split(' ')) + ' 👏' if len(clapped) > 900: await ctx.send("That message is too long to convert") return await ctx.send(clapped) @command(brief="{Emojify your Text}", usage="emojify <text>", aliases=['emofy']) @guild_only() @cooldown(1, 2.5, BucketType.user) async def emojify(self, ctx, *, msg): #Letters to try and emojify letters = 'abcdefghijklmnopqrstuvwxyz' #Empty string to add onto later text = '' #Iterate through for letter in (await self.nice(ctx)).lower(): #If the message given is in #The list of letters we made if letter in letters: text += f':regional_indicator_{letter}: ' #Else if they don't give any letters else: text += self.d.get(letter, letter) + ' ' #If the user's message is too long if len(msg) > 750: await ctx.send("Message can't be over 750 Characters") #Else if it isn't else: await ctx.send(msg) @command(brief="{Sends a bubblewrap}", usage="bubblewrap (#x#)", aliases=['bwrap']) @guild_only() @cooldown(1, 3, BucketType.user) async def bubblewrap(self, ctx, size=None): #If a size isn't given #Use a default if size is None: size = ( 10, 10, ) #Else if a size IS given else: #Split the two numbers given size = size.split('x') #If the size given is less #Than 2 characters #Should be #x# if len(size) != 2: await ctx.send( "That isn't a valid size\nExample size is: 10x10") return try: #Try to Convert the sizes given #Into a number size[0] = int(size[0]) size[1] = int(size[1]) #If it isn't a number #Send this ValueError except ValueError: await ctx.send( "That isn't a valid size\nExample size is: 10x10") return #Iterate through the size for val in size: #Check if the user gives #A size that's too big if val < 1 or val > 12: await ctx.send("The size must be between 1 and 12") #The letters users will see #When bubblewrapping bubble = '||***pop***||' #Make embed e = discord.Embed(description=f'{bubble*size[0]}\n' * size[1]) #Send embed await ctx.send(embed=e) @command(brief="{See how big your Penis is}", usage="pp", aliases=['penis', 'ppsize', 'penissize', 'penisize']) @guild_only() @cooldown(1, 1.5, BucketType.user) async def pp(self, ctx): #The response for the embed to send penis = f"8{'=' * randint(1,25)}D" #Multiplies our '=' by a random choice of 1-15 #A list to go through first_list = ["Your pp", "Your penis", "Your package"] #Get a random choice first = choice(first_list) #List of stuff to go through title_list = ["PP Analizer", "PP Inspector", "PP Rater"] title = choice(title_list) #Make the embed e = discord.Embed(title=title, description=f"*{first} {penis}*", color=randint(0, 0xffffff)) #Send the embed await ctx.send(embed=e) @command(brief="{See how gay you are}", usage="gay", aliases=['gayrater', 'gayrate']) @guild_only() @cooldown(1, 1.5, BucketType.user) async def gay(self, ctx): #Makes stuff shorter mem = ctx.author #Our responses for the embed #To send res = [ f"You're {randint(15, 125)}% Gay 🏳️🌈🏳️🌈🏳️🌈", f"{mem.mention} Stop Being so Gay, you were rated {randint(15, 135)}% Gay 🏳️🌈🏳️🌈🏳️🌈" ] #Make embed e = discord.Embed(title="Gay Patrol 🔫", description=choice(res), color=randint(0, 0xffffff)) #Send embed await ctx.send(embed=e) @command(brief="{Make your Message a Fancy Embed}", usage="embed <message>") @guild_only() @cooldown(1, 2.5, BucketType.user) async def embed(self, ctx, *, d): #Define the author #Makes stuff shorter mem = ctx.author #Make embed e = discord.Embed(description=d) #Set the embed author e.set_author(name=mem, icon_url=mem.avatar_url) #Send embed await ctx.send(embed=e) @command(brief="{Turn your words into a Banner}", usage="banner <text>") @guild_only() @cooldown(1, 2.5, BucketType.user) async def banner(self, ctx, *, text): #Used to format the user's text formatted = pyfiglet.figlet_format(text) e = discord.Embed(description=f"```{formatted}```") await ctx.send(embed=e)
def route(request): session = yield from get_session(request) if 'uid' in session: uid = session['uid'] else: # uid = 4 return toolbox.javaify(403, "forbidden") if request.content_type != "multipart/form-data": return toolbox.javaify(400, "content type error") query_parameters = request.rel_url.query if "dir" in query_parameters: directory = query_parameters["dir"] else: return toolbox.javaify(400, "miss parameter") with (yield from request.app['pool']) as connect: cursor = yield from connect.cursor() directory_check = yield from fs.directory_exists( cursor, uid, directory) if not directory_check: yield from cursor.close() connect.close() return toolbox.javaify(400, "target error") elif directory_check['status'] == 0: yield from cursor.close() connect.close() return toolbox.javaify(400, "target error") try: reader = yield from request.multipart() part = yield from reader.next() except Exception as e: print(e) yield from cursor.close() connect.close() return toolbox.javaify(400, "bad request") if part is None: yield from cursor.close() connect.close() return toolbox.javaify(400, "bad request") try: file_name = re.search(r'filename="([^"]+)"', part.headers["Content-Disposition"]).group(1) file_name = os.path.split(file_name)[1] except: yield from cursor.close() connect.close() return toolbox.javaify(400, "bad request") if fs.name_illegal(file_name): return toolbox.javaify(400, "name illegal") file_check = yield from fs.file_exists( cursor, uid, os.path.join(directory, file_name)) if file_check and file_check["type"] == "directory" and file_check[ "status"] == 1: yield from cursor.close() connect.close() return toolbox.javaify(400, "directory exists") yield from cursor.close() connect.close() session = ClientSession() boundary = '----------{}'.format(uuid.uuid4().hex) content_type = 'multipart/form-data; boundary={}'.format(boundary) try: response = yield from session.post( 'http://up-z2.qiniu.com', data=rewrite(uid, part, boundary), headers={'Content-Type': content_type}) json_back = yield from response.text() json_back = json.loads(json_back) file_type = json_back["type"] size = int(json_back["size"]) md5 = json_back["key"].split("/")[-1] except Exception as error: print(error) yield from session.close() return toolbox.javaify(500, "something wrong") else: yield from session.close() with (yield from request.app['pool']) as connect: cursor = yield from connect.cursor() file_check = yield from fs.file_exists( cursor, uid, os.path.join(directory, file_name)) if file_check and file_check["type"] == "directory" and file_check[ "status"] == 1: yield from cursor.close() connect.close() return toolbox.javaify(400, "directory exists") elif file_check and file_check["type"] == "directory" and file_check[ "status"] == 0: yield from fs.directory_delete(cursor, uid, os.path.join(directory, file_name)) if not file_check: yield from fs.file_create( cursor, [uid, directory, file_name, file_type, size, md5, 1]) else: yield from fs.file_rewrite(cursor, uid, os.path.join(directory, file_name), [file_type, size, md5]) yield from connect.commit() yield from cursor.close() connect.close() now = datetime.datetime.now() file_extension = os.path.splitext(file_name)[-1][1:] return toolbox.javaify( 200, "success", { "name": file_name, "type": file_type, "extension": file_extension, "modify": toolbox.time_utc(now), "owner": "self", "size": size, "status": 1, "source": mask.generate(uid, md5) })
class Owner(Cog, name="Owner Category"): """`{Commands for the One and Only Bot Owner}`""" def __init__(self, bot): self.bot = bot self.db = self.bot.get_cog('Database') self.ses = ClientSession(loop=self.bot.loop) #Set the role persist to False on default self.per = False def cog_unload(self): self.bot.loop.create_task(self.ses.close()) #•----------Commands----------•# @command() @is_owner() async def color(self, ctx): #Our random color color = randint(0x000000, 0xffffff) #Our image for our embed im = Image.new('RGB', (512, 512), color=color) #Save the image as a png file im.save('ran_color.png') c = Image.open('ran_color.png') c.thumbnail((512, 512)) c.show() #file = discord.File('ran_color.png', filename='ran_color.png') desc = f"Hex Code -> **{color}**" e = discord.Embed(title="Pick a Color Here", url="https://htmlcolorcodes.com", description=desc, color=color) e.set_image(url=f"attachment://{c}") await ctx.send(embed=e) @command(brief="{Temporarily Ban a User}", usage="tempban <user> (reason) <time>", aliases=['temporaryban']) @guild_only() #@bot_has_permissions(ban_members=True) #@has_permissions(ban_members=True) #@cooldown(1, 5, BucketType.user) @is_owner() async def tempban(self, ctx, member: discord.Member, *, time: TimeConverter): redmark = "<:redmark:738415723172462723>" #If a time isn't given if not time: e = discord.Embed( description= f"{redmark} __*{ctx.author.mention}, you have to give a time for this user to be banned for*__", color=0x420000) await ctx.send(embed=e) return try: #Make the embed e = discord.Embed(timestamp=datetime.utcnow(), description=f"⚠️ **Temp Ban**", color=0x420000) e.set_thumbnail(url=ctx.guild.icon_url) e.set_footer(text=f"Banned from {ctx.guild}") #Make fields fields = [("__*Time Banned for*__", time, False), ("__*Temp Banned By*__", ctx.author.mention, False)] #Add the fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) await member.send(embed=e) except Exception: pass #Ban the member await ctx.guild.ban(user=member) e = discord.Embed( timestamp=datetime.utcnow(), description= f"<:ban:741030012848832533> **{member.mention} was temp banned!**", color=0x420000) e.set_author(name=f"Duration -> {time}") e.set_footer(text=f"ID -> {member.id}") await ctx.send(embed=e) #Wait for the amount of time to unban the user await asyncio.sleep(time) #Unban the user await ctx.guild.unban(user=member) try: await member.send("Unbanned") except Exception: pass await ctx.send( f"{member.mention} has successfully been unbanned after {time}") @command() @is_owner() async def upcoming(self, ctx): url = "https://api.themoviedb.org/3/movie/upcoming?api_key=91841633d0b2b91d9e313adcce2cc2c7" r = await self.ses.get(url) respon = await r.json() resp = respon['results'] page = 0 msg = None #Check for making sure only author #Can trigger reactions def author(reaction, user): return user == ctx.author and str(reaction.emoji) in ['⬅️', '➡️'] while True: #Text for each page body = '' #Iterate through the dict/json #for n in resp[page]: #Add to the empty string try: reaction, user = await self.bot.wait_for('reaction_add', timeout=180.0, check=author) #If user takes too long to react except asyncio.TimeoutError: await ctx.send(embed=e) break else: if str(reaction.emoji) == '⬅️': await m.remove_reaction(reaction, user) page -= 1 elif str(reaction.emoji) == '➡️': await m.remove_reaction(reaction, user) page += 1 else: await m.remove_reaction(reaction, user) @command(brief="{List of Upcoming Movies}", usage="upcmovie", aliases=['upcomingmovies', 'moviesupcoming', 'movieupc']) @guild_only() #@cooldown(1, 2.5, BucketType.user) #@bot_has_permissions(use_external_emojis=True) @is_owner() async def upcmovie(self, ctx): url = "https://api.themoviedb.org/3/movie/upcoming?api_key=91841633d0b2b91d9e313adcce2cc2c7" #Get the url with aiohttp session r = await self.ses.get(url) #Convert into json format to make easier #To access respon = await r.json() #Define the json response to make stuff easier #To access res = respon['results'] page = 0 def author(reaction, user): return user == ctx.author and str(reaction.emoji) in ['⬅️', '➡️'] while True: try: #Wait for the user's reaction reaction, user = await self.bot.wait_for('reaction_add', check=author, timeout=180.0) #If user takes too long except asyncio.TimeoutError: await ctx.send("Took too long") break else: #Edit embed with previous page if str(reaction.emoji) == '⬅️': await m.remove_reaction(reaction, user) page -= 1 #Edit embed with next page elif str(reaction.emoji) == '➡️': await m.remove_reaction(reaction, user) page += 1 #If user tries to go to far back/forward else: await m.remove_reaction(reaction, user) @command(brief="{List of Popular TV Shows}", usage="populartv (page)", aliases=['tvpopular', 'popularshows']) @guild_only() #@cooldown(1, 2.5, BucketType.user) #@bot_has_permissions(use_external_emojis=True) @is_owner() async def populartv(self, ctx, page_num: Optional[int]): redmark = "<:redmark:738415>" #Api key needed to have this work #Check their website to make one url = f"https://api.themoviedb.org/3/tv/popular?api_key=91841633d0b2b91d9e313adcce2cc2c7" r = await self.ses.get(url) #Convert into a json format #To make stuff easier to access resp = await r.json() #Used to show pages p = resp['page'] totalp = resp['total_pages'] totalr = resp['total_results'] if page_num is not None: #Used to show the current page/total pages m = resp['results'][page_num] else: m = resp['results'][0] #If something with api goes wrong if r.status == 404: e = discord.Embed( description= f"{redmark} __*{ctx.author.mention}, something went wrong when trying to get the tv shows*__", color=0x420000) await ctx.send(embed=e) return #Make embed e = discord.Embed( description= f"*Showing Info for {m['name']} - Ranked* **#{page_num}**") #Make fields fields = [("🔗 __*Misc Info*__", f"Genre IDS -> {m['genre_ids']}" + f"\nOrigin (Country) -> {m['origin_country']}" + f"\nOriginal Lang. -> {m['original_language']}" + f"\nMovie ID -> {m['id']}", False), ("⬆️ __*Votes*__", f"Total Votes -> {m['vote_count']}" + f"Vote Average -> {m['vote_average']}", False), ("__*Overview*__", m['overview'], True)] #Add fields for n, v, i in fields: e.add_field(name=n, value=v, inline=i) #Set author e.set_author(name=f"Page {p}/{totalp}\nTotal Results : {totalr}") #Make the thumbnail the tv show cover e.set_thumbnail( url=f"https://image.tmdb.org/t/p/w500/{m['poster_path']}") #Set footer e.set_footer(text=f"Requested by {ctx.author}") #Send embed await ctx.send(embed=e) @command(brief="{Get a List of Guilds the Bot's in}", usage="bguilds", aliases=['botguilds']) @guild_only() @is_owner() async def bguilds(self, ctx): #Empty String #To add guild names later g_list = '' #Iterate through servers bot's in for g in self.bot.guilds: name_owner = f"{g.name} **{{{len(g.members)} Mem}}** - {g.owner}" #Add the guild names #To the empty string g_list += f'• {"".join(name_owner)}\n' #Make embed e = discord.Embed( title=f"__*Total Guilds {{{len(self.bot.guilds)}}}*__", description=g_list) e.timestamp = datetime.utcnow() e.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url) await ctx.send(embed=e) @command(name='reload', brief="{Reloads all/specificied cog(s)", usage="reload (cog_name)") @guild_only() @is_owner() async def reload(self, ctx, cog=None): if not cog: # No cog, means we reload all cogs async with ctx.typing(): e = discord.Embed(title="Reloading all cogs!", timestamp=datetime.utcnow()) for ext in os.listdir("./cogs/"): if ext.endswith(".py") and not ext.startswith("_"): try: self.bot.unload_extension(f"cogs.{ext[:-3]}") self.bot.load_extension(f"cogs.{ext[:-3]}") e.add_field(name=f"Reloaded: `{ext}`", value='\uFEFF', inline=True) except Exception as e: e.add_field( name=f"__*Failed to reload*__ ``{ext}``", value=e, inline=True) await asyncio.sleep(0.5) await ctx.send(embed=e) else: # reload the specific cog async with ctx.typing(): e = discord.Embed(title="__*Reloading all cogs*__", timestamp=datetime.utcnow()) ext = f"{cog.lower()}.py" if not os.path.exists(f"./cogs/{ext}"): # if the file does not exist e.add_field(name=f"__*Failed to reload*__ ``{ext}``", value="This cog doesn't exist", inline=True) elif ext.endswith(".py") and not ext.startswith("_"): try: self.bot.unload_extension(f"cogs.{ext[:-3]}") self.bot.load_extension(f"cogs.{ext[:-3]}") e.add_field(name=f"__*Reloaded*__ ``{ext}``", value='\uFEFF', inline=True) except Exception: trace = traceback.format_exc() if len(trace) > 1024: length = len(trace) - 1024 trace = f"```{trace[:1024]}``` and **{length}** more words..." else: trace = f"```{trace}```" e.add_field(name=f"__*Failed to reload*__ ``{ext}``", value=trace, inline=True) await ctx.send(embed=e) @command(brief="{Load all/specific cogs}", usage="load (cog_name)") @guild_only() @is_owner() async def load(self, ctx, cog=None): #If a cog isn't given #Load all the cogs if not cog: # No cog, means we reload all cogs async with ctx.typing(): e = discord.Embed(title="__*Reloading all cogs*__", timestamp=datetime.utcnow()) #Iterate through the cog files for ext in os.listdir("./cogs/"): if ext.endswith(".py") and not ext.startswith("_"): try: #Load the cog(s) self.bot.load_extension(f"cogs.{ext[:-3]}") e.add_field(name=f"__*Reloaded*__ ``{ext}``", value='\uFEFF', inline=True) except Exception as e: e.add_field( name=f"__*Failed to load in*__ ``{ext}``", value=e, inline=True) await asyncio.sleep(0.5) await ctx.send(embed=e) else: #Load the specific cog async with ctx.typing(): e = discord.Embed(title=f"__*Loading in*__ ``{cog}``", timestamp=datetime.utcnow()) ext = f"{cog.lower()}.py" if not os.path.exists(f"./cogs/{ext}"): # if the file does not exist e.add_field(name=f"__*Failed to load in*__ ``{ext}``", value="This cog doesn't exist", inline=True) elif ext.endswith(".py") and not ext.startswith("_"): try: #Load the cog(s) self.bot.load_extension(f"cogs.{ext[:-3]}") e.add_field(name=f"__*Loaded*__ ``{ext}``", value='\uFEFF', inline=True) except Exception: trace = traceback.format_exc() if len(trace) > 1024: length = len(trace) - 1024 trace = f"```{trace[:1024]}``` and **{length}** more words..." else: trace = f"```{trace}```" e.add_field(name=f"__*Failed to load*__ ``{ext}``", value=trace, inline=True) await ctx.send(embed=e) @command(brief="{Unload a cog}", usage="unload <cog_name>") @guild_only() @is_owner() async def unload(self, ctx, cog): #Unload the specific cog async with ctx.typing(): e = discord.Embed(title=f"__*Unloading*__ ``{cog}``", timestamp=datetime.utcnow()) ext = f"{cog.lower()}.py" if not os.path.exists(f"./cogs/{ext}"): #If the file doesn't exist e.add_field(name=f"__*Failed to Unload*__ ``{ext}``", value="This cog doesn't exist", inline=True) elif ext.endswith(".py") and not ext.startswith("_"): try: #Unload the cog self.bot.unload_extension(f"cogs.{ext[:-3]}") e.add_field(name=f"__*Unloaded*__ ``{ext}``", value='\uFEFF', inline=True) except Exception: desired_trace = traceback.format_exc() e.add_field(name=f"__*Failed to reload*__ ``{ext}``", value=desired_trace, inline=True) await ctx.send(embed=e) @command(brief="{DM a User}", usage="dm <user> <message>", aliases=['senddm']) @is_owner() @guild_only() async def dm(self, ctx, user: discord.User, *, msg): await user.send(msg) @command(brief="{Shutdown the Bot}", usage="shutdown", aliases=['logout', 'turnoff']) @is_owner() @guild_only() async def shutdown(self, ctx): await ctx.send("I'm shutting down now 👋🏽") await asyncio.sleep(1) #Makes bot logout await self.bot.logout()
class OwnerOnly(object): def __init__(self, bot): self.bot = bot self.session = ClientSession(loop=bot.loop) def __unload(self): self.session.close() @commands.command(pass_context=True) @permissionChecker(check='is_owner') async def editrolecolour(self, ctx, colour, *, name): ''' Lets you change the profile. ''' r = [ i for i in ctx.message.server.roles if name.lower() in i.name.lower() ] if len(r) > 1: await self.bot.say('Too many roles etc') return elif len(r) < 1: await self.bot.say('nop no roles like that') return if len(colour) == 6: colour = Colour(int(colour, 16)) else: await self.bot.say('Idk what colours are, man') return await self.bot.edit_role(ctx.message.server, r[0], colour=colour) await self.bot.say('Done.') @commands.command(pass_context=True) @permissionChecker(check='is_owner') async def givemerole(self, ctx, *, name): ''' Lets you change the profile. ''' r = [ i for i in ctx.message.server.roles if name.lower() in i.name.lower() ] if len(r) > 1: await self.bot.say('Too many roles etc') return elif len(r) < 1: await self.bot.say('nop no roles like that') return await self.bot.add_roles(ctx.message.author, r[0]) await self.bot.say('Done.') @commands.command(pass_context=True) @permissionChecker(check='is_owner') async def takemerole(self, ctx, *, name): ''' Lets you change the profile. ''' r = [ i for i in ctx.message.server.roles if name.lower() in i.name.lower() ] if len(r) > 1: await self.bot.say('Too many roles etc') return elif len(r) < 1: await self.bot.say('nop no roles like that') return await self.bot.remove_roles(ctx.message.author, r[0]) await self.bot.say('Done.') @commands.group() @permissionChecker(check='is_owner') async def profile(self): ''' Lets you change the profile. ''' pass @profile.command() @permissionChecker(check='is_owner') async def name(self, *, name: str = None): ''' Changes the name of the profile. ''' if name == None: await self.bot.say('`!profile name [NAME]`') return await self.bot.edit_profile(username=name) w = await self.bot.say('👌') await sleep(2) await self.bot.delete_message(w) @profile.command() @permissionChecker(check='is_owner') async def avatar(self, *, avatar: str = None): ''' Changes the profile picture of the bot. ''' if avatar == None: await self.bot.say('`!profile avatar [URL]`') return async with self.session.get(avatar) as r: content = r.read() await self.bot.edit_profile(avatar=content) w = await self.bot.say('👌') await sleep(2) await self.bot.delete_message(w) @commands.command(pass_context=True, hidden=True) @permissionChecker(check='is_owner') async def ev(self, ctx, *, content: str): ''' Evaluates a given Python expression ''' # Eval and print the answer try: output = eval(content) except Exception: type_, value_, traceback_ = exc_info() ex = format_exception(type_, value_, traceback_) output = ''.join(ex) await self.bot.say('```python\n{}```'.format(output)) @commands.command(pass_context=True, hidden=True) @permissionChecker(check='is_owner') async def cls(self, ctx): ''' Clears the console ''' print('\n' * 50) await self.bot.say('Done.') @commands.command(pass_context=True, hidden=True) @permissionChecker(check='is_owner') async def kill(self, ctx): ''' Kills the bot. Makes it deaded ''' # If it is, tell the user the bot it dying await self.bot.say('*Finally*.') await self.bot.change_presence(status=Status.invisible, game=None) exit() @commands.command(pass_context=True, hidden=True, aliases=['rs']) @permissionChecker(check='is_owner') async def restart(self, ctx): ''' Restarts the bot. Literally everything ''' # If it is, tell the user the bot it dying await self.bot.say('Now restarting.') await self.bot.change_presence(status=Status.dnd, game=None) execl(executable, *([executable] + argv)) @commands.command(pass_context=True, hidden=True) @permissionChecker(check='is_owner') async def rld(self, ctx, *, extention: str): ''' Reloads a cog from the bot ''' extention = f'Cogs.{extention}' # Unload the extention await self.bot.say("Reloading extension **{}**...".format(extention)) try: self.bot.unload_extension(extention) except: pass # Load the new one try: self.bot.load_extension(extention) except Exception: type_, value_, traceback_ = exc_info() ex = format_exception(type_, value_, traceback_) output = ''.join(ex) await self.bot.say('```python\n{}```'.format(output)) return # Boop the user await self.bot.say("Done!")