basic discord bot stuff

This commit is contained in:
sneakers-the-rat 2022-10-11 19:40:33 -07:00
parent 8d2b92e319
commit e4ba87171b
6 changed files with 205 additions and 4 deletions

95
poetry.lock generated
View file

@ -1,3 +1,42 @@
[[package]]
name = "aiohttp"
version = "3.8.3"
description = "Async http client/server framework (asyncio)"
category = "main"
optional = false
python-versions = ">=3.6"
[package.dependencies]
aiosignal = ">=1.1.2"
async-timeout = ">=4.0.0a3,<5.0"
attrs = ">=17.3.0"
charset-normalizer = ">=2.0,<3.0"
frozenlist = ">=1.1.1"
multidict = ">=4.5,<7.0"
yarl = ">=1.0,<2.0"
[package.extras]
speedups = ["aiodns", "brotli", "cchardet"]
[[package]]
name = "aiosignal"
version = "1.2.0"
description = "aiosignal: a list of registered asynchronous callbacks"
category = "main"
optional = false
python-versions = ">=3.6"
[package.dependencies]
frozenlist = ">=1.1.0"
[[package]]
name = "async-timeout"
version = "4.0.2"
description = "Timeout context manager for asyncio programs"
category = "main"
optional = false
python-versions = ">=3.6"
[[package]] [[package]]
name = "atomicwrites" name = "atomicwrites"
version = "1.4.0" version = "1.4.0"
@ -10,7 +49,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
name = "attrs" name = "attrs"
version = "21.4.0" version = "21.4.0"
description = "Classes Without Boilerplate" description = "Classes Without Boilerplate"
category = "dev" category = "main"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
@ -58,6 +97,23 @@ python-versions = "*"
[package.extras] [package.extras]
test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"]
[[package]]
name = "discord.py"
version = "2.0.1"
description = "A Python wrapper for the Discord API"
category = "main"
optional = false
python-versions = ">=3.8.0"
[package.dependencies]
aiohttp = ">=3.7.4,<4"
[package.extras]
voice = ["PyNaCl (>=1.3.0,<1.6)"]
test = ["typing-extensions (>=4.3,<5)", "pytest-mock", "pytest-cov", "pytest-asyncio", "pytest", "coverage"]
speed = ["cchardet (==2.1.7)", "brotli", "aiodns (>=1.1)", "orjson (>=3.5.4)"]
docs = ["typing-extensions (>=4.3,<5)", "sphinxcontrib-websupport", "sphinxcontrib-trio (==1.1.2)", "sphinx (==4.4.0)"]
[[package]] [[package]]
name = "faker" name = "faker"
version = "15.1.0" version = "15.1.0"
@ -69,6 +125,14 @@ python-versions = ">=3.7"
[package.dependencies] [package.dependencies]
python-dateutil = ">=2.4" python-dateutil = ">=2.4"
[[package]]
name = "frozenlist"
version = "1.3.1"
description = "A list-like structure which implements collections.abc.MutableSequence"
category = "main"
optional = false
python-versions = ">=3.7"
[[package]] [[package]]
name = "idna" name = "idna"
version = "3.3" version = "3.3"
@ -85,6 +149,14 @@ category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
[[package]]
name = "multidict"
version = "6.0.2"
description = "multidict implementation"
category = "main"
optional = false
python-versions = ">=3.7"
[[package]] [[package]]
name = "oauthlib" name = "oauthlib"
version = "3.2.0" version = "3.2.0"
@ -316,12 +388,27 @@ brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"]
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[[package]]
name = "yarl"
version = "1.8.1"
description = "Yet another URL library"
category = "main"
optional = false
python-versions = ">=3.7"
[package.dependencies]
idna = ">=2.0"
multidict = ">=4.0"
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.9" python-versions = "^3.9"
content-hash = "c5c99285ff355e2be2ef7a9133813b15c6b445b52f191f5720911d059b937750" content-hash = "a12006faa296b74e34d600ab7300f2926d58c153fa76c15a5b73f7c91077b6ab"
[metadata.files] [metadata.files]
aiohttp = []
aiosignal = []
async-timeout = []
atomicwrites = [ atomicwrites = [
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
@ -346,7 +433,9 @@ commonmark = [
{file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
{file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
] ]
"discord.py" = []
faker = [] faker = []
frozenlist = []
idna = [ idna = [
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
{file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
@ -355,6 +444,7 @@ iniconfig = [
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
] ]
multidict = []
oauthlib = [ oauthlib = [
{file = "oauthlib-3.2.0-py3-none-any.whl", hash = "sha256:6db33440354787f9b7f3a6dbd4febf5d0f93758354060e802f6c06cb493022fe"}, {file = "oauthlib-3.2.0-py3-none-any.whl", hash = "sha256:6db33440354787f9b7f3a6dbd4febf5d0f93758354060e802f6c06cb493022fe"},
{file = "oauthlib-3.2.0.tar.gz", hash = "sha256:23a8208d75b902797ea29fd31fa80a15ed9dc2c6c16fe73f5d346f83f6fa27a2"}, {file = "oauthlib-3.2.0.tar.gz", hash = "sha256:23a8208d75b902797ea29fd31fa80a15ed9dc2c6c16fe73f5d346f83f6fa27a2"},
@ -419,3 +509,4 @@ urllib3 = [
{file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
{file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},
] ]
yarl = []

View file

@ -18,6 +18,7 @@ rich = "^12.4.4"
parse = "^1.19.0" parse = "^1.19.0"
pywikibot = "^7.7.0" pywikibot = "^7.7.0"
pyparsing = "^3.0.9" pyparsing = "^3.0.9"
"discord.py" = "^2.0.1"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
pytest = "^7.1.2" pytest = "^7.1.2"

View file

@ -0,0 +1,8 @@
"""
Bots that listen to different sources.
Quick and dirty for now, not bothering to generalize this, but in the future
would be nice to be able to have multiple clients listening to different sources,
apply (contextually modified) actions, and then optionally send on to some interface/format
"""

View file

@ -0,0 +1,85 @@
import discord
from discord import Client, Intents
from wiki_postbot.creds import Discord_Creds
from wiki_postbot.patterns.wikilink import Wikilink
from discord.ext import commands
from discord import Emoji
intents = Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='/', intents=intents)
DEBUG = False
@bot.event
async def on_message(message:discord.Message):
print(message)
if message.content == 'ping':
await message.channel.send('pong')
if 'good bot' in message.content:
await message.add_reaction("❤️‍🔥")
wl = Wikilink.parse(message.content)
if len(wl) > 0:
if DEBUG:
await message.channel.send(f"Wikilinks detected: \n" + '\n'.join([str(l) for l in wl]))
else:
await message.add_reaction("")
await bot.process_commands(message)
@bot.command()
async def debug(ctx:discord.ext.commands.Context, arg):
print('debug command')
global DEBUG
if arg == "on":
DEBUG = True
await ctx.message.add_reaction("🧪")
elif arg == "off":
DEBUG = False
await ctx.message.add_reaction("🤐")
else:
await ctx.message.reply("usage: /debug off or /debug on")
# @bot.command
#
# class MyClient(Client):
#
# def __init__(self, intents=None, **kwargs):
# if intents is None:
# intents = Intents.default()
# intents.message_content = True
#
# super(MyClient, self).__init__(intents=intents, **kwargs)
#
#
# async def on_ready(self):
# print('Logged on as', self.user)
#
# async def on_message(self, message):
# print(message)
# # don't respond to ourselves
# if message.author == self.user:
# return
#
# if message.content == 'ping':
# await message.channel.send('pong')
#
# wl = Wikilink.parse(message.content)
# if len(wl)>0:
# await message.channel.send(f"Wikilinks detected: \n" + '\n'.join([str(l) for l in wl]))
if __name__ == "__main__":
creds = Discord_Creds.from_json('discord_creds.json')
# client = MyClient()
# client.run(creds.token)
bot.run(creds.token)

View file

@ -32,3 +32,12 @@ class Zenodo_Creds:
creds = json.load(jfile) creds = json.load(jfile)
return Zenodo_Creds(**creds) return Zenodo_Creds(**creds)
@dataclass
class Discord_Creds:
token:str
@classmethod
def from_json(cls, path:Path) -> 'Discord_Creds':
with open(path, 'r') as jfile:
creds = json.load(jfile)
return Discord_Creds(**creds)

View file

@ -1,8 +1,9 @@
import re import re
from wiki_postbot.patterns import Pattern from wiki_postbot.patterns.patterns import Pattern
from dataclasses import dataclass from dataclasses import dataclass
from typing import Optional, Union, List from typing import Optional, Union, List
import pyparsing as pp import pyparsing as pp
from pprint import pformat
WIKILINK = re.compile(r'\[\[(.*?)\]\]', re.IGNORECASE) WIKILINK = re.compile(r'\[\[(.*?)\]\]', re.IGNORECASE)
@ -73,6 +74,9 @@ class NBack:
def __eq__(self, other:'NBack'): def __eq__(self, other:'NBack'):
return all([getattr(self, f) == getattr(other, f) for f in self.FIELDS]) return all([getattr(self, f) == getattr(other, f) for f in self.FIELDS])
def __repr__(self) -> str:
return pformat({f:getattr(self, f) for f in self.FIELDS})
class Wikilink(Pattern): class Wikilink(Pattern):
""" """
Pattern for detecting wikilinks! Pattern for detecting wikilinks!
@ -84,7 +88,7 @@ class Wikilink(Pattern):
In each of the following examples, `LINK` is a placeholder for the text of the wikilink to be made. In each of the following examples, `LINK` is a placeholder for the text of the wikilink to be made.
# N-Back Links # N-Back Links (see :class:`.NBack`)
For all of these, whitespace in-between the n-back specifier and the link text will be ignored. So For all of these, whitespace in-between the n-back specifier and the link text will be ignored. So
`[[^LINK]]` and `[[^ LINK]]` are both valid. `[[^LINK]]` and `[[^ LINK]]` are both valid.
@ -171,5 +175,8 @@ class Wikilink(Pattern):
def __eq__(self, other:'Wikilink'): def __eq__(self, other:'Wikilink'):
return all(getattr(self, f) == getattr(other, f) for f in self.FIELDS) return all(getattr(self, f) == getattr(other, f) for f in self.FIELDS)
def __repr__(self) -> str:
return pformat({f:getattr(self, f) for f in self.FIELDS if getattr(self, f) is not None})