You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
8.3 KiB
Python
214 lines
8.3 KiB
Python
import sys, os
|
|
import pydle
|
|
import asyncio
|
|
import arrow
|
|
from supportbot.reddit import Reddit
|
|
from supportbot.db import SupportRequest, IRCSupportOperator
|
|
from supportbot import config
|
|
|
|
|
|
class IRCBot(pydle.Client):
|
|
|
|
async def on_connect(self):
|
|
for room in config.ROOMS:
|
|
await self.join(room)
|
|
while True:
|
|
print("Checking reddit for new posts")
|
|
r = Reddit()
|
|
new_requests = []
|
|
subreddit = r.reddit.subreddit(r.subreddit)
|
|
|
|
# Check for new submissions
|
|
for submission in subreddit.new():
|
|
if not SupportRequest.select().where(SupportRequest.post_id == submission.id):
|
|
s = SupportRequest(
|
|
post_id=submission.id,
|
|
author=submission.author,
|
|
title=submission.title,
|
|
permalink=submission.permalink,
|
|
timestamp=submission.created_utc
|
|
)
|
|
s.save()
|
|
print(f"Added Reddit post {submission.id} as record {s.id}")
|
|
new_requests.append(s)
|
|
|
|
# Only post the totals into IRC
|
|
if new_requests:
|
|
await self.message(room, f"Found {len(new_requests)} new Reddit posts in /r/monerosupport. Use `.list` to see the list and `.request x` to see each one.")
|
|
|
|
# Check stored posts to see if they're solved
|
|
posts = SupportRequest.select().where(SupportRequest.solved == False)
|
|
for post in posts:
|
|
p = r.reddit.submission(post.post_id)
|
|
if p.link_flair_text:
|
|
print(f"Marking post {post.id} ({post.post_id}) as solved")
|
|
post.solved = True
|
|
post.save()
|
|
|
|
# Add configured admins as admins
|
|
for nick in config.ADMIN_NICKNAMES:
|
|
if not IRCSupportOperator.select().where(IRCSupportOperator.irc_nick == nick):
|
|
print(f"Adding {nick} as an admin")
|
|
i = IRCSupportOperator(
|
|
irc_nick=nick,
|
|
is_a_regular=True,
|
|
is_support_admin=True,
|
|
)
|
|
i.save()
|
|
|
|
await asyncio.sleep(120)
|
|
|
|
async def on_message(self, target, source, message):
|
|
if source == self.nickname:
|
|
return
|
|
else:
|
|
print(f"Target: {target} - Source: {source} - Message: {message}")
|
|
|
|
if self.nickname in message:
|
|
await self.message(target, f"Sup. I'm not very helpful yet, but getting there. Try `.help`")
|
|
|
|
# list command to show series of unsolved/active support requests
|
|
if message in [".list"]:
|
|
s = []
|
|
reqs = SupportRequest.select().where(
|
|
SupportRequest.solved==False
|
|
).order_by(SupportRequest.timestamp)
|
|
for req in reqs:
|
|
s.append(f"{req.id}")
|
|
await self.message(target, ", ".join(s))
|
|
|
|
# request command to view meta about a specific support request
|
|
if message.startswith(".request ") or message in [".request"]:
|
|
msg = message.split()
|
|
if not len(msg) > 1:
|
|
await self.message(target, "Invalid arguments")
|
|
return
|
|
|
|
try:
|
|
post_id = int(msg[1])
|
|
except:
|
|
await self.message(target, "Invalid arguments")
|
|
return
|
|
|
|
req = SupportRequest.select().where(
|
|
SupportRequest.id==post_id
|
|
).first()
|
|
if req:
|
|
if req.assigned:
|
|
_a = f"ASSIGNED ({req.assignee.irc_nick})"
|
|
else:
|
|
_a = "UNASSIGNED"
|
|
if req.solved:
|
|
_s = "SOLVED"
|
|
else:
|
|
_s = "UNSOLVED"
|
|
await self.message(target, f"{req.id}: {req.title} - {arrow.get(req.timestamp).humanize()} - https://reddit.com{req.permalink} - {_a} - {_s}")
|
|
else:
|
|
await self.message(target, "No record with that ID")
|
|
|
|
# claim support ticket - you become the assignee/helpers
|
|
if message.startswith(".claim ") or message in [".claim"]:
|
|
msg = message.split()
|
|
if not len(msg) > 1:
|
|
await self.message(target, "Invalid arguments")
|
|
return
|
|
|
|
try:
|
|
post_id = int(msg[1])
|
|
except:
|
|
await self.message(target, "Invalid arguments")
|
|
return
|
|
|
|
req = SupportRequest.select().where(
|
|
SupportRequest.id == post_id
|
|
).first()
|
|
if req:
|
|
if not await self.is_registered(source):
|
|
i = IRCSupportOperator(irc_nick=source)
|
|
i.save()
|
|
else:
|
|
i = IRCSupportOperator.select().where(IRCSupportOperator.irc_nick == source)
|
|
req.assigned = True
|
|
req.assignee = i
|
|
req.save()
|
|
await self.message(target, f"Support request {req.id} claimed by {source}")
|
|
else:
|
|
await self.message(target, "No record with that ID")
|
|
|
|
# queue command only shows things assigned to you
|
|
if message in [".queue"]:
|
|
user = IRCSupportOperator.select().where(IRCSupportOperator.irc_nick == source)
|
|
if not user:
|
|
await self.message(target, "You don't have a queue.")
|
|
return
|
|
reqs = SupportRequest.select().where(
|
|
SupportRequest.assignee == user,
|
|
SupportRequest.solved == False
|
|
)
|
|
if reqs:
|
|
await self.message(target, ", ".join(reqs))
|
|
else:
|
|
await self.message(target, "No support requests assigned to you.")
|
|
|
|
if message.startswith(".promote ") or message in [".promote"]:
|
|
msg = message.split()
|
|
if not len(msg) > 1:
|
|
await self.message(target, "Invalid arguments.")
|
|
return
|
|
|
|
promoted_nick = str(msg[1])
|
|
if not await self.is_admin(source):
|
|
await self.message(target, "You are not an admin of the support bot.")
|
|
return
|
|
|
|
if IRCSupportOperator.select().where(IRCSupportOperator.irc_nick == promoted_nick):
|
|
await self.message(target, "User already exists!")
|
|
return
|
|
|
|
i = IRCSupportOperator(
|
|
irc_nick=promoted_nick,
|
|
is_support_admin=True,
|
|
is_a_regular=True
|
|
)
|
|
i.save()
|
|
await self.message(target, "Added IRC support user:", irc_nick)
|
|
|
|
# help command shows available commands
|
|
if message in [".help"]:
|
|
await self.message(target, "`.list`: Show open support tickets on Reddit and synchronized to the database. | `.request x`: Show metadata of support request \"x\". | `.claim x`: Claim support request \"x\" | `.queue`: Show support requests assigned to you | `.promote x`: Allow user \"x\" to manage more support duties")
|
|
|
|
async def is_admin(self, nickname):
|
|
admin = False
|
|
if nickname in config.ADMIN_NICKNAMES:
|
|
info = await self.whois(nickname)
|
|
admin = info['identified']
|
|
print("info: ", info)
|
|
return admin
|
|
|
|
async def is_support_admin(self, nickname):
|
|
if IRCSupportOperator.select().where(IRCSupportOperator.is_support_admin == True):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
async def is_registered(self, nickname):
|
|
irc_nick = IRCSupportOperator.select().where(
|
|
IRCSupportOperator.irc_nick==nickname
|
|
).first()
|
|
if irc_nick:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def run_bot():
|
|
try:
|
|
print(f"[+] Starting IRC bot connecting to {config.IRC_HOST}...\n")
|
|
client = IRCBot(nickname=config.BOT_NICKNAME)
|
|
client.run(config.IRC_HOST, tls=True, tls_verify=False)
|
|
except KeyboardInterrupt:
|
|
print(' - Adios')
|
|
try:
|
|
sys.exit(0)
|
|
except SystemExit:
|
|
os._exit(0)
|