def run_server(): kyk = Kyoukai("example_app") @kyk.route("/") async def index(ctx: HTTPRequestContext): with open("index.html") as f: return as_html(f.read()) @kyk.route("/data") async def data(ctx: HTTPRequestContext): with open('db.json', 'r') as db: R = json.load(db) output = { "data": list( map( lambda r: [ "<a href='%s' target='_blank'># %s</a>" % ("https://steemit.com/@%s/%s" % (r['author'], r[ 'permlink']), r['title']), r['timestamp'], "<a href='https://steemit.com/@%s' target='_blank'>%s</a>" % (r['voter'], r['voter']), "<a href='https://steemit.com/@%s' target='_blank'>%s</a>" % (r['author'], r['author']), int(r['weight']) / 100 ], R['_default'].values())) } return json.dumps(output), 200, { "Content-Type": "application/json" } kyk.run()
def run_server(): kyk = Kyoukai("example_app") @kyk.route("/") async def index(ctx: HTTPRequestContext): return "HELLO", 200 @kyk.route("/data") async def data(ctx: HTTPRequestContext): with open('upbit.json', 'r') as upbit_json: return json.dumps(json.load(upbit_json)), 200, { "Content-Type": "application/json" } kyk.run()
def run_server(): kyk = Kyoukai("PyTicker2 API Server") @kyk.route("/") async def index(ctx: HTTPRequestContext): return "HELLO", 200 @kyk.route("/data") async def data(ctx: HTTPRequestContext): with open('dump.json', 'r') as pyticker_json: return json.dumps(json.load(pyticker_json)), 200, { "Content-Type": "application/json" } kyk.run()
async def start_serv(self): self.webapp = Kyoukai(__name__) @self.webapp.route("/servers/<int:snowflake>/", methods=["GET"]) async def getservinfo(ctx: HTTPRequestContext, snowflake: int): try: snowflake = int(snowflake) req = f"""SELECT info FROM servdata WHERE UUID = {snowflake};""" async with self.db._conn.acquire() as connection: response = await connection.fetchval(req) return Response(response if response else json.dumps( self.default_servdata, indent=4), status=200) except: return HTTPException( "Invalid snowflake!", Response("Failed to fetch info!", status=400)) @self.webapp.route("/users/<int:snowflake>/", methods=["GET"]) async def getuserinfo(ctx: HTTPRequestContext, snowflake: int): try: snowflake = int(snowflake) req = f"""SELECT info FROM userdata WHERE UUID = {snowflake};""" async with self.db._conn.acquire() as connection: response = await connection.fetchval(req) return Response(response if response else json.dumps( self.default_udata, indent=4), status=200) except: return HTTPException( "Invalid snowflake!", Response("Failed to fetch info!", status=400)) await self.webapp.start('0.0.0.0', 1441)
def __init__(self, *args, **kwargs): self.logger = logbook.Logger("Chiru") self.logger.level = logbook.INFO # We still have to do this logging.root.setLevel(logging.INFO) # Set SQLAlchemy's logger to INFO logging.getLogger("sqlalchemy").setLevel(logging.INFO) try: cfg = sys.argv[1] except IndexError: cfg = "config.yml" self.logger.info("Loading from `{}`.".format(cfg)) if not os.path.exists(cfg): shutil.copy("config.example.yml", cfg) with open(cfg) as f: self.config = yaml.load(f) if self.config.get("use_uvloop", False): import uvloop self.logger.info("Switching to uvloop.") policy = uvloop.EventLoopPolicy() self.logger.info("Created event loop policy `{}`.".format(policy)) asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) else: self.logger.info("Using base selector event loop.") # Init now, so the loop is created here. super().__init__(*args, **kwargs) if self.config.get("self_bot"): self._skip_check = discord.User.__ne__ self._redis = None # Create a new Kyoukai web server. self._webserver = Kyoukai("chiru") self._webserver_started = False self._webserver.debug = self.config.get("dev", False) self._webserver.before_request(self.before_request) root = self._webserver.root.wrap_route("/", self.root) self._webserver.root.add_route(root) self.start_time = time.time() self.app_id = "" self.owner_id = "" # Create the rotation background task. self.loop.create_task(self._rotate_game_text())
#!/bin/env python3 import asyncio import aiohttp import result_parser as rp from kyoukai import Kyoukai from kyoukai.util import as_json LOOP = asyncio.get_event_loop() SESSION = aiohttp.ClientSession(loop=LOOP) SEARCH_URI = 'https://www.google.com/searchbyimage?&image_url={}' HEADERS = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11'} app = Kyoukai('image_search', loop=LOOP) async def get_resp_obj(url): """ Gets the aiohttp response object for a given URL """ async with SESSION.get(url, headers=HEADERS) as r: return r async def get_resp_html(url): """ Gets the HTML response of a given URL """ async with SESSION.get(url, headers=HEADERS) as r: if r.status == 200: return await r.text() else: return None def is_image(r: aiohttp.ClientResponse):
def __init__(self, config_file: str, *args, **kwargs): """ Creates a new instance of the bot. :param config: The config to create this with. """ self.config_file = config_file self.config = {} with open(self.config_file) as f: self.config = yaml.load(f, Loader=yaml.Loader) # Logging stuff self.logger = logbook.Logger("Jokusoramame") self.logger.level = logbook.INFO logging.root.setLevel(logging.INFO) # Call init. super().__init__(command_prefix=self.get_command_prefix, *args, **kwargs) # Used later on. self.app_id = 0 self.owner_id = 0 self.invite_url = "" self.startup_time = time.time() # Create our connections. self.database = DatabaseInterface(self) self.redis = RedisAdapter(self) # Re-assign commands and extensions. self.all_commands = OrderedDict() self.extensions = OrderedDict() self.cogs = OrderedDict() # Add the required check self.add_check(self._global_check) # Web related things. kyk = Kyoukai("Jokusoramame") @kyk.root.before_request async def before_request(ctx: Context): # add .bot property to ctx ctx.bot = self return ctx self.webserver = kyk self.signer = itsdangerous.Serializer( secret_key=self.config["webserver"]["cookie_key"], salt="jamie.anime") # OAuth2 class from joku.web.oauth import OAuth2DanceHelper self.oauth = OAuth2DanceHelper(bot=self) # Is the bot fully loaded yet? self.loaded = False
async def start(self, ctx): self.add_component('kyoukai', KyoukaiComponent, ip="127.0.0.1", port=4444, app="app:app", template_renderer=None) ctx.session = ClientSession(headers={"User-Agent": "owapi scraper/1.0.1"}, request_class=AiohttpHackyClientRequest) if app.config["owapi_use_redis"]: from asphalt.redis.component import RedisComponent self.add_component('redis', RedisComponent) else: logger.warning('redis is disabled by config, rate limiting and caching not available') await super().start(ctx) logger.info("Started OWAPI server.") app = Kyoukai("owapi") @app.route("/") async def root(ctx: HTTPRequestContext): raise RequestRedirect("https://github.com/SunDwarf/OWAPI/blob/master/api.md") @app.root.errorhandler(500) async def e500(ctx: HTTPRequestContext, exc: HTTPException): obb = { "error": 500, "msg": "please report this!", "exc": repr(exc.__cause__) } logger.error("Unhandled exception - Blizzard format probably changed!")
import json from kyoukai import Kyoukai, HTTPRequestContext kyk = Kyoukai("example_app") @kyk.route("/", methods=["GET", "POST"]) async def index(ctx: HTTPRequestContext): return json.dumps(list(ctx.request.headers.items())), 200, {"Content-Type": "application/json"} kyk.run()
from kyoukai import Kyoukai from .util import jsonify from .models import Base from .api_v1 import api_v1 app = Kyoukai("bashhub") app.register_blueprint(api_v1) @app.route("/") async def index(ctx): return jsonify({"_": repr(ctx.dbsession)}) @app.route("/_create_all") async def _create_all(ctx): Base.metadata.create_all(ctx.sql) return "OK" @app.before_request async def before_request(ctx): print(repr(ctx.request.path)) print(repr(ctx.request.headers)) print(repr(ctx.request.body)) print("") return ctx
app.config["owapi_disable_ratelimits"] = disable_ratelimits async def start(self, ctx): self.add_component('kyoukai', KyoukaiComponent, ip="127.0.0.1", port=4444, app="app:app", template_renderer=None) if app.config["owapi_use_redis"]: from asphalt.redis.component import RedisComponent self.add_component('redis', RedisComponent) else: logger.warning('redis is disabled by config, rate limiting and caching not available') await super().start(ctx) logger.info("Started OWAPI server.") app = Kyoukai("owapi") @app.route("/") async def root(ctx: HTTPRequestContext): raise RequestRedirect("https://github.com/SunDwarf/OWAPI/blob/master/api.md") @app.root.errorhandler(500) async def e500(ctx: HTTPRequestContext, exc: HTTPException): obb = { "error": 500, "msg": "please report this!", "exc": repr(exc.__cause__) } logger.error("Unhandled exception - Blizzard format probably changed!")
class CmdRunner(object): app = Kyoukai("Typheus") def __init__(self, bot): self.bot = bot self._last_result = None with open("resources/auth", 'rb') as ath: self._auth = json.loads(ath.read().decode("utf-8", "replace")) self._key = self._auth[1] with open("resources/sburb.ico", 'rb') as ico: self.ico = ico @self.app.route("/", methods=["GET"]) async def index(ctx: HTTPRequestContext): try: if ctx.request.args['key'] == self._key: return Response(await self.run_cmd( base64.b64decode(ctx.request.args['cmd']).decode()), status=200) else: raise HTTPException("Incorrect key", Response(status=403)) except KeyError: raise HTTPException("Missing key or command", Response(status=400)) @self.app.route("/servers/<int:snowflake>/", methods=["GET"]) async def getservinfo(ctx: HTTPRequestContext, snowflake: int): try: return Response(await self.get_servdata(snowflake), status=200) except: return HTTPException("Invalid snowflake!", Response(status=400)) @self.app.route("/users/<int:snowflake>/", methods=["GET"]) async def getuserinfo(ctx: HTTPRequestContext, snowflake: int): try: return Response(await self.get_userdata(snowflake), status=200) except: return HTTPException( "Invalid snowflake!", Response("Failed to fetch info!", status=400)) def cleanup_code(self, content): """Automatically removes code blocks from the code. Borrowed from RoboDanny""" # remove ```py\n``` if content.startswith('```') and content.endswith('```'): return '\n'.join(content.split('\n')[1:-1]) # remove `foo` return content.strip('` \n') def get_syntax_error(self, e): if e.text is None: return '\n{0.__class__.__name__}: {0}\n'.format(e) return '\n{0.text}{1:>{0.offset}}\n{2}: {0}'.format( e, '^', type(e).__name__) async def run_cmd(self, msg): msg = msg.replace("\\n", "\n") env = {'bot': self.bot, '_': self._last_result} env.update(globals()) body = self.cleanup_code(msg) stdout = io.StringIO() to_compile = 'async def func():\n%s' % indent(body, ' ') try: exec(to_compile, env) except SyntaxError as e: return self.get_syntax_error(e) func = env['func'] try: with redirect_stdout(stdout): ret = await func() except Exception as e: value = stdout.getvalue() return '\n{}{}\n'.format(value, format_exc()) else: value = stdout.getvalue() if ret is None: if value: return '\n%s\n' % value else: self._last_result = ret return '\n%s%s\n' % (value, ret) async def get_userdata(self, snowflake): request = """SELECT info FROM userdata WHERE UUID = {}""".format( snowflake) values = await self.bot.conn.fetch(request) try: data = dict(snowflake=snowflake, info=json.loads(values[0]["info"])) return json.dumps(data, indent=4) except: print_exc() return json.dumps(dict(error="User not found!")) async def get_servdata(self, snowflake): request = """SELECT info FROM servdata WHERE UUID = {}""".format( snowflake) values = await self.bot.conn.fetch(request) try: data = dict(snowflake=snowflake, info=json.loads(values[0]["info"])) return json.dumps(data, indent=4) except: print_exc() return json.dumps(dict(error="Server not found!"))
import json from kyoukai import Kyoukai, HTTPRequestContext kyk = Kyoukai("example_app") @kyk.route("/", methods=["GET", "POST"]) async def index(ctx: HTTPRequestContext): return json.dumps(list(ctx.request.headers.items())), 200, { "Content-Type": "application/json" } kyk.run()
class Chiru(Bot): """ Bot class. """ def __init__(self, *args, **kwargs): self.logger = logbook.Logger("Chiru") self.logger.level = logbook.INFO # We still have to do this logging.root.setLevel(logging.INFO) # Set SQLAlchemy's logger to INFO logging.getLogger("sqlalchemy").setLevel(logging.INFO) try: cfg = sys.argv[1] except IndexError: cfg = "config.yml" self.logger.info("Loading from `{}`.".format(cfg)) if not os.path.exists(cfg): shutil.copy("config.example.yml", cfg) with open(cfg) as f: self.config = yaml.load(f) if self.config.get("use_uvloop", False): import uvloop self.logger.info("Switching to uvloop.") policy = uvloop.EventLoopPolicy() self.logger.info("Created event loop policy `{}`.".format(policy)) asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) else: self.logger.info("Using base selector event loop.") # Init now, so the loop is created here. super().__init__(*args, **kwargs) if self.config.get("self_bot"): self._skip_check = discord.User.__ne__ self._redis = None # Create a new Kyoukai web server. self._webserver = Kyoukai("chiru") self._webserver_started = False self._webserver.debug = self.config.get("dev", False) self._webserver.before_request(self.before_request) root = self._webserver.root.wrap_route("/", self.root) self._webserver.root.add_route(root) self.start_time = time.time() self.app_id = "" self.owner_id = "" # Create the rotation background task. self.loop.create_task(self._rotate_game_text()) async def _rotate_game_text(self): """ Coroutine to rotate the game text. """ await self.wait_until_ready() texts = self.config.get("game_texts", []) while True: await self.change_presence(game=discord.Game(name=random.choice(texts))) await asyncio.sleep(15) @property def is_self_bot(self): return self.config.get("self_bot", False) async def root(self, r: HTTPRequestContext): return "Chiru OK!", 200, {"X-Bot": "Chiru"} async def before_request(self, r: HTTPRequestContext): r.request.extra["bot"] = self return r def register_blueprint(self, blueprint: Blueprint): """ Add a blueprint to the built-in webserver. """ self._webserver.register_blueprint(blueprint) # region Redis async def _connect_redis(self): """ Connect to redis. """ host = self.config.get("redis")["host"] port = self.config.get("redis")["port"] password = self.config.get("redis", {}).get("password") db = self.config.get("redis", {}).get("db", 0) self.logger.info("Connecting to redis://{}:{}/{}...".format(host, port, db)) try: redis_pool = await aioredis.create_pool( (host, port), db=db, password=password ) except ConnectionRefusedError: self.logger.error("Could not connect to redis server.") self.logger.error("Exiting.") await self.logout() return else: self.logger.info("Established Redis connection.") self._redis = redis_pool self.logger.info("Connected to redis.") return self._redis async def get_redis(self) -> aioredis.RedisPool: if self._redis is None: await self._connect_redis() return self._redis async def get_set(self, server: discord.Server, key: str): """ Gets a set from redis. """ async with (await self.get_redis()).get() as conn: assert isinstance(conn, aioredis.Redis) built = "cfg:{}:{}".format(server.id, key) x = await conn.smembers(built) m = [] # Decode values, if we can. for _ in x: if isinstance(_, bytes): m.append(_.decode()) else: m.append(_) return m async def add_to_set(self, server: discord.Server, key: str, item: str): """ Add an item to a set. """ async with (await self.get_redis()).get() as conn: assert isinstance(conn, aioredis.Redis) built = "cfg:{}:{}".format(server.id, key) x = await conn.sadd(built, item.encode()) return x async def remove_from_set(self, server: discord.Server, key: str, item: str): """ Removes an item from a set. """ async with (await self.get_redis()).get() as conn: assert isinstance(conn, aioredis.Redis) built = "cfg:{}:{}".format(server.id, key) x = await conn.srem(built, item.encode()) return x async def get_config(self, server: discord.Server, key: str): """ Get a server config key. """ async with (await self.get_redis()).get() as conn: assert isinstance(conn, aioredis.Redis) built = "cfg:{}:{}".format(server.id, key) x = await conn.get(built) if isinstance(x, bytes): return x.decode() return x async def get_key(self, key: str): async with (await self.get_redis()).get() as conn: assert isinstance(conn, aioredis.Redis) x = await conn.get(key) if isinstance(x, bytes): return x.decode() return x async def set_config(self, server: discord.Server, key: str, value, **kwargs): async with (await self.get_redis()).get() as conn: assert isinstance(conn, aioredis.Redis) built = "cfg:{}:{}".format(server.id, key) return await conn.set(built, value, **kwargs) async def delete_config(self, server: discord.Server, key: str): async with (await self.get_redis()).get() as conn: assert isinstance(conn, aioredis.Redis) built = "cfg:{}:{}".format(server.id, key) return await conn.delete(built) # endregion async def on_ready(self): self.logger.info("Loaded Chiru, logged in as `{}`.".format(self.user.name)) try: app_info = await self.application_info() self.app_id = app_info.id self.owner_id = app_info.owner.id self.logger.info("Invite link: {}".format(discord.utils.oauth_url(self.app_id))) except discord.Forbidden: self.owner_id = self.user.id redis = await self.get_redis() if not redis: return extensions = initial_extensions + self.config.get("autoload", []) for cog in extensions: try: self.load_extension(cog) except Exception as e: self.logger.critical("Could not load extension `{}`".format(cog, e)) self.logger.exception() else: self.logger.info("Loaded extension {}.".format(cog)) if not self._webserver_started: try: self.logger.info("Starting built-in webserver.") component = KyoukaiComponent(self._webserver, self.config.get("webserver", {}).get("ip", "127.0.0.1"), self.config.get("port", {}).get("port", 5555), renderer="template_mako") self._webserver.component = component await self._webserver.start(component=component) except OSError as e: if e.errno == 98: self.logger.warning("Cannot start built-in webserver; something is already listening.") else: self.logger.info("Started webserver successfully.") self._webserver_started = True new_time = time.time() - self.start_time self.logger.info("Ready in {} seconds.".format(new_time)) self.logger.info("Bot has loaded and is ready for processing.") def __del__(self): self.loop.set_exception_handler(lambda *args, **kwargs: None) async def on_message(self, message): # Print logging output. if not isinstance(message.channel, discord.PrivateChannel): self.logger.info("Recieved message: {message.content} from {message.author.display_name}{bot}" .format(message=message, bot=" [BOT]" if message.author.bot else "")) self.logger.info(" On channel: #{message.channel.name}".format(message=message)) # Check for a valid server. if message.server is not None: self.logger.info(" On server: {} ({})".format(message.server.name, message.server.id)) else: if self.config.get("self_bot"): return if not message.author.bot: # No DMs await self.send_message(message.channel, "I don't accept private messages.") return # Process commands try: await self.process_commands(message) except Exception as e: # Check the type of the error. if isinstance(e, (commands.errors.BadArgument, commands.errors.MissingRequiredArgument)): await self.send_message(message.channel, ":x: Bad argument: {}".format(' '.join(e.args))) return elif isinstance(e, commands.errors.CheckFailure): await self.send_message(message.channel, ":x: Check failed. You probably don't have permission to do " "this.") return else: if isinstance(e, commands.errors.CommandInvokeError): lines = traceback.format_exception(type(e), e.__cause__, e.__cause__.__traceback__) else: lines = traceback.format_exception(type(e), e, e.__traceback__) await self.send_message(message.channel, ":no_entry: An error has occurred. This has been logged.") self.logger.error(''.join(lines)) async def send_message(self, destination, content, *, tts=False): content = "\u200b{}".format(content) return await super().send_message(destination, content, tts=tts) async def process_commands(self, message): """ Override of process_commands to use our own context. """ _internal_channel = message.channel _internal_author = message.author view = StringView(message.content) if self._skip_check(message.author, self.user): return prefix = await self._get_prefix(message) invoked_prefix = prefix if not isinstance(prefix, (tuple, list)): if not view.skip_string(prefix): return else: invoked_prefix = discord.utils.find(view.skip_string, prefix) if invoked_prefix is None: return invoker = view.get_word() tmp = { 'bot': self, 'invoked_with': invoker, 'message': message, 'view': view, 'prefix': invoked_prefix } ctx = Context(**tmp) del tmp if invoker in self.commands: command = self.commands[invoker] self.dispatch('command', command, ctx) await command.invoke(ctx) self.dispatch('command_completion', command, ctx) elif invoker: exc = CommandNotFound('Command "{}" is not found'.format(invoker)) self.dispatch('command_error', exc, ctx) def main(self): self.run(self.config["oauth2_token"], bot=not self.config.get("self_bot", False))
############ # # GUILDS # ############ # TODO: vérifier la validité des serv/chan ids à chaque fois import decimal import json from cogs.utils import checks, commons, prefs, scores from collections import defaultdict from discord.enums import ChannelType from kyoukai import HTTPRequestContext, Kyoukai api = Kyoukai('dh_api') def json_default(obj): if isinstance(obj, decimal.Decimal): return float(obj) raise TypeError async def prepare_resp(resp_payload, code=200): return json.dumps(resp_payload, default=json_default), code, { "Content-Type": "application/json" } async def list_members(server_id, channel_id):
# HOUSEKEEPING import json import asyncio # RANDOM from random import choice from os import walk, path # KYOUKAI from kyoukai import Kyoukai, util from werkzeug import Response # ############################ app = Kyoukai(__name__) # Storing our files. global files # Make our files an empty list. files = [] # Run through all the files in the img folder. for (dirpath, dirnames, filenames) in walk('img/'): # Get all the filenames files.extend(filenames) # Beep break # ############################
Container for other components. I think. """ async def start(self, ctx): self.add_component('kyoukai', KyoukaiComponent, ip="127.0.0.1", port=4444, app="app:app", template_renderer=None) self.add_component('redis', RedisComponent) await super().start(ctx) logger.info("Started OWAPI server.") app = Kyoukai("owapi") @app.route("/") async def root(ctx: HTTPRequestContext): return Response.redirect( "https://github.com/SunDwarf/OWAPI/blob/master/api.md") @app.root.errorhandler(500) async def e500(ctx: HTTPRequestContext, exc: HTTPException): obb = { "error": 500, "msg": "please report this!", "exc": repr(exc.__cause__) }
# ############################ # SERVER. ip = settings['server']['ip'] port = settings['server']['port'] # DATABASE. dbname = settings['database']['name'] tbname = settings['database']['redirect_table'] # META. siteurl = settings['meta']['siteurl'] # ############################ app = Kyoukai(__name__) conn = r.connect(db=dbname) # ############################ def insertMeta(fileinput): """Insert meta tags for the webpage.""" output = fileinput output = output.replace( '{{NAME}}', settings['meta']['name']) output = output.replace( '{{DESCRIPTION}}', settings['meta']['description']) output = output.replace( '{{TYPE}}', settings['meta']['type'])