This repository was archived by the owner on Jan 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLegacyBotController.py
More file actions
139 lines (122 loc) · 5.65 KB
/
LegacyBotController.py
File metadata and controls
139 lines (122 loc) · 5.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
"""
Text commands will be removed in the future (if not already), see:
https://discord.com/blog/slash-commands-permissions-discord-apps-bots
"""
import asyncio
import re
import asyncpraw
from asyncpraw import exceptions as rexc
from discord.ext import commands as cmd
from bot_commands import bot_cmds
from bot_commands import cmd_keys_list
from cfg import settings # see note in README.md
prefix = settings['discordAPI']['prefix']
bot = cmd.Bot(
command_prefix=prefix,
help_command=None
) # create discord instance
reddit_agent = asyncpraw.Reddit(
client_id=settings['redditAPI']['client_id'],
client_secret=settings['redditAPI']['client_secret'],
user_agent=settings['redditAPI']['user_agent']
) # creates single (shared) read-only reddit instance
async def shutdown():
# safe log-out from reddit && discord
await reddit_agent.close()
await bot.close()
@bot.event
async def on_ready():
print(f'@ Boot successful. Logged as {bot.user}, prefix: "{prefix}"')
# tells host if bot is ready to use
print(f'@ Permissions: Reddit.read_only={reddit_agent.read_only}')
# tells if bot has permissions to read/write comments && posts
@bot.command()
async def about(context):
await context.channel.send(f'Open source Discord bot that converts '
f'reddit "share" links into embedded files/text.\n'
f'List all available commands: `{prefix}help`\n'
f'Project page on Github: '
f'<https://github.com/HardcoreMagazine/RedditToDiscordShare>')
@bot.command()
async def cv(context, message):
typesafe_url = message.replace("<", "").replace(">", "").replace("|", "")
# remove garbage from URL if present
try:
submission = await reddit_agent.submission(url=typesafe_url)
# request all data from selected post
embedded_link = submission.url
await context.channel.send(embedded_link)
except Exception as exc:
if isinstance(exc, rexc.InvalidURL):
await context.channel.send('Invalid URL')
elif isinstance(exc, rexc.RedditAPIException):
await context.channel.send('Reddit API is down, try again later')
print(f'@ An exception has occurred: "{exc}"')
@bot.command()
async def cvt(context, message):
typesafe_url = message.replace("<", "").replace(">", "").replace("|", "")
# remove garbage from URL if present
try:
submission = await reddit_agent.submission(url=typesafe_url)
# request all data from selected post
s_title = submission.title
s_text: str = submission.selftext
if len(s_text) > 4000:
await context.channel.send('Submission contains more than 4000 '
'characters, unable to process '
'due to Discord limitations')
else:
regex = r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)" \
r"(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))" \
r"+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)" \
r"|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))"
link_list = re.findall(regex, s_text)
if link_list: # if list is not empty
for link in link_list:
conv_link = ''.join(link)
s_text = s_text.replace(conv_link, f"<{conv_link}>")
# hide all internal links ("HTTP(S)://") in <> brackets
s_text = s_text.replace("​", '')
# "​" - zero-width space character
# pops up occasionally due to random
# errors on Reddit side
await context.channel.send(f'> **{s_title}**\n\n'
f'' # escape discord quote
f'{s_text}')
except Exception as exc:
if isinstance(exc, rexc.InvalidURL):
await context.channel.send('Invalid URL')
elif isinstance(exc, rexc.RedditAPIException):
await context.channel.send('Reddit API is down, try again later')
print(f'@ An exception has occurred: "{exc}"')
@bot.command()
async def help(context, message=None):
if message is None:
msg = '```Available commands:\n\n'
for c in cmd_keys_list:
msg += f'{c} - {bot_cmds[c]["brief"]}\n'
msg += f'\nUse {prefix}help [command] ' \
f'to show help on specific command```'
await context.channel.send(msg)
else:
if message in cmd_keys_list:
await context.channel.send(f'```{bot_cmds[message]["description"]}\n\n'
f'{bot_cmds[message]["usage"]}```')
else:
await context.channel.send(f'Command "{message}" not found\n'
f'Use `{prefix}help` to '
f'list all available commands')
@bot.event # universal error handler for commands
async def on_command_error(context, error):
if isinstance(error, cmd.CommandNotFound):
await context.channel.send(f'Unrecognized command\n'
f'Use `{prefix}help` to list '
f'all available commands')
elif isinstance(error, cmd.MissingRequiredArgument):
await context.channel.send(f'Missing line argument\n'
f'Use: `{prefix}help [command]`')
print(f'@ An exception has occurred: "{error}"')
bot.run(settings['discordAPI']['token']) # creates discord bot instance
# code below this line executes on program shutdown
print('@ Shutdown in progress')
asyncio.run(shutdown())