Renamed src package to sebimachine.
- Gave the package a descriptive name.
- Passed over with black once more.
- Created setup.py to install dependencies.
- Updated author to reflect repo ownership to Dusty.
- Changed `git` command to use the __url__ attribute.
- Changed music to use ogg vorbis instead of mp3, purely for
performance.
- Tried to make sure nothing broke.
- Updated dockerfile. Pretty sure we don't need it though...
This commit is contained in:
parent
001d6aa0ac
commit
4f5a1b518a
@ -16,4 +16,4 @@ RUN python3.6 -m pip install --upgrade pip && \
|
|||||||
python3.6 -m pip install -r requirements.txt && \
|
python3.6 -m pip install -r requirements.txt && \
|
||||||
python3.6 -m pip install -U git+https://github.com/Rapptz/discord.py@rewrite#egg=discord.py[voice]
|
python3.6 -m pip install -U git+https://github.com/Rapptz/discord.py@rewrite#egg=discord.py[voice]
|
||||||
|
|
||||||
cmd ["python3.6","-m","src"]
|
cmd ["python3.6","-m","sebimachine"]
|
||||||
|
|||||||
@ -9,7 +9,7 @@ trap "echo 'Received interrupt. Exiting.'; exit 0" SIGINT
|
|||||||
# Also loads the venv if it is present.
|
# Also loads the venv if it is present.
|
||||||
[ -d .venv/bin ] && source .venv/bin/activate && echo "Entered venv." || echo "No venv detected."
|
[ -d .venv/bin ] && source .venv/bin/activate && echo "Entered venv." || echo "No venv detected."
|
||||||
|
|
||||||
until python -m src; do
|
until python -m sebimachine; do
|
||||||
# Added colouring to ensure the date of shutdown and the exit code stands
|
# Added colouring to ensure the date of shutdown and the exit code stands
|
||||||
# out from the other clutter in the traceback that might have been output.
|
# out from the other clutter in the traceback that might have been output.
|
||||||
echo -e "\e[0;31m[$(date --utc)]\e[0m Sebi-Machine shutdown with error \e[0;31m$?\e[0m. Restarting..." >&2
|
echo -e "\e[0;31m[$(date --utc)]\e[0m Sebi-Machine shutdown with error \e[0;31m$?\e[0m. Restarting..." >&2
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
Sebi-Machine.
|
Sebi-Machine.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = "Annihilator708"
|
__author__ = "Dusty.P"
|
||||||
__contributors__ = (__author__, "Neko404NotFound", "Dusty.P", "davfsa", "YashKandalkar")
|
__contributors__ = (__author__, "Neko404NotFound", "Dusty.P", "davfsa", "YashKandalkar")
|
||||||
|
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
@ -8,19 +8,19 @@ Something meaningful here, eventually.
|
|||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import random
|
|
||||||
import traceback
|
|
||||||
import os
|
import os
|
||||||
|
import random
|
||||||
import sys
|
import sys
|
||||||
|
import traceback
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from src.config.config import LoadConfig
|
from .config.config import LoadConfig
|
||||||
from src.shared_libs.loggable import Loggable
|
from .shared_libs import database
|
||||||
from src.shared_libs.ioutils import in_here
|
from .shared_libs.ioutils import in_here
|
||||||
from src.shared_libs import database
|
from .shared_libs.loggable import Loggable
|
||||||
from typing import Dict
|
|
||||||
|
|
||||||
|
|
||||||
# Init logging to output on INFO level to stderr.
|
# Init logging to output on INFO level to stderr.
|
||||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@ -1,9 +1,9 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import asyncio
|
||||||
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
import discord
|
import discord
|
||||||
import asyncio
|
|
||||||
|
|
||||||
|
|
||||||
class BasicCommands:
|
class BasicCommands:
|
||||||
@ -1,248 +1,248 @@
|
|||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
import traceback
|
import traceback
|
||||||
import discord
|
import discord
|
||||||
import inspect
|
import inspect
|
||||||
import textwrap
|
import textwrap
|
||||||
from contextlib import redirect_stdout
|
from contextlib import redirect_stdout
|
||||||
import io
|
import io
|
||||||
|
|
||||||
|
|
||||||
class REPL:
|
class REPL:
|
||||||
"""Python in Discords"""
|
"""Python in Discords"""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self._last_result = None
|
self._last_result = None
|
||||||
self.sessions = set()
|
self.sessions = set()
|
||||||
|
|
||||||
def cleanup_code(self, content):
|
def cleanup_code(self, content):
|
||||||
"""
|
"""
|
||||||
Automatically removes code blocks from the code.
|
Automatically removes code blocks from the code.
|
||||||
"""
|
"""
|
||||||
# remove ```py\n```
|
# remove ```py\n```
|
||||||
if content.startswith("```") and content.endswith("```"):
|
if content.startswith("```") and content.endswith("```"):
|
||||||
return "\n".join(content.split("\n")[1:-1])
|
return "\n".join(content.split("\n")[1:-1])
|
||||||
|
|
||||||
# remove `foo`
|
# remove `foo`
|
||||||
return content.strip("` \n")
|
return content.strip("` \n")
|
||||||
|
|
||||||
def get_syntax_error(self, e):
|
def get_syntax_error(self, e):
|
||||||
if e.text is None:
|
if e.text is None:
|
||||||
return "{0.__class__.__name__}: {0}".format(e)
|
return "{0.__class__.__name__}: {0}".format(e)
|
||||||
return "{0.text}{1:>{0.offset}}\n{2}: {0}".format(e, "^", type(e).__name__)
|
return "{0.text}{1:>{0.offset}}\n{2}: {0}".format(e, "^", type(e).__name__)
|
||||||
|
|
||||||
@commands.command(name="exec")
|
@commands.command(name="exec")
|
||||||
async def _eval(self, ctx, *, body: str = None):
|
async def _eval(self, ctx, *, body: str = None):
|
||||||
"""
|
"""
|
||||||
Execute python code in discord chat.
|
Execute python code in discord chat.
|
||||||
Only the owner of this bot can use this command.
|
Only the owner of this bot can use this command.
|
||||||
|
|
||||||
Alias:
|
Alias:
|
||||||
- exec
|
- exec
|
||||||
Usage:
|
Usage:
|
||||||
- exec < python code >
|
- exec < python code >
|
||||||
Example:
|
Example:
|
||||||
- exec print(546132)
|
- exec print(546132)
|
||||||
"""
|
"""
|
||||||
if ctx.author.id not in self.bot.ownerlist:
|
if ctx.author.id not in self.bot.ownerlist:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"Only my contributors can use me like this :blush:", delete_after=10
|
"Only my contributors can use me like this :blush:", delete_after=10
|
||||||
)
|
)
|
||||||
|
|
||||||
if body is None:
|
if body is None:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"Please, use\n"
|
"Please, use\n"
|
||||||
f'`{self.bot.config["prefix"]}exec`\n\n'
|
f'`{self.bot.config["prefix"]}exec`\n\n'
|
||||||
"\n`\\`\\`\\`py\n[python code]\n\\`\\`\\`\n"
|
"\n`\\`\\`\\`py\n[python code]\n\\`\\`\\`\n"
|
||||||
"to get the most out of the command"
|
"to get the most out of the command"
|
||||||
)
|
)
|
||||||
|
|
||||||
env = {
|
env = {
|
||||||
"bot": self.bot,
|
"bot": self.bot,
|
||||||
"ctx": ctx,
|
"ctx": ctx,
|
||||||
"channel": ctx.message.channel,
|
"channel": ctx.message.channel,
|
||||||
"author": ctx.message.author,
|
"author": ctx.message.author,
|
||||||
"server": ctx.message.guild,
|
"server": ctx.message.guild,
|
||||||
"message": ctx.message,
|
"message": ctx.message,
|
||||||
"_": self._last_result,
|
"_": self._last_result,
|
||||||
}
|
}
|
||||||
|
|
||||||
env.update(globals())
|
env.update(globals())
|
||||||
|
|
||||||
body = self.cleanup_code(body)
|
body = self.cleanup_code(body)
|
||||||
stdout = io.StringIO()
|
stdout = io.StringIO()
|
||||||
|
|
||||||
to_compile = "async def func():\n%s" % textwrap.indent(body, " ")
|
to_compile = "async def func():\n%s" % textwrap.indent(body, " ")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
exec(to_compile, env)
|
exec(to_compile, env)
|
||||||
except SyntaxError as e:
|
except SyntaxError as e:
|
||||||
try:
|
try:
|
||||||
await ctx.send(f"```py\n{self.get_syntax_error(e)}\n```")
|
await ctx.send(f"```py\n{self.get_syntax_error(e)}\n```")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error = [
|
error = [
|
||||||
self.get_syntax_error(e)[i : i + 2000]
|
self.get_syntax_error(e)[i : i + 2000]
|
||||||
for i in range(0, len(self.get_syntax_error(e)), 2000)
|
for i in range(0, len(self.get_syntax_error(e)), 2000)
|
||||||
]
|
]
|
||||||
for i in error:
|
for i in error:
|
||||||
await ctx.send(f"```py\n{i}\n```")
|
await ctx.send(f"```py\n{i}\n```")
|
||||||
|
|
||||||
func = env["func"]
|
func = env["func"]
|
||||||
try:
|
try:
|
||||||
with redirect_stdout(stdout):
|
with redirect_stdout(stdout):
|
||||||
ret = await func()
|
ret = await func()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
value = stdout.getvalue()
|
value = stdout.getvalue()
|
||||||
try:
|
try:
|
||||||
await ctx.send(f"```py\n{value}{traceback.format_exc()}\n```")
|
await ctx.send(f"```py\n{value}{traceback.format_exc()}\n```")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error = [value[i : i + 2000] for i in range(0, len(value), 2000)]
|
error = [value[i : i + 2000] for i in range(0, len(value), 2000)]
|
||||||
for i in error:
|
for i in error:
|
||||||
await ctx.send(f"```py\n{i}\n```")
|
await ctx.send(f"```py\n{i}\n```")
|
||||||
|
|
||||||
tracebackerror = [
|
tracebackerror = [
|
||||||
traceback.format_exc()[i : i + 2000]
|
traceback.format_exc()[i : i + 2000]
|
||||||
for i in range(0, len(traceback.format_exc()), 2000)
|
for i in range(0, len(traceback.format_exc()), 2000)
|
||||||
]
|
]
|
||||||
for i in tracebackerror:
|
for i in tracebackerror:
|
||||||
await ctx.send(f"```py\n{i}\n```")
|
await ctx.send(f"```py\n{i}\n```")
|
||||||
else:
|
else:
|
||||||
value = stdout.getvalue()
|
value = stdout.getvalue()
|
||||||
if ret is None:
|
if ret is None:
|
||||||
if value:
|
if value:
|
||||||
try:
|
try:
|
||||||
await ctx.send(f"```py\n{value}\n```")
|
await ctx.send(f"```py\n{value}\n```")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
code = [value[i : i + 1980] for i in range(0, len(value), 1980)]
|
code = [value[i : i + 1980] for i in range(0, len(value), 1980)]
|
||||||
for i in code:
|
for i in code:
|
||||||
await ctx.send(f"```py\n{i}\n```")
|
await ctx.send(f"```py\n{i}\n```")
|
||||||
else:
|
else:
|
||||||
self._last_result = ret
|
self._last_result = ret
|
||||||
try:
|
try:
|
||||||
code = [value[i : i + 1980] for i in range(0, len(value), 1980)]
|
code = [value[i : i + 1980] for i in range(0, len(value), 1980)]
|
||||||
for i in code:
|
for i in code:
|
||||||
await ctx.send(f"```py\n{i}\n```")
|
await ctx.send(f"```py\n{i}\n```")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
code = [value[i : i + 1980] for i in range(0, len(value), 1980)]
|
code = [value[i : i + 1980] for i in range(0, len(value), 1980)]
|
||||||
for i in code:
|
for i in code:
|
||||||
await ctx.send(f"```py\n{i}\n```")
|
await ctx.send(f"```py\n{i}\n```")
|
||||||
modifyd_ret = [ret[i : i + 1980] for i in range(0, len(ret), 1980)]
|
modifyd_ret = [ret[i : i + 1980] for i in range(0, len(ret), 1980)]
|
||||||
for i in modifyd_ret:
|
for i in modifyd_ret:
|
||||||
await ctx.send(f"```py\n{i}\n```")
|
await ctx.send(f"```py\n{i}\n```")
|
||||||
|
|
||||||
@commands.command(hidden=True)
|
@commands.command(hidden=True)
|
||||||
async def repl(self, ctx):
|
async def repl(self, ctx):
|
||||||
"""
|
"""
|
||||||
Start a interactive python shell in chat.
|
Start a interactive python shell in chat.
|
||||||
Only the owner of this bot can use this command.
|
Only the owner of this bot can use this command.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
- repl < python code >
|
- repl < python code >
|
||||||
Example:
|
Example:
|
||||||
- repl print(205554)
|
- repl print(205554)
|
||||||
"""
|
"""
|
||||||
if ctx.author.id not in self.bot.ownerlist:
|
if ctx.author.id not in self.bot.ownerlist:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"Only my contributors can use me like this :blush:", delete_after=10
|
"Only my contributors can use me like this :blush:", delete_after=10
|
||||||
)
|
)
|
||||||
|
|
||||||
msg = ctx.message
|
msg = ctx.message
|
||||||
|
|
||||||
variables = {
|
variables = {
|
||||||
"ctx": ctx,
|
"ctx": ctx,
|
||||||
"bot": self.bot,
|
"bot": self.bot,
|
||||||
"message": msg,
|
"message": msg,
|
||||||
"server": msg.guild,
|
"server": msg.guild,
|
||||||
"channel": msg.channel,
|
"channel": msg.channel,
|
||||||
"author": msg.author,
|
"author": msg.author,
|
||||||
"_": None,
|
"_": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.channel.id in self.sessions:
|
if msg.channel.id in self.sessions:
|
||||||
msg = await ctx.send(
|
msg = await ctx.send(
|
||||||
"Already running a REPL session in this channel. Exit it with `quit`."
|
"Already running a REPL session in this channel. Exit it with `quit`."
|
||||||
)
|
)
|
||||||
|
|
||||||
self.sessions.add(msg.channel.id)
|
self.sessions.add(msg.channel.id)
|
||||||
|
|
||||||
await ctx.send("Enter code to execute or evaluate. `exit()` or `quit` to exit.")
|
await ctx.send("Enter code to execute or evaluate. `exit()` or `quit` to exit.")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
response = await self.bot.wait_for(
|
response = await self.bot.wait_for(
|
||||||
"message",
|
"message",
|
||||||
check=lambda m: m.content.startswith("`")
|
check=lambda m: m.content.startswith("`")
|
||||||
and m.author == ctx.author
|
and m.author == ctx.author
|
||||||
and m.channel == ctx.channel,
|
and m.channel == ctx.channel,
|
||||||
)
|
)
|
||||||
|
|
||||||
cleaned = self.cleanup_code(response.content)
|
cleaned = self.cleanup_code(response.content)
|
||||||
|
|
||||||
if cleaned in ("quit", "exit", "exit()"):
|
if cleaned in ("quit", "exit", "exit()"):
|
||||||
msg = await ctx.send("Exiting.")
|
msg = await ctx.send("Exiting.")
|
||||||
self.sessions.remove(msg.channel.id)
|
self.sessions.remove(msg.channel.id)
|
||||||
return
|
return
|
||||||
|
|
||||||
executor = exec
|
executor = exec
|
||||||
if cleaned.count("\n") == 0:
|
if cleaned.count("\n") == 0:
|
||||||
# single statement, potentially 'eval'
|
# single statement, potentially 'eval'
|
||||||
try:
|
try:
|
||||||
code = compile(cleaned, "<repl session>", "eval")
|
code = compile(cleaned, "<repl session>", "eval")
|
||||||
except SyntaxError:
|
except SyntaxError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
executor = eval
|
executor = eval
|
||||||
|
|
||||||
if executor is exec:
|
if executor is exec:
|
||||||
try:
|
try:
|
||||||
code = compile(cleaned, "<repl session>", "exec")
|
code = compile(cleaned, "<repl session>", "exec")
|
||||||
except SyntaxError as e:
|
except SyntaxError as e:
|
||||||
try:
|
try:
|
||||||
await ctx.send(f"```Python\n{self.get_syntax_error(e)}\n```")
|
await ctx.send(f"```Python\n{self.get_syntax_error(e)}\n```")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error = [
|
error = [
|
||||||
self.get_syntax_error(e)[i : i + 2000]
|
self.get_syntax_error(e)[i : i + 2000]
|
||||||
for i in range(0, len(self.get_syntax_error(e)), 2000)
|
for i in range(0, len(self.get_syntax_error(e)), 2000)
|
||||||
]
|
]
|
||||||
for i in error:
|
for i in error:
|
||||||
await ctx.send(f"```Python\n{i}\n```")
|
await ctx.send(f"```Python\n{i}\n```")
|
||||||
|
|
||||||
variables["message"] = response
|
variables["message"] = response
|
||||||
fmt = None
|
fmt = None
|
||||||
stdout = io.StringIO()
|
stdout = io.StringIO()
|
||||||
try:
|
try:
|
||||||
with redirect_stdout(stdout):
|
with redirect_stdout(stdout):
|
||||||
result = executor(code, variables)
|
result = executor(code, variables)
|
||||||
if inspect.isawaitable(result):
|
if inspect.isawaitable(result):
|
||||||
result = await result
|
result = await result
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
value = stdout.getvalue()
|
value = stdout.getvalue()
|
||||||
await ctx.send(f"```Python\n{value}{traceback.format_exc()}\n```")
|
await ctx.send(f"```Python\n{value}{traceback.format_exc()}\n```")
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
value = stdout.getvalue()
|
value = stdout.getvalue()
|
||||||
if result is not None:
|
if result is not None:
|
||||||
fmt = "{}{}".format(value, result)
|
fmt = "{}{}".format(value, result)
|
||||||
variables["_"] = result
|
variables["_"] = result
|
||||||
elif value:
|
elif value:
|
||||||
fmt = value
|
fmt = value
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if fmt is not None:
|
if fmt is not None:
|
||||||
if len(fmt) > 1980:
|
if len(fmt) > 1980:
|
||||||
code = [fmt[i : i + 1980] for i in range(0, len(fmt), 1980)]
|
code = [fmt[i : i + 1980] for i in range(0, len(fmt), 1980)]
|
||||||
for i in code:
|
for i in code:
|
||||||
await ctx.send(f"```py\n{i}\n```")
|
await ctx.send(f"```py\n{i}\n```")
|
||||||
else:
|
else:
|
||||||
await ctx.send(fmt)
|
await ctx.send(fmt)
|
||||||
|
|
||||||
except discord.Forbidden:
|
except discord.Forbidden:
|
||||||
pass
|
pass
|
||||||
except discord.HTTPException as e:
|
except discord.HTTPException as e:
|
||||||
await ctx.send(f"Unexpected error: `{e}`")
|
await ctx.send(f"Unexpected error: `{e}`")
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(REPL(bot))
|
bot.add_cog(REPL(bot))
|
||||||
@ -1,146 +1,146 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
import discord
|
import discord
|
||||||
import traceback
|
import traceback
|
||||||
import aiofiles
|
import aiofiles
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
class Upload:
|
class Upload:
|
||||||
"""
|
"""
|
||||||
CogName should be the name of the cog
|
CogName should be the name of the cog
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
print("upload loaded")
|
print("upload loaded")
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def reload(self, ctx, *, extension: str):
|
async def reload(self, ctx, *, extension: str):
|
||||||
"""Reload an extension."""
|
"""Reload an extension."""
|
||||||
await ctx.trigger_typing()
|
await ctx.trigger_typing()
|
||||||
if ctx.author.id not in self.bot.ownerlist:
|
if ctx.author.id not in self.bot.ownerlist:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"Only my contributors can use me like this :blush:", delete_after=10
|
"Only my contributors can use me like this :blush:", delete_after=10
|
||||||
)
|
)
|
||||||
|
|
||||||
extension = extension.lower()
|
extension = extension.lower()
|
||||||
try:
|
try:
|
||||||
self.bot.unload_extension("src.cogs.{}".format(extension))
|
self.bot.unload_extension("src.cogs.{}".format(extension))
|
||||||
self.bot.load_extension("src.cogs.{}".format(extension))
|
self.bot.load_extension("src.cogs.{}".format(extension))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
await ctx.send(f"Could not reload `{extension}` -> `{e}`")
|
await ctx.send(f"Could not reload `{extension}` -> `{e}`")
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"Reloaded `{extension}`.")
|
await ctx.send(f"Reloaded `{extension}`.")
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def reloadall(self, ctx):
|
async def reloadall(self, ctx):
|
||||||
"""Reload all extensions."""
|
"""Reload all extensions."""
|
||||||
await ctx.trigger_typing()
|
await ctx.trigger_typing()
|
||||||
if ctx.author.id not in self.bot.ownerlist:
|
if ctx.author.id not in self.bot.ownerlist:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"Only my contributors can use me like this :blush:", delete_after=10
|
"Only my contributors can use me like this :blush:", delete_after=10
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for extension in self.bot.extensions:
|
for extension in self.bot.extensions:
|
||||||
self.bot.unload_extension(extension)
|
self.bot.unload_extension(extension)
|
||||||
self.bot.load_extension(extension)
|
self.bot.load_extension(extension)
|
||||||
await ctx.send(f"Reload success! :thumbsup:\n")
|
await ctx.send(f"Reload success! :thumbsup:\n")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await ctx.send(f"Could not reload `{extension}` -> `{e}`.\n")
|
await ctx.send(f"Could not reload `{extension}` -> `{e}`.\n")
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def unload(self, ctx, *, extension: str):
|
async def unload(self, ctx, *, extension: str):
|
||||||
"""Unload an extension."""
|
"""Unload an extension."""
|
||||||
await ctx.trigger_typing()
|
await ctx.trigger_typing()
|
||||||
if ctx.author.id not in self.bot.ownerlist:
|
if ctx.author.id not in self.bot.ownerlist:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"Only my contributors can use me like this :blush:", delete_after=10
|
"Only my contributors can use me like this :blush:", delete_after=10
|
||||||
)
|
)
|
||||||
|
|
||||||
extension = extension.lower()
|
extension = extension.lower()
|
||||||
try:
|
try:
|
||||||
self.bot.unload_extension("src.cogs.{}".format(extension))
|
self.bot.unload_extension("src.cogs.{}".format(extension))
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
if ctx.message.author.id not in self.bot.owner_list:
|
if ctx.message.author.id not in self.bot.owner_list:
|
||||||
await ctx.send(f"Could not unload `{extension}` -> `{e}`")
|
await ctx.send(f"Could not unload `{extension}` -> `{e}`")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"Unloaded `{extension}`.")
|
await ctx.send(f"Unloaded `{extension}`.")
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def load(self, ctx, *, extension: str):
|
async def load(self, ctx, *, extension: str):
|
||||||
"""Load an extension."""
|
"""Load an extension."""
|
||||||
await ctx.trigger_typing()
|
await ctx.trigger_typing()
|
||||||
if ctx.author.id not in self.bot.ownerlist:
|
if ctx.author.id not in self.bot.ownerlist:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"Only my contributors can use me like this :blush:", delete_after=10
|
"Only my contributors can use me like this :blush:", delete_after=10
|
||||||
)
|
)
|
||||||
|
|
||||||
extension = extension.lower()
|
extension = extension.lower()
|
||||||
try:
|
try:
|
||||||
self.bot.load_extension("src.cogs.{}".format(extension))
|
self.bot.load_extension("src.cogs.{}".format(extension))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
await ctx.send(f"Could not load `{extension}` -> `{e}`")
|
await ctx.send(f"Could not load `{extension}` -> `{e}`")
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"Loaded `{extension}`.")
|
await ctx.send(f"Loaded `{extension}`.")
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def permunload(self, ctx, extension=None):
|
async def permunload(self, ctx, extension=None):
|
||||||
"""Disables permanently a cog."""
|
"""Disables permanently a cog."""
|
||||||
await ctx.trigger_typing()
|
await ctx.trigger_typing()
|
||||||
if ctx.author.id not in self.bot.ownerlist:
|
if ctx.author.id not in self.bot.ownerlist:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"Only my contributors can use me like this :blush:", delete_after=10
|
"Only my contributors can use me like this :blush:", delete_after=10
|
||||||
)
|
)
|
||||||
|
|
||||||
if cog is None:
|
if cog is None:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"Please provide a extension. Do `help permunload` for more info"
|
"Please provide a extension. Do `help permunload` for more info"
|
||||||
)
|
)
|
||||||
|
|
||||||
extension = extension.lower()
|
extension = extension.lower()
|
||||||
|
|
||||||
async with aiofiles.open("extension.txt") as fp:
|
async with aiofiles.open("extension.txt") as fp:
|
||||||
lines = fp.readlines()
|
lines = fp.readlines()
|
||||||
|
|
||||||
removed = False
|
removed = False
|
||||||
async with aiofiles.open("extension.txt", "w") as fp:
|
async with aiofiles.open("extension.txt", "w") as fp:
|
||||||
for i in lines:
|
for i in lines:
|
||||||
if i.replace("\n", "") != extension:
|
if i.replace("\n", "") != extension:
|
||||||
fp.write(i)
|
fp.write(i)
|
||||||
else:
|
else:
|
||||||
removed = True
|
removed = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if removed is True:
|
if removed is True:
|
||||||
try:
|
try:
|
||||||
self.bot.unload_extension(extension)
|
self.bot.unload_extension(extension)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return await ctx.send("Extension removed successfully")
|
return await ctx.send("Extension removed successfully")
|
||||||
|
|
||||||
await ctx.send("Extension not found")
|
await ctx.send("Extension not found")
|
||||||
|
|
||||||
@commands.command(hidden=True)
|
@commands.command(hidden=True)
|
||||||
async def reboot(self, ctx):
|
async def reboot(self, ctx):
|
||||||
if ctx.author.id not in self.bot.ownerlist:
|
if ctx.author.id not in self.bot.ownerlist:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"Only my contributors can use me like this :blush:", delete_after=10
|
"Only my contributors can use me like this :blush:", delete_after=10
|
||||||
)
|
)
|
||||||
await ctx.send("Sebi-Machine is restarting.")
|
await ctx.send("Sebi-Machine is restarting.")
|
||||||
with open(f"src/config/reboot", "w") as f:
|
with open(f"src/config/reboot", "w") as f:
|
||||||
f.write(f"1\n{ctx.channel.id}")
|
f.write(f"1\n{ctx.channel.id}")
|
||||||
# noinspection PyProtectedMember
|
# noinspection PyProtectedMember
|
||||||
os._exit(1)
|
os._exit(1)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Upload(bot))
|
bot.add_cog(Upload(bot))
|
||||||
@ -1,26 +1,26 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
import discord
|
import discord
|
||||||
|
|
||||||
|
|
||||||
class CogName:
|
class CogName:
|
||||||
"""
|
"""
|
||||||
CogName should be the name of the cog
|
CogName should be the name of the cog
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def ping(self, ctx):
|
async def ping(self, ctx):
|
||||||
"""Say pong"""
|
"""Say pong"""
|
||||||
now = ctx.message.created_at
|
now = ctx.message.created_at
|
||||||
msg = await ctx.send("Pong")
|
msg = await ctx.send("Pong")
|
||||||
sub = msg.created_at - now
|
sub = msg.created_at - now
|
||||||
await msg.edit(content=f"🏓Pong, **{sub.total_seconds() * 1000}ms**")
|
await msg.edit(content=f"🏓Pong, **{sub.total_seconds() * 1000}ms**")
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(CogName(bot))
|
bot.add_cog(CogName(bot))
|
||||||
@ -1,47 +1,47 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
import discord
|
import discord
|
||||||
import random
|
import random
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
|
|
||||||
class Fun:
|
class Fun:
|
||||||
"""
|
"""
|
||||||
CogName should be the name of the cog
|
CogName should be the name of the cog
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def sebisauce(self, ctx):
|
async def sebisauce(self, ctx):
|
||||||
"""
|
"""
|
||||||
Get a image related to Sebi.
|
Get a image related to Sebi.
|
||||||
Sebi is a random guy with perfect code related jokes.
|
Sebi is a random guy with perfect code related jokes.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
- sebisauce
|
- sebisauce
|
||||||
"""
|
"""
|
||||||
await ctx.trigger_typing()
|
await ctx.trigger_typing()
|
||||||
url = "http://ikbengeslaagd.com/API/sebisauce.json"
|
url = "http://ikbengeslaagd.com/API/sebisauce.json"
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.get(url) as response:
|
async with session.get(url) as response:
|
||||||
source = await response.json(encoding="utf8")
|
source = await response.json(encoding="utf8")
|
||||||
|
|
||||||
total_sebi = 0
|
total_sebi = 0
|
||||||
for key in dict.keys(source):
|
for key in dict.keys(source):
|
||||||
total_sebi += 1
|
total_sebi += 1
|
||||||
|
|
||||||
im = random.randint(0, int(total_sebi) - 1)
|
im = random.randint(0, int(total_sebi) - 1)
|
||||||
|
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
embed=discord.Embed(
|
embed=discord.Embed(
|
||||||
title="\t", description="\t", color=self.bot.embed_color
|
title="\t", description="\t", color=self.bot.embed_color
|
||||||
).set_image(url=source[str(im)])
|
).set_image(url=source[str(im)])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Fun(bot))
|
bot.add_cog(Fun(bot))
|
||||||
@ -29,8 +29,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from src.shared_libs.utils import paginate, run_command
|
from sebimachine.shared_libs.utils import paginate, run_command
|
||||||
from src.shared_libs.loggable import Loggable
|
from sebimachine.shared_libs.loggable import Loggable
|
||||||
|
|
||||||
|
from sebimachine import __url__
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
|
|
||||||
@ -41,7 +43,8 @@ class Git(Loggable):
|
|||||||
@commands.group(case_insensitive=True, invoke_without_command=True)
|
@commands.group(case_insensitive=True, invoke_without_command=True)
|
||||||
async def git(self, ctx):
|
async def git(self, ctx):
|
||||||
"""Run help git for more info"""
|
"""Run help git for more info"""
|
||||||
await ctx.send("https://github.com/dustinpianalto/Sebi-Machine/")
|
# await ctx.send("https://github.com/dustinpianalto/Sebi-Machine/")
|
||||||
|
await ctx.send(__url__ or "No URL specified in __init__.py")
|
||||||
|
|
||||||
@commands.command(case_insensitive=True, brief="Gets the Trello link.")
|
@commands.command(case_insensitive=True, brief="Gets the Trello link.")
|
||||||
async def trello(self, ctx):
|
async def trello(self, ctx):
|
||||||
@ -15,7 +15,7 @@ from .utils import noblock
|
|||||||
|
|
||||||
|
|
||||||
YT_DL_OPTS = {
|
YT_DL_OPTS = {
|
||||||
"format": "mp3[abr>0]/bestaudio/best",
|
"format": "ogg[abr>0]/bestaudio/best",
|
||||||
"ignoreerrors": True,
|
"ignoreerrors": True,
|
||||||
"default_search": "auto",
|
"default_search": "auto",
|
||||||
"source_address": "0.0.0.0",
|
"source_address": "0.0.0.0",
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"sar": "sar",
|
"sar": "sar",
|
||||||
"selfrole": "sar",
|
"selfrole": "sar",
|
||||||
"selfroles": "sar"
|
"selfroles": "sar"
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import asyncpg
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
|
import asyncpg
|
||||||
|
|
||||||
|
|
||||||
class DatabaseConnection:
|
class DatabaseConnection:
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -31,9 +31,10 @@ Utility for creating Paginated responses
|
|||||||
|
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import discord
|
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
|
import discord
|
||||||
|
|
||||||
|
|
||||||
class Paginator:
|
class Paginator:
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -1,115 +1,115 @@
|
|||||||
"""
|
"""
|
||||||
===
|
===
|
||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2018 Dusty.P https://github.com/dustinpianalto
|
Copyright (c) 2018 Dusty.P https://github.com/dustinpianalto
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
"Software"), to deal in the Software without restriction, including
|
"Software"), to deal in the Software without restriction, including
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
the following conditions:
|
the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
The above copyright notice and this permission notice shall be
|
||||||
included in all copies or substantial portions of the Software.
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
import sys
|
import sys
|
||||||
import asyncio
|
import asyncio
|
||||||
import discord
|
import discord
|
||||||
from discord.ext.commands.formatter import Paginator
|
from discord.ext.commands.formatter import Paginator
|
||||||
|
|
||||||
|
|
||||||
class Capturing(list):
|
class Capturing(list):
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self._stdout = sys.stdout
|
self._stdout = sys.stdout
|
||||||
sys.stdout = self._stringio = StringIO()
|
sys.stdout = self._stringio = StringIO()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __exit__(self, *args):
|
def __exit__(self, *args):
|
||||||
self.extend(self._stringio.getvalue().splitlines())
|
self.extend(self._stringio.getvalue().splitlines())
|
||||||
del self._stringio # free up some memory
|
del self._stringio # free up some memory
|
||||||
sys.stdout = self._stdout
|
sys.stdout = self._stdout
|
||||||
|
|
||||||
|
|
||||||
def to_list_of_str(items, out: list = list(), level=1, recurse=0):
|
def to_list_of_str(items, out: list = list(), level=1, recurse=0):
|
||||||
def rec_loop(item, key, out, level):
|
def rec_loop(item, key, out, level):
|
||||||
quote = '"'
|
quote = '"'
|
||||||
if type(item) == list:
|
if type(item) == list:
|
||||||
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}[')
|
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}[')
|
||||||
new_level = level + 1
|
new_level = level + 1
|
||||||
out = to_list_of_str(item, out, new_level, 1)
|
out = to_list_of_str(item, out, new_level, 1)
|
||||||
out.append(f'{" "*level}]')
|
out.append(f'{" "*level}]')
|
||||||
elif type(item) == dict:
|
elif type(item) == dict:
|
||||||
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}{{')
|
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}{{')
|
||||||
new_level = level + 1
|
new_level = level + 1
|
||||||
out = to_list_of_str(item, out, new_level, 1)
|
out = to_list_of_str(item, out, new_level, 1)
|
||||||
out.append(f'{" "*level}}}')
|
out.append(f'{" "*level}}}')
|
||||||
else:
|
else:
|
||||||
out.append(
|
out.append(
|
||||||
f'{" "*level}{quote+key+quote+": " if key else ""}{repr(item)},'
|
f'{" "*level}{quote+key+quote+": " if key else ""}{repr(item)},'
|
||||||
)
|
)
|
||||||
|
|
||||||
if type(items) == list:
|
if type(items) == list:
|
||||||
if not recurse:
|
if not recurse:
|
||||||
out = list()
|
out = list()
|
||||||
out.append("[")
|
out.append("[")
|
||||||
for item in items:
|
for item in items:
|
||||||
rec_loop(item, None, out, level)
|
rec_loop(item, None, out, level)
|
||||||
if not recurse:
|
if not recurse:
|
||||||
out.append("]")
|
out.append("]")
|
||||||
elif type(items) == dict:
|
elif type(items) == dict:
|
||||||
if not recurse:
|
if not recurse:
|
||||||
out = list()
|
out = list()
|
||||||
out.append("{")
|
out.append("{")
|
||||||
for key in items:
|
for key in items:
|
||||||
rec_loop(items[key], key, out, level)
|
rec_loop(items[key], key, out, level)
|
||||||
if not recurse:
|
if not recurse:
|
||||||
out.append("}")
|
out.append("}")
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def paginate(text, maxlen=1990):
|
def paginate(text, maxlen=1990):
|
||||||
paginator = Paginator(prefix="```py", max_size=maxlen + 10)
|
paginator = Paginator(prefix="```py", max_size=maxlen + 10)
|
||||||
if type(text) == list:
|
if type(text) == list:
|
||||||
data = to_list_of_str(text)
|
data = to_list_of_str(text)
|
||||||
elif type(text) == dict:
|
elif type(text) == dict:
|
||||||
data = to_list_of_str(text)
|
data = to_list_of_str(text)
|
||||||
else:
|
else:
|
||||||
data = str(text).split("\n")
|
data = str(text).split("\n")
|
||||||
for line in data:
|
for line in data:
|
||||||
if len(line) > maxlen:
|
if len(line) > maxlen:
|
||||||
n = maxlen
|
n = maxlen
|
||||||
for l in [line[i : i + n] for i in range(0, len(line), n)]:
|
for l in [line[i : i + n] for i in range(0, len(line), n)]:
|
||||||
paginator.add_line(l)
|
paginator.add_line(l)
|
||||||
else:
|
else:
|
||||||
paginator.add_line(line)
|
paginator.add_line(line)
|
||||||
return paginator.pages
|
return paginator.pages
|
||||||
|
|
||||||
|
|
||||||
async def run_command(args):
|
async def run_command(args):
|
||||||
# Create subprocess
|
# Create subprocess
|
||||||
process = await asyncio.create_subprocess_shell(
|
process = await asyncio.create_subprocess_shell(
|
||||||
args,
|
args,
|
||||||
# stdout must a pipe to be accessible as process.stdout
|
# stdout must a pipe to be accessible as process.stdout
|
||||||
stdout=asyncio.subprocess.PIPE,
|
stdout=asyncio.subprocess.PIPE,
|
||||||
)
|
)
|
||||||
# Wait for the subprocess to finish
|
# Wait for the subprocess to finish
|
||||||
stdout, stderr = await process.communicate()
|
stdout, stderr = await process.communicate()
|
||||||
# Return stdout
|
# Return stdout
|
||||||
return stdout.decode().strip()
|
return stdout.decode().strip()
|
||||||
47
setup.py
Normal file
47
setup.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/bin/env python3.6
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Setup.
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
from setuptools import setup
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
|
package_name = 'sebimachine'
|
||||||
|
|
||||||
|
|
||||||
|
req_line_test = lambda l: l and l[0] != '#'
|
||||||
|
|
||||||
|
|
||||||
|
with open('README.md') as fp:
|
||||||
|
readme = fp.read()
|
||||||
|
|
||||||
|
|
||||||
|
with open('requirements.txt') as fp:
|
||||||
|
requirements = {*filter(req_line_test, map(str.lstrip, fp.read().split('\n')))}
|
||||||
|
|
||||||
|
|
||||||
|
with open(f'{package_name}/__init__.py') as fp:
|
||||||
|
attrs = {}
|
||||||
|
print('Attributes:')
|
||||||
|
for k, v in re.findall(r'^__(\w+)__\s?=\s?"([^"]*)"', fp.read(), re.M):
|
||||||
|
k = 'name' if k == 'title' else k
|
||||||
|
attrs[k] = v
|
||||||
|
print(k, v)
|
||||||
|
|
||||||
|
|
||||||
|
# Use pip on invoke to install requirements. Ensures we can essentially just run this
|
||||||
|
# script without setuptools arguments. TODO: fix.
|
||||||
|
try:
|
||||||
|
import pip
|
||||||
|
pip.main(['install', *install_requires])
|
||||||
|
except (ModuleNotFoundError, ImportError):
|
||||||
|
print('Failed to import pip. Install git dependencies manually.')
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
|
||||||
|
setup(
|
||||||
|
long_description=readme,
|
||||||
|
**attrs
|
||||||
|
)
|
||||||
Loading…
x
Reference in New Issue
Block a user