def default_mask(trigger): welcome = formatting.color('Welcome to:', formatting.colors.PURPLE) chan = formatting.color(trigger.sender, formatting.colors.TEAL) topic_ = formatting.bold('Topic:') topic_ = formatting.color('| ' + topic_, formatting.colors.PURPLE) arg = formatting.color('{}', formatting.colors.GREEN) return '{} {} {} {}'.format(welcome, chan, topic_, arg)
def rpost_info(bot, trigger, match=None): r = praw.Reddit(user_agent=USER_AGENT) match = match or trigger if len(match.group(1)) < 10: post_url = "https://www.reddit.com/comments/{}/".format(match.group(1)) else: post_url = match.group(1) s = r.get_submission(url=post_url) message = ('[reddit] {title} {link}{nsfw} | {points} points ({percent}) | ' '{comments} comments | Posted by {author} {post_time}') if s.is_self: link = '(self.{})'.format(s.subreddit.display_name) else: link = '({}) to r/{}'.format(s.url, s.subreddit.display_name) if s.over_18: nsfw = bold(color(' [NSFW]', colors.RED)) # TODO implement per-channel settings db, and make this able to kick else: nsfw = '' if s.author: author = s.author.name else: author = '[deleted]' if s.created: post_time = arrow.get(s.created_utc, tzinfo="utc").humanize() else: post_time = '' if s.score > 0: point_color = colors.GREEN else: point_color = colors.RED percent = color(str(int(s.upvote_ratio * 100)) + '%', point_color) message = message.format(title=s.title, link=link, nsfw=nsfw, points=s.score, percent=percent, comments=s.num_comments, author=author, post_time=post_time) bot.say(message)
def rpost_info(bot, trigger, match=None): r = praw.Reddit(user_agent=USER_AGENT) match = match or trigger if len(match.group(1)) < 10: post_url = "https://www.reddit.com/comments/{}/".format(match.group(1)) else: post_url = match.group(1) s = r.get_submission(url=post_url) message = ('[reddit] {title} {link}{nsfw} | {points} points ({percent}) | ' '{comments} comments | Posted by {author} {post_time}') if s.is_self: link = '(self.{})'.format(s.subreddit.display_name) else: link = '({}) to r/{}'.format(s.url, s.subreddit.display_name) if s.over_18: nsfw = bold(color(' [NSFW]', colors.RED)) # TODO implement per-channel settings db, and make this able to kick else: nsfw = '' if s.author: author = s.author.name else: author = '[deleted]' if s.created: post_time = arrow.get(s.created_utc, tzinfo="utc").humanize() else: post_time = '' if s.score > 0: point_color = colors.GREEN else: point_color = colors.RED percent = color(str(int(s.upvote_ratio * 100)) + '%', point_color) message = message.format( title=s.title, link=link, nsfw=nsfw, points=s.score, percent=percent, comments=s.num_comments, author=author, post_time=post_time) bot.say(message)
def rpost_info(bot, trigger, match=None): r = praw.Reddit(user_agent=USER_AGENT) match = match or trigger s = r.get_submission(url=match.group(1)) message = ('[reddit] {title} {link}{nsfw} | {points} points ({percent}) | ' '{comments} comments | Posted by {author}') if s.is_self: link = '(self.{})'.format(s.subreddit.display_name) else: link = '({}) to r/{}'.format(s.url, s.subreddit.display_name) if s.over_18: nsfw = bold(color(' [NSFW]', colors.RED)) # TODO implement per-channel settings db, and make this able to kick else: nsfw = '' if s.author: author = s.author.name else: author = '[deleted]' # TODO add creation time with s.created if s.score > 0: point_color = colors.GREEN else: point_color = colors.RED percent = color(unicode(int(s.upvote_ratio * 100)) + '%', point_color) message = message.format( title=s.title, link=link, nsfw=nsfw, points=s.score, percent=percent, comments=s.num_comments, author=author) bot.say(message)
def _rss_list(self, bot, trigger): """Get information on all feeds in the database. Usage: .rss list [#channel] [Feed_Name]""" pattern = r""" ^\.rss\s+list (?:\s+([~&#+!][^\s,]+))? # channel (optional) (?:\s+("[^"]+"|[\w-]+))? # name (optional) """ match = re.match(pattern, trigger.group(), re.IGNORECASE | re.VERBOSE) if match is None: self._show_doc(bot, 'list') return channel = match.group(1) feed_name = match.group(2).strip('"') if match.group(2) else None feeds = [RSSFeed(row) for row in bot.db._execute('SELECT * FROM rss_feeds').fetchall()] if not feeds: bot.reply("No RSS feeds in the database.") return filtered = [feed for feed in feeds if (feed.channel == channel or channel is None) and (feed_name is None or feed.name.lower() == feed_name.lower())] if not filtered: bot.reply("No feeds matched the command.") return noun = 'feeds' if len(feeds) != 1 else 'feed' bot.reply("Showing {0} of {1} RSS {2} in the database:".format( len(filtered), len(feeds), noun)) for feed in filtered: bot.say(" {0} {1} {2}{3} {4} {5}".format( feed.channel, color(feed.name, feed.fg, feed.bg), feed.url, " (disabled)" if not feed.enabled else '', feed.fg, feed.bg))
def read_feeds(bot, force=False): if not bot.memory['rss_manager'].running and not force: return feeds = bot.db._execute('SELECT * FROM rss_feeds').fetchall() if not feeds: return for feed_row in feeds: feed = RSSFeed(feed_row) if not feed.enabled: continue try: fp = feedparser.parse(feed.url, etag=feed.etag, modified=feed.modified) except IOError as e: LOGGER.exception("Can't parse feed on %s, disabling.", feed.name) _disable_feed(feed) continue # fp.status will only exist if pulling from an online feed # fp.version sometimes runs into AttributeError fp.status = getattr(fp, 'status', 'unknown') fp.version = getattr(fp, 'version', 'unknown') LOGGER.debug("%s: status = %s, version = '%s', items = %s", feed.name, fp.status, fp.version, len(fp.entries)) # check HTTP status if fp.status == 301: # MOVED_PERMANENTLY bot.warning( "Got HTTP 301 (Moved Permanently) on %s, updating URI to %s", feed.name, fp.href ) bot.db._execute(''' UPDATE rss_feeds SET feed_url = ? WHERE channel = ? AND feed_name = ? ''', (fp.href, feed.channel, feed.name)) elif fp.status == 410: # GONE LOGGER.warning("Got HTTP 410 (Gone) on {0}, disabling", feed.name) _disable_feed(feed) if not fp.entries: continue feed_etag = getattr(fp, 'etag', None) feed_modified = getattr(fp, 'modified', None) entry = fp.entries[0] # parse published and updated times into datetime objects (or None) entry_dt = (datetime.fromtimestamp(time.mktime(entry.published_parsed)) if hasattr(entry, 'published_parsed') else None) entry_update_dt = (datetime.fromtimestamp(time.mktime(entry.updated_parsed)) if hasattr(entry, 'updated_parsed') else None) # check if article is new, and skip otherwise if (feed.title == entry.title and feed.link == entry.link and feed.etag == feed_etag and feed.modified == feed_modified): LOGGER.info(u"Skipping previously read entry: [%s] %s", feed.name, entry.title) continue # save article title, url, and modified date bot.db._execute(''' UPDATE rss_feeds SET article_title = ?, article_url = ?, published = ?, etag = ?, modified = ? WHERE channel = ? AND feed_name = ? ''', (entry.title, entry.link, entry_dt, feed_etag, feed_modified, feed.channel, feed.name)) if feed.published and entry_dt: published_dt = datetime.strptime(feed.published, "%Y-%m-%d %H:%M:%S") if published_dt >= entry_dt: # This will make more sense once iterating over the feed is # implemented. Once that happens, deleting or modifying the # latest item would result in the whole feed getting re-msg'd. # This will prevent that from happening. LOGGER.info( "Skipping older entry: [%s] %s, because %s >= %s", feed.name, entry.title, published_dt, entry_dt) continue # Don't use long reddit urls, use short version entry_link = entry.link if "www.reddit.com/r/" in entry.link: short_url = "https://redd.it/{}" reddit_re= "https://www\.reddit\.com\/r\/.*comments/(.*?)\/" try: entry_link = short_url.format(re.search(reddit_re, entry_link).group(1)) except: LOGGER.debug("Matching reddit url {} failed".format(entry_link)) # create message for new entry message = u"[{0}] {1} - {2}".format( bold(color(feed.name, feed.fg, feed.bg)), bold(entry.title), entry_link) # append update time if it exists, or published time if it doesn't # timestamp = entry_update_dt or entry_dt # if timestamp: # # attempt to get time format from preferences # tformat = bot.db.get_channel_value(feed.channel, 'time_format') # if not tformat and bot.config.has_option('clock', 'time_format'): # tformat = bot.config.clock.time_format # # message += " - {0}".format(timestamp.strftime(tformat or '%F - %T%Z')) # print message bot.msg(feed.channel, message)