Release the Cats! - Reorganised extensions and recategorised commands

Fixes #389 - Main issue
Fixes #388 - Accidental, Satmatch deadcode removal
This commit is contained in:
0x5c 2021-03-28 09:50:51 -04:00
parent f6d69f7498
commit 6e54a27f14
No known key found for this signature in database
GPG Key ID: A57F71C3176B9581
17 changed files with 190 additions and 127 deletions

View File

@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Configuration option to use another rTeX instance for `?tex`. - Configuration option to use another rTeX instance for `?tex`.
### Changed ### Changed
- Main name and aliases of `?bandplan`. - Main name and aliases of `?bandplan`.
- Recategorized the commands.
### Fixed ### Fixed
- Lack of input sanitisation in `?xkcd`. - Lack of input sanitisation in `?xkcd`.
- Incorrect capitalisation of the categories in the `?help` command. - Incorrect capitalisation of the categories in the `?help` command.
@ -85,7 +86,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [2.3.1] - 2020-04-02 ## [2.3.1] - 2020-04-02
### Fixed ### Fixed
- Wordlist containing innappropriate words. - Wordlist containing inappropriate words.
## [2.3.0] - 2020-03-30 ## [2.3.0] - 2020-03-30

View File

@ -48,11 +48,14 @@ class BoltCats(enum.Enum):
# meow # meow
class Cats(enum.Enum): class Cats(enum.Enum):
LOOKUP = "Information Lookup" CALC = "Calculators"
CODES = "Code References and Tools"
FUN = "Fun" FUN = "Fun"
MAPS = "Mapping" LOOKUP = "Information Lookup"
REF = "Reference" REF = "Reference"
STUDY = "Exam Study" STUDY = "Exam Study"
TIME = "Time and Time Zones"
UTILS = "Utilities"
WEATHER = "Land and Space Weather" WEATHER = "Land and Space Weather"

View File

@ -26,7 +26,7 @@ class QrmHelpCommand(commands.HelpCommand):
super().__init__(command_attrs={ super().__init__(command_attrs={
"help": "Shows help about qrm or a command", "help": "Shows help about qrm or a command",
"aliases": ["h"], "aliases": ["h"],
# TODO "category": cmn.BoltCats.INFO "category": cmn.BoltCats.INFO
}) })
self.verify_checks = True self.verify_checks = True
self.context: commands.Context self.context: commands.Context
@ -140,7 +140,7 @@ class BaseCog(commands.Cog):
self.bot_invite = (f"https://discordapp.com/oauth2/authorize?client_id={self.bot.user.id}" self.bot_invite = (f"https://discordapp.com/oauth2/authorize?client_id={self.bot.user.id}"
f"&scope=bot&permissions={opt.invite_perms}") f"&scope=bot&permissions={opt.invite_perms}")
@commands.command(name="info", aliases=["about"]) # TODO , category=cmn.BoltCats.INFO) @commands.command(name="info", aliases=["about"], category=cmn.BoltCats.INFO)
async def _info(self, ctx: commands.Context): async def _info(self, ctx: commands.Context):
"""Shows info about qrm.""" """Shows info about qrm."""
embed = cmn.embed_factory(ctx) embed = cmn.embed_factory(ctx)
@ -158,7 +158,7 @@ class BaseCog(commands.Cog):
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"]) # TODO , category=cmn.BoltCats.INFO) @commands.command(name="ping", aliases=["beep"], category=cmn.BoltCats.INFO)
async def _ping(self, ctx: commands.Context): async def _ping(self, ctx: commands.Context):
"""Shows the current latency to the discord endpoint.""" """Shows the current latency to the discord endpoint."""
embed = cmn.embed_factory(ctx) embed = cmn.embed_factory(ctx)
@ -171,7 +171,7 @@ class BaseCog(commands.Cog):
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"]) # TODO , category=cmn.BoltCats.INFO) @commands.command(name="changelog", aliases=["clog"], category=cmn.BoltCats.INFO)
async def _changelog(self, ctx: commands.Context, version: str = "latest"): async def _changelog(self, ctx: commands.Context, version: str = "latest"):
"""Shows what has changed in a bot version. Defaults to the latest version.""" """Shows what has changed in a bot version. Defaults to the latest version."""
embed = cmn.embed_factory(ctx) embed = cmn.embed_factory(ctx)
@ -207,7 +207,7 @@ class BaseCog(commands.Cog):
await ctx.send(embed=embed) await ctx.send(embed=embed)
@commands.command(name="issue") # TODO , category=cmn.BoltCats.INFO) @commands.command(name="issue", category=cmn.BoltCats.INFO)
async def _issue(self, ctx: commands.Context): async def _issue(self, ctx: commands.Context):
"""Shows how to create a bug report or feature request about the bot.""" """Shows how to create a bug report or feature request about the bot."""
embed = cmn.embed_factory(ctx) embed = cmn.embed_factory(ctx)
@ -219,7 +219,7 @@ class BaseCog(commands.Cog):
[miaowware/qrm-resources](https://github.com/miaowware/qrm-resources/issues).""" [miaowware/qrm-resources](https://github.com/miaowware/qrm-resources/issues)."""
await ctx.send(embed=embed) await ctx.send(embed=embed)
@commands.command(name="donate", aliases=["tip"]) # TODO , category=cmn.BoltCats.INFO) @commands.command(name="donate", aliases=["tip"], category=cmn.BoltCats.INFO)
async def _donate(self, ctx: commands.Context): async def _donate(self, ctx: commands.Context):
"""Shows ways to help support development of the bot via donations.""" """Shows ways to help support development of the bot via donations."""
embed = cmn.embed_factory(ctx) embed = cmn.embed_factory(ctx)
@ -230,7 +230,7 @@ class BaseCog(commands.Cog):
embed.add_field(name=title, value=url, inline=False) embed.add_field(name=title, value=url, inline=False)
await ctx.send(embed=embed) await ctx.send(embed=embed)
@commands.command(name="invite", enabled=opt.enable_invite_cmd) # TODO , category=cmn.BoltCats.INFO) @commands.command(name="invite", enabled=opt.enable_invite_cmd, category=cmn.BoltCats.INFO)
async def _invite(self, ctx: commands.Context): async def _invite(self, ctx: commands.Context):
"""Generates a link to invite the bot to a server.""" """Generates a link to invite the bot to a server."""
if not (await self.bot.application_info()).bot_public: if not (await self.bot.application_info()).bot_public:

View File

@ -1,7 +1,8 @@
""" """
QRZ extension for qrm Callsign Lookup extension for qrm
--- ---
Copyright (C) 2019-2020 Abigail Gold, 0x5c Copyright (C) 2019-2020 Abigail Gold, 0x5c (as qrz.py)
Copyright (C) 2021 Abigail Gold, 0x5c
This file is part of qrm2 and is released under the terms of This file is part of qrm2 and is released under the terms of
the GNU General Public License, version 2. the GNU General Public License, version 2.

View File

@ -1,7 +1,8 @@
""" """
Ham extension for qrm Codes extension for qrm
--- ---
Copyright (C) 2019-2021 Abigail Gold, 0x5c Copyright (C) 2019-2021 Abigail Gold, 0x5c (as ham.py)
Copyright (C) 2021 Abigail Gold, 0x5c
This file is part of qrm2 and is released under the terms of This file is part of qrm2 and is released under the terms of
the GNU General Public License, version 2. the GNU General Public License, version 2.
@ -9,18 +10,15 @@ the GNU General Public License, version 2.
import json import json
from datetime import datetime
import discord.ext.commands as commands import discord.ext.commands as commands
import common as cmn import common as cmn
from resources import callsign_info
class HamCog(commands.Cog): class HamCog(commands.Cog):
def __init__(self, bot: commands.Bot): def __init__(self, bot: commands.Bot):
self.bot = bot self.bot = bot
self.pfxs = callsign_info.options
with open(cmn.paths.resources / "phonetics.1.json") as file: with open(cmn.paths.resources / "phonetics.1.json") as file:
d = json.load(file) d = json.load(file)
self.phonetics: dict[str, str] = d["phonetics"] self.phonetics: dict[str, str] = d["phonetics"]
@ -28,7 +26,7 @@ class HamCog(commands.Cog):
with open(cmn.paths.resources / "qcodes.1.json") as file: with open(cmn.paths.resources / "qcodes.1.json") as file:
self.qcodes: dict = json.load(file) self.qcodes: dict = json.load(file)
@commands.command(name="qcode", aliases=["q"], category=cmn.Cats.REF) @commands.command(name="qcode", aliases=["q"], category=cmn.Cats.CODES)
async def _qcode_lookup(self, ctx: commands.Context, qcode: str): async def _qcode_lookup(self, ctx: commands.Context, qcode: str):
"""Looks up the meaning of a Q Code.""" """Looks up the meaning of a Q Code."""
qcode = qcode.upper() qcode = qcode.upper()
@ -42,7 +40,7 @@ class HamCog(commands.Cog):
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.Cats.REF) @commands.command(name="phonetics", aliases=["ph", "phoneticize", "phoneticise", "phone"], category=cmn.Cats.CODES)
async def _phonetics_lookup(self, ctx: commands.Context, *, msg: str): async def _phonetics_lookup(self, ctx: commands.Context, *, msg: str):
"""Returns NATO phonetics for a word or phrase.""" """Returns NATO phonetics for a word or phrase."""
result = "" result = ""
@ -58,51 +56,7 @@ class HamCog(commands.Cog):
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.Cats.REF) @commands.command(name="phoneticweight", aliases=["pw"], category=cmn.Cats.CODES)
async def _utc_lookup(self, ctx: commands.Context):
"""Returns the current time in UTC."""
now = datetime.utcnow()
result = "**" + now.strftime("%Y-%m-%d %H:%M") + "Z**"
embed = cmn.embed_factory(ctx)
embed.title = "The current time is:"
embed.description = result
embed.colour = cmn.colours.good
await ctx.send(embed=embed)
@commands.command(name="prefixes", aliases=["vanity", "pfx", "vanities", "prefix"], category=cmn.Cats.REF)
async def _vanity_prefixes(self, ctx: commands.Context, country: str = ""):
"""Lists valid callsign prefixes for different countries."""
country = country.lower()
embed = cmn.embed_factory(ctx)
if country not in self.pfxs:
desc = "Possible arguments are:\n"
for key, val in self.pfxs.items():
desc += f"`{key}`: {val.title}{(' ' + val.emoji if val.emoji else '')}\n"
embed.title = f"{country} Not Found!"
embed.description = desc
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return
else:
data = self.pfxs[country]
embed.title = data.title + (" " + data.emoji if data.emoji else "")
embed.description = data.desc
embed.colour = cmn.colours.good
for name, val in data.calls.items():
embed.add_field(name=name, value=val, inline=False)
await ctx.send(embed=embed)
@commands.command(name="contests", aliases=["cc", "tests"], category=cmn.Cats.REF)
async def _contests(self, ctx: commands.Context):
embed = cmn.embed_factory(ctx)
embed.title = "Contest Calendar"
embed.description = ("*We are currently rewriting the old, Chrome-based `contests` command. In the meantime, "
"use [the website](https://www.contestcalendar.com/weeklycont.php).*")
embed.colour = cmn.colours.good
await ctx.send(embed=embed)
@commands.command(name="phoneticweight", aliases=["pw"], category=cmn.Cats.REF)
async def _weight(self, ctx: commands.Context, *, msg: str): async def _weight(self, ctx: commands.Context, *, msg: str):
"""Calculates the phonetic weight of a callsign or message.""" """Calculates the phonetic weight of a callsign or message."""
embed = cmn.embed_factory(ctx) embed = cmn.embed_factory(ctx)

28
exts/contests.py Normal file
View File

@ -0,0 +1,28 @@
"""
Contest Calendar extension for qrm
---
Copyright (C) 2021 Abigail Gold, 0x5c
This file is part of qrm2 and is released under the terms of
the GNU General Public License, version 2.
"""
import discord.ext.commands as commands
import common as cmn
class ContestCalendarCog(commands.Cog):
@commands.command(name="contests", aliases=["cc", "tests"], category=cmn.Cats.LOOKUP)
async def _contests(self, ctx: commands.Context):
embed = cmn.embed_factory(ctx)
embed.title = "Contest Calendar"
embed.description = ("*We are currently rewriting the old, Chrome-based `contests` command. In the meantime, "
"use [the website](https://www.contestcalendar.com/weeklycont.php).*")
embed.colour = cmn.colours.good
await ctx.send(embed=embed)
def setup(bot: commands.Bot):
bot.add_cog(ContestCalendarCog(bot))

View File

@ -67,7 +67,7 @@ class DbConvCog(commands.Cog):
def __init__(self, bot: commands.Bot): def __init__(self, bot: commands.Bot):
self.bot = bot self.bot = bot
@commands.command(name="dbconv", aliases=["dbc"], category=cmn.Cats.REF) @commands.command(name="dbconv", aliases=["dbc"], category=cmn.Cats.CALC)
async def _db_conv(self, ctx: commands.Context, async def _db_conv(self, ctx: commands.Context,
value: Optional[float] = None, value: Optional[float] = None,
unit_from: Optional[UnitConverter] = None, unit_from: Optional[UnitConverter] = None,

View File

@ -1,7 +1,8 @@
""" """
Lookup extension for qrm DXCC Prefix Lookup extension for qrm
--- ---
Copyright (C) 2019-2020 Abigail Gold, 0x5c Copyright (C) 2019-2020 Abigail Gold, 0x5c (as lookup.py)
Copyright (C) 2021 Abigail Gold, 0x5c
This file is part of qrm2 and is released under the terms of This file is part of qrm2 and is released under the terms of
the GNU General Public License, version 2. the GNU General Public License, version 2.
@ -21,7 +22,7 @@ import common as cmn
cty_path = Path("./data/cty.json") cty_path = Path("./data/cty.json")
class LookupCog(commands.Cog): class DXCCCog(commands.Cog):
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
try: try:
@ -29,18 +30,6 @@ class LookupCog(commands.Cog):
except OSError: except OSError:
self.cty = BigCty() self.cty = BigCty()
# TODO: See #107
# @commands.command(name="sat", category=cmn.Cats.Lookup)
# async def _sat_lookup(self, ctx: commands.Context, sat_name: str, grid1: str, grid2: str = None):
# """Links to info about satellite passes on satmatch.com."""
# now = datetime.utcnow().strftime("%Y-%m-%d%%20%H:%M")
# if grid2 is None or grid2 == "":
# await ctx.send(f"http://www.satmatch.com/satellite/{sat_name}/obs1/{grid1}"
# f"?search_start_time={now}&duration_hrs=24")
# else:
# await ctx.send(f"http://www.satmatch.com/satellite/{sat_name}/obs1/{grid1}"
# f"/obs2/{grid2}?search_start_time={now}&duration_hrs=24")
@commands.command(name="dxcc", aliases=["dx"], category=cmn.Cats.LOOKUP) @commands.command(name="dxcc", aliases=["dx"], category=cmn.Cats.LOOKUP)
async def _dxcc_lookup(self, ctx: commands.Context, query: str): async def _dxcc_lookup(self, ctx: commands.Context, query: str):
"""Gets DXCC info about a callsign prefix.""" """Gets DXCC info about a callsign prefix."""
@ -82,6 +71,6 @@ def run_update(cty_obj, dump_loc):
def setup(bot: commands.Bot): def setup(bot: commands.Bot):
lookupcog = LookupCog(bot) dxcccog = DXCCCog(bot)
bot.add_cog(lookupcog) bot.add_cog(dxcccog)
lookupcog._update_cty.start() dxcccog._update_cty.start()

View File

@ -19,7 +19,7 @@ class GridCog(commands.Cog):
def __init__(self, bot: commands.Bot): def __init__(self, bot: commands.Bot):
self.bot = bot self.bot = bot
@commands.command(name="grid", category=cmn.Cats.MAPS) @commands.command(name="grid", category=cmn.Cats.CALC)
async def _grid_sq_lookup(self, ctx: commands.Context, lat: float, lon: float): async def _grid_sq_lookup(self, ctx: commands.Context, lat: float, lon: float):
("""Calculates the grid square for latitude and longitude coordinates.""" ("""Calculates the grid square for latitude and longitude coordinates."""
"""\n\nCoordinates should be in decimal format, with negative being latitude South and longitude West.""" """\n\nCoordinates should be in decimal format, with negative being latitude South and longitude West."""
@ -33,7 +33,7 @@ class GridCog(commands.Cog):
embed.colour = cmn.colours.good embed.colour = cmn.colours.good
await ctx.send(embed=embed) await ctx.send(embed=embed)
@commands.command(name="latlong", aliases=["latlon", "loc", "ungrid"], category=cmn.Cats.MAPS) @commands.command(name="latlong", aliases=["latlon", "loc", "ungrid"], category=cmn.Cats.CALC)
async def _location_lookup(self, ctx: commands.Context, grid: str): async def _location_lookup(self, ctx: commands.Context, grid: str):
("""Calculates the latitude and longitude for the center of a grid locator.""" ("""Calculates the latitude and longitude for the center of a grid locator."""
"""\n\nTo calculate the grid locator from a latitude and longitude, use `grid`""" """\n\nTo calculate the grid locator from a latitude and longitude, use `grid`"""
@ -49,7 +49,7 @@ class GridCog(commands.Cog):
"latlong` to see other names for this command.*")) "latlong` to see other names for this command.*"))
await ctx.send(embed=embed) await ctx.send(embed=embed)
@commands.command(name="griddistance", aliases=["griddist", "distance", "dist"], category=cmn.Cats.MAPS) @commands.command(name="griddistance", aliases=["griddist", "distance", "dist"], category=cmn.Cats.CALC)
async def _dist_lookup(self, ctx: commands.Context, grid1: str, grid2: str): async def _dist_lookup(self, ctx: commands.Context, grid1: str, grid2: str):
"""Calculates the great circle distance and azimuthal bearing between two grid locators.""" """Calculates the great circle distance and azimuthal bearing between two grid locators."""
g1 = gridtools.Grid(grid1) g1 = gridtools.Grid(grid1)

View File

@ -9,7 +9,6 @@ the GNU General Public License, version 2.
import aiohttp import aiohttp
from datetime import datetime
import discord.ext.commands as commands import discord.ext.commands as commands
@ -19,8 +18,6 @@ import data.options as opt
class ImageCog(commands.Cog): class ImageCog(commands.Cog):
gl_baseurl = "https://www.fourmilab.ch/cgi-bin/uncgi/Earth?img=ETOPO1_day-m.evif&dynimg=y&opt=-p"
def __init__(self, bot: commands.Bot): def __init__(self, bot: commands.Bot):
self.bot = bot self.bot = bot
self.bandcharts = cmn.ImagesGroup(cmn.paths.resources / "bandcharts.1.json") self.bandcharts = cmn.ImagesGroup(cmn.paths.resources / "bandcharts.1.json")
@ -32,21 +29,11 @@ class ImageCog(commands.Cog):
"""Gets the frequency allocations chart for a given country.""" """Gets the frequency allocations chart for a given country."""
await ctx.send(embed=create_embed(ctx, "Bandchart", self.bandcharts, chart_id)) await ctx.send(embed=create_embed(ctx, "Bandchart", self.bandcharts, chart_id))
@commands.command(name="map", category=cmn.Cats.MAPS) @commands.command(name="map", category=cmn.Cats.REF)
async def _map(self, ctx: commands.Context, map_id: str = ""): async def _map(self, ctx: commands.Context, map_id: str = ""):
"""Posts a ham-relevant map.""" """Posts a ham-relevant map."""
await ctx.send(embed=create_embed(ctx, "Map", self.maps, map_id)) await ctx.send(embed=create_embed(ctx, "Map", self.maps, map_id))
@commands.command(name="grayline", aliases=["greyline", "grey", "gray", "gl"], category=cmn.Cats.MAPS)
async def _grayline(self, ctx: commands.Context):
"""Gets a map of the current greyline, where HF propagation is the best."""
embed = cmn.embed_factory(ctx)
embed.title = "Current Greyline Conditions"
embed.colour = cmn.colours.good
date_params = f"&date=1&utc={datetime.utcnow():%Y-%m-%d+%H:%M:%S}"
embed.set_image(url=self.gl_baseurl + date_params)
await ctx.send(embed=embed)
def create_embed(ctx: commands.Context, not_found_name: str, db: cmn.ImagesGroup, img_id: str): def create_embed(ctx: commands.Context, not_found_name: str, db: cmn.ImagesGroup, img_id: str):
"""Creates an embed for the image and its metadata, or list available images in the group.""" """Creates an embed for the image and its metadata, or list available images in the group."""

View File

@ -1,7 +1,8 @@
""" """
Weather extension for qrm Land Weather extension for qrm
--- ---
Copyright (C) 2019-2020 Abigail Gold, 0x5c Copyright (C) 2019-2020 Abigail Gold, 0x5c (as weather.py)
Copyright (C) 2021 Abigail Gold, 0x5c
This file is part of qrm2 and is released under the terms of This file is part of qrm2 and is released under the terms of
the GNU General Public License, version 2. the GNU General Public License, version 2.
@ -26,20 +27,6 @@ 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="solarweather", aliases=["solar", "bandconditions", "cond", "condx", "conditions"],
category=cmn.Cats.WEATHER)
async def solarweather(self, ctx: commands.Context):
"""Gets a solar weather report."""
embed = cmn.embed_factory(ctx)
embed.title = "☀️ Current Solar Weather"
if ctx.invoked_with in ["bandconditions", "cond", "condx", "conditions"]:
embed.add_field(name="⚠️ Deprecated Command Alias",
value=(f"This command has been renamed to `{ctx.prefix}solar`!\n"
"The alias you used will be removed in the next version."))
embed.colour = cmn.colours.good
embed.set_image(url="http://www.hamqsl.com/solarsun.php")
await ctx.send(embed=embed)
@commands.group(name="weather", aliases=["wttr"], case_insensitive=True, category=cmn.Cats.WEATHER) @commands.group(name="weather", aliases=["wttr"], case_insensitive=True, category=cmn.Cats.WEATHER)
async def _weather_conditions(self, ctx: commands.Context): async def _weather_conditions(self, ctx: commands.Context):
"""Gets local weather conditions from [wttr.in](http://wttr.in/). """Gets local weather conditions from [wttr.in](http://wttr.in/).

View File

@ -23,7 +23,7 @@ class MorseCog(commands.Cog):
self.morse: dict[str, str] = d["morse"] self.morse: dict[str, str] = d["morse"]
self.ascii: dict[str, int] = d["ascii"] self.ascii: dict[str, int] = d["ascii"]
@commands.command(name="morse", aliases=["cw"], category=cmn.Cats.REF) @commands.command(name="morse", aliases=["cw"], category=cmn.Cats.CODES)
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."""
result = "" result = ""
@ -39,7 +39,7 @@ class MorseCog(commands.Cog):
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.Cats.REF) @commands.command(name="unmorse", aliases=["demorse", "uncw", "decw"], category=cmn.Cats.CODES)
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."""
result = "" result = ""
@ -59,7 +59,7 @@ class MorseCog(commands.Cog):
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.Cats.REF) @commands.command(name="cwweight", aliases=["weight", "cww"], category=cmn.Cats.CODES)
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)

48
exts/prefixes.py Normal file
View File

@ -0,0 +1,48 @@
"""
Prefixes Lookup extension for qrm
---
Copyright (C) 2021 Abigail Gold, 0x5c
This file is part of qrm2 and is released under the terms of
the GNU General Public License, version 2.
"""
import discord.ext.commands as commands
import common as cmn
from resources import callsign_info
class PrefixesCog(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
self.pfxs = callsign_info.options
@commands.command(name="prefixes", aliases=["vanity", "pfx", "vanities", "prefix"], category=cmn.Cats.REF)
async def _vanity_prefixes(self, ctx: commands.Context, country: str = ""):
"""Lists valid callsign prefixes for different countries."""
country = country.lower()
embed = cmn.embed_factory(ctx)
if country not in self.pfxs:
desc = "Possible arguments are:\n"
for key, val in self.pfxs.items():
desc += f"`{key}`: {val.title}{(' ' + val.emoji if val.emoji else '')}\n"
embed.title = f"{country} Not Found!"
embed.description = desc
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return
else:
data = self.pfxs[country]
embed.title = data.title + (" " + data.emoji if data.emoji else "")
embed.description = data.desc
embed.colour = cmn.colours.good
for name, val in data.calls.items():
embed.add_field(name=name, value=val, inline=False)
await ctx.send(embed=embed)
def setup(bot: commands.Bot):
bot.add_cog(PrefixesCog(bot))

View File

@ -12,6 +12,7 @@ from io import BytesIO
import aiohttp import aiohttp
import cairosvg import cairosvg
from datetime import datetime
import discord import discord
import discord.ext.commands as commands import discord.ext.commands as commands
@ -22,6 +23,8 @@ import common as cmn
class PropagationCog(commands.Cog): class PropagationCog(commands.Cog):
muf_url = "https://prop.kc2g.com/renders/current/mufd-normal-now.svg" muf_url = "https://prop.kc2g.com/renders/current/mufd-normal-now.svg"
fof2_url = "https://prop.kc2g.com/renders/current/fof2-normal-now.svg" fof2_url = "https://prop.kc2g.com/renders/current/fof2-normal-now.svg"
gl_baseurl = "https://www.fourmilab.ch/cgi-bin/uncgi/Earth?img=ETOPO1_day-m.evif&dynimg=y&opt=-p"
n0nbh_sun_url = "http://www.hamqsl.com/solarsun.php"
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
@ -55,6 +58,30 @@ class PropagationCog(commands.Cog):
embed.set_image(url="attachment://fof2_map.png") embed.set_image(url="attachment://fof2_map.png")
await ctx.send(file=file, embed=embed) await ctx.send(file=file, embed=embed)
@commands.command(name="grayline", aliases=["greyline", "grey", "gray", "gl"], category=cmn.Cats.WEATHER)
async def grayline(self, ctx: commands.Context):
"""Gets a map of the current greyline, where HF propagation is the best."""
embed = cmn.embed_factory(ctx)
embed.title = "Current Greyline Conditions"
embed.colour = cmn.colours.good
date_params = f"&date=1&utc={datetime.utcnow():%Y-%m-%d+%H:%M:%S}"
embed.set_image(url=self.gl_baseurl + date_params)
await ctx.send(embed=embed)
@commands.command(name="solarweather", aliases=["solar", "bandconditions", "cond", "condx", "conditions"],
category=cmn.Cats.WEATHER)
async def solarweather(self, ctx: commands.Context):
"""Gets a solar weather report."""
embed = cmn.embed_factory(ctx)
embed.title = "☀️ Current Solar Weather"
if ctx.invoked_with in ["bandconditions", "cond", "condx", "conditions"]:
embed.add_field(name="⚠️ Deprecated Command Alias",
value=(f"This command has been renamed to `{ctx.prefix}solar`!\n"
"The alias you used will be removed in the next version."))
embed.colour = cmn.colours.good
embed.set_image(url=self.n0nbh_sun_url)
await ctx.send(embed=embed)
def setup(bot: commands.Bot): def setup(bot: commands.Bot):
bot.add_cog(PropagationCog(bot)) bot.add_cog(PropagationCog(bot))

View File

@ -26,7 +26,7 @@ class TexCog(commands.Cog):
with open(cmn.paths.resources / "template.1.tex") as latex_template: with open(cmn.paths.resources / "template.1.tex") as latex_template:
self.template = latex_template.read() self.template = latex_template.read()
@commands.command(name="tex", aliases=["latex"], category=cmn.Cats.FUN) @commands.command(name="tex", aliases=["latex"], category=cmn.Cats.UTILS)
async def tex(self, ctx: commands.Context, *, expr: str): async def tex(self, ctx: commands.Context, *, expr: str):
"""Renders a LaTeX expression.""" """Renders a LaTeX expression."""
payload = { payload = {

35
exts/time.py Normal file
View File

@ -0,0 +1,35 @@
"""
Time extension for qrm
---
Copyright (C) 2021 classabbyamp, 0x5c
This file is part of qrm2 and is released under the terms of
the GNU General Public License, version 2.
"""
from datetime import datetime
import discord.ext.commands as commands
import common as cmn
class TimeCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command(name="utc", aliases=["z"], category=cmn.Cats.TIME)
async def _utc_lookup(self, ctx: commands.Context):
"""Returns the current time in UTC."""
now = datetime.utcnow()
result = "**" + now.strftime("%Y-%m-%d %H:%M") + "Z**"
embed = cmn.embed_factory(ctx)
embed.title = "The current time is:"
embed.description = result
embed.colour = cmn.colours.good
await ctx.send(embed=embed)
def setup(bot: commands.Bot):
bot.add_cog(TimeCog(bot))

View File

@ -31,20 +31,23 @@ owners_uids = (200102491231092736, 564766093051166729)
# The extensions to load when running the bot. # The extensions to load when running the bot.
exts = [ exts = [
"ae7q",
"base", "base",
"ae7q",
"callsign",
"codes",
"contests",
"dbconv",
"dxcc",
"fun", "fun",
"grid", "grid",
"ham",
"image", "image",
"lookup", "land_weather",
"morse", "morse",
"qrz", "prefixes",
"propagation",
"study", "study",
"tex", "tex",
"weather", "time",
"dbconv",
"propagation",
] ]
# URL to the resources # URL to the resources