mirror of
https://github.com/miaowware/qrm2.git
synced 2024-10-31 14:27:11 -04:00
Normalised string quote type
- "" instead of '', except for dictionary lookups in f-strings Element of #142 New year lint removal
This commit is contained in:
parent
29e75c38e1
commit
29d0440d3d
38
common.py
38
common.py
@ -34,24 +34,24 @@ colours = SimpleNamespace(good=0x43B581,
|
||||
neutral=0x7289DA,
|
||||
bad=0xF04747)
|
||||
# meow
|
||||
cat = SimpleNamespace(lookup='Information Lookup',
|
||||
fun='Fun',
|
||||
maps='Mapping',
|
||||
ref='Reference',
|
||||
study='Exam Study',
|
||||
weather='Land and Space Weather',
|
||||
admin='Bot Control')
|
||||
cat = SimpleNamespace(lookup="Information Lookup",
|
||||
fun="Fun",
|
||||
maps="Mapping",
|
||||
ref="Reference",
|
||||
study="Exam Study",
|
||||
weather="Land and Space Weather",
|
||||
admin="Bot Control")
|
||||
|
||||
emojis = SimpleNamespace(check_mark='✅',
|
||||
x='❌',
|
||||
warning='⚠️',
|
||||
question='❓',
|
||||
no_entry='⛔',
|
||||
bangbang='‼️',
|
||||
a='🇦',
|
||||
b='🇧',
|
||||
c='🇨',
|
||||
d='🇩')
|
||||
emojis = SimpleNamespace(check_mark="✅",
|
||||
x="❌",
|
||||
warning="⚠️",
|
||||
question="❓",
|
||||
no_entry="⛔",
|
||||
bangbang="‼️",
|
||||
a="🇦",
|
||||
b="🇧",
|
||||
c="🇨",
|
||||
d="🇩")
|
||||
|
||||
paths = SimpleNamespace(data=Path("./data/"),
|
||||
resources=Path("./resources/"),
|
||||
@ -117,7 +117,7 @@ class GlobalChannelConverter(commands.IDConverter):
|
||||
async def convert(self, ctx: commands.Context, argument: str):
|
||||
bot = ctx.bot
|
||||
guild = ctx.guild
|
||||
match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument)
|
||||
match = self._get_id_match(argument) or re.match(r"<#([0-9]+)>$", argument)
|
||||
result = None
|
||||
if match is None:
|
||||
# not a mention/ID
|
||||
@ -150,7 +150,7 @@ def error_embed_factory(ctx: commands.Context, exception: Exception, debug_mode:
|
||||
fmtd_ex = traceback.format_exception_only(exception.__class__, exception)
|
||||
embed = embed_factory(ctx)
|
||||
embed.title = "⚠️ Error"
|
||||
embed.description = "```\n" + '\n'.join(fmtd_ex) + "```"
|
||||
embed.description = "```\n" + "\n".join(fmtd_ex) + "```"
|
||||
embed.colour = colours.bad
|
||||
return embed
|
||||
|
||||
|
156
exts/ae7q.py
156
exts/ae7q.py
@ -29,16 +29,16 @@ class AE7QCog(commands.Cog):
|
||||
|
||||
@commands.group(name="ae7q", aliases=["ae"], category=cmn.cat.lookup)
|
||||
async def _ae7q_lookup(self, ctx: commands.Context):
|
||||
'''Look up a callsign, FRN, or Licensee ID on [ae7q.com](http://ae7q.com/).'''
|
||||
"""Look up a callsign, FRN, or Licensee ID on [ae7q.com](http://ae7q.com/)."""
|
||||
if ctx.invoked_subcommand is None:
|
||||
await ctx.send_help(ctx.command)
|
||||
|
||||
@_ae7q_lookup.command(name="call", aliases=["c"], category=cmn.cat.lookup)
|
||||
async def _ae7q_call(self, ctx: commands.Context, callsign: str):
|
||||
'''Look up the history of a callsign on [ae7q.com](http://ae7q.com/).'''
|
||||
"""Look up the history of a callsign on [ae7q.com](http://ae7q.com/)."""
|
||||
with ctx.typing():
|
||||
callsign = callsign.upper()
|
||||
desc = ''
|
||||
desc = ""
|
||||
base_url = "http://ae7q.com/query/data/CallHistory.php?CALL="
|
||||
embed = cmn.embed_factory(ctx)
|
||||
|
||||
@ -56,20 +56,20 @@ class AE7QCog(commands.Cog):
|
||||
if len(table[0]) == 1:
|
||||
for row in table:
|
||||
desc += " ".join(row.getText().split())
|
||||
desc += '\n'
|
||||
desc = desc.replace(callsign, f'`{callsign}`')
|
||||
desc += "\n"
|
||||
desc = desc.replace(callsign, f"`{callsign}`")
|
||||
table = tables[1]
|
||||
|
||||
table_headers = table[0].find_all("th")
|
||||
first_header = ''.join(table_headers[0].strings) if len(table_headers) > 0 else None
|
||||
first_header = "".join(table_headers[0].strings) if len(table_headers) > 0 else None
|
||||
|
||||
# catch if the wrong table was selected
|
||||
if first_header is None or first_header != 'Entity Name':
|
||||
if first_header is None or first_header != "Entity Name":
|
||||
embed.title = f"AE7Q History for {callsign}"
|
||||
embed.colour = cmn.colours.bad
|
||||
embed.url = base_url + callsign
|
||||
embed.description = desc
|
||||
embed.description += f'\nNo records found for `{callsign}`'
|
||||
embed.description += f"\nNo records found for `{callsign}`"
|
||||
await ctx.send(embed=embed)
|
||||
return
|
||||
|
||||
@ -82,18 +82,18 @@ class AE7QCog(commands.Cog):
|
||||
|
||||
# add the first three rows of the table to the embed
|
||||
for row in table[0:3]:
|
||||
header = f'**{row[0]}** ({row[1]})' # **Name** (Applicant Type)
|
||||
body = (f'Class: *{row[2]}*\n'
|
||||
f'Region: *{row[3]}*\n'
|
||||
f'Status: *{row[4]}*\n'
|
||||
f'Granted: *{row[5]}*\n'
|
||||
f'Effective: *{row[6]}*\n'
|
||||
f'Cancelled: *{row[7]}*\n'
|
||||
f'Expires: *{row[8]}*')
|
||||
header = f"**{row[0]}** ({row[1]})" # **Name** (Applicant Type)
|
||||
body = (f"Class: *{row[2]}*\n"
|
||||
f"Region: *{row[3]}*\n"
|
||||
f"Status: *{row[4]}*\n"
|
||||
f"Granted: *{row[5]}*\n"
|
||||
f"Effective: *{row[6]}*\n"
|
||||
f"Cancelled: *{row[7]}*\n"
|
||||
f"Expires: *{row[8]}*")
|
||||
embed.add_field(name=header, value=body, inline=False)
|
||||
|
||||
if len(table) > 3:
|
||||
desc += f'\nRecords 1 to 3 of {len(table)}. See ae7q.com for more...'
|
||||
desc += f"\nRecords 1 to 3 of {len(table)}. See ae7q.com for more..."
|
||||
|
||||
embed.description = desc
|
||||
|
||||
@ -101,10 +101,10 @@ class AE7QCog(commands.Cog):
|
||||
|
||||
@_ae7q_lookup.command(name="trustee", aliases=["t"], category=cmn.cat.lookup)
|
||||
async def _ae7q_trustee(self, ctx: commands.Context, callsign: str):
|
||||
'''Look up the licenses for which a licensee is trustee on [ae7q.com](http://ae7q.com/).'''
|
||||
"""Look up the licenses for which a licensee is trustee on [ae7q.com](http://ae7q.com/)."""
|
||||
with ctx.typing():
|
||||
callsign = callsign.upper()
|
||||
desc = ''
|
||||
desc = ""
|
||||
base_url = "http://ae7q.com/query/data/CallHistory.php?CALL="
|
||||
embed = cmn.embed_factory(ctx)
|
||||
|
||||
@ -123,12 +123,12 @@ class AE7QCog(commands.Cog):
|
||||
embed.colour = cmn.colours.bad
|
||||
embed.url = base_url + callsign
|
||||
embed.description = desc
|
||||
embed.description += f'\nNo records found for `{callsign}`'
|
||||
embed.description += f"\nNo records found for `{callsign}`"
|
||||
await ctx.send(embed=embed)
|
||||
return
|
||||
|
||||
table_headers = table[0].find_all("th")
|
||||
first_header = ''.join(table_headers[0].strings) if len(table_headers) > 0 else None
|
||||
first_header = "".join(table_headers[0].strings) if len(table_headers) > 0 else None
|
||||
|
||||
# catch if the wrong table was selected
|
||||
if first_header is None or not first_header.startswith("With"):
|
||||
@ -136,7 +136,7 @@ class AE7QCog(commands.Cog):
|
||||
embed.colour = cmn.colours.bad
|
||||
embed.url = base_url + callsign
|
||||
embed.description = desc
|
||||
embed.description += f'\nNo records found for `{callsign}`'
|
||||
embed.description += f"\nNo records found for `{callsign}`"
|
||||
await ctx.send(embed=embed)
|
||||
return
|
||||
|
||||
@ -149,18 +149,18 @@ class AE7QCog(commands.Cog):
|
||||
|
||||
# add the first three rows of the table to the embed
|
||||
for row in table[0:3]:
|
||||
header = f'**{row[0]}** ({row[3]})' # **Name** (Applicant Type)
|
||||
body = (f'Name: *{row[2]}*\n'
|
||||
f'Region: *{row[1]}*\n'
|
||||
f'Status: *{row[4]}*\n'
|
||||
f'Granted: *{row[5]}*\n'
|
||||
f'Effective: *{row[6]}*\n'
|
||||
f'Cancelled: *{row[7]}*\n'
|
||||
f'Expires: *{row[8]}*')
|
||||
header = f"**{row[0]}** ({row[3]})" # **Name** (Applicant Type)
|
||||
body = (f"Name: *{row[2]}*\n"
|
||||
f"Region: *{row[1]}*\n"
|
||||
f"Status: *{row[4]}*\n"
|
||||
f"Granted: *{row[5]}*\n"
|
||||
f"Effective: *{row[6]}*\n"
|
||||
f"Cancelled: *{row[7]}*\n"
|
||||
f"Expires: *{row[8]}*")
|
||||
embed.add_field(name=header, value=body, inline=False)
|
||||
|
||||
if len(table) > 3:
|
||||
desc += f'\nRecords 1 to 3 of {len(table)}. See ae7q.com for more...'
|
||||
desc += f"\nRecords 1 to 3 of {len(table)}. See ae7q.com for more..."
|
||||
|
||||
embed.description = desc
|
||||
|
||||
@ -168,11 +168,11 @@ class AE7QCog(commands.Cog):
|
||||
|
||||
@_ae7q_lookup.command(name="applications", aliases=["a"], category=cmn.cat.lookup)
|
||||
async def _ae7q_applications(self, ctx: commands.Context, callsign: str):
|
||||
'''Look up the application history for a callsign on [ae7q.com](http://ae7q.com/).'''
|
||||
"""Look up the application history for a callsign on [ae7q.com](http://ae7q.com/)."""
|
||||
"""
|
||||
with ctx.typing():
|
||||
callsign = callsign.upper()
|
||||
desc = ''
|
||||
desc = ""
|
||||
base_url = "http://ae7q.com/query/data/CallHistory.php?CALL="
|
||||
embed = cmn.embed_factory(ctx)
|
||||
|
||||
@ -190,14 +190,14 @@ class AE7QCog(commands.Cog):
|
||||
if len(table[0]) == 1:
|
||||
for row in table:
|
||||
desc += " ".join(row.getText().split())
|
||||
desc += '\n'
|
||||
desc = desc.replace(callsign, f'`{callsign}`')
|
||||
desc += "\n"
|
||||
desc = desc.replace(callsign, f"`{callsign}`")
|
||||
|
||||
# select the last table to get applications
|
||||
table = tables[-1]
|
||||
|
||||
table_headers = table[0].find_all("th")
|
||||
first_header = ''.join(table_headers[0].strings) if len(table_headers) > 0 else None
|
||||
first_header = "".join(table_headers[0].strings) if len(table_headers) > 0 else None
|
||||
|
||||
# catch if the wrong table was selected
|
||||
if first_header is None or not first_header.startswith("Receipt"):
|
||||
@ -205,7 +205,7 @@ class AE7QCog(commands.Cog):
|
||||
embed.colour = cmn.colours.bad
|
||||
embed.url = base_url + callsign
|
||||
embed.description = desc
|
||||
embed.description += f'\nNo records found for `{callsign}`'
|
||||
embed.description += f"\nNo records found for `{callsign}`"
|
||||
await ctx.send(embed=embed)
|
||||
return
|
||||
|
||||
@ -218,16 +218,16 @@ class AE7QCog(commands.Cog):
|
||||
|
||||
# add the first three rows of the table to the embed
|
||||
for row in table[0:3]:
|
||||
header = f'**{row[1]}** ({row[3]})' # **Name** (Callsign)
|
||||
body = (f'Received: *{row[0]}*\n'
|
||||
f'Region: *{row[2]}*\n'
|
||||
f'Purpose: *{row[5]}*\n'
|
||||
f'Last Action: *{row[7]}*\n'
|
||||
f'Application Status: *{row[8]}*\n')
|
||||
header = f"**{row[1]}** ({row[3]})" # **Name** (Callsign)
|
||||
body = (f"Received: *{row[0]}*\n"
|
||||
f"Region: *{row[2]}*\n"
|
||||
f"Purpose: *{row[5]}*\n"
|
||||
f"Last Action: *{row[7]}*\n"
|
||||
f"Application Status: *{row[8]}*\n")
|
||||
embed.add_field(name=header, value=body, inline=False)
|
||||
|
||||
if len(table) > 3:
|
||||
desc += f'\nRecords 1 to 3 of {len(table)}. See ae7q.com for more...'
|
||||
desc += f"\nRecords 1 to 3 of {len(table)}. See ae7q.com for more..."
|
||||
|
||||
embed.description = desc
|
||||
|
||||
@ -238,7 +238,7 @@ class AE7QCog(commands.Cog):
|
||||
|
||||
@_ae7q_lookup.command(name="frn", aliases=["f"], category=cmn.cat.lookup)
|
||||
async def _ae7q_frn(self, ctx: commands.Context, frn: str):
|
||||
'''Look up the history of an FRN on [ae7q.com](http://ae7q.com/).'''
|
||||
"""Look up the history of an FRN on [ae7q.com](http://ae7q.com/)."""
|
||||
"""
|
||||
NOTES:
|
||||
- 2 tables: callsign history and application history
|
||||
@ -260,21 +260,21 @@ class AE7QCog(commands.Cog):
|
||||
embed.title = f"AE7Q History for FRN {frn}"
|
||||
embed.colour = cmn.colours.bad
|
||||
embed.url = base_url + frn
|
||||
embed.description = f'No records found for FRN `{frn}`'
|
||||
embed.description = f"No records found for FRN `{frn}`"
|
||||
await ctx.send(embed=embed)
|
||||
return
|
||||
|
||||
table = tables[0]
|
||||
|
||||
table_headers = table[0].find_all("th")
|
||||
first_header = ''.join(table_headers[0].strings) if len(table_headers) > 0 else None
|
||||
first_header = "".join(table_headers[0].strings) if len(table_headers) > 0 else None
|
||||
|
||||
# catch if the wrong table was selected
|
||||
if first_header is None or not first_header.startswith('With Licensee'):
|
||||
if first_header is None or not first_header.startswith("With Licensee"):
|
||||
embed.title = f"AE7Q History for FRN {frn}"
|
||||
embed.colour = cmn.colours.bad
|
||||
embed.url = base_url + frn
|
||||
embed.description = f'No records found for FRN `{frn}`'
|
||||
embed.description = f"No records found for FRN `{frn}`"
|
||||
await ctx.send(embed=embed)
|
||||
return
|
||||
|
||||
@ -287,25 +287,25 @@ class AE7QCog(commands.Cog):
|
||||
|
||||
# add the first three rows of the table to the embed
|
||||
for row in table[0:3]:
|
||||
header = f'**{row[0]}** ({row[3]})' # **Callsign** (Applicant Type)
|
||||
body = (f'Name: *{row[2]}*\n'
|
||||
f'Class: *{row[4]}*\n'
|
||||
f'Region: *{row[1]}*\n'
|
||||
f'Status: *{row[5]}*\n'
|
||||
f'Granted: *{row[6]}*\n'
|
||||
f'Effective: *{row[7]}*\n'
|
||||
f'Cancelled: *{row[8]}*\n'
|
||||
f'Expires: *{row[9]}*')
|
||||
header = f"**{row[0]}** ({row[3]})" # **Callsign** (Applicant Type)
|
||||
body = (f"Name: *{row[2]}*\n"
|
||||
f"Class: *{row[4]}*\n"
|
||||
f"Region: *{row[1]}*\n"
|
||||
f"Status: *{row[5]}*\n"
|
||||
f"Granted: *{row[6]}*\n"
|
||||
f"Effective: *{row[7]}*\n"
|
||||
f"Cancelled: *{row[8]}*\n"
|
||||
f"Expires: *{row[9]}*")
|
||||
embed.add_field(name=header, value=body, inline=False)
|
||||
|
||||
if len(table) > 3:
|
||||
embed.description = f'Records 1 to 3 of {len(table)}. See ae7q.com for more...'
|
||||
embed.description = f"Records 1 to 3 of {len(table)}. See ae7q.com for more..."
|
||||
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@_ae7q_lookup.command(name="licensee", aliases=["l"], category=cmn.cat.lookup)
|
||||
async def _ae7q_licensee(self, ctx: commands.Context, licensee_id: str):
|
||||
'''Look up the history of a licensee ID on [ae7q.com](http://ae7q.com/).'''
|
||||
"""Look up the history of a licensee ID on [ae7q.com](http://ae7q.com/)."""
|
||||
with ctx.typing():
|
||||
licensee_id = licensee_id.upper()
|
||||
base_url = "http://ae7q.com/query/data/LicenseeIdHistory.php?ID="
|
||||
@ -323,21 +323,21 @@ class AE7QCog(commands.Cog):
|
||||
embed.title = f"AE7Q History for Licensee {licensee_id}"
|
||||
embed.colour = cmn.colours.bad
|
||||
embed.url = base_url + licensee_id
|
||||
embed.description = f'No records found for Licensee `{licensee_id}`'
|
||||
embed.description = f"No records found for Licensee `{licensee_id}`"
|
||||
await ctx.send(embed=embed)
|
||||
return
|
||||
|
||||
table = tables[0]
|
||||
|
||||
table_headers = table[0].find_all("th")
|
||||
first_header = ''.join(table_headers[0].strings) if len(table_headers) > 0 else None
|
||||
first_header = "".join(table_headers[0].strings) if len(table_headers) > 0 else None
|
||||
|
||||
# catch if the wrong table was selected
|
||||
if first_header is None or not first_header.startswith('With FCC'):
|
||||
if first_header is None or not first_header.startswith("With FCC"):
|
||||
embed.title = f"AE7Q History for Licensee {licensee_id}"
|
||||
embed.colour = cmn.colours.bad
|
||||
embed.url = base_url + licensee_id
|
||||
embed.description = f'No records found for Licensee `{licensee_id}`'
|
||||
embed.description = f"No records found for Licensee `{licensee_id}`"
|
||||
await ctx.send(embed=embed)
|
||||
return
|
||||
|
||||
@ -350,19 +350,19 @@ class AE7QCog(commands.Cog):
|
||||
|
||||
# add the first three rows of the table to the embed
|
||||
for row in table[0:3]:
|
||||
header = f'**{row[0]}** ({row[3]})' # **Callsign** (Applicant Type)
|
||||
body = (f'Name: *{row[2]}*\n'
|
||||
f'Class: *{row[4]}*\n'
|
||||
f'Region: *{row[1]}*\n'
|
||||
f'Status: *{row[5]}*\n'
|
||||
f'Granted: *{row[6]}*\n'
|
||||
f'Effective: *{row[7]}*\n'
|
||||
f'Cancelled: *{row[8]}*\n'
|
||||
f'Expires: *{row[9]}*')
|
||||
header = f"**{row[0]}** ({row[3]})" # **Callsign** (Applicant Type)
|
||||
body = (f"Name: *{row[2]}*\n"
|
||||
f"Class: *{row[4]}*\n"
|
||||
f"Region: *{row[1]}*\n"
|
||||
f"Status: *{row[5]}*\n"
|
||||
f"Granted: *{row[6]}*\n"
|
||||
f"Effective: *{row[7]}*\n"
|
||||
f"Cancelled: *{row[8]}*\n"
|
||||
f"Expires: *{row[9]}*")
|
||||
embed.add_field(name=header, value=body, inline=False)
|
||||
|
||||
if len(table) > 3:
|
||||
embed.description = f'Records 1 to 3 of {len(table)}. See ae7q.com for more...'
|
||||
embed.description = f"Records 1 to 3 of {len(table)}. See ae7q.com for more..."
|
||||
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@ -372,13 +372,13 @@ async def process_table(table: list):
|
||||
table_contents = []
|
||||
for tr in table:
|
||||
row = []
|
||||
for td in tr.find_all('td'):
|
||||
for td in tr.find_all("td"):
|
||||
cell_val = td.getText().strip()
|
||||
row.append(cell_val if cell_val else '-')
|
||||
row.append(cell_val if cell_val else "-")
|
||||
|
||||
# take care of columns that span multiple rows by copying the contents rightward
|
||||
if 'colspan' in td.attrs and int(td.attrs['colspan']) > 1:
|
||||
for i in range(int(td.attrs['colspan']) - 1):
|
||||
if "colspan" in td.attrs and int(td.attrs["colspan"]) > 1:
|
||||
for i in range(int(td.attrs["colspan"]) - 1):
|
||||
row.append(row[-1])
|
||||
|
||||
# get rid of ditto marks by copying the contents from the previous row
|
||||
|
86
exts/base.py
86
exts/base.py
@ -24,7 +24,7 @@ import data.options as opt
|
||||
|
||||
class QrmHelpCommand(commands.HelpCommand):
|
||||
def __init__(self):
|
||||
super().__init__(command_attrs={'help': 'Shows help about qrm or a command', 'aliases': ['h']})
|
||||
super().__init__(command_attrs={"help": "Shows help about qrm or a command", "aliases": ["h"]})
|
||||
self.verify_checks = True
|
||||
|
||||
async def get_bot_mapping(self):
|
||||
@ -32,7 +32,7 @@ class QrmHelpCommand(commands.HelpCommand):
|
||||
mapping = {}
|
||||
|
||||
for cmd in await self.filter_commands(bot.commands, sort=True):
|
||||
cat = cmd.__original_kwargs__.get('category', None)
|
||||
cat = cmd.__original_kwargs__.get("category", None)
|
||||
if cat in mapping:
|
||||
mapping[cat].append(cmd)
|
||||
else:
|
||||
@ -42,27 +42,27 @@ class QrmHelpCommand(commands.HelpCommand):
|
||||
async def get_command_signature(self, command):
|
||||
parent = command.full_parent_name
|
||||
if command.aliases != []:
|
||||
aliases = ', '.join(command.aliases)
|
||||
aliases = ", ".join(command.aliases)
|
||||
fmt = command.name
|
||||
if parent:
|
||||
fmt = f'{parent} {fmt}'
|
||||
fmt = f"{parent} {fmt}"
|
||||
alias = fmt
|
||||
return f'{opt.prefix}{alias} {command.signature}\n *Aliases:* {aliases}'
|
||||
alias = command.name if not parent else f'{parent} {command.name}'
|
||||
return f'{opt.prefix}{alias} {command.signature}'
|
||||
return f"{opt.prefix}{alias} {command.signature}\n *Aliases:* {aliases}"
|
||||
alias = command.name if not parent else f"{parent} {command.name}"
|
||||
return f"{opt.prefix}{alias} {command.signature}"
|
||||
|
||||
async def send_error_message(self, error):
|
||||
embed = cmn.embed_factory(self.context)
|
||||
embed.title = 'qrm Help Error'
|
||||
embed.title = "qrm Help Error"
|
||||
embed.description = error
|
||||
embed.colour = cmn.colours.bad
|
||||
await self.context.send(embed=embed)
|
||||
|
||||
async def send_bot_help(self, mapping):
|
||||
embed = cmn.embed_factory(self.context)
|
||||
embed.title = 'qrm Help'
|
||||
embed.description = (f'For command-specific help and usage, use `{opt.prefix}help [command name]`'
|
||||
'. Many commands have shorter aliases.')
|
||||
embed.title = "qrm Help"
|
||||
embed.description = (f"For command-specific help and usage, use `{opt.prefix}help [command name]`."
|
||||
" Many commands have shorter aliases.")
|
||||
mapping = await mapping
|
||||
|
||||
for cat, cmds in mapping.items():
|
||||
@ -70,9 +70,9 @@ class QrmHelpCommand(commands.HelpCommand):
|
||||
continue
|
||||
names = sorted([cmd.name for cmd in cmds])
|
||||
if cat is not None:
|
||||
embed.add_field(name=cat.title(), value=', '.join(names), inline=False)
|
||||
embed.add_field(name=cat.title(), value=", ".join(names), inline=False)
|
||||
else:
|
||||
embed.add_field(name='Other', value=', '.join(names), inline=False)
|
||||
embed.add_field(name="Other", value=", ".join(names), inline=False)
|
||||
await self.context.send(embed=embed)
|
||||
|
||||
async def send_command_help(self, command):
|
||||
@ -112,27 +112,27 @@ class BaseCog(commands.Cog):
|
||||
|
||||
embed.add_field(name="Authors", value=", ".join(info.authors))
|
||||
embed.add_field(name="License", value=info.license)
|
||||
embed.add_field(name="Version", value=f'v{info.release}')
|
||||
embed.add_field(name="Version", value=f"v{info.release}")
|
||||
embed.add_field(name="Contributing", value=info.contributing, inline=False)
|
||||
embed.add_field(name="Official Server", value=info.bot_server, inline=False)
|
||||
embed.set_thumbnail(url=str(self.bot.user.avatar_url))
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.command(name="ping", aliases=['beep'])
|
||||
@commands.command(name="ping", aliases=["beep"])
|
||||
async def _ping(self, ctx: commands.Context):
|
||||
"""Show the current latency to the discord endpoint."""
|
||||
embed = cmn.embed_factory(ctx)
|
||||
content = ''
|
||||
content = ""
|
||||
if ctx.invoked_with == "beep":
|
||||
embed.title = "**Boop!**"
|
||||
else:
|
||||
content = ctx.message.author.mention if random.random() < 0.05 else ''
|
||||
content = ctx.message.author.mention if random.random() < 0.05 else ""
|
||||
embed.title = "🏓 **Pong!**"
|
||||
embed.description = f'Current ping is {self.bot.latency*1000:.1f} ms'
|
||||
embed.description = f"Current ping is {self.bot.latency*1000:.1f} ms"
|
||||
await ctx.send(content, embed=embed)
|
||||
|
||||
@commands.command(name="changelog", aliases=["clog"])
|
||||
async def _changelog(self, ctx: commands.Context, version: str = 'latest'):
|
||||
async def _changelog(self, ctx: commands.Context, version: str = "latest"):
|
||||
"""Show what has changed in a bot version."""
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = "qrm Changelog"
|
||||
@ -144,25 +144,25 @@ class BaseCog(commands.Cog):
|
||||
|
||||
version = version.lower()
|
||||
|
||||
if version == 'latest':
|
||||
if version == "latest":
|
||||
version = info.release
|
||||
if version == 'unreleased':
|
||||
version = 'Unreleased'
|
||||
if version == "unreleased":
|
||||
version = "Unreleased"
|
||||
|
||||
try:
|
||||
log = changelog[version]
|
||||
except KeyError:
|
||||
embed.title += ": Version Not Found"
|
||||
embed.description += '\n\n**Valid versions:** latest, '
|
||||
embed.description += ', '.join(vers)
|
||||
embed.description += "\n\n**Valid versions:** latest, "
|
||||
embed.description += ", ".join(vers)
|
||||
embed.colour = cmn.colours.bad
|
||||
await ctx.send(embed=embed)
|
||||
return
|
||||
|
||||
if 'date' in log:
|
||||
embed.description += f'\n\n**v{version}** ({log["date"]})'
|
||||
if "date" in log:
|
||||
embed.description += f"\n\n**v{version}** ({log['date']})"
|
||||
else:
|
||||
embed.description += f'\n\n**v{version}**'
|
||||
embed.description += f"\n\n**v{version}**"
|
||||
embed = await format_changelog(log, embed)
|
||||
|
||||
await ctx.send(embed=embed)
|
||||
@ -190,36 +190,36 @@ class BaseCog(commands.Cog):
|
||||
|
||||
def parse_changelog():
|
||||
changelog = OrderedDict()
|
||||
ver = ''
|
||||
heading = ''
|
||||
ver = ""
|
||||
heading = ""
|
||||
|
||||
with open('CHANGELOG.md') as changelog_file:
|
||||
with open("CHANGELOG.md") as changelog_file:
|
||||
for line in changelog_file.readlines():
|
||||
if line.strip() == '':
|
||||
if line.strip() == "":
|
||||
continue
|
||||
if re.match(r'##[^#]', line):
|
||||
ver_match = re.match(r'\[(.+)\](?: - )?(\d{4}-\d{2}-\d{2})?', line.lstrip('#').strip())
|
||||
if re.match(r"##[^#]", line):
|
||||
ver_match = re.match(r"\[(.+)\](?: - )?(\d{4}-\d{2}-\d{2})?", line.lstrip("#").strip())
|
||||
if ver_match is not None:
|
||||
ver = ver_match.group(1)
|
||||
changelog[ver] = dict()
|
||||
if ver_match.group(2):
|
||||
changelog[ver]['date'] = ver_match.group(2)
|
||||
elif re.match(r'###[^#]', line):
|
||||
heading = line.lstrip('#').strip()
|
||||
changelog[ver]["date"] = ver_match.group(2)
|
||||
elif re.match(r"###[^#]", line):
|
||||
heading = line.lstrip("#").strip()
|
||||
changelog[ver][heading] = []
|
||||
elif ver != '' and heading != '':
|
||||
if line.startswith('-'):
|
||||
changelog[ver][heading].append(line.lstrip('-').strip())
|
||||
elif ver != "" and heading != "":
|
||||
if line.startswith("-"):
|
||||
changelog[ver][heading].append(line.lstrip("-").strip())
|
||||
return changelog
|
||||
|
||||
|
||||
async def format_changelog(log: dict, embed: discord.Embed):
|
||||
for header, lines in log.items():
|
||||
formatted = ''
|
||||
if header != 'date':
|
||||
formatted = ""
|
||||
if header != "date":
|
||||
for line in lines:
|
||||
formatted += f'- {line}\n'
|
||||
embed.add_field(name=f'**{header}**', value=formatted, inline=False)
|
||||
formatted += f"- {line}\n"
|
||||
embed.add_field(name=f"**{header}**", value=formatted, inline=False)
|
||||
return embed
|
||||
|
||||
|
||||
|
26
exts/fun.py
26
exts/fun.py
@ -17,37 +17,37 @@ import common as cmn
|
||||
class FunCog(commands.Cog):
|
||||
def __init__(self, bot: commands.Bot):
|
||||
self.bot = bot
|
||||
with open('resources/words') as words_file:
|
||||
with open("resources/words") as words_file:
|
||||
self.words = words_file.read().lower().splitlines()
|
||||
|
||||
@commands.command(name="xkcd", aliases=['x'], category=cmn.cat.fun)
|
||||
@commands.command(name="xkcd", aliases=["x"], category=cmn.cat.fun)
|
||||
async def _xkcd(self, ctx: commands.Context, number: str):
|
||||
'''Look up an xkcd by number.'''
|
||||
await ctx.send('http://xkcd.com/' + number)
|
||||
"""Look up an xkcd by number."""
|
||||
await ctx.send("http://xkcd.com/" + number)
|
||||
|
||||
@commands.command(name="tar", category=cmn.cat.fun)
|
||||
async def _tar(self, ctx: commands.Context):
|
||||
'''Returns an xkcd about tar.'''
|
||||
await ctx.send('http://xkcd.com/1168')
|
||||
"""Returns an xkcd about tar."""
|
||||
await ctx.send("http://xkcd.com/1168")
|
||||
|
||||
@commands.command(name="xd", hidden=True, category=cmn.cat.fun)
|
||||
async def _xd(self, ctx: commands.Context):
|
||||
'''ecks dee'''
|
||||
await ctx.send('ECKS DEE :smirk:')
|
||||
"""ecks dee"""
|
||||
await ctx.send("ECKS DEE :smirk:")
|
||||
|
||||
@commands.command(name="funetics", aliases=['fun'], category=cmn.cat.fun)
|
||||
@commands.command(name="funetics", aliases=["fun"], category=cmn.cat.fun)
|
||||
async def _funetics_lookup(self, ctx: commands.Context, *, msg: str):
|
||||
'''Get fun phonetics for a word or phrase.'''
|
||||
"""Get fun phonetics for a word or phrase."""
|
||||
with ctx.typing():
|
||||
result = ''
|
||||
result = ""
|
||||
for char in msg.lower():
|
||||
if char.isalpha():
|
||||
result += random.choice([word for word in self.words if word[0] == char])
|
||||
else:
|
||||
result += char
|
||||
result += ' '
|
||||
result += " "
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'Funetics for {msg}'
|
||||
embed.title = f"Funetics for {msg}"
|
||||
embed.description = result.title()
|
||||
embed.colour = cmn.colours.good
|
||||
await ctx.send(embed=embed)
|
||||
|
64
exts/grid.py
64
exts/grid.py
@ -20,27 +20,27 @@ class GridCog(commands.Cog):
|
||||
|
||||
@commands.command(name="grid", category=cmn.cat.maps)
|
||||
async def _grid_sq_lookup(self, ctx: commands.Context, lat: str, lon: str):
|
||||
'''Calculates the grid square for latitude and longitude coordinates,
|
||||
with negative being latitude South and longitude West.'''
|
||||
"""Calculates the grid square for latitude and longitude coordinates,
|
||||
with negative being latitude South and longitude West."""
|
||||
with ctx.typing():
|
||||
grid = "**"
|
||||
latf = float(lat) + 90
|
||||
lonf = float(lon) + 180
|
||||
if 0 <= latf <= 180 and 0 <= lonf <= 360:
|
||||
grid += chr(ord('A') + int(lonf / 20))
|
||||
grid += chr(ord('A') + int(latf / 10))
|
||||
grid += chr(ord('0') + int((lonf % 20)/2))
|
||||
grid += chr(ord('0') + int((latf % 10)/1))
|
||||
grid += chr(ord('a') + int((lonf - (int(lonf/2)*2)) / (5/60)))
|
||||
grid += chr(ord('a') + int((latf - (int(latf/1)*1)) / (2.5/60)))
|
||||
grid += chr(ord("A") + int(lonf / 20))
|
||||
grid += chr(ord("A") + int(latf / 10))
|
||||
grid += chr(ord("0") + int((lonf % 20)/2))
|
||||
grid += chr(ord("0") + int((latf % 10)/1))
|
||||
grid += chr(ord("a") + int((lonf - (int(lonf/2)*2)) / (5/60)))
|
||||
grid += chr(ord("a") + int((latf - (int(latf/1)*1)) / (2.5/60)))
|
||||
grid += "**"
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'Maidenhead Grid Locator for {float(lat):.6f}, {float(lon):.6f}'
|
||||
embed.title = f"Maidenhead Grid Locator for {float(lat):.6f}, {float(lon):.6f}"
|
||||
embed.description = grid
|
||||
embed.colour = cmn.colours.good
|
||||
else:
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'Error generating grid square for {lat}, {lon}.'
|
||||
embed.title = f"Error generating grid square for {lat}, {lon}."
|
||||
embed.description = ("Coordinates out of range.\n"
|
||||
"The valid ranges are:\n"
|
||||
"- Latitude: `-90` to `+90`\n"
|
||||
@ -48,29 +48,29 @@ with negative being latitude South and longitude West.'''
|
||||
embed.colour = cmn.colours.bad
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.command(name="ungrid", aliases=['loc'], category=cmn.cat.maps)
|
||||
@commands.command(name="ungrid", aliases=["loc"], category=cmn.cat.maps)
|
||||
async def _location_lookup(self, ctx: commands.Context, grid: str, grid2: str = None):
|
||||
'''Calculates the latitude and longitude for the center of a grid square.
|
||||
If two grid squares are given, the distance and azimuth between them is calculated.'''
|
||||
"""Calculates the latitude and longitude for the center of a grid square.
|
||||
If two grid squares are given, the distance and azimuth between them is calculated."""
|
||||
with ctx.typing():
|
||||
if grid2 is None or grid2 == '':
|
||||
if grid2 is None or grid2 == "":
|
||||
try:
|
||||
grid = grid.upper()
|
||||
loc = get_coords(grid)
|
||||
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'Latitude and Longitude for {grid}'
|
||||
embed.title = f"Latitude and Longitude for {grid}"
|
||||
embed.colour = cmn.colours.good
|
||||
|
||||
if len(grid) >= 6:
|
||||
embed.description = f'**{loc[0]:.5f}, {loc[1]:.5f}**'
|
||||
embed.url = f'https://www.openstreetmap.org/#map=13/{loc[0]:.5f}/{loc[1]:.5f}'
|
||||
embed.description = f"**{loc[0]:.5f}, {loc[1]:.5f}**"
|
||||
embed.url = f"https://www.openstreetmap.org/#map=13/{loc[0]:.5f}/{loc[1]:.5f}"
|
||||
else:
|
||||
embed.description = f'**{loc[0]:.1f}, {loc[1]:.1f}**'
|
||||
embed.url = f'https://www.openstreetmap.org/#map=10/{loc[0]:.1f}/{loc[1]:.1f}'
|
||||
embed.description = f"**{loc[0]:.1f}, {loc[1]:.1f}**"
|
||||
embed.url = f"https://www.openstreetmap.org/#map=10/{loc[0]:.1f}/{loc[1]:.1f}"
|
||||
except Exception as e:
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'Error generating latitude and longitude for grid {grid}.'
|
||||
embed.title = f"Error generating latitude and longitude for grid {grid}."
|
||||
embed.description = str(e)
|
||||
embed.colour = cmn.colours.bad
|
||||
else:
|
||||
@ -101,12 +101,12 @@ If two grid squares are given, the distance and azimuth between them is calculat
|
||||
bearing = (math.degrees(math.atan2(y_dist, x_dist)) + 360) % 360
|
||||
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'Great Circle Distance and Bearing from {grid} to {grid2}'
|
||||
embed.description = f'**Distance:** {d:.1f} km ({d_mi:.1f} mi)\n**Bearing:** {bearing:.1f}°'
|
||||
embed.title = f"Great Circle Distance and Bearing from {grid} to {grid2}"
|
||||
embed.description = f"**Distance:** {d:.1f} km ({d_mi:.1f} mi)\n**Bearing:** {bearing:.1f}°"
|
||||
embed.colour = cmn.colours.good
|
||||
except Exception as e:
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'Error generating great circle distance and bearing from {grid} and {grid2}.'
|
||||
embed.title = f"Error generating great circle distance and bearing from {grid} and {grid2}."
|
||||
embed.description = str(e)
|
||||
embed.colour = cmn.colours.bad
|
||||
await ctx.send(embed=embed)
|
||||
@ -114,23 +114,23 @@ If two grid squares are given, the distance and azimuth between them is calculat
|
||||
|
||||
def get_coords(grid: str):
|
||||
if len(grid) < 3:
|
||||
raise ValueError('The grid locator must be at least 4 characters long.')
|
||||
raise ValueError("The grid locator must be at least 4 characters long.")
|
||||
|
||||
if not grid[0:2].isalpha() or not grid[2:4].isdigit():
|
||||
if len(grid) <= 4:
|
||||
raise ValueError('The grid locator must be of the form AA##.')
|
||||
raise ValueError("The grid locator must be of the form AA##.")
|
||||
if len(grid) >= 6 and not grid[5:7].isalpha():
|
||||
raise ValueError('The grid locator must be of the form AA##AA.')
|
||||
raise ValueError("The grid locator must be of the form AA##AA.")
|
||||
|
||||
lon = ((ord(grid[0]) - ord('A')) * 20) - 180
|
||||
lat = ((ord(grid[1]) - ord('A')) * 10) - 90
|
||||
lon += ((ord(grid[2]) - ord('0')) * 2)
|
||||
lat += ((ord(grid[3]) - ord('0')) * 1)
|
||||
lon = ((ord(grid[0]) - ord("A")) * 20) - 180
|
||||
lat = ((ord(grid[1]) - ord("A")) * 10) - 90
|
||||
lon += ((ord(grid[2]) - ord("0")) * 2)
|
||||
lat += ((ord(grid[3]) - ord("0")) * 1)
|
||||
|
||||
if len(grid) >= 6:
|
||||
# have subsquares
|
||||
lon += ((ord(grid[4])) - ord('A')) * (5/60)
|
||||
lat += ((ord(grid[5])) - ord('A')) * (2.5/60)
|
||||
lon += ((ord(grid[4])) - ord("A")) * (5/60)
|
||||
lat += ((ord(grid[5])) - ord("A")) * (2.5/60)
|
||||
# move to center of subsquare
|
||||
lon += (2.5/60)
|
||||
lat += (1.25/60)
|
||||
|
30
exts/ham.py
30
exts/ham.py
@ -21,9 +21,9 @@ class HamCog(commands.Cog):
|
||||
def __init__(self, bot: commands.Bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command(name="qcode", aliases=['q'], category=cmn.cat.ref)
|
||||
@commands.command(name="qcode", aliases=["q"], category=cmn.cat.ref)
|
||||
async def _qcode_lookup(self, ctx: commands.Context, qcode: str):
|
||||
'''Look up a Q Code.'''
|
||||
"""Look up a Q Code."""
|
||||
with ctx.typing():
|
||||
qcode = qcode.upper()
|
||||
embed = cmn.embed_factory(ctx)
|
||||
@ -32,49 +32,49 @@ class HamCog(commands.Cog):
|
||||
embed.description = qcodes.qcodes[qcode]
|
||||
embed.colour = cmn.colours.good
|
||||
else:
|
||||
embed.title = f'Q Code {qcode} not found'
|
||||
embed.title = f"Q Code {qcode} not found"
|
||||
embed.colour = cmn.colours.bad
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.command(name="phonetics", aliases=['ph', 'phoneticize', 'phoneticise', 'phone'], category=cmn.cat.ref)
|
||||
@commands.command(name="phonetics", aliases=["ph", "phoneticize", "phoneticise", "phone"], category=cmn.cat.ref)
|
||||
async def _phonetics_lookup(self, ctx: commands.Context, *, msg: str):
|
||||
'''Get phonetics for a word or phrase.'''
|
||||
"""Get phonetics for a word or phrase."""
|
||||
with ctx.typing():
|
||||
result = ''
|
||||
result = ""
|
||||
for char in msg.lower():
|
||||
if char.isalpha():
|
||||
result += phonetics.phonetics[char]
|
||||
else:
|
||||
result += char
|
||||
result += ' '
|
||||
result += " "
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'Phonetics for {msg}'
|
||||
embed.title = f"Phonetics for {msg}"
|
||||
embed.description = result.title()
|
||||
embed.colour = cmn.colours.good
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.command(name="utc", aliases=['z'], category=cmn.cat.ref)
|
||||
@commands.command(name="utc", aliases=["z"], category=cmn.cat.ref)
|
||||
async def _utc_lookup(self, ctx: commands.Context):
|
||||
'''Gets the current time in UTC.'''
|
||||
"""Gets the current time in UTC."""
|
||||
with ctx.typing():
|
||||
now = datetime.utcnow()
|
||||
result = '**' + now.strftime('%Y-%m-%d %H:%M') + 'Z**'
|
||||
result = "**" + now.strftime("%Y-%m-%d %H:%M") + "Z**"
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = 'The current time is:'
|
||||
embed.title = "The current time is:"
|
||||
embed.description = result
|
||||
embed.colour = cmn.colours.good
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.command(name="prefixes", aliases=["vanity", "pfx", "vanities", "prefix"], category=cmn.cat.ref)
|
||||
async def _vanity_prefixes(self, ctx: commands.Context, country: str = None):
|
||||
'''Lists valid prefixes for countries.'''
|
||||
"""Lists valid prefixes for countries."""
|
||||
if country is None:
|
||||
await ctx.send_help(ctx.command)
|
||||
return
|
||||
embed = cmn.embed_factory(ctx)
|
||||
if country.lower() not in callsign_info.options:
|
||||
embed.title = f'{country} not found!',
|
||||
embed.description = f'Valid countries: {", ".join(callsign_info.options.keys())}',
|
||||
embed.title = f"{country} not found!",
|
||||
embed.description = f"Valid countries: {', '.join(callsign_info.options.keys())}",
|
||||
embed.colour = cmn.colours.bad
|
||||
else:
|
||||
embed.title = callsign_info.options[country.lower()][0]
|
||||
|
@ -18,8 +18,8 @@ import common as cmn
|
||||
|
||||
|
||||
class ImageCog(commands.Cog):
|
||||
gl_url = ('http://www.fourmilab.ch/cgi-bin/uncgi/Earth?img=NOAAtopo.evif'
|
||||
'&imgsize=320&dynimg=y&opt=-p&lat=&lon=&alt=&tle=&date=0&utc=&jd=')
|
||||
gl_url = ("http://www.fourmilab.ch/cgi-bin/uncgi/Earth?img=NOAAtopo.evif"
|
||||
"&imgsize=320&dynimg=y&opt=-p&lat=&lon=&alt=&tle=&date=0&utc=&jd=")
|
||||
|
||||
def __init__(self, bot: commands.Bot):
|
||||
self.bot = bot
|
||||
@ -27,17 +27,17 @@ class ImageCog(commands.Cog):
|
||||
self.maps = cmn.ImagesGroup(cmn.paths.maps / "meta.json")
|
||||
self.session = aiohttp.ClientSession(connector=bot.qrm.connector)
|
||||
|
||||
@commands.command(name="bandplan", aliases=['plan', 'bands'], category=cmn.cat.ref)
|
||||
async def _bandplan(self, ctx: commands.Context, region: str = ''):
|
||||
'''Posts an image of Frequency Allocations.'''
|
||||
@commands.command(name="bandplan", aliases=["plan", "bands"], category=cmn.cat.ref)
|
||||
async def _bandplan(self, ctx: commands.Context, region: str = ""):
|
||||
"""Posts an image of Frequency Allocations."""
|
||||
async with ctx.typing():
|
||||
arg = region.lower()
|
||||
embed = cmn.embed_factory(ctx)
|
||||
if arg not in self.bandcharts:
|
||||
desc = 'Possible arguments are:\n'
|
||||
desc = "Possible arguments are:\n"
|
||||
for key, img in self.bandcharts.items():
|
||||
desc += f'`{key}`: {img.name}{(" " + img.emoji if img.emoji else "")}\n'
|
||||
embed.title = f'Bandplan Not Found!'
|
||||
desc += f"`{key}`: {img.name}{(' ' + img.emoji if img.emoji else '')}\n"
|
||||
embed.title = f"Bandplan Not Found!"
|
||||
embed.description = desc
|
||||
embed.colour = cmn.colours.bad
|
||||
await ctx.send(embed=embed)
|
||||
@ -51,20 +51,20 @@ class ImageCog(commands.Cog):
|
||||
embed.add_field(name="Source", value=metadata.source)
|
||||
embed.title = metadata.long_name + (" " + metadata.emoji if metadata.emoji else "")
|
||||
embed.colour = cmn.colours.good
|
||||
embed.set_image(url='attachment://' + metadata.filename)
|
||||
embed.set_image(url="attachment://" + metadata.filename)
|
||||
await ctx.send(embed=embed, file=img)
|
||||
|
||||
@commands.command(name="map", category=cmn.cat.maps)
|
||||
async def _map(self, ctx: commands.Context, map_id: str = ''):
|
||||
'''Posts an image of a ham-relevant map.'''
|
||||
async def _map(self, ctx: commands.Context, map_id: str = ""):
|
||||
"""Posts an image of a ham-relevant map."""
|
||||
async with ctx.typing():
|
||||
arg = map_id.lower()
|
||||
embed = cmn.embed_factory(ctx)
|
||||
if arg not in self.maps:
|
||||
desc = 'Possible arguments are:\n'
|
||||
desc = "Possible arguments are:\n"
|
||||
for key, img in self.maps.items():
|
||||
desc += f'`{key}`: {img.name}{(" " + img.emoji if img.emoji else "")}\n'
|
||||
embed.title = 'Map Not Found!'
|
||||
desc += f"`{key}`: {img.name}{(' ' + img.emoji if img.emoji else '')}\n"
|
||||
embed.title = "Map Not Found!"
|
||||
embed.description = desc
|
||||
embed.colour = cmn.colours.bad
|
||||
await ctx.send(embed=embed)
|
||||
@ -78,22 +78,22 @@ class ImageCog(commands.Cog):
|
||||
embed.add_field(name="Source", value=metadata.source)
|
||||
embed.title = metadata.long_name + (" " + metadata.emoji if metadata.emoji else "")
|
||||
embed.colour = cmn.colours.good
|
||||
embed.set_image(url='attachment://' + metadata.filename)
|
||||
embed.set_image(url="attachment://" + metadata.filename)
|
||||
await ctx.send(embed=embed, file=img)
|
||||
|
||||
@commands.command(name="grayline", aliases=['greyline', 'grey', 'gray', 'gl'], category=cmn.cat.maps)
|
||||
@commands.command(name="grayline", aliases=["greyline", "grey", "gray", "gl"], category=cmn.cat.maps)
|
||||
async def _grayline(self, ctx: commands.Context):
|
||||
'''Posts a map of the current greyline, where HF propagation is the best.'''
|
||||
"""Posts a map of the current greyline, where HF propagation is the best."""
|
||||
async with ctx.typing():
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = 'Current Greyline Conditions'
|
||||
embed.title = "Current Greyline Conditions"
|
||||
embed.colour = cmn.colours.good
|
||||
async with self.session.get(self.gl_url) as resp:
|
||||
if resp.status != 200:
|
||||
raise cmn.BotHTTPError(resp)
|
||||
data = io.BytesIO(await resp.read())
|
||||
embed.set_image(url=f'attachment://greyline.jpg')
|
||||
await ctx.send(embed=embed, file=discord.File(data, 'greyline.jpg'))
|
||||
embed.set_image(url=f"attachment://greyline.jpg")
|
||||
await ctx.send(embed=embed, file=discord.File(data, "greyline.jpg"))
|
||||
|
||||
|
||||
def setup(bot: commands.Bot):
|
||||
|
@ -19,48 +19,48 @@ class LookupCog(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
try:
|
||||
self.cty = BigCty('./data/cty.json')
|
||||
self.cty = BigCty("./data/cty.json")
|
||||
except OSError:
|
||||
self.cty = BigCty()
|
||||
|
||||
# TODO: See #107
|
||||
# @commands.command(name="sat", category=cmn.cat.lookup)
|
||||
# async def _sat_lookup(self, ctx: commands.Context, sat_name: str, grid1: str, grid2: str = None):
|
||||
# '''Links to info about satellite passes on satmatch.com.'''
|
||||
# now = datetime.utcnow().strftime('%Y-%m-%d%%20%H:%M')
|
||||
# if grid2 is None or grid2 == '':
|
||||
# await ctx.send(f'http://www.satmatch.com/satellite/{sat_name}/obs1/{grid1}'
|
||||
# f'?search_start_time={now}&duration_hrs=24')
|
||||
# """Links to info about satellite passes on satmatch.com."""
|
||||
# now = datetime.utcnow().strftime("%Y-%m-%d%%20%H:%M")
|
||||
# if grid2 is None or grid2 == "":
|
||||
# await ctx.send(f"http://www.satmatch.com/satellite/{sat_name}/obs1/{grid1}"
|
||||
# f"?search_start_time={now}&duration_hrs=24")
|
||||
# else:
|
||||
# await ctx.send(f'http://www.satmatch.com/satellite/{sat_name}/obs1/{grid1}'
|
||||
# f'/obs2/{grid2}?search_start_time={now}&duration_hrs=24')
|
||||
# await ctx.send(f"http://www.satmatch.com/satellite/{sat_name}/obs1/{grid1}"
|
||||
# f"/obs2/{grid2}?search_start_time={now}&duration_hrs=24")
|
||||
|
||||
@commands.command(name="dxcc", aliases=['dx'], category=cmn.cat.lookup)
|
||||
@commands.command(name="dxcc", aliases=["dx"], category=cmn.cat.lookup)
|
||||
async def _dxcc_lookup(self, ctx: commands.Context, query: str):
|
||||
'''Gets info about a DXCC prefix.'''
|
||||
"""Gets info about a DXCC prefix."""
|
||||
with ctx.typing():
|
||||
query = query.upper()
|
||||
full_query = query
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'DXCC Info for '
|
||||
embed.description = f'*Last Updated: {self.cty.formatted_version}*'
|
||||
embed.title = f"DXCC Info for "
|
||||
embed.description = f"*Last Updated: {self.cty.formatted_version}*"
|
||||
embed.colour = cmn.colours.bad
|
||||
while query:
|
||||
if query in self.cty.keys():
|
||||
data = self.cty[query]
|
||||
embed.add_field(name="Entity", value=data['entity'])
|
||||
embed.add_field(name="CQ Zone", value=data['cq'])
|
||||
embed.add_field(name="ITU Zone", value=data['itu'])
|
||||
embed.add_field(name="Continent", value=data['continent'])
|
||||
embed.add_field(name="Entity", value=data["entity"])
|
||||
embed.add_field(name="CQ Zone", value=data["cq"])
|
||||
embed.add_field(name="ITU Zone", value=data["itu"])
|
||||
embed.add_field(name="Continent", value=data["continent"])
|
||||
embed.add_field(name="Time Zone",
|
||||
value=f'+{data["tz"]}' if data['tz'] > 0 else str(data['tz']))
|
||||
value=f"+{data['tz']}" if data["tz"] > 0 else str(data["tz"]))
|
||||
embed.title += query
|
||||
embed.colour = cmn.colours.good
|
||||
break
|
||||
else:
|
||||
query = query[:-1]
|
||||
else:
|
||||
embed.title += full_query + ' not found'
|
||||
embed.title += full_query + " not found"
|
||||
embed.colour = cmn.colours.bad
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
|
@ -17,63 +17,63 @@ class MorseCog(commands.Cog):
|
||||
def __init__(self, bot: commands.Bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command(name="morse", aliases=['cw'], category=cmn.cat.ref)
|
||||
@commands.command(name="morse", aliases=["cw"], category=cmn.cat.ref)
|
||||
async def _morse(self, ctx: commands.Context, *, msg: str):
|
||||
"""Converts ASCII to international morse code."""
|
||||
with ctx.typing():
|
||||
result = ''
|
||||
result = ""
|
||||
for char in msg.upper():
|
||||
try:
|
||||
result += morse.morse[char]
|
||||
except KeyError:
|
||||
result += '<?>'
|
||||
result += ' '
|
||||
result += "<?>"
|
||||
result += " "
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'Morse Code for {msg}'
|
||||
embed.description = '**' + result + '**'
|
||||
embed.title = f"Morse Code for {msg}"
|
||||
embed.description = "**" + result + "**"
|
||||
embed.colour = cmn.colours.good
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.command(name="unmorse", aliases=['demorse', 'uncw', 'decw'], category=cmn.cat.ref)
|
||||
@commands.command(name="unmorse", aliases=["demorse", "uncw", "decw"], category=cmn.cat.ref)
|
||||
async def _unmorse(self, ctx: commands.Context, *, msg: str):
|
||||
'''Converts international morse code to ASCII.'''
|
||||
"""Converts international morse code to ASCII."""
|
||||
with ctx.typing():
|
||||
result = ''
|
||||
result = ""
|
||||
msg0 = msg
|
||||
msg = msg.split('/')
|
||||
msg = msg.split("/")
|
||||
msg = [m.split() for m in msg]
|
||||
for word in msg:
|
||||
for char in word:
|
||||
try:
|
||||
result += morse.ascii[char]
|
||||
except KeyError:
|
||||
result += '<?>'
|
||||
result += ' '
|
||||
result += "<?>"
|
||||
result += " "
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'ASCII for {msg0}'
|
||||
embed.title = f"ASCII for {msg0}"
|
||||
embed.description = result
|
||||
embed.colour = cmn.colours.good
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.command(name="cwweight", aliases=["weight", 'cww'], category=cmn.cat.ref)
|
||||
@commands.command(name="cwweight", aliases=["weight", "cww"], category=cmn.cat.ref)
|
||||
async def _weight(self, ctx: commands.Context, *, msg: str):
|
||||
'''Calculates the CW Weight of a callsign or message.'''
|
||||
"""Calculates the CW Weight of a callsign or message."""
|
||||
embed = cmn.embed_factory(ctx)
|
||||
with ctx.typing():
|
||||
msg = msg.upper()
|
||||
weight = 0
|
||||
for char in msg:
|
||||
try:
|
||||
cw_char = morse.morse[char].replace('-', '==')
|
||||
cw_char = morse.morse[char].replace("-", "==")
|
||||
weight += len(cw_char) * 2 + 2
|
||||
except KeyError:
|
||||
embed.title = 'Error in calculation of CW weight'
|
||||
embed.description = f'Unknown character `{char}` in message'
|
||||
embed.title = "Error in calculation of CW weight"
|
||||
embed.description = f"Unknown character `{char}` in message"
|
||||
embed.colour = cmn.colours.bad
|
||||
await ctx.send(embed=embed)
|
||||
return
|
||||
embed.title = f'CW Weight of {msg}'
|
||||
embed.description = f'The CW weight is **{weight}**'
|
||||
embed.title = f"CW Weight of {msg}"
|
||||
embed.description = f"The CW weight is **{weight}**"
|
||||
embed.colour = cmn.colours.good
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
|
146
exts/qrz.py
146
exts/qrz.py
@ -26,11 +26,11 @@ class QRZCog(commands.Cog):
|
||||
|
||||
@commands.command(name="call", aliases=["qrz"], category=cmn.cat.lookup)
|
||||
async def _qrz_lookup(self, ctx: commands.Context, callsign: str, *flags):
|
||||
'''Look up a callsign on [QRZ.com](https://www.qrz.com/). Add `--link` to only link the QRZ page.'''
|
||||
"""Look up a callsign on [QRZ.com](https://www.qrz.com/). Add `--link` to only link the QRZ page."""
|
||||
flags = [f.lower() for f in flags]
|
||||
|
||||
if keys.qrz_user == '' or keys.qrz_pass == '' or '--link' in flags:
|
||||
await ctx.send(f'http://qrz.com/db/{callsign}')
|
||||
if keys.qrz_user == "" or keys.qrz_pass == "" or "--link" in flags:
|
||||
await ctx.send(f"http://qrz.com/db/{callsign}")
|
||||
return
|
||||
|
||||
try:
|
||||
@ -38,38 +38,38 @@ class QRZCog(commands.Cog):
|
||||
except ConnectionError:
|
||||
await self.get_session()
|
||||
|
||||
url = f'http://xmldata.qrz.com/xml/current/?s={self.key};callsign={callsign}'
|
||||
url = f"http://xmldata.qrz.com/xml/current/?s={self.key};callsign={callsign}"
|
||||
async with self.session.get(url) as resp:
|
||||
if resp.status != 200:
|
||||
raise ConnectionError(f'Unable to connect to QRZ (HTTP Error {resp.status})')
|
||||
raise ConnectionError(f"Unable to connect to QRZ (HTTP Error {resp.status})")
|
||||
with BytesIO(await resp.read()) as resp_file:
|
||||
resp_xml = etree.parse(resp_file).getroot()
|
||||
|
||||
resp_xml_session = resp_xml.xpath('/x:QRZDatabase/x:Session', namespaces={'x': 'http://xmldata.qrz.com'})
|
||||
resp_session = {el.tag.split('}')[1]: el.text for el in resp_xml_session[0].getiterator()}
|
||||
if 'Error' in resp_session:
|
||||
if 'Session Timeout' in resp_session['Error']:
|
||||
resp_xml_session = resp_xml.xpath("/x:QRZDatabase/x:Session", namespaces={"x": "http://xmldata.qrz.com"})
|
||||
resp_session = {el.tag.split("}")[1]: el.text for el in resp_xml_session[0].getiterator()}
|
||||
if "Error" in resp_session:
|
||||
if "Session Timeout" in resp_session["Error"]:
|
||||
await self.get_session()
|
||||
await self._qrz_lookup(ctx, callsign)
|
||||
return
|
||||
if 'Not found' in resp_session['Error']:
|
||||
if "Not found" in resp_session["Error"]:
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f"QRZ Data for {callsign.upper()}"
|
||||
embed.colour = cmn.colours.bad
|
||||
embed.description = 'No data found!'
|
||||
embed.description = "No data found!"
|
||||
await ctx.send(embed=embed)
|
||||
return
|
||||
raise ValueError(resp_session['Error'])
|
||||
raise ValueError(resp_session["Error"])
|
||||
|
||||
resp_xml_data = resp_xml.xpath('/x:QRZDatabase/x:Callsign', namespaces={'x': 'http://xmldata.qrz.com'})
|
||||
resp_data = {el.tag.split('}')[1]: el.text for el in resp_xml_data[0].getiterator()}
|
||||
resp_xml_data = resp_xml.xpath("/x:QRZDatabase/x:Callsign", namespaces={"x": "http://xmldata.qrz.com"})
|
||||
resp_data = {el.tag.split("}")[1]: el.text for el in resp_xml_data[0].getiterator()}
|
||||
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f"QRZ Data for {resp_data['call']}"
|
||||
embed.colour = cmn.colours.good
|
||||
embed.url = f'http://www.qrz.com/db/{resp_data["call"]}'
|
||||
if 'image' in resp_data:
|
||||
embed.set_thumbnail(url=resp_data['image'])
|
||||
embed.url = f"http://www.qrz.com/db/{resp_data['call']}"
|
||||
if "image" in resp_data:
|
||||
embed.set_thumbnail(url=resp_data["image"])
|
||||
|
||||
data = qrz_process_info(resp_data)
|
||||
|
||||
@ -81,14 +81,14 @@ class QRZCog(commands.Cog):
|
||||
async def get_session(self):
|
||||
"""Session creation and caching."""
|
||||
self.key = await qrz_login(keys.qrz_user, keys.qrz_pass, self.session)
|
||||
with open('data/qrz_session', 'w') as qrz_file:
|
||||
with open("data/qrz_session", "w") as qrz_file:
|
||||
qrz_file.write(self.key)
|
||||
|
||||
@tasks.loop(count=1)
|
||||
async def _qrz_session_init(self):
|
||||
"""Helper task to allow obtaining a session at cog instantiation."""
|
||||
try:
|
||||
with open('data/qrz_session') as qrz_file:
|
||||
with open("data/qrz_session") as qrz_file:
|
||||
self.key = qrz_file.readline().strip()
|
||||
await qrz_test_session(self.key, self.session)
|
||||
except (FileNotFoundError, ConnectionError):
|
||||
@ -96,86 +96,86 @@ class QRZCog(commands.Cog):
|
||||
|
||||
|
||||
async def qrz_login(user: str, passwd: str, session: aiohttp.ClientSession):
|
||||
url = f'http://xmldata.qrz.com/xml/current/?username={user};password={passwd};agent=discord-qrm2'
|
||||
url = f"http://xmldata.qrz.com/xml/current/?username={user};password={passwd};agent=discord-qrm2"
|
||||
async with session.get(url) as resp:
|
||||
if resp.status != 200:
|
||||
raise ConnectionError(f'Unable to connect to QRZ (HTTP Error {resp.status})')
|
||||
raise ConnectionError(f"Unable to connect to QRZ (HTTP Error {resp.status})")
|
||||
with BytesIO(await resp.read()) as resp_file:
|
||||
resp_xml = etree.parse(resp_file).getroot()
|
||||
|
||||
resp_xml_session = resp_xml.xpath('/x:QRZDatabase/x:Session', namespaces={'x': 'http://xmldata.qrz.com'})
|
||||
resp_session = {el.tag.split('}')[1]: el.text for el in resp_xml_session[0].getiterator()}
|
||||
if 'Error' in resp_session:
|
||||
raise ConnectionError(resp_session['Error'])
|
||||
if resp_session['SubExp'] == 'non-subscriber':
|
||||
raise ConnectionError('Invalid QRZ Subscription')
|
||||
return resp_session['Key']
|
||||
resp_xml_session = resp_xml.xpath("/x:QRZDatabase/x:Session", namespaces={"x": "http://xmldata.qrz.com"})
|
||||
resp_session = {el.tag.split("}")[1]: el.text for el in resp_xml_session[0].getiterator()}
|
||||
if "Error" in resp_session:
|
||||
raise ConnectionError(resp_session["Error"])
|
||||
if resp_session["SubExp"] == "non-subscriber":
|
||||
raise ConnectionError("Invalid QRZ Subscription")
|
||||
return resp_session["Key"]
|
||||
|
||||
|
||||
async def qrz_test_session(key: str, session: aiohttp.ClientSession):
|
||||
url = f'http://xmldata.qrz.com/xml/current/?s={key}'
|
||||
url = f"http://xmldata.qrz.com/xml/current/?s={key}"
|
||||
async with session.get(url) as resp:
|
||||
if resp.status != 200:
|
||||
raise ConnectionError(f'Unable to connect to QRZ (HTTP Error {resp.status})')
|
||||
raise ConnectionError(f"Unable to connect to QRZ (HTTP Error {resp.status})")
|
||||
with BytesIO(await resp.read()) as resp_file:
|
||||
resp_xml = etree.parse(resp_file).getroot()
|
||||
|
||||
resp_xml_session = resp_xml.xpath('/x:QRZDatabase/x:Session', namespaces={'x': 'http://xmldata.qrz.com'})
|
||||
resp_session = {el.tag.split('}')[1]: el.text for el in resp_xml_session[0].getiterator()}
|
||||
if 'Error' in resp_session:
|
||||
raise ConnectionError(resp_session['Error'])
|
||||
resp_xml_session = resp_xml.xpath("/x:QRZDatabase/x:Session", namespaces={"x": "http://xmldata.qrz.com"})
|
||||
resp_session = {el.tag.split("}")[1]: el.text for el in resp_xml_session[0].getiterator()}
|
||||
if "Error" in resp_session:
|
||||
raise ConnectionError(resp_session["Error"])
|
||||
|
||||
|
||||
def qrz_process_info(data: dict):
|
||||
if 'name' in data:
|
||||
if 'fname' in data:
|
||||
name = data['fname'] + ' ' + data['name']
|
||||
if "name" in data:
|
||||
if "fname" in data:
|
||||
name = data["fname"] + " " + data["name"]
|
||||
else:
|
||||
name = data['name']
|
||||
name = data["name"]
|
||||
else:
|
||||
name = None
|
||||
if 'state' in data:
|
||||
state = f', {data["state"]}'
|
||||
if "state" in data:
|
||||
state = f", {data['state']}"
|
||||
else:
|
||||
state = ''
|
||||
address = data.get('addr1', '') + '\n' + data.get('addr2', '') + state + ' ' + data.get('zip', '')
|
||||
state = ""
|
||||
address = data.get("addr1", "") + "\n" + data.get("addr2", "") + state + " " + data.get("zip", "")
|
||||
address = address.strip()
|
||||
if address == '':
|
||||
if address == "":
|
||||
address = None
|
||||
if 'eqsl' in data:
|
||||
eqsl = 'Yes' if data['eqsl'] == 1 else 'No'
|
||||
if "eqsl" in data:
|
||||
eqsl = "Yes" if data["eqsl"] == 1 else "No"
|
||||
else:
|
||||
eqsl = 'Unknown'
|
||||
if 'mqsl' in data:
|
||||
mqsl = 'Yes' if data['mqsl'] == 1 else 'No'
|
||||
eqsl = "Unknown"
|
||||
if "mqsl" in data:
|
||||
mqsl = "Yes" if data["mqsl"] == 1 else "No"
|
||||
else:
|
||||
mqsl = 'Unknown'
|
||||
if 'lotw' in data:
|
||||
lotw = 'Yes' if data['lotw'] == 1 else 'No'
|
||||
mqsl = "Unknown"
|
||||
if "lotw" in data:
|
||||
lotw = "Yes" if data["lotw"] == 1 else "No"
|
||||
else:
|
||||
lotw = 'Unknown'
|
||||
lotw = "Unknown"
|
||||
|
||||
return OrderedDict([('Name', name),
|
||||
('Country', data.get('country', None)),
|
||||
('Address', address),
|
||||
('Grid Square', data.get('grid', None)),
|
||||
('County', data.get('county', None)),
|
||||
('CQ Zone', data.get('cqzone', None)),
|
||||
('ITU Zone', data.get('ituzone', None)),
|
||||
('IOTA Designator', data.get('iota', None)),
|
||||
('Expires', data.get('expdate', None)),
|
||||
('Aliases', data.get('aliases', None)),
|
||||
('Previous Callsign', data.get('p_call', None)),
|
||||
('License Class', data.get('class', None)),
|
||||
('Trustee', data.get('trustee', None)),
|
||||
('eQSL?', eqsl),
|
||||
('Paper QSL?', mqsl),
|
||||
('LotW?', lotw),
|
||||
('QSL Info', data.get('qslmgr', None)),
|
||||
('CQ Zone', data.get('cqzone', None)),
|
||||
('ITU Zone', data.get('ituzone', None)),
|
||||
('IOTA Designator', data.get('iota', None)),
|
||||
('Born', data.get('born', None))])
|
||||
return OrderedDict([("Name", name),
|
||||
("Country", data.get("country", None)),
|
||||
("Address", address),
|
||||
("Grid Square", data.get("grid", None)),
|
||||
("County", data.get("county", None)),
|
||||
("CQ Zone", data.get("cqzone", None)),
|
||||
("ITU Zone", data.get("ituzone", None)),
|
||||
("IOTA Designator", data.get("iota", None)),
|
||||
("Expires", data.get("expdate", None)),
|
||||
("Aliases", data.get("aliases", None)),
|
||||
("Previous Callsign", data.get("p_call", None)),
|
||||
("License Class", data.get("class", None)),
|
||||
("Trustee", data.get("trustee", None)),
|
||||
("eQSL?", eqsl),
|
||||
("Paper QSL?", mqsl),
|
||||
("LotW?", lotw),
|
||||
("QSL Info", data.get("qslmgr", None)),
|
||||
("CQ Zone", data.get("cqzone", None)),
|
||||
("ITU Zone", data.get("ituzone", None)),
|
||||
("IOTA Designator", data.get("iota", None)),
|
||||
("Born", data.get("born", None))])
|
||||
|
||||
|
||||
def setup(bot):
|
||||
|
@ -21,17 +21,17 @@ from resources import study
|
||||
|
||||
|
||||
class StudyCog(commands.Cog):
|
||||
choices = {cmn.emojis.a: 'A', cmn.emojis.b: 'B', cmn.emojis.c: 'C', cmn.emojis.d: 'D'}
|
||||
choices = {cmn.emojis.a: "A", cmn.emojis.b: "B", cmn.emojis.c: "C", cmn.emojis.d: "D"}
|
||||
|
||||
def __init__(self, bot: commands.Bot):
|
||||
self.bot = bot
|
||||
self.lastq = dict()
|
||||
self.source = 'Data courtesy of [HamStudy.org](https://hamstudy.org/)'
|
||||
self.source = "Data courtesy of [HamStudy.org](https://hamstudy.org/)"
|
||||
self.session = aiohttp.ClientSession(connector=bot.qrm.connector)
|
||||
|
||||
@commands.command(name="hamstudy", aliases=['rq', 'randomquestion', 'randomq'], category=cmn.cat.study)
|
||||
async def _random_question(self, ctx: commands.Context, country: str = '', level: str = ''):
|
||||
'''Gets a random question from [HamStudy's](https://hamstudy.org) question pools.'''
|
||||
@commands.command(name="hamstudy", aliases=["rq", "randomquestion", "randomq"], category=cmn.cat.study)
|
||||
async def _random_question(self, ctx: commands.Context, country: str = "", level: str = ""):
|
||||
"""Gets a random question from [HamStudy's](https://hamstudy.org) question pools."""
|
||||
with ctx.typing():
|
||||
embed = cmn.embed_factory(ctx)
|
||||
|
||||
@ -52,7 +52,7 @@ class StudyCog(commands.Cog):
|
||||
embed.description = "Possible arguments are:"
|
||||
embed.colour = cmn.colours.bad
|
||||
for cty in study.pool_names:
|
||||
levels = '`, `'.join(study.pool_names[cty].keys())
|
||||
levels = "`, `".join(study.pool_names[cty].keys())
|
||||
embed.add_field(name=f"**Country: `{cty}` {study.pool_emojis[cty]}**",
|
||||
value=f"Levels: `{levels}`", inline=False)
|
||||
embed.add_field(name="**Random**", value="To select a random pool or country, use `random` or `r`")
|
||||
@ -70,7 +70,7 @@ class StudyCog(commands.Cog):
|
||||
embed.description = "Possible arguments are:"
|
||||
embed.colour = cmn.colours.bad
|
||||
for cty in study.pool_names:
|
||||
levels = '`, `'.join(study.pool_names[cty].keys())
|
||||
levels = "`, `".join(study.pool_names[cty].keys())
|
||||
embed.add_field(name=f"**Country: `{cty}` {study.pool_emojis[cty]}**",
|
||||
value=f"Levels: `{levels}`", inline=False)
|
||||
embed.add_field(name="**Random**", value="To select a random pool or country, use `random` or `r`")
|
||||
@ -99,7 +99,7 @@ class StudyCog(commands.Cog):
|
||||
embed.description = "Possible arguments are:"
|
||||
embed.colour = cmn.colours.bad
|
||||
for cty in study.pool_names:
|
||||
levels = '`, `'.join(study.pool_names[cty].keys())
|
||||
levels = "`, `".join(study.pool_names[cty].keys())
|
||||
embed.add_field(name=f"**Country: `{cty}` {study.pool_emojis[cty]}**",
|
||||
value=f"Levels: `{levels}`", inline=False)
|
||||
embed.add_field(name="**Random**", value="To select a random pool or country, use `random` or `r`")
|
||||
@ -108,31 +108,31 @@ class StudyCog(commands.Cog):
|
||||
|
||||
pool_meta = pools[pool]
|
||||
|
||||
async with self.session.get(f'https://hamstudy.org/pools/{pool}') as resp:
|
||||
async with self.session.get(f"https://hamstudy.org/pools/{pool}") as resp:
|
||||
if resp.status != 200:
|
||||
raise cmn.BotHTTPError(resp)
|
||||
pool = json.loads(await resp.read())['pool']
|
||||
pool = json.loads(await resp.read())["pool"]
|
||||
|
||||
# Select a question
|
||||
pool_section = random.choice(pool)['sections']
|
||||
pool_questions = random.choice(pool_section)['questions']
|
||||
pool_section = random.choice(pool)["sections"]
|
||||
pool_questions = random.choice(pool_section)["questions"]
|
||||
question = random.choice(pool_questions)
|
||||
|
||||
embed.title = f"{study.pool_emojis[country]} {pool_meta['class']} {question['id']}"
|
||||
embed.description = self.source
|
||||
embed.add_field(name='Question:', value=question['text'], inline=False)
|
||||
embed.add_field(name='Answers:',
|
||||
embed.add_field(name="Question:", value=question["text"], inline=False)
|
||||
embed.add_field(name="Answers:",
|
||||
value=(f"**{cmn.emojis.a}** {question['answers']['A']}"
|
||||
f"\n**{cmn.emojis.b}** {question['answers']['B']}"
|
||||
f"\n**{cmn.emojis.c}** {question['answers']['C']}"
|
||||
f"\n**{cmn.emojis.d}** {question['answers']['D']}"),
|
||||
inline=False)
|
||||
embed.add_field(name='To Answer:',
|
||||
value=('Answer with reactions below. If not answered within 10 minutes,'
|
||||
' the answer will be revealed.'),
|
||||
embed.add_field(name="To Answer:",
|
||||
value=("Answer with reactions below. If not answered within 10 minutes,"
|
||||
" the answer will be revealed."),
|
||||
inline=False)
|
||||
if 'image' in question:
|
||||
image_url = f'https://hamstudy.org/_1330011/images/{pool.split("_",1)[1]}/{question["image"]}'
|
||||
if "image" in question:
|
||||
image_url = f"https://hamstudy.org/_1330011/images/{pool.split('_',1)[1]}/{question['image']}"
|
||||
embed.set_image(url=image_url)
|
||||
|
||||
q_msg = await ctx.send(embed=embed)
|
||||
@ -148,13 +148,13 @@ class StudyCog(commands.Cog):
|
||||
and str(reaction.emoji) in self.choices.keys())
|
||||
|
||||
try:
|
||||
reaction, user = await self.bot.wait_for('reaction_add', timeout=600.0, check=check)
|
||||
reaction, user = await self.bot.wait_for("reaction_add", timeout=600.0, check=check)
|
||||
except asyncio.TimeoutError:
|
||||
embed.remove_field(2)
|
||||
embed.add_field(name="Answer:", value=f"Timed out! The correct answer was **{question['answer']}**.")
|
||||
await q_msg.edit(embed=embed)
|
||||
else:
|
||||
if self.choices[str(reaction.emoji)] == question['answer']:
|
||||
if self.choices[str(reaction.emoji)] == question["answer"]:
|
||||
embed.remove_field(2)
|
||||
embed.add_field(name="Answer:", value=f"Correct! The answer was **{question['answer']}**.")
|
||||
embed.colour = cmn.colours.good
|
||||
@ -166,7 +166,7 @@ class StudyCog(commands.Cog):
|
||||
await q_msg.edit(embed=embed)
|
||||
|
||||
async def hamstudy_get_pools(self):
|
||||
async with self.session.get('https://hamstudy.org/pools/') as resp:
|
||||
async with self.session.get("https://hamstudy.org/pools/") as resp:
|
||||
if resp.status != 200:
|
||||
raise cmn.BotHTTPError(resp)
|
||||
else:
|
||||
|
@ -25,23 +25,23 @@ class WeatherCog(commands.Cog):
|
||||
self.bot = bot
|
||||
self.session = aiohttp.ClientSession(connector=bot.qrm.connector)
|
||||
|
||||
@commands.command(name="bandconditions", aliases=['cond', 'condx', 'conditions'], category=cmn.cat.weather)
|
||||
@commands.command(name="bandconditions", aliases=["cond", "condx", "conditions"], category=cmn.cat.weather)
|
||||
async def _band_conditions(self, ctx: commands.Context):
|
||||
'''Posts an image of HF Band Conditions.'''
|
||||
"""Posts an image of HF Band Conditions."""
|
||||
async with ctx.typing():
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = 'Current Solar Conditions'
|
||||
embed.title = "Current Solar Conditions"
|
||||
embed.colour = cmn.colours.good
|
||||
async with self.session.get('http://www.hamqsl.com/solarsun.php') as resp:
|
||||
async with self.session.get("http://www.hamqsl.com/solarsun.php") as resp:
|
||||
if resp.status != 200:
|
||||
raise cmn.BotHTTPError(resp)
|
||||
data = io.BytesIO(await resp.read())
|
||||
embed.set_image(url=f'attachment://condx.png')
|
||||
await ctx.send(embed=embed, file=discord.File(data, 'condx.png'))
|
||||
embed.set_image(url=f"attachment://condx.png")
|
||||
await ctx.send(embed=embed, file=discord.File(data, "condx.png"))
|
||||
|
||||
@commands.group(name="weather", aliases=['wttr'], category=cmn.cat.weather)
|
||||
@commands.group(name="weather", aliases=["wttr"], category=cmn.cat.weather)
|
||||
async def _weather_conditions(self, ctx: commands.Context):
|
||||
'''Posts an image of Local Weather Conditions from [wttr.in](http://wttr.in/).
|
||||
"""Posts an image of Local Weather Conditions from [wttr.in](http://wttr.in/).
|
||||
|
||||
*Supported location types:*
|
||||
city name: `paris`
|
||||
@ -51,71 +51,71 @@ class WeatherCog(commands.Cog):
|
||||
domain name `@stackoverflow.com`
|
||||
area codes: `12345`
|
||||
GPS coordinates: `-78.46,106.79`
|
||||
'''
|
||||
"""
|
||||
if ctx.invoked_subcommand is None:
|
||||
await ctx.send_help(ctx.command)
|
||||
|
||||
@_weather_conditions.command(name='forecast', aliases=['fc', 'future'], category=cmn.cat.weather)
|
||||
@_weather_conditions.command(name="forecast", aliases=["fc", "future"], category=cmn.cat.weather)
|
||||
async def _weather_conditions_forecast(self, ctx: commands.Context, *, location: str):
|
||||
'''Posts an image of Local Weather Conditions for the next three days from [wttr.in](http://wttr.in/).
|
||||
See help for weather command for possible location types. Add a `-c` or `-f` to use Celcius or Fahrenheit.'''
|
||||
"""Posts an image of Local Weather Conditions for the next three days from [wttr.in](http://wttr.in/).
|
||||
See help for weather command for possible location types. Add a `-c` or `-f` to use Celcius or Fahrenheit."""
|
||||
async with ctx.typing():
|
||||
try:
|
||||
units_arg = re.search(self.wttr_units_regex, location).group(1)
|
||||
except AttributeError:
|
||||
units_arg = ''
|
||||
if units_arg.lower() == 'f':
|
||||
units = 'u'
|
||||
elif units_arg.lower() == 'c':
|
||||
units = 'm'
|
||||
units_arg = ""
|
||||
if units_arg.lower() == "f":
|
||||
units = "u"
|
||||
elif units_arg.lower() == "c":
|
||||
units = "m"
|
||||
else:
|
||||
units = ''
|
||||
units = ""
|
||||
|
||||
loc = self.wttr_units_regex.sub('', location).strip()
|
||||
loc = self.wttr_units_regex.sub("", location).strip()
|
||||
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'Weather Forecast for {loc}'
|
||||
embed.description = 'Data from [wttr.in](http://wttr.in/).'
|
||||
embed.title = f"Weather Forecast for {loc}"
|
||||
embed.description = "Data from [wttr.in](http://wttr.in/)."
|
||||
embed.colour = cmn.colours.good
|
||||
|
||||
loc = loc.replace(' ', '+')
|
||||
async with self.session.get(f'http://wttr.in/{loc}_{units}pnFQ.png') as resp:
|
||||
loc = loc.replace(" ", "+")
|
||||
async with self.session.get(f"http://wttr.in/{loc}_{units}pnFQ.png") as resp:
|
||||
if resp.status != 200:
|
||||
raise cmn.BotHTTPError(resp)
|
||||
data = io.BytesIO(await resp.read())
|
||||
embed.set_image(url=f'attachment://wttr_forecast.png')
|
||||
await ctx.send(embed=embed, file=discord.File(data, 'wttr_forecast.png'))
|
||||
embed.set_image(url=f"attachment://wttr_forecast.png")
|
||||
await ctx.send(embed=embed, file=discord.File(data, "wttr_forecast.png"))
|
||||
|
||||
@_weather_conditions.command(name='now', aliases=['n'], category=cmn.cat.weather)
|
||||
@_weather_conditions.command(name="now", aliases=["n"], category=cmn.cat.weather)
|
||||
async def _weather_conditions_now(self, ctx: commands.Context, *, location: str):
|
||||
'''Posts an image of current Local Weather Conditions from [wttr.in](http://wttr.in/).
|
||||
See help for weather command for possible location types. Add a `-c` or `-f` to use Celcius or Fahrenheit.'''
|
||||
"""Posts an image of current Local Weather Conditions from [wttr.in](http://wttr.in/).
|
||||
See help for weather command for possible location types. Add a `-c` or `-f` to use Celcius or Fahrenheit."""
|
||||
async with ctx.typing():
|
||||
try:
|
||||
units_arg = re.search(self.wttr_units_regex, location).group(1)
|
||||
except AttributeError:
|
||||
units_arg = ''
|
||||
if units_arg.lower() == 'f':
|
||||
units = 'u'
|
||||
elif units_arg.lower() == 'c':
|
||||
units = 'm'
|
||||
units_arg = ""
|
||||
if units_arg.lower() == "f":
|
||||
units = "u"
|
||||
elif units_arg.lower() == "c":
|
||||
units = "m"
|
||||
else:
|
||||
units = ''
|
||||
units = ""
|
||||
|
||||
loc = self.wttr_units_regex.sub('', location).strip()
|
||||
loc = self.wttr_units_regex.sub("", location).strip()
|
||||
|
||||
embed = cmn.embed_factory(ctx)
|
||||
embed.title = f'Current Weather for {loc}'
|
||||
embed.description = 'Data from [wttr.in](http://wttr.in/).'
|
||||
embed.title = f"Current Weather for {loc}"
|
||||
embed.description = "Data from [wttr.in](http://wttr.in/)."
|
||||
embed.colour = cmn.colours.good
|
||||
|
||||
loc = loc.replace(' ', '+')
|
||||
async with self.session.get(f'http://wttr.in/{loc}_0{units}pnFQ.png') as resp:
|
||||
loc = loc.replace(" ", "+")
|
||||
async with self.session.get(f"http://wttr.in/{loc}_0{units}pnFQ.png") as resp:
|
||||
if resp.status != 200:
|
||||
raise cmn.BotHTTPError(resp)
|
||||
data = io.BytesIO(await resp.read())
|
||||
embed.set_image(url=f'attachment://wttr_now.png')
|
||||
await ctx.send(embed=embed, file=discord.File(data, 'wttr_now.png'))
|
||||
embed.set_image(url=f"attachment://wttr_now.png")
|
||||
await ctx.send(embed=embed, file=discord.File(data, "wttr_now.png"))
|
||||
|
||||
|
||||
def setup(bot: commands.Bot):
|
||||
|
4
info.py
4
info.py
@ -24,5 +24,5 @@ authors = ("@ClassAbbyAmplifier#2229", "@0x5c#0639")
|
||||
description = """A bot with various useful ham radio-related functions, written in Python."""
|
||||
license = "Released under the GNU General Public License v2"
|
||||
contributing = "Check out the source on GitHub, contributions welcome: https://github.com/classabbyamp/discord-qrm2"
|
||||
release = '2.1.0'
|
||||
bot_server = 'https://discord.gg/Ntbg3J4'
|
||||
release = "2.1.0"
|
||||
bot_server = "https://discord.gg/Ntbg3J4"
|
||||
|
6
main.py
6
main.py
@ -167,7 +167,7 @@ async def on_command_error(ctx: commands.Context, err: commands.CommandError):
|
||||
await cmn.add_react(ctx.message, cmn.emojis.bangbang)
|
||||
elif isinstance(err, (commands.CommandInvokeError, commands.ConversionError)):
|
||||
# Emulating discord.py's default beaviour.
|
||||
print('Ignoring exception in command {}:'.format(ctx.command), file=sys.stderr)
|
||||
print("Ignoring exception in command {}:".format(ctx.command), file=sys.stderr)
|
||||
traceback.print_exception(type(err), err, err.__traceback__, file=sys.stderr)
|
||||
|
||||
embed = cmn.error_embed_factory(ctx, err.original, bot.qrm.debug_mode)
|
||||
@ -176,7 +176,7 @@ async def on_command_error(ctx: commands.Context, err: commands.CommandError):
|
||||
await ctx.send(embed=embed)
|
||||
else:
|
||||
# Emulating discord.py's default beaviour. (safest bet)
|
||||
print('Ignoring exception in command {}:'.format(ctx.command), file=sys.stderr)
|
||||
print("Ignoring exception in command {}:".format(ctx.command), file=sys.stderr)
|
||||
traceback.print_exception(type(err), err, err.__traceback__, file=sys.stderr)
|
||||
await cmn.add_react(ctx.message, cmn.emojis.warning)
|
||||
|
||||
@ -221,7 +221,7 @@ async def _ensure_activity_fixed():
|
||||
# --- Run ---
|
||||
|
||||
for ext in opt.exts:
|
||||
bot.load_extension(ext_dir + '.' + ext)
|
||||
bot.load_extension(ext_dir + "." + ext)
|
||||
|
||||
|
||||
try:
|
||||
|
@ -11,45 +11,45 @@ from collections import OrderedDict
|
||||
|
||||
|
||||
us_calls_title = "Valid US Vanity Callsigns"
|
||||
us_calls_desc = ('#x# is the number of letters in the prefix and suffix of a callsign. '
|
||||
'E.g., WY4RC would be a 2x2 callsign, with prefix WY and suffix RC.')
|
||||
us_calls = OrderedDict([('**Group A** (Extra Only)', ('**Any:** K, N, W (1x2)\n'
|
||||
' AA-AL, KA-KZ, NA-NZ, WA-WZ (2x1)\n'
|
||||
' AA-AL (2x2)\n'
|
||||
'*Except*\n'
|
||||
'**Alaska:** AL, KL, NL, WL (2x1)\n'
|
||||
'**Caribbean:** KP, NP, WP (2x1)\n'
|
||||
'**Pacific:** AH, KH, NH, WH (2x1)')),
|
||||
('**Group B** (Advanced and Extra Only)', ('**Any:** KA-KZ, NA-NZ, WA-WZ (2x2)\n'
|
||||
'*Except*\n'
|
||||
'**Alaska:** AL (2x2)\n'
|
||||
'**Caribbean:** KP (2x2)\n'
|
||||
'**Pacific:** AH (2x2)')),
|
||||
('**Group C** (Technician, General, Advanced, Extra Only)', ('**Any Region:** K, N, W (1x3)\n'
|
||||
'*Except*\n'
|
||||
'**Alaska:** KL, NL, WL (2x2)\n'
|
||||
'**Caribbean:** NP, WP (2x2)\n'
|
||||
'**Pacific:** KH, NH, WH (2x2)')),
|
||||
('**Group D** (Any License Class)', ('**Any Region:** KA-KZ, WA-WZ (2x3)\n'
|
||||
'*Except*\n'
|
||||
'**Alaska:** KL, WL (2x3)\n'
|
||||
'**Caribbean:** KP, WP (2x3)\n'
|
||||
'**Pacific:** KH, WH (2x3)')),
|
||||
('**Unavailable**', ('- KA2AA-KA9ZZ: US Army in Japan\n'
|
||||
'- KC4AAA-KC4AAF: NSF in Antartica\n'
|
||||
'- KC4USA-KC4USZ: US Navy in Antartica\n'
|
||||
'- KG4AA-KG4ZZ: US Navy in Guantanamo Bay\n'
|
||||
'- KL9KAA-KL9KHZ: US military in Korea\n'
|
||||
'- KC6AA-KC6ZZ: Former US (Eastern and Western Caroline Islands), '
|
||||
'now Federated States of Micronesia (V6) and Republic of Palau (T8)\n'
|
||||
'- KX6AA-KX6ZZ: Former US (Marshall Islands), '
|
||||
'now Republic of the Marshall Islands (V73)\n'
|
||||
'- Any suffix SOS or QRA-QUZ\n'
|
||||
'- Any 2x3 with X as the first suffix letter\n'
|
||||
'- Any 2x3 with AF, KF, NF, or WF prefix and suffix EMA: FEMA\n'
|
||||
'- Any 2x3 with AA-AL, NA-NZ, WC, WK, WM, WR, or WT prefix: "Group X"\n'
|
||||
'- Any 2x1, 2x2, or 2x3 with KP, NP, WP prefix and 0, 6, 7, 8, 9 number\n'
|
||||
'- Any 1x1 callsign: Special Event'))])
|
||||
us_calls_desc = ("#x# is the number of letters in the prefix and suffix of a callsign. "
|
||||
"E.g., WY4RC would be a 2x2 callsign, with prefix WY and suffix RC.")
|
||||
us_calls = OrderedDict([("**Group A** (Extra Only)", ("**Any:** K, N, W (1x2)\n"
|
||||
" AA-AL, KA-KZ, NA-NZ, WA-WZ (2x1)\n"
|
||||
" AA-AL (2x2)\n"
|
||||
"*Except*\n"
|
||||
"**Alaska:** AL, KL, NL, WL (2x1)\n"
|
||||
"**Caribbean:** KP, NP, WP (2x1)\n"
|
||||
"**Pacific:** AH, KH, NH, WH (2x1)")),
|
||||
("**Group B** (Advanced and Extra Only)", ("**Any:** KA-KZ, NA-NZ, WA-WZ (2x2)\n"
|
||||
"*Except*\n"
|
||||
"**Alaska:** AL (2x2)\n"
|
||||
"**Caribbean:** KP (2x2)\n"
|
||||
"**Pacific:** AH (2x2)")),
|
||||
("**Group C** (Technician, General, Advanced, Extra Only)", ("**Any Region:** K, N, W (1x3)\n"
|
||||
"*Except*\n"
|
||||
"**Alaska:** KL, NL, WL (2x2)\n"
|
||||
"**Caribbean:** NP, WP (2x2)\n"
|
||||
"**Pacific:** KH, NH, WH (2x2)")),
|
||||
("**Group D** (Any License Class)", ("**Any Region:** KA-KZ, WA-WZ (2x3)\n"
|
||||
"*Except*\n"
|
||||
"**Alaska:** KL, WL (2x3)\n"
|
||||
"**Caribbean:** KP, WP (2x3)\n"
|
||||
"**Pacific:** KH, WH (2x3)")),
|
||||
("**Unavailable**", ("- KA2AA-KA9ZZ: US Army in Japan\n"
|
||||
"- KC4AAA-KC4AAF: NSF in Antartica\n"
|
||||
"- KC4USA-KC4USZ: US Navy in Antartica\n"
|
||||
"- KG4AA-KG4ZZ: US Navy in Guantanamo Bay\n"
|
||||
"- KL9KAA-KL9KHZ: US military in Korea\n"
|
||||
"- KC6AA-KC6ZZ: Former US (Eastern and Western Caroline Islands), "
|
||||
"now Federated States of Micronesia (V6) and Republic of Palau (T8)\n"
|
||||
"- KX6AA-KX6ZZ: Former US (Marshall Islands), "
|
||||
"now Republic of the Marshall Islands (V73)\n"
|
||||
"- Any suffix SOS or QRA-QUZ\n"
|
||||
"- Any 2x3 with X as the first suffix letter\n"
|
||||
"- Any 2x3 with AF, KF, NF, or WF prefix and suffix EMA: FEMA\n"
|
||||
"- Any 2x3 with AA-AL, NA-NZ, WC, WK, WM, WR, or WT prefix: \"Group X\"\n"
|
||||
"- Any 2x1, 2x2, or 2x3 with KP, NP, WP prefix and 0, 6, 7, 8, 9 number\n"
|
||||
"- Any 1x1 callsign: Special Event"))])
|
||||
|
||||
# format: country: (title, description, text)
|
||||
options = {'us': (us_calls_title, us_calls_desc, us_calls)}
|
||||
options = {"us": (us_calls_title, us_calls_desc, us_calls)}
|
||||
|
@ -7,8 +7,8 @@ This file is part of discord-qrmbot and is released under the terms of the GNU
|
||||
General Public License, version 2.
|
||||
"""
|
||||
|
||||
phonetics = {'a': 'alfa', 'b': 'bravo', 'c': 'charlie', 'd': 'delta', 'e': 'echo', 'f': 'foxtrot',
|
||||
'g': 'golf', 'h': 'hotel', 'i': 'india', 'j': 'juliett', 'k': 'kilo', 'l': 'lima',
|
||||
'm': 'mike', 'n': 'november', 'o': 'oscar', 'p': 'papa', 'q': 'quebec', 'r': 'romeo',
|
||||
's': 'sierra', 't': 'tango', 'u': 'uniform', 'v': 'victor', 'w': 'whiskey', 'x': 'x-ray',
|
||||
'y': 'yankee', 'z': 'zulu'}
|
||||
phonetics = {"a": "alfa", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot",
|
||||
"g": "golf", "h": "hotel", "i": "india", "j": "juliett", "k": "kilo", "l": "lima",
|
||||
"m": "mike", "n": "november", "o": "oscar", "p": "papa", "q": "quebec", "r": "romeo",
|
||||
"s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey", "x": "x-ray",
|
||||
"y": "yankee", "z": "zulu"}
|
||||
|
@ -7,43 +7,43 @@ This file is part of discord-qrmbot and is released under the terms of the GNU
|
||||
General Public License, version 2.
|
||||
"""
|
||||
|
||||
pool_names = {'us': {'technician': 'E2',
|
||||
'tech': 'E2',
|
||||
't': 'E2',
|
||||
'general': 'E3',
|
||||
'gen': 'E3',
|
||||
'g': 'E3',
|
||||
'extra': 'E4',
|
||||
'e': 'E4'},
|
||||
'ca': {'basic': 'CA_B',
|
||||
'b': 'CA_B',
|
||||
'advanced': 'CA_A',
|
||||
'adv': 'CA_A',
|
||||
'a': 'CA_A',
|
||||
'basic_fr': 'CA_FB',
|
||||
'b_fr': 'CA_FB',
|
||||
'base': 'CA_FB',
|
||||
'advanced_fr': 'CA_FS',
|
||||
'adv_fr': 'CA_FS',
|
||||
'a_fr': 'CA_FS',
|
||||
'supérieure': 'CA_FS',
|
||||
'superieure': 'CA_FS',
|
||||
's': 'CA_FS'},
|
||||
'us_c': {'c1': 'C1',
|
||||
'comm1': 'C1',
|
||||
'c3': 'C3',
|
||||
'comm3': 'C3',
|
||||
'c6': 'C6',
|
||||
'comm6': 'C6',
|
||||
'c7': 'C7',
|
||||
'comm7': 'C7',
|
||||
'c7r': 'C7R',
|
||||
'comm7r': 'C7R',
|
||||
'c8': 'C8',
|
||||
'comm8': 'C8',
|
||||
'c9': 'C9',
|
||||
'comm9': 'C9'}}
|
||||
pool_names = {"us": {"technician": "E2",
|
||||
"tech": "E2",
|
||||
"t": "E2",
|
||||
"general": "E3",
|
||||
"gen": "E3",
|
||||
"g": "E3",
|
||||
"extra": "E4",
|
||||
"e": "E4"},
|
||||
"ca": {"basic": "CA_B",
|
||||
"b": "CA_B",
|
||||
"advanced": "CA_A",
|
||||
"adv": "CA_A",
|
||||
"a": "CA_A",
|
||||
"basic_fr": "CA_FB",
|
||||
"b_fr": "CA_FB",
|
||||
"base": "CA_FB",
|
||||
"advanced_fr": "CA_FS",
|
||||
"adv_fr": "CA_FS",
|
||||
"a_fr": "CA_FS",
|
||||
"supérieure": "CA_FS",
|
||||
"superieure": "CA_FS",
|
||||
"s": "CA_FS"},
|
||||
"us_c": {"c1": "C1",
|
||||
"comm1": "C1",
|
||||
"c3": "C3",
|
||||
"comm3": "C3",
|
||||
"c6": "C6",
|
||||
"comm6": "C6",
|
||||
"c7": "C7",
|
||||
"comm7": "C7",
|
||||
"c7r": "C7R",
|
||||
"comm7r": "C7R",
|
||||
"c8": "C8",
|
||||
"comm8": "C8",
|
||||
"c9": "C9",
|
||||
"comm9": "C9"}}
|
||||
|
||||
pool_emojis = {'us': '🇺🇸',
|
||||
'ca': '🇨🇦',
|
||||
'us_c': '🇺🇸 🏢'}
|
||||
pool_emojis = {"us": "🇺🇸",
|
||||
"ca": "🇨🇦",
|
||||
"us_c": "🇺🇸 🏢"}
|
||||
|
@ -27,7 +27,7 @@ debug = False
|
||||
owners_uids = (200102491231092736,)
|
||||
|
||||
# The extensions to load when running the bot.
|
||||
exts = ['ae7q', 'base', 'fun', 'grid', 'ham', 'image', 'lookup', 'morse', 'qrz', 'study', 'weather']
|
||||
exts = ["ae7q", "base", "fun", "grid", "ham", "image", "lookup", "morse", "qrz", "study", "weather"]
|
||||
|
||||
# Either "time", "random", or "fixed" (first item in statuses)
|
||||
status_mode = "fixed"
|
||||
@ -37,17 +37,17 @@ statuses = ["with lids on the air", "with fire"]
|
||||
|
||||
# Timezone for the status (string)
|
||||
# See https://pythonhosted.org/pytz/ for more info
|
||||
status_tz = 'US/Eastern'
|
||||
status_tz = "US/Eastern"
|
||||
|
||||
# The text to put in the "playing" status, with start and stop times
|
||||
time_statuses = [('with lids on 3.840', (00, 00), (6, 00)),
|
||||
('with lids on 7.200', (6, 00), (10, 00)),
|
||||
('with lids on 14.313', (10, 00), (18, 00)),
|
||||
('with lids on 7.200', (18, 00), (20, 00)),
|
||||
('with lids on 3.840', (20, 00), (23, 59))]
|
||||
time_statuses = [("with lids on 3.840", (00, 00), (6, 00)),
|
||||
("with lids on 7.200", (6, 00), (10, 00)),
|
||||
("with lids on 14.313", (10, 00), (18, 00)),
|
||||
("with lids on 7.200", (18, 00), (20, 00)),
|
||||
("with lids on 3.840", (20, 00), (23, 59))]
|
||||
|
||||
# Emoji IDs and keywords for emoji reactions
|
||||
# Use the format {emoji_id (int): ('tuple', 'of', 'lowercase', 'keywords')}
|
||||
# Use the format {emoji_id (int): ("tuple", "of", "lowercase", "keywords")}
|
||||
msg_reacts = {}
|
||||
|
||||
# A :pika: emote's ID, None for no emote :c
|
||||
|
Loading…
Reference in New Issue
Block a user