ERROR: Unrecoverable exception thrown when parsing ./help_text_gen.py! This should NEVER happen.
If encountered, please open an issue: https://github.com/PyCQA/isort/issues/new
Traceback (most recent call last):
File "/Users/bryanhu/.pyenv/versions/3.6.0/bin/isort", line 8, in <module>
sys.exit(main())
File "/Users/bryanhu/.pyenv/versions/3.6.0/lib/python3.6/site-packages/isort/main.py", line 953, in main
for sort_attempt in attempt_iterator:
File "/Users/bryanhu/.pyenv/versions/3.6.0/lib/python3.6/site-packages/isort/main.py", line 947, in <genexpr>
for file_name in file_names
File "/Users/bryanhu/.pyenv/versions/3.6.0/lib/python3.6/site-packages/isort/main.py", line 100, in sort_imports
**kwargs,
File "/Users/bryanhu/.pyenv/versions/3.6.0/lib/python3.6/site-packages/isort/api.py", line 303, in sort_file
with io.File.read(filename) as source_file:
AttributeError: type object 'File' has no attribute 'read'
My code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Initial author: Bryan Hu .
@ThatXliner .
Version: v0.1.0
A discord bot for `chat@vcs (Discord)`
Because we need it.
"""
import asyncio
import json
import random
import sys
import datetime
import aiohttp
import discord
from bs4 import BeautifulSoup
# from rich.traceback import install
# install(theme="monokai") # For better error messages
# from typing import Iterable
# NOTE: In the future, we'll be using discord.Role instead of IDs
# Intent chooser
intents = discord.Intents.all()
client = discord.Client(intents=intents)
PREFIX = "bb"
TOKEN = "SECRET"
with open("help_text.json", mode="rt") as f:
HELP_TEXT = json.loads(f.read())
@client.event
async def on_ready() -> None:
print(
"We have logged in as {0.user}. All systems go!".format(client), file=sys.stderr
)
@client.event
async def on_message(message: discord.Message) -> None:
try:
# Shortened versions
CHANNEL: discord.TextChannel = message.channel
SEND = CHANNEL.send # NOTE: Is it preferred to do `SEND` or `CHANNEL.send`
GUILD: discord.Guild = message.guild
AUTHOR: discord.Member = message.author
if AUTHOR.bot: # It is a bot
return
STATUS_UPDATE_CHANNEL = GUILD.get_channel(766077636975788072)
LOG_CHANNEL = GUILD.get_channel(773686991212380161)
# Useful constants
MENTIONED: bool = False
_ = GUILD.get_role
ROLES = { # These are in here because of dynamicism
"Role #1": _(766780249589153873),
"Role #2": _(766780358908837898),
"Role #3": _(766780549930156042),
"Role #4": _(766780732089434162),
"Role #5": _(766780860157919232),
"Role #6": _(766781042916196382),
"Verify | Pending": _(766066811963179029),
"Verify | In progress": _(766110909755293746),
"Verified": _(766057652400160818),
"Administrator": _(766032588829491200),
"Assistants": _(766063222360375326),
"Moderators": _(766030895215542303),
}
NEED_VERIFY = [
ROLES["Role #1"],
ROLES["Role #2"],
ROLES["Role #3"],
ROLES["Role #4"],
ROLES["Role #5"],
ROLES["Role #6"],
ROLES["Verify | Pending"],
ROLES["Verify | In progress"],
]
IS_PREVILEGED: bool = AUTHOR.roles in (
ROLES["Administrator"],
ROLES["Assistants"],
ROLES["Moderators"],
)
async def command_delete(messages: int) -> None:
await CHANNEL.purge(limit=messages)
await SEND(
f"I have deleted {int(lexed_message[1])} messages! :partying_face:",
delete_after=1,
)
async def command_verify() -> None:
if IS_PREVILEGED:
try:
person_to_verify: discord.Member = GUILD.get_member(int(arg2[3:-1]))
except IndexError:
await SEND(
"You must enter the @Mention of the person to verify. ;-;"
)
else:
if (
person_to_verify is not None
and person_to_verify in CHANNEL.members
):
# Add the "Verified" role
await person_to_verify.add_roles(
ROLES["VERIFIED"],
reason="Automatic role verification.",
)
# Remove the "need verification" roles
await person_to_verify.remove_roles(
[
role
for role in person_to_verify.roles
if role in NEED_VERIFY
],
reason="Automatic role verification.",
)
await SEND("Done! Updating status message...")
# Update the status message
await STATUS_UPDATE_CHANNEL.send(
f"STATUS UPDATE:\n{person_to_verify.mention} : Verified"
)
else:
await SEND("That person does not exist in this server.")
else:
await SEND(
f"Sorry, {AUTHOR.mention},"
" you don't have permission to use that."
)
async def command_meme() -> None:
provider = random.choice(("imgflip", "memedroid"))
async with aiohttp.ClientSession() as session:
if provider == "imgflip":
async with session.get(
f"https://imgflip.com/?page={random.randint(0,10)}"
) as response:
html = BeautifulSoup(await response.text(), features="lxml")
image_url = (
"https:"
+ random.choice(
html.find_all("img", attrs={"class": "base-img"})
)["src"]
)
elif provider == "memedroid":
async with session.get("https://www.memedroid.com/") as response:
soup = BeautifulSoup(await response.text(), features="lxml")
image_url = random.choice(
[
str(img.get("src"))
for img in soup.find_all(class_="img-responsive")
if str(img.get("src")).startswith("https://")
]
)
await SEND(image_url)
async def command_help() -> None:
if arg2 is None:
await SEND(HELP_TEXT["main"])
else:
command_to_help = HELP_TEXT.get(arg2)
await SEND(
command_to_help
if command_to_help is not None
else "Invalid help choice ;-;"
)
# Message parsing
_ = message.content
if _.lstrip().startswith(PREFIX):
_ = _[len(PREFIX) :] # If this fails (i.e. IndexError) we'll catch it
MENTIONED = True
elif client.user in message.mentions:
_ = _.replace(f"<@!{client.user.id}>", "") # Pinging the bot
MENTIONED = True
# Main driver point
if MENTIONED:
# NOTE(ThatXliner): Should we put this in "message parsing"?
lexed_message = _.split()
try:
arg2 = lexed_message[1]
except IndexError:
arg2 = None
# We do the following for case insensitivity
COMMAND: str = lexed_message[0].lower() # Case insensitive
# The reason why we make our own message parsing system
# is because of *control*. I want full control of
# parsing, etc because I might make this into a
# framework...
# COMMAND: Ping
if COMMAND == "ping":
await SEND("pong")
# COMMAND: Delete
elif COMMAND in {"!", "del", "delete"}:
if arg2 is None:
arg2 = 0
await command_delete(int(arg2) + 1)
# COMMAND: Verify
elif COMMAND in {"v", "verify"}:
await command_verify()
# COMMAND: Help
elif COMMAND in {"help", "h"}:
await command_help()
# COMMAND: Meme
elif COMMAND in {"m", "meme", "memes"}:
await command_meme()
else:
await SEND("Invalid command ;-;")
except IndexError as e: # `CLEAN_MESSAGE = CLEAN_MESSAGE[1:]` from 85:13 failed
print(e)
await SEND("mhm?")
except Exception as e:
await LOG_CHANNEL.send("Oh no, something went wrong. :boom: . Exception:")
await LOG_CHANNEL.send(e)
await LOG_CHANNEL.send(f"MESSAGE: {message.content}")
print(f"MESSAGE: {message.content}")
raise e
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(client.start(TOKEN))
except KeyboardInterrupt:
loop.run_until_complete(client.logout())
# cancel all tasks lingering
with open("logs.log") as f:
f.write(f.read() + f"\n---{datetime.date.today()}---") # Appends date to logs
finally:
loop.close()
My code: