# coding=utf8 from __future__ import unicode_literals, absolute_import, division, print_function """ This is the SpiceBot Reddit system. """ from sopel.config.types import StaticSection, ValidatedAttribute from sopel.formatting import bold, color, colors import spicemanip import datetime as dt import praw import prawcore from random import randint from .Config import config as botconfig from .Logs import logs class SpiceBot_Reddit_MainSection(StaticSection): client_id = ValidatedAttribute('client_id', default=None) client_secret = ValidatedAttribute('client_secret', default=None) class BotReddit(): """This Logs all channels known to the server""" def __init__(self): self.setup_reddit() self.cache = {} self.client_id = botconfig.SpiceBot_Reddit.client_id self.client_secret = botconfig.SpiceBot_Reddit.client_secret if not self.client_id or not self.client_secret: self.praw = None logs.log('SpiceBot_Reddit', "Client ID or Secret missing from config", True) else: self.praw = praw.Reddit( client_id=self.client_id, client_secret=self.client_secret, user_agent='spicebot:net.example.myredditapp:v1.2.3 (by /u/SpiceBot-dbb)' ) def setup_reddit(self): botconfig.define_section("SpiceBot_Reddit", SpiceBot_Reddit_MainSection, validate=False) def prerun(self, trigger): if not self.praw: return "Reddit API is not available" message = "if you see this, there may be an error" trigger_argsdict = self.trigger_handler(trigger) if trigger_argsdict["slashcomm"] == "u": return self.user_handler(trigger_argsdict) elif trigger_argsdict["slashcomm"] == "r": return self.subreddit_handler(trigger_argsdict) return message def user_handler(self, trigger_argsdict): subcommand_valid = ['check'] subcommand = spicemanip.main([x for x in trigger_argsdict["args"] if x in subcommand_valid], 1) or 'check' userreal = self.reddit_user_exists(trigger_argsdict["command"]) if not userreal["exists"]: return userreal["error"] fulluurul = str("https://www.reddit.com/" + trigger_argsdict["slashcomm"] + "/" + trigger_argsdict["command"]) if subcommand == 'check': u = self.praw.redditor(trigger_argsdict["command"]) message = ['[REDDITOR] ' + u.name] is_cakeday = self.user_cakeday(u.created_utc) if is_cakeday: message.append(bold(color('Cake day', colors.LIGHT_PURPLE))) message.append(fulluurul) if u.is_gold: message.append(bold(color('Gold', colors.YELLOW))) if u.is_mod: message.append(bold(color('Mod', colors.GREEN))) message.append('Link: ' + str(u.link_karma)) message.append('Comment: ' + str(u.comment_karma)) return message def user_cakeday(self, created): now = dt.datetime.utcnow() cakeday_start = dt.datetime.utcfromtimestamp(created) cakeday_start = cakeday_start.replace(year=now.year) day = dt.timedelta(days=1) year_div_by_400 = now.year % 400 == 0 year_div_by_100 = now.year % 100 == 0 year_div_by_4 = now.year % 4 == 0 is_leap = year_div_by_400 or ((not year_div_by_100) and year_div_by_4) if (not is_leap) and ((cakeday_start.month, cakeday_start.day) == (2, 29)): # If cake day is 2/29 and it's not a leap year, cake day is 3/1. # Cake day begins at exact account creation time. is_cakeday = cakeday_start + day <= now <= cakeday_start + (2 * day) else: is_cakeday = cakeday_start <= now <= cakeday_start + day return is_cakeday def subreddit_handler(self, trigger_argsdict): subcommand_valid = ['check', 'hot', 'new', 'top', 'random', 'controversial', 'gilded', 'rising', 'best'] subcommand = spicemanip.main([x for x in trigger_argsdict["args"] if x in subcommand_valid], 1) or 'check' fullrurul = str("https://www.reddit.com/" + trigger_argsdict["slashcomm"] + "/" + trigger_argsdict["command"]) subredditcheck = self.reddit_subreddit_check(trigger_argsdict["command"]) if not subredditcheck["exists"]: return subredditcheck["error"] subreddit = self.praw.subreddit(trigger_argsdict["command"]) if subcommand == 'check': dispmsg = [] dispmsg.append("[Reddit " + trigger_argsdict["slashcomm"] + "/" + trigger_argsdict["command"] + "]") if subreddit.over18: dispmsg.append("") dispmsg.append(str(subreddit.public_description)) dispmsg.append(fullrurul) return dispmsg if subcommand == 'random': targnum = spicemanip.main([x for x in trigger_argsdict["args"] if str(x).isdigit()], 1) or 500 else: targnum = spicemanip.main([x for x in trigger_argsdict["args"] if str(x).isdigit()], 1) or 1 targnum = int(targnum) if subcommand == 'new': submissions = subreddit.new(limit=targnum) elif subcommand == 'top': submissions = subreddit.top(limit=targnum) elif subcommand == 'hot': submissions = subreddit.hot(limit=targnum) elif subcommand == 'controversial': submissions = subreddit.controversial(limit=targnum) elif subcommand == 'gilded': submissions = subreddit.gilded(limit=targnum) elif subcommand == 'rising': submissions = subreddit.rising(limit=targnum) elif subcommand == 'random': submissions = subreddit.hot(limit=targnum) else: return "An error has occured." listarray = [] for submission in submissions: listarray.append(submission) if listarray == []: submission = None elif subcommand == 'random': submission = listarray[randint(0, len(listarray) - 1)] else: submission = listarray[targnum - 1] dispmsg = [] dispmsg.append("[Reddit " + trigger_argsdict["slashcomm"] + "/" + trigger_argsdict["command"] + " " + subcommand + "]") if subreddit.over18: dispmsg.append("") if submission: dispmsg.append("{" + str(submission.score) + "}") dispmsg.append(submission.title) dispmsg.append(submission.url) else: dispmsg.append("No Content Found.") return dispmsg def trigger_handler(self, trigger): trigger_args = spicemanip.main(trigger.args[1], 'create') trigger_argsdict = { "slashcomm": spicemanip.main(trigger_args, 1).lower()[:1], "command": spicemanip.main(trigger_args, 1).lower()[2:], "args": spicemanip.main(trigger_args, "2+", 'list') } if trigger_argsdict["slashcomm"] == "u": trigger_argsdict["urltypetxt"] = "user" if trigger_argsdict["slashcomm"] == "r": trigger_argsdict["urltypetxt"] = "subreddit" return trigger_argsdict def reddit_subreddit_check(self, sub): returndict = {"exists": True, "error": None} try: self.praw.subreddits.search_by_name(sub, exact=True) except prawcore.exceptions.NotFound: returndict["error"] = str(sub + " appears to not exist!") returndict["exists"] = False return returndict try: subtype = self.praw.subreddit(sub).subreddit_type returndict["subtype"] = subtype except Exception as e: returndict["exists"] = False if str(e) == "received 403 HTTP response": returndict["error"] = str(sub + " appears to be an private subreddit!") return returndict elif str(e) == "received 404 HTTP response": returndict["error"] = str(sub + " appears to be an banned subreddit!") return returndict else: returndict["error"] = str(sub + " appears to not have a type") return returndict return returndict def reddit_user_exists(self, user): returndict = {"exists": True, "error": None} try: self.praw.redditor(user).fullname except prawcore.exceptions.NotFound: returndict["exists"] = False returndict["error"] = str(user + " appears to not exist!") return returndict return returndict reddit = BotReddit()