-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
148 lines (114 loc) · 5.05 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import io
import logging
import re
import subprocess
import dict_deep
import discord
from discord.ext import commands
from tinydb import Query
import config
from consts import *
Servers = Query()
async def cmdSuccess(ctx, text, *, delete_after=None):
return await ctx.send(f'{config.greenTick} {text}', delete_after=delete_after)
async def cmdFail(ctx, text, *, delete_after=None):
return await ctx.send(f'{config.redTick} {text}', delete_after=delete_after)
def getGitInfo(*, initialize=False, ref_commit=None):
try:
commit_hash = subprocess.check_output(['git','rev-parse','HEAD']).decode('ascii').strip()
origin_url = subprocess.check_output(['git','config','--get','remote.origin.url']).decode('ascii').strip()
modified = subprocess.call(['git','diff-index','--quiet','HEAD']) != 0
except Exception as e:
logging.warn(e)
return False
# If we are initializing commit info on bot startup, we only want the commit hash.
if initialize:
return commit_hash
fork = re.match(GIT_REPO_REGEX, GIT_REPO_URL).groups() != re.match(GIT_REPO_REGEX, origin_url).groups()
multiple = ref_commit != commit_hash
commit_short = (f'{ref_commit[:7]}..' if multiple else '') + commit_hash[:7] + ('*' if modified else '')
commit_url = f'{GIT_COMPARE_BASE}{ref_commit}^...{commit_hash}' if multiple else f'{GIT_COMMIT_BASE}{commit_hash}'
s = 's' if multiple else ''
version = f'Commit{s} `{commit_short}` (Fork)' if fork else f'Commit{s} [`{commit_short}`]({commit_url})'
return (version, fork)
def guild_in_db():
async def predicate(ctx):
if not ctx.bot.db.contains(Servers.id == ctx.guild.id):
default_document = {
'id': ctx.guild.id,
'requests_opts': {
'channel': None,
'hidejoins': False,
'ratelimit': True
},
'requests': {},
'roles': {}
}
ctx.bot.db.insert(default_document)
logging.info(f'[Bot] Guild initalized to database: {ctx.guild} ({ctx.guild.id})')
return True
return commands.check(predicate)
def getGuildDoc(bot, guild):
return bot.db.get( Servers.id == guild.id )
def guildKeySet(bot, guild, key, val):
def predicate(key, val):
def transform(doc):
dict_deep.deep_set(doc, key, val)
return transform
return bot.db.update(predicate(key, val), Servers.id == guild.id)
def guildKeyDel(bot, guild, key):
def predicate(key):
def transform(doc):
dict_deep.deep_del(doc, key)
return transform
return bot.db.update(predicate(key), Servers.id == guild.id)
def removeGuild(bot, guild_id):
logging.info(f'[Bot] Removed guild from db: {guild_id}')
return bot.db.remove(Servers.id == guild_id)
async def sendListEmbed(ctx, title, lst, *, raw_override=None, footer=None):
overall_limit = EMBED_LENGTH_LIMITS['overall'] - len(title) - (0 if not footer else len(footer))
lengths = list(map(lambda x: len(x), lst))
lenOverall = 0
lastItem = None
# Start building with description
description = ''
for i in range(len(lst)):
# Description < Overall, so we won't have to worry about hitting it yet; + 1 for newline
if len(description) + lengths[i] + 1 > EMBED_LENGTH_LIMITS['description']: break
description += lst[i] + '\n'
lastItem = i
lenOverall += len(description)
# If description is full, start with fields; 24 Fields, reserve last one for maximum length link
fields = []
for f in range(24):
if lastItem + 1 == len(lst): break
if lenOverall + lengths[lastItem+1] + 1 > overall_limit: break
fields.append('')
for i in range(lastItem+1, len(lst)):
if lenOverall + len(fields[f]) + lengths[i] + 1 > overall_limit: break
if len(fields[f]) + lengths[i] + 1 > EMBED_LENGTH_LIMITS['field_values']: break
fields[f] += lst[i] + '\n'
lastItem = i
lenOverall += len(fields[f])
# If its still too large, send the 'raw' list as a file.
if lastItem + 1 < len(lst):
fields.append(f'Showing {lastItem+1} items.')
raw = '\r\n'.join(lst) if not raw_override else raw_override
file = discord.File(fp=io.BytesIO(str.encode(raw)), filename='list.txt')
else:
file = None
# Create the embed object (finally)
embed = discord.Embed(title=title, description=description)
if footer: embed.set_footer(text=footer)
for field in fields:
embed.add_field(name='\uFEFF', value=field, inline=False) # \uFEFF = ZERO WIDTH NO-BREAK SPACE
message = await ctx.send(embed=embed, file=file)
# Update the message embed with the file url
if file:
url = message.attachments[0].url
newValue = fields[len(fields)-1] + f' [See all {len(lst)}.]({url})'
embed.remove_field(len(fields)-1)
embed.add_field(name='\uFEFF', value=newValue, inline=False)
return await message.edit(embed=embed)
else:
return message