41 Commits

Author SHA1 Message Date
0x5c 940f45f4d4 Merge pull request #305 from miaowware/changelog
Bump version 2.5.0 + changelog
2020-10-31 21:10:52 -04:00
0x5c be7e29b387 Bump version 2.5.0 + changelog 2020-10-31 21:08:44 -04:00
0x5c 518ead9ccd Merge pull request #304 from miaowware/maps-plans-ordering
Re-ordered the maps and plans
2020-10-31 21:05:03 -04:00
0x5c 6e5acba6e9 Re-ordered the maps and plans
Maps:
Followed order (all alphabetic) countrycode, ITU, other organisations.

Plans:
Followed countrycode (alphabetic).

Fixes #292
2020-10-31 20:56:39 -04:00
classabbyamp ad50a86f9d Merge pull request #291 from miaowware/moar-bandcharts
add australian and italian band charts
2020-10-31 20:34:38 -04:00
classabbyamp 0bfa0c6e41 Merge branch 'master' into moar-bandcharts 2020-10-31 20:28:18 -04:00
0x5c ce64d882b8 Merge pull request #303 from miaowware/pr221
[Compressed] Japan and Nederlands Bandplan Update (#221)
2020-10-31 20:26:14 -04:00
0x5c 0aac09f3bc [Compressed] Japan and Nederlands Bandplan Update (#221)
PR originally by MadIceTea

note: will take care of miaowware/qrm-resources#5 once applied there

Co-authored-by: Alexander Wiegman (Taniguchi) <7548448+MadIceTea@users.noreply.github.com>
Co-authored-by: MadIceTea <7548448+MadIceTea@users.noreply.github.com>
2020-10-31 20:08:01 -04:00
0x5c e3534d02d7 Merge pull request #302 from miaowware/cl-gl
Add missing changelog entry for greyline fix
2020-10-30 09:10:11 -04:00
0x5c cdcb0e17d2 Add missing changelog entry for greyline fix 2020-10-30 09:09:13 -04:00
0x5c cd2503c953 Merge pull request #300 from miaowware/paths
Moved paths to pathlib
2020-10-30 08:58:16 -04:00
0x5c b4c165851c Merge pull request #298 from miaowware/intents
Changed the intents and member cache
2020-10-30 08:57:57 -04:00
0x5c 77a5af73bc Merge pull request #297 from miaowware/no-dl
Switch to sending an URL instead of fetching images
2020-10-30 08:57:44 -04:00
0x5c 4b7064cad9 Merge pull request #301 from miaowware/ihaveocd
Yes, this is a PR to remove a newline
2020-10-30 08:49:55 -04:00
0x5c d8fe3cfa02 Yes, this is a PR to remove a newline
Yes, I have OCD

Yes, I made an issue just for that too
Fixes #299
2020-10-30 07:18:58 -04:00
0x5c ffc3be7e24 Moved paths to pathlib
Turns out most paths were already using pathlib, only remained
some in lookup.py and fun.py

Fixes #45
2020-10-30 07:07:56 -04:00
0x5c 5dab93b7d3 Changed the intents and member cache
- Now only intents GUILDS, GUILD_MESSAGES, DIRECT_MESSAGES.
- Member cache now from intents.

Fixes #296
2020-10-30 06:14:14 -04:00
0x5c e660b1a8f5 Switch to sending an URL instead of fetching images
This only applies to images that were downloaded.
Images that are hosted in the bot are not affected.

Fixes #230
Fixes #295
2020-10-30 05:22:16 -04:00
Abigail G 3d96a43c50 add australian and italian band charts
fixes #225
fixes #242
2020-10-29 00:52:44 -04:00
0x5c e8bb18ea8c Merge pull request #290 from miaowware/error
Fixed numerous small potential bugs
2020-10-28 23:33:58 -04:00
0x5c 19952396f2 Fixed numerous small potential bugs
- Most are typing related

Fixes #289
2020-10-28 23:22:28 -04:00
0x5c 1831c56f58 Merge pull request #286 from miaowware/unpin
Unpinned the versions of most dependencies
2020-10-28 21:06:47 -04:00
classabbyamp 77e14a109c convert Unit into a dataclass, move parse to converter (#257)
fixes #256
2020-10-28 21:06:30 -04:00
classabbyamp 2ac13346d4 Merge pull request #276 from miaowware/release-fixes
Release fixes
2020-10-28 21:05:58 -04:00
classabbyamp 2eea7dce23 move CallsignInfoData to resources/callsign_info (#258)
fixes #255
2020-10-28 21:04:14 -04:00
classabbyamp f26a7af928 fixed qsl/lotw status being incorrectly shown (#278)
fixes #277
2020-10-28 21:03:41 -04:00
classabbyamp 786440edcb Merge pull request #281 from miaowware/efix-docker-workflow 2020-10-28 21:01:32 -04:00
0x5c c47d211016 Unpinned the versions of most stuff, made the remaining version pinning less strict 2020-10-28 11:31:10 -04:00
Abigail G 855935a26e outputs can't be shared between jobs :oof: 2020-10-11 14:47:25 -04:00
classabbyamp ff9d46f379 add deploy workflow job (#280)
Fixes #279
2020-10-11 14:42:09 -04:00
classabbyamp 0f0c3bf723 fix variables not working correctly
Fixes #275
2020-10-06 23:44:58 -04:00
classabbyamp 7c818cfb34 fix tag bug in release workflow
progress on #275
2020-10-06 22:58:20 -04:00
0x5c 27863ae6bf Merge pull request #274 from miaowware/e-release
Bump version+changelog 2.4.1
2020-10-06 19:36:37 -04:00
classabbyamp de999bc39d fix error in workflow (#273) 2020-10-06 19:31:19 -04:00
0x5c 80d80ab718 Bump version+changelog 2.4.1 2020-10-06 19:26:57 -04:00
classabbyamp 8cb1a8df15 update docker documentation to remove docker hub mentions (#265)
Fixes #263
2020-10-06 19:17:02 -04:00
classabbyamp fa2dded81b Merge pull request #272 from miaowware/worflows-updates
add/update workflows
2020-10-06 19:16:13 -04:00
Abigail G bda0540fa8 add/update workflows
Fixes #270
Fixes #271
2020-10-06 19:13:00 -04:00
0x5c c9510ad9b9 Merge pull request #269 from miaowware/newcrap
Made bot work with new Intents system + only cache needed things
2020-10-06 19:01:46 -04:00
0x5c 00f9929deb Made bot work with new Intents system + only cache needed things
- all in one
- Bumped discord.py to 1.5.0

Fixes #267
Fixes #268
2020-10-06 18:56:45 -04:00
classabbyamp 3597367046 Create developer guide, remove issue/pr templates (#260)
* Create developer guide
* remove issue templates (they are in miaowware/.github now)
2020-10-04 22:29:00 -04:00
29 changed files with 314 additions and 333 deletions
-29
View File
@@ -1,29 +0,0 @@
---
name: Bug report
about: Report a bug to help us improve qrm
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Run command '...' with input '...'
2. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**System (include if related to running the bot):**
- OS: [e.g. Linux, Docker]
- Version: [e.g. 22]
**Additional context**
Add any other context about the problem here.
-20
View File
@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for qrm
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
-29
View File
@@ -1,29 +0,0 @@
### Description
*Describe the changes you made here.*
Fixes #{issue}
### Type of change
Please delete options that are not relevant.
- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing functionality to not work as expected)
- This change requires a documentation update
### How has this been tested?
*Describe the procedure used for verifying your changes here.*
### Checklist
- [ ] Issue exists for PR
- [ ] Code reviewed by the author
- [ ] Code documented (comments or other documentation)
- [ ] Changes tested
- [ ] `flake8` passes
- [ ] `CHANGELOG.md` updated
- [ ] Informative commit messages
- [ ] Descriptive PR title
+37 -28
View File
@@ -1,11 +1,13 @@
name: Docker Build and Push
# vim: ts=2 sw=2:
name: Docker Build and Deploy
on:
push:
# Publish `master` as Docker `dev` image.
branches:
- master
# Publish `v*` tags as releases and as `latest`.
# Publish `v*` tags as x.x.x images and as `latest`.
tags:
- v*
@@ -13,46 +15,53 @@ env:
IMAGE_NAME: qrm2
jobs:
build-and-push:
runs-on: ubuntu-latest
docker:
name: Build and push docker images
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v2
with:
ref: ${{ github.ref }}
- name: Write ref to file
run: git rev-list -n 1 $GITHUB_REF > ./git_commit
- name: Build image
run: |
echo ${{ github.sha }} > git_commit
docker build . --file Dockerfile -t $IMAGE_NAME
run: docker build . --file Dockerfile -t $IMAGE_NAME
- name: Log into Github Package Registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login docker.pkg.github.com -u ${{ github.actor }} --password-stdin
- name: Log into Docker Hub
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
- name: Push image to registries
- name: Tag image
id: tag_image
run: |
GITHUB_IMAGE_ID=docker.pkg.github.com/${{ github.repository }}/$IMAGE_NAME
DOCKER_IMAGE_ID=${{ secrets.DOCKER_USERNAME }}/$IMAGE_NAME
IMAGE_ID=docker.pkg.github.com/${{ github.repository }}/$IMAGE_NAME
echo IMAGE_ID=$IMAGE_ID
echo ::set-output name=image_id::$IMAGE_ID
# Strip git ref prefix from version
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
# Strip "v" prefix from tag name
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
# if version is master, set version to dev
[[ "$VERSION" == "master" ]] && VERSION=dev
echo GITHUB_IMAGE_ID=$GITHUB_IMAGE_ID
echo DOCKER_IMAGE_ID=$DOCKER_IMAGE_ID
echo VERSION=$VERSION
echo ::set-output name=version::$VERSION
# tag for Github Registry
docker tag $IMAGE_NAME $GITHUB_IMAGE_ID:$VERSION
[[ "$VERSION" != "dev" ]] && docker tag $IMAGE_NAME $GITHUB_IMAGE_ID:latest
docker push $GITHUB_IMAGE_ID
# tag dev or x.x.x
docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
# tag latest if not a dev release
[[ "$VERSION" != "dev" ]] && docker tag $IMAGE_NAME $IMAGE_ID:latest || true
# tag for Docker Hub
docker tag $IMAGE_NAME $DOCKER_IMAGE_ID:$VERSION
[[ "$VERSION" != "dev" ]] && docker tag $IMAGE_NAME $DOCKER_IMAGE_ID:latest
docker push $DOCKER_IMAGE_ID
- name: Push images to registry
run: docker push ${{ steps.tag_image.outputs.image_id }}
- name: Deploy official images
id: deploy_images
uses: satak/webrequest-action@v1
with:
url: ${{ secrets.DEPLOY_URL }}
method: POST
headers: '{"Authentication": "Token ${{ secrets.DEPLOY_TOKEN }}"}'
payload: '{"version": "${{ steps.tag_image.outputs.version }}"}'
+62
View File
@@ -0,0 +1,62 @@
# vim: ts=2 sw=2:
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
name: Create Release
jobs:
release:
name: Create Release
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
with:
ref: ${{ github.ref }}
- name: Get Version Info
id: get_tag
shell: bash
run: |
SUBJECT=$(/usr/bin/git tag -l ${GITHUB_REF#refs/tags/} --format='%(subject)')
BODY=$(/usr/bin/git tag -l ${GITHUB_REF#refs/tags/} --format='%(body)' | sed '/-----BEGIN PGP SIGNATURE-----/,$d')
echo "SUBJECT=$SUBJECT"
echo "BODY=$BODY"
echo 'tag_subject<<EOS' >> $GITHUB_ENV
echo "$SUBJECT" >> $GITHUB_ENV
echo 'EOS' >> $GITHUB_ENV
echo 'tag_body<<EOB' >> $GITHUB_ENV
echo "$BODY" >> $GITHUB_ENV
echo 'EOB' >> $GITHUB_ENV
echo "tag_version=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
echo "version_num=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- name: Get Changelog Content
id: changelog_reader
uses: mindsers/changelog-reader-action@v2
with:
version: ${{ env.version_num }}
path: ./CHANGELOG.md
- name: Publish Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ env.tag_version }}
release_name: ${{ env.tag_subject }}
body: |
${{ env.tag_body }}
## Changelog
${{ steps.changelog_reader.outputs.changes }}
draft: false
prerelease: false
+17 -1
View File
@@ -7,6 +7,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]
## [2.5.0] - 2020-10-31
### Added
- Italian (`it_hf`, `it_vhf`, `it_shf`), Japanese (`jp`) and Australian (`au`) band charts.
### Fixed
- Details to the Netherlands bandplan command to accurately represent VERNON (Netherlands ARRL equivalent organisation).
- eQSL, paper QSL, and Logbook of the World status in `?qrz` sometimes being shown incorrectly.
- Fixed network error in `?greyline`.
## [2.4.1] - 2020-10-06
### Changed
- Bumped discord.py to 1.5.0
## [2.4.0] - 2020-09-27
### Added
- Canadian prefix info to the `?prefixes` command.
@@ -124,7 +138,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## 1.0.0 - 2019-07-31 [YANKED]
[Unreleased]: https://github.com/miaowware/qrm2/compare/v2.4.0...HEAD
[Unreleased]: https://github.com/miaowware/qrm2/compare/v2.5.0...HEAD
[2.5.0]: https://github.com/miaowware/qrm2/releases/tag/v2.5.0
[2.4.1]: https://github.com/miaowware/qrm2/releases/tag/v2.4.1
[2.4.0]: https://github.com/miaowware/qrm2/releases/tag/v2.4.0
[2.3.2]: https://github.com/miaowware/qrm2/releases/tag/v2.3.2
[2.3.1]: https://github.com/miaowware/qrm2/releases/tag/v2.3.1
-77
View File
@@ -1,77 +0,0 @@
# Contributing to qrm
## Before You Start
- Make sure there's an issue for the feature, bugfix, or other improvement you want to make.
- Make sure it's something that the project maintainers want.
We can discuss it and assign the issue to you.
- Make sure work isn't already being done on the issue.
### Environment Setup
Once all of the above is done, you can get started by setting up your development envronment.
1. [Fork this repo][1] into your own GitHub namespace.
1. Make sure the `master` branch is up to date, then make yourself a new branch with a descriptive name.
1. Once the forked repo is cloned and on the proper branch, you can set up the development environment.
1. Install python 3.7 or higher.
1. Run `make dev-install`.
This should install everything you need to develop and run qrm.
1. [Create a bot and token][2], and add it to `data/keys.py`.
Also add your [QRZ credentials][3] if needed.
1. In `data/options.py`, change values as needed.
Some commands require adding your Discord user ID to `owner_uids`.
1. To activate the virtual env that was created by `make`, run `source botenv/bin/activate` (or the equivelent for your shell or operating system).
## While You Develop
To run qrm, use the command `./run.sh`.
We recommend you use the `--pass-errors` flags to avoid perpetual restart loops if you break the bot.
It exists because repeatedly mashing [Ctrl+C] at high speed to break a fast loop is not fun.
Commit messages should be descriptive and mention issues that they fix ("fixes #123") or contain progress on ("progress on #123").
Make commits as needed, but try to keep it reasonable.
If there are too many, your contribution may be squashed when merged.
You may want to squash your commits locally yourself:
```sh
git reset --soft [commit before your changes]
git commit
```
Make sure to document your code as you go, in both comments and external documentation (in `/dev-notes/`) as needed.
`dev-notes` is especially important if you introduce a new json file format or to document some development process (like the command to crush the various images in the repository).
**Test your changes.**
If your code doesn't work, it's not ready for merging.
Make sure you not only test intended behaviour, but also edge cases and error cases.
Make sure to run `flake8` to ensure your code uses the proper style, and `mypy [files...]` to ensure proper typing.
If you're making a user-facing change, put a quick summary in `CHANGELOG.md` under the `[Unreleased]` heading.
Follow the [Keep a Changelog][4] format.
### A Note on Style
qrm tries to keep to PEP 8 style whenever possible.
Use the utility `flake8` to check that you follow this style.
When you start a PR or push commits, GitHub will automatically run this for you;
if that fails, you will be expected to fix those errors before merge.
Otherwise, try to follow the existing style:
double-quotes except when required to be single,
indentation of mult-line structures matching other examples in the code,
add type hints,
etc.
## When You're Ready to Merge
1. When you have finished working on your contribution, create a pull request from your fork's branch into the master branch of this repository.
1. Read through and complete the pull request template.
If the checklist is not complete, your contribution will not be merged.
1. Your pull request will get reviewed by at least one maintainer.
1. If approved, another maintainer may merge the pull request if everything looks good.
[1]: https://github.com/miaowware/qrm2/fork
[2]: https://discordpy.readthedocs.io/en/latest/discord.html
[3]: https://www.qrz.com/page/xml_data.html
[4]: https://keepachangelog.com/en/1.0.0/
+54
View File
@@ -0,0 +1,54 @@
# Development Guide for qrm
**Make sure to also read [`CONTRIBUTING.md`][0], everything in there applies here.**
### Environment Setup
1. [Fork this repo][1] into your own GitHub namespace.
1. Make sure the `master` branch is up to date, then make yourself a new branch with a descriptive name.
1. Once the forked repo is cloned and on the proper branch, you can set up the development environment.
1. Install python 3.7 or higher.
1. Run `make dev-install`.
This should install everything you need to develop and run qrm.
1. [Create a bot and token][2], and add it to `data/keys.py`.
Also add your [QRZ credentials][3] if needed.
1. In `data/options.py`, change values as needed.
Some commands require adding your Discord user ID to `owner_uids`.
1. To activate the virtual env that was created by `make`, run `source botenv/bin/activate` (or the equivelent for your shell or operating system).
These instructions are fairly \*NIX-centric, so if you would like to develop on Windows, it is suggested that the Windows Subsystem for Linux be used.
## While You Develop
To run qrm, use the command `./run.sh`.
We recommend you use the `--pass-errors` flag to avoid perpetual restart loops if you break the bot.
It exists because repeatedly mashing [Ctrl+C] at high speed to break a fast loop is not fun.
Make sure to add [type hints][4] to your code.
This is what `mypy` validates in the code.
Using `dev-notes` for documentation is especially important if you introduce a new json file format (like for maps and bandplans) or to document some development process (like the command to crush the various images in the repository).
### Test your changes
In addition to testing functionality, make sure to run `flake8` to ensure your code uses the proper style, and `mypy [files...]` to ensure proper typing.
You can also enable them for this project in your IDE if supported.
This will give you automatic and continuous linting and type checking.
### A Note on Style
qrm tries to keep to PEP 8 style whenever possible.
Use the utility `flake8` to check that you follow this style.
When you start a PR or push commits, GitHub will automatically run this for you,
but we prefer that developers check this before committing and opening PRs.
Otherwise, try to follow the existing style:
- double-quotes except when required to be single,
- indentation of mult-line structures matching other examples in the code,
- etc.
[0]: https://github.com/miaowware/.github/blob/master/CONTRIBUTING.md
[1]: https://github.com/miaowware/qrm2/fork
[2]: https://discordpy.readthedocs.io/en/latest/discord.html
[3]: https://www.qrz.com/page/xml_data.html
[4]: https://docs.python.org/3/library/typing.html
+6 -8
View File
@@ -23,16 +23,14 @@ This is the easiest method for running the bot without any modifications.
version: '3'
services:
qrm2:
image: "classabbyamp/qrm2:latest"
# OR
# image: "docker.pkg.github.com/miaowware/qrm2/qrm2:latest"
image: "docker.pkg.github.com/miaowware/qrm2/qrm2:latest"
restart: on-failure
volumes:
- "./data:/app/data:rw"
environment:
- PYTHONUNBUFFERED=1
```
> Note that there are two possible sources for the image: docker's and github's registry. Github's registry requires [a few extra steps](https://docs.github.com/en/packages/using-github-packages-with-your-projects-ecosystem/configuring-docker-for-use-with-github-packages) during the initial setup.
*Note that Github's registry requires [a few extra steps](https://docs.github.com/en/packages/using-github-packages-with-your-projects-ecosystem/configuring-docker-for-use-with-github-packages) during the initial setup.*
3. Create a subdirectory named `data`.
@@ -45,7 +43,7 @@ This is the easiest method for running the bot without any modifications.
$ docker-compose up -d
```
> Run without "-d" to test the bot. (run in foreground)
*Run without "-d" to test the bot (run in foreground).*
@@ -81,7 +79,7 @@ This is the easiest method to run the bot with modifications.
$ docker-compose up -d
```
> Run without "-d" to test the bot. (run in foreground)
*Run without "-d" to test the bot (run in foreground).*
@@ -113,5 +111,5 @@ This methods is not very nice to use.
```
Where `[image]` is either of:
- `discord-qrm2:local-latest` if you are building your own.
- `classabbyamp/discord-qrm2:latest` if you want to use the prebuilt image.
- `qrm2:local-latest` if you are building your own.
- `docker.pkg.github.com/miaowware/qrm2/qrm2:latest` if you want to use the prebuilt image.
+6 -12
View File
@@ -15,11 +15,13 @@ import traceback
from datetime import datetime
from pathlib import Path
from types import SimpleNamespace
from typing import Union
import aiohttp
import discord
import discord.ext.commands as commands
from discord import Emoji, Reaction, PartialEmoji
import data.options as opt
@@ -72,15 +74,6 @@ paths = SimpleNamespace(
# --- Classes ---
class CallsignInfoData:
"""Represents a country's callsign info"""
def __init__(self, data: list):
self.title: str = data[0]
self.desc: str = data[1]
self.calls: str = data[2]
self.emoji: str = data[3]
class ImageMetadata:
"""Represents the metadata of a single image."""
def __init__(self, metadata: list):
@@ -158,7 +151,7 @@ class GlobalChannelConverter(commands.IDConverter):
def embed_factory(ctx: commands.Context) -> discord.Embed:
"""Creates an embed with neutral colour and standard footer."""
embed = discord.Embed(timestamp=datetime.utcnow(), colour=colours.neutral)
embed.set_footer(text=ctx.author, icon_url=str(ctx.author.avatar_url))
embed.set_footer(text=str(ctx.author), icon_url=str(ctx.author.avatar_url))
return embed
@@ -175,11 +168,12 @@ def error_embed_factory(ctx: commands.Context, exception: Exception, debug_mode:
return embed
async def add_react(msg: discord.Message, react: str):
async def add_react(msg: discord.Message, react: Union[Emoji, Reaction, PartialEmoji, str]):
try:
await msg.add_reaction(react)
except discord.Forbidden:
print(f"[!!] Missing permissions to add reaction in '{msg.guild.id}/{msg.channel.id}'!")
idpath = (f"{msg.guild.id}/" if msg.guild else "") + str(msg.channel.id)
print(f"[!!] Missing permissions to add reaction in '{idpath}'!")
# --- Checks ---
+1 -1
View File
@@ -1,3 +1,3 @@
-r requirements.txt
flake8
discord.py-stubs
discord.py-stubs==1.5.0
-1
View File
@@ -108,7 +108,6 @@ class BaseCog(commands.Cog):
embed = cmn.embed_factory(ctx)
embed.title = "About qrm"
embed.description = info.description
embed.add_field(name="Authors", value=", ".join(info.authors))
embed.add_field(name="License", value=info.license)
embed.add_field(name="Version", value=f"v{info.release}")
+32 -33
View File
@@ -11,6 +11,7 @@ the GNU General Public License, version 2.
import math
from enum import Enum
from typing import Optional
from dataclasses import dataclass
import discord.ext.commands as commands
@@ -21,49 +22,47 @@ from data import options as opt
# not sure why but UnitConverter and Unit need to be defined before DbConvCog and convert()
class UnitConverter(commands.Converter):
async def convert(self, ctx: commands.Context, argument: str):
is_db = None
mult = None
unit = None
utype = None
try:
return Unit(argument)
s = argument.lower()
if len(s) > 2 and s[:2] == "db":
is_db = True
if s[2:] in units:
u = units[s[2:]]
mult = u["mult"]
unit = u["log"]
utype = u["type"]
elif s in units:
is_db = False
u = units[s]
mult = u["mult"]
unit = u["scalar"]
utype = u["type"]
else:
raise ValueError(f"Invalid unit: {argument}")
return Unit(argument, unit, utype, is_db, mult)
except ValueError as e:
raise commands.BadArgument(message=str(e))
class Unit:
def __init__(self, raw: str):
self.raw: str = raw
self.unit: str
self.type: UnitType
self.is_db: bool
self.mult: int
self._parse()
def _parse(self):
s = self.raw.lower()
if len(s) > 2 and s[:2] == "db":
self.is_db = True
if s[2:] in units:
u = units[s[2:]]
self.mult = u["mult"]
self.unit = u["log"]
self.type = u["type"]
elif s in units:
self.is_db = False
u = units[s]
self.mult = u["mult"]
self.unit = u["scalar"]
self.type = u["type"]
else:
raise ValueError(f"Invalid unit: {self.raw}")
def __str__(self):
return self.unit
class UnitType(Enum):
voltage = 1
power = 2
antenna = 3
@dataclass
class Unit:
raw: str
unit: str
type: UnitType
is_db: bool
mult: int
class DbConvCog(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
@@ -85,7 +84,7 @@ class DbConvCog(commands.Cog):
if value is not None and unit_from is not None and unit_to is not None:
converted = convert(value, unit_from, unit_to)
embed.title = f"{value:.3g} {unit_from} = {converted:.3g} {unit_to}"
embed.title = f"{value:.3g} {unit_from.unit} = {converted:.3g} {unit_to.unit}"
embed.colour = cmn.colours.good
else:
embed.title = "Decibel Quick Reference"
+1 -1
View File
@@ -19,7 +19,7 @@ import common as cmn
class FunCog(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
with open("resources/words") as words_file:
with open(cmn.paths.resources / "words") as words_file:
self.words = words_file.read().lower().splitlines()
@commands.command(name="xkcd", aliases=["x"], category=cmn.cat.fun)
+5 -12
View File
@@ -8,8 +8,6 @@ the GNU General Public License, version 2.
"""
import io
import aiohttp
import discord
@@ -85,16 +83,11 @@ class ImageCog(commands.Cog):
@commands.command(name="grayline", aliases=["greyline", "grey", "gray", "gl"], category=cmn.cat.maps)
async def _grayline(self, ctx: commands.Context):
"""Gets a map of the current greyline, where HF propagation is the best."""
async with ctx.typing():
embed = cmn.embed_factory(ctx)
embed.title = "Current Greyline Conditions"
embed.colour = cmn.colours.good
async with self.session.get(self.gl_url) as resp:
if resp.status != 200:
raise cmn.BotHTTPError(resp)
data = io.BytesIO(await resp.read())
embed.set_image(url="attachment://greyline.jpg")
await ctx.send(embed=embed, file=discord.File(data, "greyline.jpg"))
embed = cmn.embed_factory(ctx)
embed.title = "Current Greyline Conditions"
embed.colour = cmn.colours.good
embed.set_image(url=self.gl_url)
await ctx.send(embed=embed)
def setup(bot: commands.Bot):
+6 -2
View File
@@ -9,6 +9,7 @@ the GNU General Public License, version 2.
import threading
from pathlib import Path
from ctyparser import BigCty
@@ -17,11 +18,14 @@ from discord.ext import commands, tasks
import common as cmn
cty_path = Path("./data/cty.json")
class LookupCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
try:
self.cty = BigCty("./data/cty.json")
self.cty = BigCty(cty_path)
except OSError:
self.cty = BigCty()
@@ -67,7 +71,7 @@ class LookupCog(commands.Cog):
@tasks.loop(hours=24)
async def _update_cty(self):
update = threading.Thread(target=run_update, args=(self.cty, "./data/cty.json"))
update = threading.Thread(target=run_update, args=(self.cty, cty_path))
update.start()
+3 -3
View File
@@ -146,15 +146,15 @@ def qrz_process_info(data: dict):
if address == "":
address = None
if "eqsl" in data:
eqsl = "Yes" if data["eqsl"] == 1 else "No"
eqsl = "Yes" if data["eqsl"] == "1" else "No"
else:
eqsl = "Unknown"
if "mqsl" in data:
mqsl = "Yes" if data["mqsl"] == 1 else "No"
mqsl = "Yes" if data["mqsl"] == "1" else "No"
else:
mqsl = "Unknown"
if "lotw" in data:
lotw = "Yes" if data["lotw"] == 1 else "No"
lotw = "Yes" if data["lotw"] == "1" else "No"
else:
lotw = "Unknown"
+41 -58
View File
@@ -8,12 +8,10 @@ the GNU General Public License, version 2.
"""
import io
import re
import aiohttp
import discord
import discord.ext.commands as commands
import common as cmn
@@ -29,16 +27,11 @@ class WeatherCog(commands.Cog):
@commands.command(name="bandconditions", aliases=["cond", "condx", "conditions"], category=cmn.cat.weather)
async def _band_conditions(self, ctx: commands.Context):
"""Gets a solar conditions report."""
async with ctx.typing():
embed = cmn.embed_factory(ctx)
embed.title = "Current Solar Conditions"
embed.colour = cmn.colours.good
async with self.session.get("http://www.hamqsl.com/solarsun.php") as resp:
if resp.status != 200:
raise cmn.BotHTTPError(resp)
data = io.BytesIO(await resp.read())
embed.set_image(url="attachment://condx.png")
await ctx.send(embed=embed, file=discord.File(data, "condx.png"))
embed = cmn.embed_factory(ctx)
embed.title = "Current Solar Conditions"
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.cat.weather)
async def _weather_conditions(self, ctx: commands.Context):
@@ -61,63 +54,53 @@ class WeatherCog(commands.Cog):
async def _weather_conditions_forecast(self, ctx: commands.Context, *, location: str):
"""Gets local weather forecast for the next three days from [wttr.in](http://wttr.in/).
See help of the `weather` command for possible location types and options."""
async with ctx.typing():
try:
units_arg = re.search(self.wttr_units_regex, location).group(1)
except AttributeError:
units_arg = ""
if units_arg.lower() == "f":
units = "u"
elif units_arg.lower() == "c":
units = "m"
else:
units = ""
try:
units_arg = re.search(self.wttr_units_regex, location).group(1)
except AttributeError:
units_arg = ""
if units_arg.lower() == "f":
units = "u"
elif units_arg.lower() == "c":
units = "m"
else:
units = ""
loc = self.wttr_units_regex.sub("", location).strip()
loc = self.wttr_units_regex.sub("", location).strip()
embed = cmn.embed_factory(ctx)
embed.title = f"Weather Forecast for {loc}"
embed.description = "Data from [wttr.in](http://wttr.in/)."
embed.colour = cmn.colours.good
embed = cmn.embed_factory(ctx)
embed.title = f"Weather Forecast for {loc}"
embed.description = "Data from [wttr.in](http://wttr.in/)."
embed.colour = cmn.colours.good
loc = loc.replace(" ", "+")
async with self.session.get(f"http://wttr.in/{loc}_{units}pnFQ.png") as resp:
if resp.status != 200:
raise cmn.BotHTTPError(resp)
data = io.BytesIO(await resp.read())
embed.set_image(url="attachment://wttr_forecast.png")
await ctx.send(embed=embed, file=discord.File(data, "wttr_forecast.png"))
loc = loc.replace(" ", "+")
embed.set_image(url=f"http://wttr.in/{loc}_{units}pnFQ.png")
await ctx.send(embed=embed)
@_weather_conditions.command(name="now", aliases=["n"], category=cmn.cat.weather)
async def _weather_conditions_now(self, ctx: commands.Context, *, location: str):
"""Gets current local weather conditions from [wttr.in](http://wttr.in/).
See help of the `weather` command for possible location types and options."""
async with ctx.typing():
try:
units_arg = re.search(self.wttr_units_regex, location).group(1)
except AttributeError:
units_arg = ""
if units_arg.lower() == "f":
units = "u"
elif units_arg.lower() == "c":
units = "m"
else:
units = ""
try:
units_arg = re.search(self.wttr_units_regex, location).group(1)
except AttributeError:
units_arg = ""
if units_arg.lower() == "f":
units = "u"
elif units_arg.lower() == "c":
units = "m"
else:
units = ""
loc = self.wttr_units_regex.sub("", location).strip()
loc = self.wttr_units_regex.sub("", location).strip()
embed = cmn.embed_factory(ctx)
embed.title = f"Current Weather for {loc}"
embed.description = "Data from [wttr.in](http://wttr.in/)."
embed.colour = cmn.colours.good
embed = cmn.embed_factory(ctx)
embed.title = f"Current Weather for {loc}"
embed.description = "Data from [wttr.in](http://wttr.in/)."
embed.colour = cmn.colours.good
loc = loc.replace(" ", "+")
async with self.session.get(f"http://wttr.in/{loc}_0{units}pnFQ.png") as resp:
if resp.status != 200:
raise cmn.BotHTTPError(resp)
data = io.BytesIO(await resp.read())
embed.set_image(url="attachment://wttr_now.png")
await ctx.send(embed=embed, file=discord.File(data, "wttr_now.png"))
loc = loc.replace(" ", "+")
embed.set_image(url=f"http://wttr.in/{loc}_0{units}pnFQ.png")
await ctx.send(embed=embed)
def setup(bot: commands.Bot):
+1 -1
View File
@@ -12,5 +12,5 @@ authors = ("@ClassAbbyAmplifier#2229", "@0x5c#0639")
description = """A bot with various useful ham radio-related functions, written in Python."""
license = "Released under the GNU General Public License v2"
contributing = "Check out the source on GitHub, contributions welcome: https://github.com/miaowware/qrm2"
release = "2.4.0"
release = "2.5.0"
bot_server = "https://discord.gg/Ntbg3J4"
+12 -2
View File
@@ -44,9 +44,19 @@ debug_mode = opt.debug # Separate assignement in-case we define an override (te
loop = asyncio.get_event_loop()
connector = loop.run_until_complete(conn.new_connector())
# Defining the intents
intents = discord.Intents.none()
intents.guilds = True
intents.guild_messages = True
intents.dm_messages = True
member_cache = discord.MemberCacheFlags.from_intents(intents)
bot = commands.Bot(command_prefix=opt.prefix,
case_insensitive=True,
description=info.description, help_command=commands.MinimalHelpCommand(),
intents=intents,
member_cache=member_cache,
loop=loop,
connector=connector)
@@ -88,7 +98,7 @@ async def _extctl(ctx: commands.Context):
"""Extension control commands.
Defaults to `list` if no subcommand specified"""
if ctx.invoked_subcommand is None:
cmd = bot.get_command("extctl list")
cmd = _extctl_list
await ctx.invoke(cmd)
@@ -156,7 +166,7 @@ async def on_command_error(ctx: commands.Context, err: commands.CommandError):
await cmn.add_react(ctx.message, cmn.emojis.warning)
await ctx.send_help(ctx.command)
elif isinstance(err, commands.CommandNotFound):
if ctx.invoked_with.startswith(("?", "!")):
if ctx.invoked_with and ctx.invoked_with.startswith(("?", "!")):
return
else:
await cmn.add_react(ctx.message, cmn.emojis.question)
+5 -5
View File
@@ -1,5 +1,5 @@
discord.py==1.3.4
ctyparser==2.0.0.post1
beautifulsoup4==4.9.1
lxml==4.5.2
pytz==2020.1
discord.py~=1.5.0
ctyparser~=2.0
beautifulsoup4
lxml
pytz
+14 -4
View File
@@ -7,12 +7,22 @@ This file is part of discord-qrmbot and is released under the terms of
the GNU General Public License, version 2.
"""
from dataclasses import dataclass
from .callsigninfos import (us, ca)
from common import CallsignInfoData
# format: country: (title, description, text)
@dataclass
class CallsignInfoData:
"""Represents a country's callsign info"""
title: str = ""
desc: str = ""
calls: str = ""
emoji: str = ""
options = {
"us": CallsignInfoData([us.title, us.desc, us.calls, us.emoji]),
"ca": CallsignInfoData([ca.title, ca.desc, ca.calls, ca.emoji]),
"us": CallsignInfoData(us.title, us.desc, us.calls, us.emoji),
"ca": CallsignInfoData(ca.title, ca.desc, ca.calls, ca.emoji),
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 416 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

+6 -1
View File
@@ -1,7 +1,12 @@
{
"au": ["au.png", "Australia", "Amateur radio bands in Australia", "", "[Radio Amateur Society of Australia](https://vkradioamateurs.org/its-my-frequency-and-ill-cry-if-i-want-to/) [[PDF]](https://vkradioamateurs.org/wp-content/uploads/2018/05/VK-Band-Plan-Quick-Reference-1.pdf)", "🇦🇺"],
"ca": ["ca.png", "Canada", "Amateur radio bands in Canada", "**This bandplan is incomplete**; some bands, like 630m, are simply not present. It also does not cover any band above 30MHz.", "[RAC 0-30MHz Band Plan](https://www.rac.ca/wp-content/uploads/files/pdf/RAC%20Bandplan%20December%201%202015.pdf)", "🇨🇦"],
"cn": ["cn.png", "China", "Amateur radio bands in China", "", "Created by KN8U and NY7H", "🇨🇳"],
"it_hf": ["it_hf.png", "Italy (HF)", "HF amateur radio bands in Italy", "", "[Associazione Radioamatori Italiani](https://www.arimi.it/download/bandplan/) [[PDF]](http://www.arimi.it/wp-content/Plan/BP%20HF%202013%2032.pdf)", "🇮🇹"],
"it_vhf": ["it_vhf.png", "Italy (VHF/UHF)", "VHF/UHF amateur radio bands in Italy", "", "[Associazione Radioamatori Italiani](https://www.arimi.it/download/bandplan/) [[PDF]](https://www.arimi.it/wp-content/Plan/BP%20V_UHF%202013%2032.pdf)", "🇮🇹"],
"it_shf": ["it_shf.png", "Italy (UHF/SHF)", "UHF/SHF amateur radio bands in Italy", "", "[Associazione Radioamatori Italiani](https://www.arimi.it/download/bandplan/) [[PDF]](https://www.arimi.it/wp-content/Plan/BP%20U-SHF.pdf)", "🇮🇹"],
"jp": ["jp.png", "Japan", "Amateur radio bands in Japan", "Pending checks against the latest update from the 総務省 (MIC) of Japan, March 2020", "[JARL Amateur-Use Bandplans](https://jarl.org/Japanese/A_Shiryo/A-3_Band_Plan/bandplan20150105.pdf)", "🇯🇵"],
"mx": ["mx.png", "Mexico", "Radio allocations in Mexico", "Full radio allocations chart for all services. No information specific to amateur radio is shown.", "Secretaría de Comunicaciones y Transportes (SCT) / Instituto Federal de Telecomunicaciones (IFT)", "🇲🇽"],
"nl": ["nl.png", "Netherlands", "Amateur radio bands in the Netherlands", "", "", "🇳🇱"],
"nl": ["nl.png", "Netherlands", "Amateur radio bands in the Netherlands", "*This version of this bandplan is no longer hosted on VERNON's website and it's accuracy cannot be guaranteed.*", "[VERNON Global Band Plan van de Telecom Agency, Ministerie van Economische Zaken en Klimaat](https://www.veron.nl/downloads/brochures/)", "🇳🇱"],
"us": ["us.png", "USA", "Amateur radio bands in the USA", "", "*[ARRL Frequency Chart](https://www.arrl.org/shop/ARRL-Frequency-Chart-11-17/)* [[PDF]](http://www.arrl.org/files/file/Regulatory/Band%20Chart/Band%20Chart%20-%2011X17%20Color.pdf)", "🇺🇸"]
}
+5 -5
View File
@@ -1,10 +1,10 @@
{
"arrl": ["arrl-rac.png", "ARRL Sections", "ARRL Sections", "", "[EI8IC](https://www.mapability.com/ei8ic/maps/maps.php)", "🇺🇸"],
"rac": ["arrl-rac.png", "RAC Sections", "RAC Sections", "", "[EI8IC](https://www.mapability.com/ei8ic/maps/maps.php)", "🇨🇦"],
"ca": ["ca.png", "Canada's Prefixes", "Map of the prefix regions in Canada", "", "[Denelson83 (Wikimedia Commons)](https://commons.wikimedia.org/wiki/File:Amateur_radio_prefixes_in_Canada.svg)", "🇨🇦"],
"cn": ["cn.png", "China's Prefixes", "Map of prefix regions in China", "", "CRAC", "🇨🇳"],
"us": ["us.png", "USA's Prefixes", "Map of prefix regions in the USA", "", "*[ARRL WAS Map](https://www.arrl.org/was-forms)* [[PDF]](http://www.arrl.org/files/file/Awards%20Application%20Forms/WASmap_Color.pdf)", "🇺🇸"],
"ca": ["ca.png", "Canada's Prefixes", "Map of the prefix regions in Canada", "", "[Denelson83 (Wikimedia Commons)](https://commons.wikimedia.org/wiki/File:Amateur_radio_prefixes_in_Canada.svg)", "🇨🇦"],
"ituz": ["itu-zones.png", "ITU Zones", "ITU Zones", "", "[EI8IC](https://www.mapability.com/ei8ic/maps/maps.php)", "🇺🇳"],
"itur": ["itu-regions.png", "ITU Regions", "ITU Regions", "These are also used by the IARU for their regions.", "[EI8IC](https://www.mapability.com/ei8ic/maps/maps.php)", "🇺🇳"],
"cq": ["cq-zones.png", "CQ Zones", "CQ Zones", "These are used for the CQWW contest.", "[EI8IC](https://www.mapability.com/ei8ic/maps/maps.php)", "🌐"]
"ituz": ["itu-zones.png", "ITU Zones", "ITU Zones", "", "[EI8IC](https://www.mapability.com/ei8ic/maps/maps.php)", "🇺🇳"],
"arrl": ["arrl-rac.png", "ARRL Sections", "ARRL Sections", "", "[EI8IC](https://www.mapability.com/ei8ic/maps/maps.php)", "🇺🇸"],
"cq": ["cq-zones.png", "CQ Zones", "CQ Zones", "These are used for the CQWW contest.", "[EI8IC](https://www.mapability.com/ei8ic/maps/maps.php)", "🌐"],
"rac": ["arrl-rac.png", "RAC Sections", "RAC Sections", "", "[EI8IC](https://www.mapability.com/ei8ic/maps/maps.php)", "🇨🇦"]
}