def _printWikiPage(self, values): action = values.get('action') if action is not None: if action == 'created': action = 'created by %s' % underline(values['author']) elif action == 'changed': action = 'changed by %s' % underline(values['author']) action = ' (%s)' % action yield format('%s%s %u', bold(values['name']), action or '', values['url'])
def _printWikiPage(self, values): action = values.get('action') if action is not None: if action == 'created': action = 'created by %s' % underline(values['author']) elif action == 'changed': action = 'changed by %s' % underline(values['author']) action = ' (%s)' % action yield format('%s%s %u', bold(values['name']), action or '', values['url'] )
def _printTicket(self, values): action = values.get('action') if action is not None: if action == 'created': action = 'created by %s' % underline(values['reporter']) elif action == 'changed': action = 'changed by %s' % underline(values['author']) comment = values['comment'] if comment: comment = ', ' + comment action = ' (%s%s)' % (action, comment) yield format('%s #%s: %s%s', bold('Ticket'), values['id'], values['summary'], action or '') yield '<%s>' % values['url']
def _finalgame(self, gamedate, gameid): """Grabs the boxscore json and prints a final statline.""" url = b64decode('aHR0cDovL2RhdGEubmJhLmNvbS9qc29uL2Ntcy9ub3NlYXNvbi9nYW1lLw==') + '%s/%s/boxscore.json' % (str(gamedate), str(gameid)) html = self._httpget(url) if not html: self.log.error("ERROR: Could not _finalgame.") return None # process json. throw this thing in a try/except block. try: jsonf = json.loads(html.decode('utf-8')) game = jsonf['sports_content']['game'] if len(game) == 0: self.log.error("_finalgame :: I found no games in the json data.") return None # output dict. we preset DD/TD for later. gamestats = {'Double-double':[], 'Triple-double':[]} # iterate over the home/visitor. for var in ['visitor', 'home']: team = game[var]['abbreviation'] fgp = game[var]['stats']['field_goals_percentage'] tpp = game[var]['stats']['three_pointers_percentage'] ftp = game[var]['stats']['free_throws_percentage'] to = game[var]['stats']['turnovers'] rb = (int(game[var]['stats']['rebounds_offensive'])+int(game[var]['stats']['rebounds_defensive'])) # total rb. ptsl = sorted(game[var]['players']['player'], key=lambda t: int(t['points']), reverse=True)[0] # sort by points astl = sorted(game[var]['players']['player'], key=lambda t: int(t['assists']), reverse=True)[0] # sort by assists. below we sort by adding rebounds. rbll = sorted(game[var]['players']['player'], key=lambda x: (int(x['rebounds_offensive']) + int(x['rebounds_defensive'])), reverse=True)[0] # inject into our gamestats dict with the text. gamestats[team] = "{0}: {1} {2}: {3} {4}: {5} {6}: {7} {8}: {9} {10} :: {11} {12} {13} {14} {15} {16} {17} {18} {19}".format(\ ircutils.bold("FG%"), fgp, ircutils.bold("FT%"), ftp, ircutils.bold("3PT%"), tpp, ircutils.bold("TO"), to, ircutils.bold("RB"), rb, ircutils.bold(ircutils.underline("LEADERS")), ircutils.bold("PTS"), ptsl['last_name'].encode('utf-8'), ptsl['points'], ircutils.bold("AST"), astl['last_name'].encode('utf-8'), astl['assists'], ircutils.bold("RB"), rbll['last_name'].encode('utf-8'), (int(rbll['rebounds_offensive'])+int(rbll['rebounds_defensive']))) # look for DD/TD for x in game[var]['players']['player']: # iterate over. tmp = {} # we make a dict with the key as the stat for later. tmp['rb'] = int(x['rebounds_offensive']) + int(x['rebounds_defensive']) tmp['blocks'] = int(x['blocks']) tmp['a'] = int(x['assists']) tmp['p'] = int(x['points']) tmp['s'] = int(x['steals']) # we only inject into matching the category and stat if 10 or over. matching = [str(z.upper()) + ": " + str(p) for (z, p) in tmp.items() if p >= 10] if len(matching) == 2: # dd. inject into gamestats in the right category. gamestats['Double-double'].append("{0}({1}) :: {2}".format(x['last_name'].encode('utf-8'), team, " | ".join(matching))) if len(matching) > 2: # likewise with td. gamestats['Triple-double'].append("{0}({1}) :: {2}".format(x['last_name'].encode('utf-8'), team, " | ".join(matching))) # return the dict. return gamestats except Exception, e: self.log.error("_finalgame: ERROR on {0} :: {1}".format(url, e)) return None
def present_listing_first(res, original_link=False, color_score=False): try: d = res.get("data", {}).get("children", [{}])[0].get("data",{}) if d: if not original_link: d["url"] = "http://www.reddit.com/r/%(subreddit)s/comments/%(id)s/" % d if color_score: score_part = "(%s|%s)[%s]" % (ircutils.bold(ircutils.mircColor("%(ups)s", "orange")), ircutils.bold(ircutils.mircColor("%(downs)s", "12")), ircutils.bold(ircutils.mircColor("%(num_comments)s", "dark grey"))) else: score_part = "(%(score)s)" title_part = "%(title)s" url_part = ircutils.underline("%(url)s") nsfw_part = "NSFW"*d['over_18'] or '' nsfw_part =ircutils.bold(ircutils.mircColor(nsfw_part, 'red')) template = "%s %s %s %s" % (nsfw_part, score_part, title_part, url_part) template = (template % d) template = template.replace('\n', ' ') template = template.replace('&','&') if d["created_utc"] < time.time() - 2678400: return False return template except IndexError: return None
def present_listing_first(res, original_link=False, color_score=False): try: d = res.get("data", {}).get("children", [{}])[0].get("data", {}) if d: if not original_link: d["url"] = "http://www.reddit.com/r/%(subreddit)s/comments/%(id)s/" % d if color_score: score_part = "(%s|%s)[%s]" % ( ircutils.bold(ircutils.mircColor("%(ups)s", "orange")), ircutils.bold(ircutils.mircColor("%(downs)s", "12")), ircutils.bold( ircutils.mircColor("%(num_comments)s", "dark grey"))) else: score_part = "(%(score)s)" title_part = "%(title)s" url_part = ircutils.underline("%(url)s") nsfw_part = "NSFW" * d['over_18'] or '' nsfw_part = ircutils.bold(ircutils.mircColor(nsfw_part, 'red')) template = "%s %s %s %s" % (nsfw_part, score_part, title_part, url_part) template = (template % d) template = template.replace('\n', ' ') template = template.replace('&', '&') if d["created_utc"] < time.time() - 2678400: return False return template except IndexError: return None
def _printChangeset(self, values): yield format('%s [%s] by %s in %s (%n): %s', bold('Changeset'), values['rev'], underline(values['author']), values['path'], (values['file_count'], 'file'), ellipsisify(values['message'].strip(), 130)) yield '<%s>' % values['url']
def testStripFormatting(self): self.assertEqual(ircutils.stripFormatting(ircutils.bold("foo")), "foo") self.assertEqual(ircutils.stripFormatting(ircutils.italic("foo")), "foo") self.assertEqual(ircutils.stripFormatting(ircutils.reverse("foo")), "foo") self.assertEqual(ircutils.stripFormatting(ircutils.underline("foo")), "foo") self.assertEqual(ircutils.stripFormatting("\x02bold\x0302,04foo\x03" "bar\x0f"), "boldfoobar") s = ircutils.mircColor("[", "blue") + ircutils.bold("09:21") self.assertEqual(ircutils.stripFormatting(s), "[09:21")
def cfbschedule(self, irc, msg, args, optteam): """[team] Display the schedule/results for team. """ lookupteam = self._lookupTeam(optteam) if lookupteam == "0": irc.reply("I could not find a schedule for: %s" % optteam) return url = 'http://www.cbssports.com/collegefootball/teams/schedule/%s/' % lookupteam try: req = urllib2.Request(url) html = (urllib2.urlopen(req)).read() except: irc.reply("Failed to open: %s" % url) return html = html.replace('&','&').replace(';','') soup = BeautifulSoup(html) if soup.find('table', attrs={'class':'data stacked'}).find('tr', attrs={'class':'title'}).find('td'): title = soup.find('table', attrs={'class':'data stacked'}).find('tr', attrs={'class':'title'}).find('td') else: irc.reply("Something broke with schedules. Did formatting change?") return div = soup.find('div', attrs={'id':'layoutTeamsPage'}) # must use this div first since there is an identical table. table = div.find('table', attrs={'class':'data', 'width':'100%'}) rows = table.findAll('tr', attrs={'class':re.compile('^row[1|2]')}) append_list = [] for row in rows: date = row.find('td') team = date.findNext('td').find('a') time = team.findNext('td') if team.text.startswith('@'): # underline home team = team.text else: team = ircutils.underline(team.text) if time.find('span'): # span has score time. empty otherwise. time = time.find('span').string append_list.append(date.text + " - " + ircutils.bold(team) + " (" + time + ")") else: time = time.string append_list.append(date.text + " - " + ircutils.bold(team)) descstring = string.join([item for item in append_list], " | ") output = "{0} for {1} :: {2}".format(title.text, ircutils.bold(optteam.title()), descstring) irc.reply(output)
def _printTicket(self, values): action = values.get('action') if action is not None: if action == 'created': action = 'created by %s' % underline(values['reporter']) elif action == 'changed': action = 'changed by %s' % underline(values['author']) comment = values['comment'] if comment: comment = ', ' + comment action = ' (%s%s)' % (action, comment) yield format('%s #%s: %s%s', bold('Ticket'), values['id'], values['summary'], action or '' ) yield '<%s>' % values['url']
def _printChangeset(self, values): yield format('%s [%s] by %s in %s (%n): %s', bold('Changeset'), values['rev'], underline(values['author']), values['path'], (values['file_count'], 'file'), ellipsisify(values['message'].strip(), 130) ) yield '<%s>' % values['url']
def testStripFormatting(self): self.assertEqual(ircutils.stripFormatting(ircutils.bold('foo')), 'foo') self.assertEqual(ircutils.stripFormatting(ircutils.reverse('foo')), 'foo') self.assertEqual(ircutils.stripFormatting(ircutils.underline('foo')), 'foo') self.assertEqual( ircutils.stripFormatting('\x02bold\x0302,04foo\x03' 'bar\x0f'), 'boldfoobar') s = ircutils.mircColor('[', 'blue') + ircutils.bold('09:21') self.assertEqual(ircutils.stripFormatting(s), '[09:21')
def _outputTweet(self, irc, msg, nick, name, text, time, tweetid): ret = ircutils.underline(ircutils.bold("@" + nick)) hideName = self.registryValue('hideRealName', msg.args[0]) if not hideName: ret += " ({0})".format(name) ret += ": {0} ({1})".format(text, ircutils.bold(time)) if self.registryValue('addShortUrl', msg.args[0]): url = self._createShortUrl(nick, tweetid) if (url): ret += " {0}".format(url) irc.reply(ret)
def port(self, irc, msg, args, port): """<port number> Looks up <port number> in Wikipedia's list of ports at https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers. """ if port > 65535: irc.error('Port numbers cannot be greater than 65535.', Raise=True) if BeautifulSoup is None: irc.error("Beautiful Soup 4 is required for this plugin: get it" " at http://www.crummy.com/software/BeautifulSoup/bs4/" "doc/#installing-beautiful-soup", Raise=True) url = "https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers" fd = utils.web.getUrlFd(url) soup = BeautifulSoup(fd) if port >= 49152: results = ['The range 49152–65535 (2^15+2^14 to 2^16−1)—above the ' 'registered ports—contains dynamic or private ports that ' 'cannot be registered with IANA. This range is used for ' 'custom or temporary purposes and for automatic ' 'allocation of ephemeral ports.'] else: results = [] for tr in soup.find_all('tr'): tds = tr.find_all('td') if not tds: continue portnum = tds[0].text if '–' in portnum: startport, endport = map(int, portnum.split('–')) p = range(startport, endport+1) else: try: p = [int(portnum)] except ValueError: continue if port in p: text = tds[3].text # Remove inline citations (text[1][2][3]), citation needed tags, etc. text = re.sub('\[.*?]', '', text) # List the port notes (tags such as "Official", "TCP", "UDP", etc.) # This is every <td> tag except the 4th one, which is the description parsed # above. notes = [t.text.strip() for t in tds[:3]+tds[4:]] notes = '; '.join(filter(None, notes)) # Remove \n, etc. in fields to prevent output corruption. s = utils.str.normalizeWhitespace('%s [%s]' % (ircutils.bold(text), notes)) results.append(s) if results: irc.reply(format('%s: %L', ircutils.bold(ircutils.underline(port)), results)) else: irc.error(_('No results found.'))
def testStripFormatting(self): self.assertEqual(ircutils.stripFormatting(ircutils.bold('foo')), 'foo') self.assertEqual(ircutils.stripFormatting(ircutils.reverse('foo')), 'foo') self.assertEqual(ircutils.stripFormatting(ircutils.underline('foo')), 'foo') self.assertEqual(ircutils.stripFormatting('\x02bold\x0302,04foo\x03' 'bar\x0f'), 'boldfoobar') s = ircutils.mircColor('[', 'blue') + ircutils.bold('09:21') self.assertEqual(ircutils.stripFormatting(s), '[09:21')
def wootshirt(self, irc, msg, args): """ Display daily woot.com deal.""" url = "http://shirt.woot.com/salerss.aspx" dom = xml.dom.minidom.parse(urllib2.urlopen(url)) product = dom.getElementsByTagName("woot:product")[0].childNodes[0].data price = dom.getElementsByTagName("woot:price")[0].childNodes[0].data purchaseurl = dom.getElementsByTagName("woot:purchaseurl")[0].childNodes[0].data soldout = dom.getElementsByTagName("woot:soldout")[0].childNodes[0].data # false shipping = dom.getElementsByTagName("woot:shipping")[0].childNodes[0].data if soldout == 'false': output = ircutils.mircColor("IN STOCK ", "green") else: output = ircutils.mircColor("SOLDOUT ", "red") output += ircutils.underline(ircutils.bold("ITEM:")) + " " + product + " " output += ircutils.underline(ircutils.bold("PRICE:")) + " " + price + " (Shipping:" + shipping + ") " output += ircutils.underline(ircutils.bold("URL:")) + " " + self._shortenUrl(purchaseurl) + " " irc.reply(output, prefixNick=True)
def tennis(self, irc, msg, args, optmatch): """<mens|womens|mensdoubles|womensdoubles> Display current Tennis scores. Defaults to Men's Singles. """ if optmatch: if optmatch == "womens": matchType = "2" elif optmatch == "mensdoubles": matchType = "3" elif optmatch == "womensdoubles": matchType = "4" else: matchType = "1" else: matchType = "1" url = 'general/tennis/dailyresults?matchType=%s' % matchType html = self._fetch(url) if html == 'None': irc.reply("Cannot fetch Tennis scores.") return soup = BeautifulSoup(html) tournament = soup.find('div', attrs={'class': 'sec row', 'style': 'white-space: nowrap;'}) tournRound = soup.findAll('div', attrs={'class': 'ind sub bold'})[1] # there are two here, only display the 2nd, which is status. divs = soup.findAll('div', attrs={'class':re.compile('^ind$|^ind alt$')}) append_list = [] for div in divs: if "a href" not in div.renderContents(): # only way to get around this as the divs are not in a container. status = div.find('b') # find bold, which is status. if status: status.extract() # extract so we may bold. div = div.renderContents().strip().replace('<br />',' ').replace(' ',' ') div = div.replace('v.',ircutils.mircColor('v.','green')).replace('d.',ircutils.mircColor('d.','red')) # colors. append_list.append(str(ircutils.underline(status.getText()) + " " + div.strip())) if len(append_list) > 0: # Sanity check. if tournament and tournRound: irc.reply(ircutils.mircColor(tournament.getText(), 'red') + " - " + ircutils.bold(tournRound.getText())) irc.reply(" | ".join(item for item in append_list)) else: irc.reply("I did not find any active tennis matches.")
def present_listing_first(res, original_link=False, color_score=False): d = res.get("data", {}).get("children", [{}])[0].get("data",{}) if d: if not original_link: d["url"] = "http://www.reddit.com/r/%(subreddit)s/comments/%(id)s/" % d if color_score: score_part = "(%s/%s)[%s]" % (ircutils.mircColor("%(ups)s", "orange"), ircutils.mircColor("%(downs)s", "light blue"), ircutils.mircColor("%(num_comments)s", "dark grey")) else: score_part = "(%(score)s)" title_part = ircutils.bold("%(title)s") url_part = ircutils.underline("%(url)s") template = "%s \"%s\" %s" % (score_part, title_part, url_part) return (template % d)
def _formatLine(self, line, channel, type): """Implements the 'format' configuration options.""" format = self.registryValue('format.%s' % type, channel) already_colored = False for item in format: if item == 'bold': line = ircutils.bold(line) elif item == 'reverse': line = ircutils.reverse(line) elif item == 'underlined': line = ircutils.underline(line) elif already_colored: line = ircutils.mircColor(line, bg=item) elif item != '': line = ircutils.mircColor(line, fg=item) return line
def cfbweeklyleaders(self, irc, msg, args): """ Display CFB weekly leaders. """ url = 'http://espn.go.com/college-football/weekly' try: req = urllib2.Request(url) html = (urllib2.urlopen(req)).read() except: irc.reply("Failed to open: %s" % url) return html = html.replace('tr class="evenrow', 'tr class="oddrow') soup = BeautifulSoup(html) title = soup.find('h1', attrs={'class':'h2'}) tables = soup.findAll('table', attrs={'class':'tablehead'}) new_data = collections.defaultdict(list) for table in tables: rows = table.findAll('tr', attrs={'class':re.compile('^oddrow.*')})[0:3] # top 3 only. List can be long. for j,row in enumerate(rows): stat = row.findPrevious('tr', attrs={'class':'stathead'}) colhead = row.findPrevious('tr', attrs={'class':'colhead'}).findAll('td') statnames = row.findAll('td') del statnames[3], colhead[3] # game is always 4th. delete this. for i,statname in enumerate(statnames): appendString = str(ircutils.bold(colhead[i].text)) + ": " + str(statname.text) # prep string to add into the list. if i == len(statnames)-1 and not j == len(rows)-1: # last in each. new_data[str(stat.getText())].append(appendString + " |") else: new_data[str(stat.getText())].append(appendString) if title: irc.reply(ircutils.mircColor(title.getText(), 'blue')) for i,j in new_data.iteritems(): output = "{0} :: {1}".format(ircutils.underline(i), string.join([item for item in j], " ")) irc.reply(output)
def schedule(self, irc, msg, args): """ """ shows = fetch(False) l = [] if shows: for show in shows: if show['show']['type'] == 'Scripted': this_show = format( '%s [%s] (%s)', ircutils.bold(show['show']['name']), str(show['season']) + 'x' + str(show['number']), show['airtime']) l.append(this_show) l[0] = " ".join((ircutils.underline("Tonight's Shows") + ":", l[0])) irc.replies(l)
def slhelp(self, irc, msg, args): """usage: slhelp display the help for this module """ user = irc.msg.nick help_content= { 'slhelp' : 'Help for this module:', 'sladdrent <postal code> <min surface> <max price> <min_num_room>': 'Adding a new rent search:', 'sladdbuy <postal code> <min surface> <max price> <min_num_room>': 'Adding a new buy search:', 'sllist': 'List your active searches:', 'sldisable <search ID>': 'Remove the given search (use sllist to get <search ID>):', 'slstatrent <postal code|\'all\'>': 'Print some stats about \'rent\' searches:', 'slstatbuy <postal code|\'all\'>': 'print some stats about \'buy\' searches:', } for cmd in help_content: msg = ircutils.underline(help_content[cmd]) irc.reply(msg,to=user,private=True) msg = ircutils.mircColor(str(cmd), 8) irc.reply(msg,to=user,private=True)
def cfbteaminfo(self, irc, msg, args, optteam): """[team] Display basic info/stats on a team """ lookupteam = self._lookupTeam(optteam) if lookupteam == "0": irc.reply("I could not find a schedule for: %s" % optteam) return url = 'http://www.cbssports.com/collegefootball/teams/page/%s/' % lookupteam try: req = urllib2.Request(url) html = (urllib2.urlopen(req)).read() except: irc.reply("Failed to open %s" % url) return html = html.replace('&','&').replace(';','') soup = BeautifulSoup(html) div = soup.find('div', attrs={'class':'pageTitle team'}) name = div.find('div', attrs={'class':'name'}).find('h1') record = div.find('div', attrs={'class':re.compile('^record')}) table = div.find('div', attrs={'class':'stats'}).find('table', attrs={'class':'data'}) rows = table.findAll('tr') rushingOff = rows[1].findAll('td')[1] rushingDef = rows[1].findAll('td')[2] passingOff = rows[2].findAll('td')[1] passingDef = rows[2].findAll('td')[2] overallOff = rows[3].findAll('td')[1] overallDef = rows[3].findAll('td')[2] output = "{0} :: {1} - Rushing: o: {2} d: {3} Passing: o: {4} d: {5} Overall: o: {6} d: {7}".format(\ ircutils.underline(name.text), record.text, rushingOff.text, rushingDef.text,\ passingOff.text, passingDef.text, overallOff.text, overallDef.text) irc.reply(output)
def fitocracy(self, irc, msg, args, user): """<ip.address> Use a GeoIP API to lookup the location of an IP. """ irc.reply(user) jsonurl = "http://fitocracy-unofficial-api.herokuapp.com/user/%" % (user) self.log.info(jsonurl) try: request = urllib2.Request(jsonurl) response = urllib2.urlopen(request) response_data = response.read() except urllib2.HTTPError as err: if err.code == 404: irc.reply("Error 404") self.log.warning("Error 404 on: %s" % (jsonurl)) elif err.code == 403: irc.reply("Error 403. Try waiting 60 minutes.") self.log.warning("Error 403 on: %s" % s(jsonurl)) else: irc.reply("Error. Check the logs.") return try: jsondata = json.loads(response_data) except: irc.reply("Failed in loading JSON data for Fitocracy.") return if len(jsondata) < 1: irc.reply("I found no Fitocracy Data.") return name = jsondata.get("name") or "N/A" progress = jsondata.get("progress_text") or "N/A" level = jsondata.get("level", None) # if user != None and city != None and region_code != None: output = ircutils.bold(ircutils.underline(user)) output += " " + name + ", " + progress + " " + level irc.reply(output)
def schedule(self, irc, msg, args): """ """ shows = fetch(False) l = [] if shows: for show in shows: if show['show']['type'] == 'Scripted': this_show = format('%s [%s] (%s)', ircutils.bold(show['show']['name']), str(show['season']) + 'x' + str(show['number']), show['airtime']) l.append(this_show) tonight_shows = ', '.join(l) irc.reply(format('%s: %s', ircutils.underline("Tonight's Shows"), tonight_shows))
def format_msg(self, data): service = data.get('service') if not service: tpl = "icinga {notification_type}: host {host} is {state}: {message}" else: tpl = "icinga {notification_type}: service {service} on {host} is {state}: {message}" state = data['state'] state = ircutils.mircColor(state, STATES[state]) notif_type = data['notification_type'] notif_type = ircutils.mircColor(notif_type, NOTIFICATION_TYPES[notif_type]) if service: service = ircutils.underline(data['service']) return tpl.format( notification_type=notif_type, host=ircutils.mircColor(data['host'], fg='light grey'), state=state, service=service, message=data['message'], )
def port(self, irc, msg, args, port): """<port number> Looks up <port number> in Wikipedia's list of ports at https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers. """ if port > 65535: irc.error('Port numbers cannot be greater than 65535.', Raise=True) if BeautifulSoup is None: irc.error( "Beautiful Soup 4 is required for this plugin: get it" " at http://www.crummy.com/software/BeautifulSoup/bs4/" "doc/#installing-beautiful-soup", Raise=True) url = "https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers" fd = utils.web.getUrlFd(url) soup = BeautifulSoup(fd) if port >= 49152: results = [ 'The range 49152–65535 (2^15+2^14 to 2^16−1)—above the ' 'registered ports—contains dynamic or private ports that ' 'cannot be registered with IANA. This range is used for ' 'custom or temporary purposes and for automatic ' 'allocation of ephemeral ports.' ] else: results = [] for tr in soup.find_all('tr'): tds = tr.find_all('td') if not tds: continue portnum = tds[0].text if '–' in portnum: startport, endport = map(int, portnum.split('–')) p = range(startport, endport + 1) else: try: p = [int(portnum)] except ValueError: continue if port in p: text = tds[3].text # Remove inline citations (text[1][2][3]), citation needed tags, etc. text = re.sub('\[.*?]', '', text) # List the port notes (tags such as "Official", "TCP", "UDP", etc.) # This is every <td> tag except the 4th one, which is the description parsed # above. notes = [t.text.strip() for t in tds[:3] + tds[4:]] notes = '; '.join(filter(None, notes)) # Remove \n, etc. in fields to prevent output corruption. s = utils.str.normalizeWhitespace( '%s [%s]' % (ircutils.bold(text), notes)) results.append(s) if results: irc.reply( format('%s: %L', ircutils.bold(ircutils.underline(port)), results)) else: irc.error(_('No results found.'))
def tv(self, irc, msg, args, opts, tvshow): """[-d | --detail] <tvshow> """ if not opts: details = False else: for (stuff, arg) in opts: if stuff == 'd': details = True elif stuff == 'details': details = True show = fetch(tvshow) if show: if show['premiered']: premiered = show['premiered'] else: premiered = "SOON" show_state = format( '%s %s (%s).', ircutils.bold(ircutils.underline(show['name'])), premiered[:4], show['status']) if ('_embedded' in show and 'previousepisode' in show['_embedded']): airtime = parse( show['_embedded']['previousepisode']['airstamp']) timedelta = datetime.datetime.now(tzlocal()) - airtime relative_time = format_timedelta(timedelta, granularity='minutes') last_episode = format( '%s: [%s] %s on %s (%s).', ircutils.underline('Previous Episode'), ircutils.bold( str(show['_embedded']['previousepisode']['season']) + 'x' + str(show['_embedded']['previousepisode']['number'])), ircutils.bold( show['_embedded']['previousepisode']['name']), ircutils.bold( show['_embedded']['previousepisode']['airdate']), ircutils.mircColor(relative_time, 'red')) else: last_episode = '' if ('_embedded' in show and 'nextepisode' in show['_embedded']): airtime = parse(show['_embedded']['nextepisode']['airstamp']) timedelta = datetime.datetime.now(tzlocal()) - airtime relative_time = format_timedelta(timedelta, granularity='minutes') next_episode = format( '%s: [%s] %s on %s (%s).', ircutils.underline('Next Episode'), ircutils.bold( str(show['_embedded']['nextepisode']['season']) + 'x' + str(show['_embedded']['nextepisode']['number'])), ircutils.bold(show['_embedded']['nextepisode']['name']), ircutils.bold(show['_embedded']['nextepisode']['airdate']), ircutils.mircColor(relative_time, 'green')) else: next_episode = format('%s: %s.', ircutils.underline('Next Episode'), ircutils.bold('not yet scheduled')) irc.reply( format('%s %s %s %s', show_state, last_episode, next_episode, show['url'])) else: irc.reply(format('No show found named "%s"', ircutils.bold(tvshow))) if details: show_network = format('%s', ircutils.bold(show['network']['name'])) show_schedule = format( '%s: %s @ %s', ircutils.underline('Schedule'), ircutils.bold(', '.join(show['schedule']['days'])), ircutils.bold(show['schedule']['time'])) show_genre = format('%s: %s/%s', ircutils.underline('Genre'), ircutils.bold(show['type']), '/'.join(show['genres'])) irc.reply( format('%s on %s. %s', show_schedule, show_network, show_genre))
def _bu(self, string): """bold and underline string.""" return ircutils.bold(ircutils.underline(string))
def testStripUnderline(self): self.assertEqual(ircutils.stripUnderline(ircutils.underline('foo')), 'foo')
def testUnderline(self): s = ircutils.underline('foo') self.assertEqual(s[0], '\x1f') self.assertEqual(s[-1], '\x1f')
def odds(self, irc, msg, args, optsport, optteam): """[sport] <team> Display wager Odds for sport. Valid sports: MLB, NHL, NCB, NBA, NFL and NCF. For NCB/NCF, you must specify team. ex: odds NCF Alabama. """ today = datetime.date.today().strftime("%m/%d/%Y") # get date for checking against games only today. Useful for MLB. optsport = optsport.upper() validsports = { 'MLB': '204', 'NBA': '200', 'NFL': '203', 'NCF': '206' } if not optsport in validsports: irc.reply(ircutils.mircColor("ERROR:", 'red') + " sportname must be one of the following: %s" % (validsports.keys())) return url = 'http://www.bettingexpress.com/lines/cgi/lines.cgi?tem=parse&sport=%s&ct=text/xml' % (validsports[optsport]) try: request = urllib2.Request(url, headers={"Accept" : "application/xml"}) u = urllib2.urlopen(request) except: irc.reply("Failed to open: %s" % url) return try: tree = ElementTree.parse(u) root = tree.getroot() games = tree.findall('Game') except: irc.reply("ERROR: I was unable to process XML entries for: %s" % optsport) return if len(games) < 1 or games == None: # last check to make sure we have at least one. irc.reply(ircutils.mircColor("ERROR:", 'red') + " I did not find any entries for: %s" % optsport) return if optsport == "NCF": if not optteam or len(optteam) < 1: irc.reply("For NCF odds, you must have a team/string to search for that is longer than one character. Ex: odds NCF bama") return counter = 0 # since we're searching for a string, a bad search string outputList = [] # make a list to output search results. for entry in games: # now transform into a dict so we can parse. game = dict() for elem in entry: game[elem.tag] = elem.text if optteam.lower() in game.get('AwayTeam', None).lower() or optteam.lower() in game.get('HomeTeam', None).lower(): # if we find a match, now go through the routine. awayTeam = game.get('AwayTeam', None) homeTeam = game.get('HomeTeam', None) total = game.get('Total', None) line = game.get('Line', None) atMl = game.get('AwayTeamMoneyLine', None) htMl = game.get('HomeTeamMoneyLine', None) date = game.get('Date', None) if htMl != None and atMl != None and awayTeam != None and homeTeam != None and total != None and line != None and date != None: date1,date2 = date.split() # time is date time, split by space. if atMl != "OFF" and htMl != "OFF" and atMl < htMl: # no line placement, so we use moneyline to determine. output = "{0} @ {1}[{2}] o/u: {3} {4}/{5} {6}".format(awayTeam, homeTeam, ircutils.bold(line.strip()), total, self._fpm(atMl), self._fpm(htMl), self._timeFmt(date2)) elif atMl != "OFF" and htMl != "OFF" and atMl > htMl: output = "{0}[-{1}] @ {2} o/u: {3} {4}/{5} {6}".format(awayTeam, ircutils.bold(abs(float(line))), homeTeam,total, self._fpm(atMl), self._fpm(htMl), self._timeFmt(date2)) else: output = "{0} @ {1}[{2}] o/u: {3} {4}/{5} {6}".format(awayTeam, homeTeam, ircutils.bold(line.strip()), total, self._fpm(atMl), self._fpm(htMl), self._timeFmt(date2)) outputList.append(output) # append to output. # now, output our list from above. if len(outputList) < 1: irc.reply("I did not find any results in {0} matching '{1}'".format(ircutils.underline(optsport), ircutils.bold(optteam))) return else: for each in outputList: if counter >= self.registryValue('maximumOutput'): irc.reply("I've reached the maxmium of {0} results searching '{1}'. Please narrow your search string.".format(self.registryValue('maximumOutput'), optteam)) return else: counter += 1 irc.reply(each) elif optsport == "NFL": for entry in games: game = dict() for elem in entry: game[elem.tag] = elem.text awayTeam = game.get('AwayTeam', None) homeTeam = game.get('HomeTeam', None) total = game.get('Total', None) line = game.get('Line', None) atMl = game.get('AwayTeamMoneyLine', None) htMl = game.get('HomeTeamMoneyLine', None) date = game.get('Date', None) if htMl != None and atMl != None and awayTeam != None and homeTeam != None and total != None and line != None and date != None: aTeam, awayCity = awayTeam.split('(', 1) hTeam, homeCity = homeTeam.split('(', 1) date1,date2 = date.split() # time is date time, split by space. if atMl != "OFF" and htMl != "OFF" and atMl < htMl: # no line placement, so we use moneyline to determine. output = "{0} @ {1}[{2}] o/u: {3} {4}/{5} {6}".format(aTeam, hTeam, ircutils.bold(line.strip()), total, self._fpm(atMl), self._fpm(htMl), self._timeFmt(date2)) elif atMl != "OFF" and htMl != "OFF" and atMl > htMl: output = "{0}[-{1}] @ {2} o/u: {3} {4}/{5} {6}".format(aTeam, ircutils.bold(abs(float(line))), hTeam,total, self._fpm(atMl), self._fpm(htMl), self._timeFmt(date2)) else: output = "{0} @ {1}[{2}] o/u: {3} {4}/{5} {6}".format(aTeam, hTeam, ircutils.bold(line.strip()), total, self._fpm(atMl), self._fpm(htMl), self._timeFmt(date2)) irc.reply(output) elif optsport == "MLB": for entry in games: game = dict() for elem in entry: game[elem.tag] = elem.text htMl = game.get('HomeTeamMoneyLine', None) atMl = game.get('AwayTeamMoneyLine', None) awayTeam = game.get('AwayTeam', None) homeTeam = game.get('HomeTeam', None) total = game.get('Total', None) date = game.get('Date', None) if htMl != None and atMl != None and awayTeam != None and homeTeam != None and total != None and date != None: ateam, acity, apitcher = self._tsplit(awayTeam, ('(',')')) # they wrap team(Pitcher) and we split using a special tsplit hteam, hcity, hpitcher = self._tsplit(homeTeam, ('(',')')) date1,date2 = date.split() if date1 == today: # so we only print today. output = "{0}({1}) @ {2}({3}) o/u: {4} {5}/{6} {7}".format(ateam, apitcher, hteam, hpitcher, total, self._fpm(atMl), self._fpm(htMl), self._timeFmt(date2)) irc.reply(output) elif optsport == "NBA": for entry in games: game = dict() for elem in entry: game[elem.tag] = elem.text htMl = game.get('HomeTeamMoneyLine', None) atMl = game.get('AwayTeamMoneyLine', None) awayTeam = game.get('AwayTeam', None) homeTeam = game.get('HomeTeam', None) total = game.get('Total', None) date = game.get('Date', None) if htMl != None and atMl != None and awayTeam != None and homeTeam != None and total != None and date != None: ateam, awaycity = awayTeam.split('(', 1) hteam, homecity = homeTeam.split('(', 1) date1,date2 = date.split() if date1 == today: # so we only print today. output = "{0}({1}) @ {2}({3}) o/u: {4} {5}/{6} {7}".format(ateam, awaycity.replace(')',''), hteam, homecity.replace(')',''),\ total, self._fpm(atMl), self._fpm(htMl), self._timeFmt(date2)) irc.reply(output) else: irc.reply("I have not done odds for: %s" % optsport)
def forecast(self, irc, msg, args, location): """<location> Fetch forecast information from <location>. """ channel = msg.args[0] darksky_api = self.registryValue('darksky_api') if not darksky_api: irc.error("No darksky.net API key.", Raise=True) geocode_api = self.registryValue('geocode_api') if not geocode_api: irc.error("No Google Geocode API key.", Raise=True) lang = self.registryValue('lang', channel=channel) units = self.registryValue('units', channel=channel) # Getting location information for i in range(0, 10): try: gmaps = googlemaps.Client(key=geocode_api) loc = gmaps.geocode(location) my_loc = {} my_loc['lat'] = loc[0]['geometry']['location']['lat'] my_loc['lng'] = loc[0]['geometry']['location']['lng'] my_loc['formatted_address'] = loc[0]['formatted_address'] except: print('Google API Error') continue # Getting forecast information try: print(my_loc) fio = ForecastIO.ForecastIO(darksky_api, units=units, lang=lang, latitude=my_loc['lat'], longitude=my_loc['lng']) print(format('URL: %s', fio.get_url())) except: irc.error('Weather API error', Raise=True) print(format('URL: %s', fio.get_url())) units = fio.flags['units'] # Unit formatting if units != 'us': _tempU = '°C' else: _tempU = '°F' if units == 'ca': _speedU = 'kph' elif units == 'si': _speedU = 'm/s' else: _speedU = 'mph' # Emoji! _icons = { 'clear-day': '☀️', 'clear-night': '🌕', 'rain': '🌧️', 'snow': '❄️', 'sleet': '🌧️❄️', 'wind': '💨', 'fog': '🌁', 'cloudy': '☁️', 'partly-cloudy-day': '🌤️', 'partly-cloudy-night': '☁️', 'thunderstorm': '⛈️', 'tornado': '🌪' } now_summary = '' if fio.has_minutely() is True: minutely = FIOMinutely.FIOMinutely(fio) now_summary = minutely.summary elif fio.has_hourly() is True: hourly = FIOHourly.FIOHourly(fio) now_summary = hourly.summary # Current Conditions if fio.has_currently() is True: currently = FIOCurrently.FIOCurrently(fio) if not now_summary: now_summary = currently.summary now = format( '%s: %s%s (≈%s%s). %s %s Hum: %s%%, Wind: %s%s %s', ircutils.bold(my_loc['formatted_address']), int(currently.temperature), _tempU, int(currently.apparentTemperature), _tempU, _icons[currently.icon], now_summary, int(currently.humidity * 100), int(currently.windSpeed), _speedU, self._degrees_to_cardinal(currently.windBearing), ) if fio.has_daily() is True: daily = FIODaily.FIODaily(fio) overall = format('%s%s', _icons[daily.icon], daily.summary) day_2 = daily.get_day(2) tomorow_name = calendar.day_name[ datetime.datetime.utcfromtimestamp(day_2['time']).weekday()] tomorow = format( '%s: %s%s Min: %s%s/%s%s Max: %s%s/%s%s', ircutils.underline(tomorow_name), _icons[day_2['icon']], day_2['summary'], int(day_2['temperatureLow']), _tempU, int(day_2['apparentTemperatureLow']), _tempU, int(day_2['temperatureHigh']), _tempU, int(day_2['apparentTemperatureHigh']), _tempU, ) day_3 = daily.get_day(3) dat_name = calendar.day_name[datetime.datetime.utcfromtimestamp( day_3['time']).weekday()] dat = format( '%s: %s%s Min: %s%s/%s%s Max: %s%s/%s%s', ircutils.underline(dat_name), _icons[day_3['icon']], day_3['summary'], int(day_3['temperatureLow']), _tempU, int(day_3['apparentTemperatureLow']), _tempU, int(day_3['temperatureHigh']), _tempU, int(day_3['apparentTemperatureHigh']), _tempU, ) irc.reply(now + ' ' + overall + ' ' + tomorow + '. ' + dat)
def medals(self, irc, msg, args, optlist, optcountry): """[--mens | --womens] [--num <value>] [<country>] Display current medal count for the olympics. Use --mens or --womens to display totals via gender. Specify optional country to only display that country. """ url = None num = 3 if optlist: for (key, value) in optlist: if key == 'mens': header = ircutils.mircColor("2012 London Summer Olympics Medal Tracker (Mens)", 'red') url = 'http://www.nbcolympics.com/medals/library/2012-standings/tabs/medals/_men.html' if key == 'womens': header = ircutils.mircColor("2012 London Summer Olympics Medal Tracker (Womens)", 'red') url = 'http://www.nbcolympics.com/medals/library/2012-standings/tabs/medals/_women.html' if key == 'num': if value < 1: num = 1 elif value > 10: irc.reply('Please. Max 10.') return else: num = value if not url: # default to all header = ircutils.mircColor("2012 London Summer Olympics Medal Tracker", 'red') url = 'http://www.nbcolympics.com/medals/library/2012-standings/tabs/medals/_overall.html' try: req = urllib2.Request(url) html = (urllib2.urlopen(req)).read() except: irc.reply("Failed to open: %s" % url) return soup = BeautifulSoup(html) tbody = soup.find('tbody') rows = tbody.findAll('tr', attrs={'class':re.compile('^or.*?')}) object_list = [] for row in rows: country = row.find('div', attrs={'class':'or-country'}).find('img')['title'] gold = row.find('td', attrs={'class':'or-gold or-c'}) silver = row.find('td', attrs={'class':'or-silver or-c'}) bronze = row.find('td', attrs={'class':'or-bronze or-c'}) total = row.find('td', attrs={'class':'or-total or-c'}) d = collections.OrderedDict() d['country'] = country d['gold'] = gold.renderContents().strip() d['silver'] = silver.renderContents().strip() d['bronze'] = bronze.renderContents().strip() d['total'] = total.renderContents().strip() object_list.append(d) if self.registryValue('sortByGold', msg.args[0]): bronze = lambda x: int(x.get('bronze')) object_list = sorted(object_list, key=bronze, reverse=True) silver = lambda x: int(x.get('silver')) object_list = sorted(object_list, key=silver, reverse=True) gold = lambda x: int(x.get('gold')) object_list = sorted(object_list, key=gold, reverse=True) # cheap way of only showing what someone searches for. if optcountry: for each in object_list: if each['country'].lower().startswith(optcountry.lower()): output = "{0:20} G: {1:5} S: {2:5} B: {3:5} T: {4:7}".format(ircutils.underline(each['country']),\ ircutils.bold(each['gold']), ircutils.bold(each['silver']), ircutils.bold(each['bronze']), ircutils.bold(ircutils.bold(each['total']))) irc.reply(output) return # red title/top irc.reply(header) # header for table output = "{0:20} {1:5} {2:5} {3:5} {4:7}".format('Country', 'G', 'S', 'B', ircutils.bold('Total')) irc.reply(output) # iterate over the top3 for each in object_list[0:num]: output = "{0:20} {1:5} {2:5} {3:5} {4:7}".format(each['country'], each['gold'], each['silver'], each['bronze'], ircutils.bold(each['total'])) irc.reply(output)
def _bu(self, string): """Returns a bold/underline string.""" return ircutils.bold(ircutils.underline(string))
def _ul(self, string): """Returns an underline string.""" return ircutils.underline(string)
def _bu(self, string): return ircutils.underline(ircutils.bold(string))
def checkdraft(self, irc): """Main handling function.""" self.log.info("checkdraft: starting check.") # first, we need a baseline set of games. if not self.draft: # we don't have them if reloading. self.log.info("checkdraft: I do not have any draft. Fetching initial draft.") self.draft = self._fetchdraft() # verify we have a baseline. if not self.draft: # we don't. must bail. self.log.info("checkdraft: after second try, I could not get self.draft.") return else: # we have games. setup the baseline stuff. draft1 = self.draft # games to compare from. # now, we must grab new games. if something goes wrong or there are None, we bail. draft2 = self._fetchdraft() if not draft2: # if something went wrong, we bail. self.log.info("checkdraft: I was unable to get new draft.") return # what we'll do is iterate through the list of dicts. # d is stored. new d is compared. # we iterate through each item and look if "plr" changes. # if plr changes, it means someone was picked. # we then announce the "pick" and also announce what pick/team is next. for (k, v) in draft1.items(): # {'rd': rd, 'pick':pick, 'plr':plr, 'col':col, 'pos':pos, 'tm':tm } if v['plr'] != draft2[k]['plr']: # plr changed. that means pick is in. self.log.info("1: {0}".format(v)) self.log.info("2: {0}".format(draft2[k])) mstr = "Round: {0} Pick: {1} :: {2} has picked {3}, {4}, {5}".format(ircutils.bold(v['rd']), ircutils.bold(v['pick']), ircutils.bold(draft2[k]['tm']), ircutils.underline(draft2[k]['plr']), draft2[k]['pos'], draft2[k]['col']) self._post(irc, mstr) # figure out who picks next. nextpick = k+1 # this is the number(int) + 1. if nextpick > 256: # this means the draft is over. self.log.info("checkdraft: pick is {0}. we have reached the end of the draft.".format(nextpick)) else: # we're not at the last pick. n = draft2[nextpick] # easier to access. {'rd': rd, 'pick':pick, 'plr':plr, 'col':col, 'pos':pos, 'tm':tm } self.log.info("n = {0}".format(n)) np = "{0} is now on the clock with the {1} pick".format(ircutils.bold(n['tm']), ircutils.bold(n['pick'])) self._post(irc, np) # now that we're done checking changes, copy the new into self.games to check against next time. self.draft = draft2 self.log.info("checkdraft: done checking. copied.")
def underline(self, irc, msg, args, text): """<text> Returns <text> underlined. """ irc.reply(ircutils.underline(text))
def tv(self, irc, msg, args, opts, tvshow): """[-d | --detail] <tvshow> """ if not opts: details = False else: for (stuff, arg) in opts: if stuff == 'd': details = True elif stuff == 'details': details = True show = fetch(tvshow) if show: if show['premiered']: premiered = show['premiered'] else: premiered = "SOON" show_state = format('%s %s (%s).', ircutils.bold(ircutils.underline(show['name'])), premiered[:4], show['status']) if ( '_embedded' in show and 'previousepisode' in show['_embedded']): airtime = parse(show['_embedded']['previousepisode']['airstamp']) timedelta = datetime.datetime.now(tzlocal()) - airtime relative_time = format_timedelta(timedelta, granularity='minutes') last_episode = format('%s: [%s] %s on %s (%s).', ircutils.underline('Previous Episode'), ircutils.bold(str(show['_embedded']['previousepisode']['season']) + 'x' + str(show['_embedded']['previousepisode']['number'])), ircutils.bold(show['_embedded']['previousepisode']['name']), ircutils.bold(show['_embedded']['previousepisode']['airdate']), ircutils.mircColor(relative_time, 'red')) else: last_episode = '' if ('_embedded' in show and 'nextepisode' in show['_embedded']): airtime = parse(show['_embedded']['nextepisode']['airstamp']) timedelta = datetime.datetime.now(tzlocal()) - airtime relative_time = format_timedelta(timedelta, granularity='minutes') next_episode = format('%s: [%s] %s on %s (%s).', ircutils.underline('Next Episode'), ircutils.bold(str(show['_embedded']['nextepisode']['season']) + 'x' + str(show['_embedded']['nextepisode']['number'])), ircutils.bold(show['_embedded']['nextepisode']['name']), ircutils.bold(show['_embedded']['nextepisode']['airdate']), ircutils.mircColor(relative_time, 'green')) else: next_episode = format('%s: %s.', ircutils.underline('Next Episode'), ircutils.bold('not yet scheduled')) irc.reply(format('%s %s %s %s', show_state, last_episode, next_episode, show['url'])) else: irc.reply(format('No show found named "%s"', ircutils.bold(tvshow))) if details: show_network = format('%s', ircutils.bold(show['network']['name'])) show_schedule = format('%s: %s @ %s', ircutils.underline('Schedule'), ircutils.bold(', '.join(show['schedule']['days'])), ircutils.bold(show['schedule']['time'])) show_genre = format('%s: %s/%s', ircutils.underline('Genre'), ircutils.bold(show['type']), '/'.join(show['genres'])) irc.reply(format('%s on %s. %s', show_schedule, show_network, show_genre))
def tv(self, irc, msg, args, opts, tvshow): """[--detail | --rip | --next | --last] <tvshow> Command accepts first option only. """ details = False rip = False next = False last = False if opts: for (stuff, arg) in opts: if stuff == 'detail': details = True elif stuff == 'rip': rip = True elif stuff == 'next': next = True elif stuff == 'last': last = True break show = fetch(tvshow) if show: if show['premiered']: premiered = show['premiered'] else: premiered = "SOON" show_title = ircutils.bold('%s (%s)' % (show['name'], premiered[:4])) if "Ended" in show['status']: show_state = ircutils.mircColor(show['status'], 'red').upper() else: show_state = ircutils.mircColor(show['status'], 'green').upper() if ('_embedded' in show and 'previousepisode' in show['_embedded']): airtime = parse( show['_embedded']['previousepisode']['airstamp']) timedelta = datetime.datetime.now(tzlocal()) - airtime relative_time = format_timedelta(timedelta, granularity='minutes') last_episode = format( '[%s] %s on %s (%s)', ircutils.bold( str(show['_embedded']['previousepisode']['season']) + 'x' + str(show['_embedded']['previousepisode']['number'])), ircutils.bold( show['_embedded']['previousepisode']['name']), ircutils.bold( show['_embedded']['previousepisode']['airdate']), ircutils.mircColor(relative_time, 'red')) else: last_episode = '' if ('_embedded' in show and 'nextepisode' in show['_embedded']): airtime = parse(show['_embedded']['nextepisode']['airstamp']) timedelta = datetime.datetime.now(tzlocal()) - airtime relative_time = format_timedelta(timedelta, granularity='minutes') next_episode = format( '[%s] %s on %s (%s)', ircutils.bold( str(show['_embedded']['nextepisode']['season']) + 'x' + str(show['_embedded']['nextepisode']['number'])), ircutils.bold(show['_embedded']['nextepisode']['name']), ircutils.bold(show['_embedded']['nextepisode']['airdate']), ircutils.mircColor(relative_time, 'green')) else: next_episode = 'not yet scheduled' if rip: irc.reply(format('%s is %s', show_title, show_state)) elif next: if ('_embedded' in show and 'nextepisode' in show['_embedded']): irc.reply( format('%s next scheduled episode is %s', show_title, next_episode)) else: if "Ended" in show['status']: irc.reply(format('%s is %s', show_title, show_state)) else: irc.reply( format( '%s is %s but does not have a release date for the next episode', show_title, show_state)) elif last: if ('_embedded' in show and 'previousepisode' in show['_embedded']): irc.reply( format('%s last scheduled episode was %s', show_title, last_episode)) else: irc.reply( format('%s has not previously run any episodes', show_title)) else: if "Ended" in show['status']: irc.reply( format('%s %s %s: %s %s', show_title, show_state, ircutils.underline('Previous Episode'), last_episode, show['url'])) else: irc.reply( format('%s %s %s: %s %s: %s %s', show_title, show_state, ircutils.underline('Next Episode'), next_episode, ircutils.underline('Previous Episode'), last_episode, show['url'])) else: irc.reply(format('No show found named "%s"', ircutils.bold(tvshow))) if details: if show['network']: show_network = format('%s', ircutils.bold(show['network']['name'])) show_schedule = format( '%s: %s @ %s', ircutils.underline('Schedule'), ircutils.bold(', '.join(show['schedule']['days'])), ircutils.bold(show['schedule']['time'])) else: show_network = format( '%s', ircutils.bold(show['webChannel']['name'])) show_schedule = format('%s: %s', ircutils.underline('Premiered'), ircutils.bold(show['premiered'])) show_genre = format('%s: %s/%s', ircutils.underline('Genre'), ircutils.bold(show['type']), '/'.join(show['genres'])) irc.reply( format('%s on %s. %s', show_schedule, show_network, show_genre))
def _ul(self, string): return ircutils.underline(string)