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