Breaking more stuff
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@ import json
|
||||
import logging
|
||||
import inspect
|
||||
import os
|
||||
from .imports import checks, utils
|
||||
from src.imports import checks, utils
|
||||
|
||||
config_dir = 'config/'
|
||||
admin_id_file = 'admin_ids'
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import logging
|
||||
from datetime import datetime
|
||||
import json
|
||||
import re
|
||||
from .imports import utils
|
||||
from src.imports import utils
|
||||
|
||||
config_dir = 'config/'
|
||||
admin_id_file = 'admin_ids'
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import logging
|
||||
from .imports.utils import Paginator, run_command
|
||||
from src.imports import Paginator, run_command
|
||||
import asyncio
|
||||
|
||||
owner_id = 351794468870946827
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
import discord
|
||||
import json
|
||||
from . import utils
|
||||
|
||||
owner_id = 351794468870946827
|
||||
|
||||
|
||||
async def check_admin_role(bot, ctx, member):
|
||||
admin_roles = json.loads(await bot.db_concon.fetchval(f"select admin_roles from guild_config where guild_id = $1",
|
||||
ctx.guild.id))
|
||||
for role in admin_roles:
|
||||
if discord.utils.get(ctx.guild.roles, id=admin_roles[role]) in member.roles:
|
||||
return True
|
||||
return member.id == ctx.guild.owner.id or member.id == owner_id
|
||||
|
||||
|
||||
async def check_rcon_role(bot, ctx, member):
|
||||
rcon_admin_roles = json.loads(await bot.db_concon.fetchval("select rcon_admin_roles from guild_config "
|
||||
"where guild_id = $1", ctx.guild.id))
|
||||
for role in rcon_admin_roles:
|
||||
if discord.utils.get(ctx.guild.roles, id=rcon_admin_roles[role]) in member.roles:
|
||||
return True
|
||||
return member.id == ctx.guild.owner.id or member.id == owner_id
|
||||
|
||||
|
||||
async def is_admin(bot, ctx):
|
||||
admin_roles = json.loads(await bot.db_concon.fetchval("select admin_roles from guild_config where guild_id = $1",
|
||||
ctx.guild.id))
|
||||
for role in admin_roles:
|
||||
if discord.utils.get(ctx.guild.roles, id=admin_roles[role]) in ctx.message.author.roles:
|
||||
return True
|
||||
return ctx.message.author.id == ctx.guild.owner.id or ctx.message.author.id == owner_id
|
||||
|
||||
|
||||
async def is_guild_owner(ctx):
|
||||
if ctx.guild:
|
||||
return ctx.message.author.id == ctx.guild.owner.id or ctx.message.author.id == owner_id
|
||||
return False
|
||||
|
||||
|
||||
async def is_rcon_admin(bot, ctx):
|
||||
rcon_admin_roles = json.loads(await bot.db_concon.fetchval("select rcon_admin_roles from guild_config "
|
||||
"where guild_id = $1", ctx.guild.id))
|
||||
for role in rcon_admin_roles:
|
||||
if discord.utils.get(ctx.guild.roles, id=rcon_admin_roles[role]) in ctx.message.author.roles:
|
||||
return True
|
||||
return ctx.message.author.id == ctx.guild.owner.id or ctx.message.author.id == owner_id
|
||||
|
||||
|
||||
def is_restricted_chan(ctx):
|
||||
if ctx.guild:
|
||||
if ctx.channel.overwrites_for(ctx.guild.default_role).read_messages is False:
|
||||
return True
|
||||
return False
|
||||
return False
|
||||
|
||||
|
||||
async def is_spam(bot, ctx):
|
||||
max_rep = 5
|
||||
rep_time = 20
|
||||
spam_rep = 5
|
||||
spam_time = 3
|
||||
spam_check = 0
|
||||
msg_check = 0
|
||||
for msg in bot.recent_msgs[ctx.guild.id]:
|
||||
if msg['author'] == ctx.author:
|
||||
if msg['time'] > ctx.message.created_at.timestamp() - spam_time:
|
||||
spam_check += 1
|
||||
if msg['content'].lower() == ctx.content.lower() \
|
||||
and msg['time'] > ctx.message.created_at.timestamp() - rep_time:
|
||||
msg_check += 1
|
||||
if spam_check == spam_rep - 1 or msg_check == max_rep - 1:
|
||||
await utils.mute(bot, ctx, admin=1, member=ctx.author.id)
|
||||
return True
|
||||
return False
|
||||
@@ -1,261 +0,0 @@
|
||||
from io import StringIO
|
||||
import sys
|
||||
import asyncio
|
||||
import discord
|
||||
from discord.ext.commands.formatter import Paginator as DannyPag
|
||||
from . import checks
|
||||
from geeksbot_dev.geeksbot import Geeksbot
|
||||
import re
|
||||
import typing
|
||||
|
||||
|
||||
class Capturing(list):
|
||||
def __enter__(self):
|
||||
self._stdout = sys.stdout
|
||||
sys.stdout = self._stringio = StringIO()
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.extend(self._stringio.getvalue().splitlines())
|
||||
del self._stringio # free up some memory
|
||||
sys.stdout = self._stdout
|
||||
|
||||
|
||||
async def mute(bot, ctx, admin=0, member_id=None):
|
||||
mute_role = bot.db_con.fetchval(f'select muted_role from guild_config where guild_id = $1', ctx.guild.id)
|
||||
if mute_role:
|
||||
if admin or await checks.is_admin(bot, ctx):
|
||||
if ctx.guild.me.guild_permissions.manage_roles:
|
||||
if member_id:
|
||||
ctx.guild.get_member(member_id).edit(roles=[discord.utils.get(ctx.guild.roles, id=mute_role)])
|
||||
|
||||
|
||||
def to_list_of_str(items, out: list=list(), level=1, recurse=0):
|
||||
# noinspection PyShadowingNames
|
||||
def rec_loop(item, key, out, level):
|
||||
quote = '"'
|
||||
if type(item) == list:
|
||||
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}[')
|
||||
new_level = level + 1
|
||||
out = to_list_of_str(item, out, new_level, 1)
|
||||
out.append(f'{" "*level}]')
|
||||
elif type(item) == dict:
|
||||
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}{{')
|
||||
new_level = level + 1
|
||||
out = to_list_of_str(item, out, new_level, 1)
|
||||
out.append(f'{" "*level}}}')
|
||||
else:
|
||||
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}{repr(item)},')
|
||||
|
||||
if type(items) == list:
|
||||
if not recurse:
|
||||
out = list()
|
||||
out.append('[')
|
||||
for item in items:
|
||||
rec_loop(item, None, out, level)
|
||||
if not recurse:
|
||||
out.append(']')
|
||||
elif type(items) == dict:
|
||||
if not recurse:
|
||||
out = list()
|
||||
out.append('{')
|
||||
for key in items:
|
||||
rec_loop(items[key], key, out, level)
|
||||
if not recurse:
|
||||
out.append('}')
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def format_output(text):
|
||||
if type(text) == list:
|
||||
text = to_list_of_str(text)
|
||||
elif type(text) == dict:
|
||||
text = to_list_of_str(text)
|
||||
return text
|
||||
|
||||
|
||||
def replace_text_ignorecase(in_str: str, old: str, new: str='') -> str:
|
||||
re_replace = re.compile(re.escape(old), re.IGNORECASE)
|
||||
return re_replace.sub(f'{new}', in_str)
|
||||
|
||||
|
||||
async def run_command(args):
|
||||
# Create subprocess
|
||||
process = await asyncio.create_subprocess_shell(
|
||||
args,
|
||||
# stdout must a pipe to be accessible as process.stdout
|
||||
stdout=asyncio.subprocess.PIPE)
|
||||
# Wait for the subprocess to finish
|
||||
stdout, stderr = await process.communicate()
|
||||
# Return stdout
|
||||
return stdout.decode().strip()
|
||||
|
||||
|
||||
class Paginator:
|
||||
def __init__(self, *,
|
||||
max_chars: int=1970,
|
||||
max_lines: int=20,
|
||||
prefix: str='```md',
|
||||
suffix: str='```',
|
||||
page_break: str='\uFFF8',
|
||||
max_line_length: int=100):
|
||||
_max_len = 1980
|
||||
assert 0 < max_lines <= max_chars
|
||||
assert 0 < max_line_length < 120
|
||||
|
||||
self._parts = list()
|
||||
self._prefix = prefix
|
||||
self._suffix = suffix
|
||||
self._max_chars = max_chars if max_chars + len(prefix) + len(suffix) + 2 <= _max_len \
|
||||
else _max_len - len(prefix) - len(suffix) - 2
|
||||
self._max_lines = max_lines - (prefix + suffix).count('\n') + 1
|
||||
self._page_break = page_break
|
||||
self._max_line_length = max_line_length
|
||||
self._pages = list()
|
||||
|
||||
def pages(self) -> typing.List[str]:
|
||||
pages = list()
|
||||
page = ''
|
||||
lines = 0
|
||||
|
||||
def open_page():
|
||||
nonlocal page, lines
|
||||
page = self._prefix
|
||||
lines = 0
|
||||
|
||||
def close_page():
|
||||
nonlocal page, lines
|
||||
page += self._suffix
|
||||
pages.append(page)
|
||||
open_page()
|
||||
|
||||
open_page()
|
||||
|
||||
for part in [str(p) for p in self._parts]:
|
||||
if part == self._page_break:
|
||||
close_page()
|
||||
|
||||
new_chars = len(page) + len(part)
|
||||
|
||||
if new_chars > self._max_chars:
|
||||
close_page()
|
||||
elif (lines + (part.count('\n') + 1 or 1)) > self._max_lines:
|
||||
close_page()
|
||||
|
||||
lines += (part.count('\n') + 1 or 1)
|
||||
page += '\n' + part
|
||||
|
||||
close_page()
|
||||
self._pages = pages
|
||||
return pages
|
||||
|
||||
def process_pages(self) -> typing.List[str]:
|
||||
_pages = self._pages or self.pages()
|
||||
_len_pages = len(_pages)
|
||||
_len_page_str = len(f'{_len_pages}/{_len_pages}')
|
||||
for i, page in enumerate(_pages):
|
||||
if len(page) + _len_page_str <= 2000:
|
||||
_pages[i] = f'{i + 1}/{_len_pages}\n{page}'
|
||||
return _pages
|
||||
|
||||
def __len__(self):
|
||||
return sum(len(p) for p in self._parts)
|
||||
|
||||
def __eq__(self, other):
|
||||
# noinspection PyProtectedMember
|
||||
return self.__class__ == other.__class__ and self._parts == other._parts
|
||||
|
||||
def add_page_break(self, *, to_beginning: bool=False) -> None:
|
||||
self.add(self._page_break, to_beginning=to_beginning)
|
||||
|
||||
def add(self, item: typing.Any, *, to_beginning: bool=False, keep_intact: bool=False) -> None:
|
||||
item = str(item)
|
||||
i = 0
|
||||
if not keep_intact and not item == self._page_break:
|
||||
item_parts = item.strip().split('\n')
|
||||
for part in item_parts:
|
||||
if len(part) > self._max_line_length:
|
||||
length = 0
|
||||
out_str = ''
|
||||
|
||||
def close_line(line):
|
||||
nonlocal i, out_str, length
|
||||
self._parts.insert(i, out_str) if to_beginning else self._parts.append(out_str)
|
||||
i += 1
|
||||
out_str = line + ' '
|
||||
length = len(out_str)
|
||||
|
||||
bits = part.split(' ')
|
||||
for bit in bits:
|
||||
next_len = length + len(bit) + 1
|
||||
if next_len <= self._max_line_length:
|
||||
out_str += bit + ' '
|
||||
length = next_len
|
||||
elif len(bit) > self._max_line_length:
|
||||
if out_str:
|
||||
close_line(line='')
|
||||
for out_str in [bit[i:i + self._max_line_length]
|
||||
for i in range(0, len(bit), self._max_line_length)]:
|
||||
close_line('')
|
||||
else:
|
||||
close_line(bit)
|
||||
close_line('')
|
||||
else:
|
||||
self._parts.insert(i, part) if to_beginning else self._parts.append(part)
|
||||
i += 1
|
||||
elif keep_intact and not item == self._page_break:
|
||||
if len(item) >= self._max_chars or item.count('\n') > self._max_lines:
|
||||
raise RuntimeError('{item} is too long to keep on a single page and is marked to keep intact.')
|
||||
if to_beginning:
|
||||
self._parts.insert(0, item)
|
||||
else:
|
||||
self._parts.append(item)
|
||||
else:
|
||||
if to_beginning:
|
||||
self._parts.insert(0, item)
|
||||
else:
|
||||
self._parts.append(item)
|
||||
|
||||
|
||||
class Book:
|
||||
def __init__(self, pag: Paginator, ctx: typing.Tuple[discord.Message,
|
||||
discord.TextChannel,
|
||||
Geeksbot,
|
||||
discord.Message]) -> None:
|
||||
if pag == Paginator():
|
||||
raise RuntimeError('Cannot create a book out of an empty Paginator.')
|
||||
|
||||
self._pages = pag.process_pages()
|
||||
self._len_pages = len(self._pages)
|
||||
self._current_page = 0
|
||||
self._message, self._channel, self._bot, self._calling_message = ctx
|
||||
self._locked = True
|
||||
|
||||
def advance_page(self) -> None:
|
||||
self._current_page += 1
|
||||
if self._current_page >= self._len_pages:
|
||||
self._current_page = 0
|
||||
|
||||
def reverse_page(self) -> None:
|
||||
self._current_page += -1
|
||||
if self._current_page < 0:
|
||||
self._current_page = self._len_pages - 1
|
||||
|
||||
async def display_page(self) -> None:
|
||||
if isinstance(self._pages[self._current_page], discord.Embed):
|
||||
await self._message.edit(content=None, embed=self._pages[self._current_page])
|
||||
else:
|
||||
await self._message.edit(content=self._pages[self._current_page], embed=None)
|
||||
|
||||
for reaction in self._bot.book_emojis:
|
||||
try:
|
||||
await self._message.add_reaction(reaction)
|
||||
except (discord.Forbidden, KeyError):
|
||||
pass
|
||||
|
||||
# async def create_book(self) -> None:
|
||||
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import json
|
||||
from .imports import checks
|
||||
from src.imports import checks
|
||||
|
||||
config_dir = 'config'
|
||||
extension_dir = 'extensions'
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import logging
|
||||
from datetime import datetime
|
||||
import asyncio
|
||||
import traceback
|
||||
from .imports import checks
|
||||
from src.imports import checks
|
||||
|
||||
config_dir = 'config'
|
||||
admin_id_file = 'admin_ids'
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import inspect
|
||||
import textwrap
|
||||
from contextlib import redirect_stdout
|
||||
import io
|
||||
from .imports.utils import run_command, format_output, Paginator
|
||||
from src.imports import run_command, format_output, Paginator
|
||||
|
||||
ownerids = [351794468870946827, 275280442884751360]
|
||||
ownerid = 351794468870946827
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import psutil
|
||||
from datetime import datetime, timedelta
|
||||
import asyncio
|
||||
import async_timeout
|
||||
from .imports import checks, utils
|
||||
from src.imports import checks, utils
|
||||
import pytz
|
||||
import gspread
|
||||
from oauth2client.service_account import ServiceAccountCredentials
|
||||
|
||||
Reference in New Issue
Block a user