def _stringifyTweet(self, tweet): """ turn a tweet object into a nice string for us to send to IRC @type tweet: dict[str, T/str] """ retweet = None # get the original tweet if this is a retweet if 'retweeted_status' in tweet: retweet = tweet tweet = retweet['retweeted_status'] tweetText = StringUtils.unescapeXHTML(tweet['text']) tweetText = re.sub('[\r\n]+', StringUtils.graySplitter, tweetText) for url in tweet['entities']['urls']: tweetText = tweetText.replace(url['url'], url['expanded_url']) timestamp = parser.parse(tweet['created_at']) timeString = timestamp.strftime('%A, %Y-%m-%d %H:%M:%S %Z') delta = datetime.datetime.utcnow() - timestamp.replace(tzinfo=None) deltaString = StringUtils.deltaTimeToString(delta) tweetText = u'{} (tweeted {}, {} ago)'.format(tweetText, timeString, deltaString) if retweet is None: user = tweet['user']['screen_name'] else: user = retweet['user']['screen_name'] tweetText = 'RT {}: {}'.format(tweet['user']['screen_name'], tweetText) link = u'https://twitter.com/{}/status/{}'.format(tweet['user']['screen_name'], tweet['id_str']) link = WebUtils.shortenGoogl(link) formatString = unicode(assembleFormattedText(A.normal[A.bold['@{0}>'], ' {1} {2}'])) newTweet = formatString.format(user, tweetText, link) return newTweet
def add(self, message): """add lat,lon - adds a nick to the chat map, or updates if already added""" coords = ''.join(message.ParameterList[1:]) if not ',' in coords: return 'lat,lon coords must be comma separated' (lat, lon) = coords.split(',') if not StringUtils.isNumber(lat) or not StringUtils.isNumber(lon): return 'latitude or longitude are not numeric' (lat, lon) = float(lat), float(lon) if not -90.0 < lat < 90.0: return 'latitude is outside valid range (-90 -> 90)' if not -180.0 < lon < 180.0: return 'longitude is outside valid range (-180 -> 180)' db = create_database("mysql://{0}:{1}@{2}:{3}/{4}".format( self.chatMapDB['User'], self.chatMapDB['Password'], self.chatMapDB['Host'], 3306, self.chatMapDB['DB'])) store = Store(db) result = store.execute( "SELECT nick, latitude, longitude FROM " + self.chatMapDB['Table'] + " WHERE nick=%s", [message.User.Name]) response = 'There has been a fatal error updating your GPS coordinates. Please contact Emily to let her know.' if result.rowcount == 1: result = store.execute( "UPDATE " + self.chatMapDB['Table'] + " SET latitude=%s, longitude=%s WHERE nick=%s", [lat, lon, message.User.Name]) if result: response = 'Your chatmap position has been updated with the new GPS coordinates!' elif result.rowcount == 0: result = store.execute( "INSERT INTO " + self.chatMapDB['Table'] + " (nick, latitude, longitude) VALUES(%s, %s, %s)", [message.User.Name, lat, lon]) if result: response = 'You are now on the chatmap at the specified GPS coordinates! ' \ 'Be sure to do an addYear to add the year you first started as a Survivor!' store.close() return response
def execute(self, message): """ @type message: IRCMessage """ date = datetime.datetime.utcnow() if len(message.ParameterList) == 1: if StringUtils.isNumber(message.ParameterList[0]): date += datetime.timedelta(days=int(message.ParameterList[0])) else: try: date = dparser.parse(message.ParameterList[0], fuzzy=True, dayfirst=True) except ValueError: pass proc = subprocess.Popen(['/usr/bin/php', '/home/ubuntu/moronbot/getloghash.php', message.ReplyTo + "-" + date.strftime('%Y%m%d')], stdout=subprocess.PIPE) logHash = proc.stdout.read() if logHash == "Not found": output = "I don't have that log." else: output = "Log for " + date.strftime('%Y/%m/%d') + ": http://www.moronic-works.co.uk/logs/?l=" + logHash return IRCResponse(ResponseType.Say, output, message.ReplyTo)
def FollowTwitter(self, tweeter, tweetID, message): webPage = WebUtils.fetchURL('https://twitter.com/{0}/status/{1}'.format(tweeter, tweetID)) soup = BeautifulSoup(webPage.body) tweet = soup.find(class_='permalink-tweet') user = tweet.find(class_='username').text tweetText = tweet.find(class_='tweet-text') tweetTimeText = tweet.find(class_='client-and-actions').text.strip() try: tweetTimeText = time.strftime('%Y/%m/%d %H:%M', time.strptime(tweetTimeText, '%I:%M %p - %d %b %Y')) except ValueError: pass links = tweetText.find_all('a', {'data-expanded-url': True}) for link in links: link.string = link['data-expanded-url'] embeddedLinks = tweetText.find_all('a', {'data-pre-embedded': 'true'}) for link in embeddedLinks: link.string = link['href'] text = StringUtils.unescapeXHTML(tweetText.text) text = re.sub('[\r\n]+', self.graySplitter, text) formatString = unicode(assembleFormattedText(A.normal[A.fg.gray['[{0}]'], A.bold[' {1}:'], ' {2}'])) return IRCResponse(ResponseType.Say, formatString.format(tweetTimeText, user, text), message.ReplyTo, {'urlfollowURL': 'https://twitter.com/{}/status/{}'.format(tweeter, tweetID)})
def FollowTwitter(self, tweeter, tweetID, message): webPage = WebUtils.fetchURL('https://twitter.com/{0}/status/{1}'.format(tweeter, tweetID)) soup = BeautifulSoup(webPage.body) tweet = soup.find(class_='permalink-tweet') user = tweet.find(class_='username').text tweetText = tweet.find(class_='tweet-text') tweetTimeText = tweet.find(class_='client-and-actions').text.strip() try: tweetTimeText = time.strftime('%Y/%m/%d %H:%M', time.strptime(tweetTimeText, '%I:%M %p - %d %b %Y')) except ValueError: pass links = tweetText.find_all('a', {'data-expanded-url': True}) for link in links: link.string = ' ' + link['data-expanded-url'] embeddedLinks = tweetText.find_all('a', {'data-pre-embedded': 'true'}) for link in embeddedLinks: link.string = ' ' + link['href'] text = StringUtils.unescapeXHTML(tweetText.text) text = re.sub('[\r\n]+', self.graySplitter, text) formatString = unicode(assembleFormattedText(A.normal[A.fg.gray['[{0}]'], A.bold[' {1}:'], ' {2}'])) return IRCResponse(ResponseType.Say, formatString.format(tweetTimeText, user, text), message.ReplyTo, {'urlfollowURL': 'https://twitter.com/{}/status/{}'.format(tweeter, tweetID)})
def FollowTwitter(self, tweeter, tweetID, message): webPage = WebUtils.fetchURL('https://twitter.com/{0}/status/{1}'.format(tweeter, tweetID)) soup = BeautifulSoup(webPage.body) tweet = soup.find(class_='permalink-tweet') user = tweet.find(class_='username').text tweetText = tweet.find(class_='tweet-text') links = tweetText.find_all('a', {'data-expanded-url': True}) for link in links: link.string = link['data-expanded-url'] embeddedLinks = tweetText.find_all('a', {'data-pre-embedded': 'true'}) for link in embeddedLinks: link.string = link['href'] text = StringUtils.unescapeXHTML(tweetText.text) text = re.sub('[\r\n]+', self.graySplitter, text) formatString = unicode(assembleFormattedText(A.normal[A.bold['{0}:'], ' {1}'])) return IRCResponse(ResponseType.Say, formatString.format(user, text), message.ReplyTo)
def execute(self, message): """ @type message: IRCMessage """ date = datetime.datetime.utcnow() if len(message.ParameterList) == 1: if StringUtils.isNumber(message.ParameterList[0]): date += datetime.timedelta(days=int(message.ParameterList[0])) else: try: date = dparser.parse(message.ParameterList[0], fuzzy=True, dayfirst=True) except ValueError: pass proc = subprocess.Popen([ '/usr/bin/php', '/home/ubuntu/moronbot/getloghash.php', message.ReplyTo + "-" + date.strftime('%Y%m%d') ], stdout=subprocess.PIPE) logHash = proc.stdout.read() if logHash == "Not found": output = "I don't have that log." else: output = "Log for " + date.strftime( '%Y/%m/%d' ) + ": http://www.moronic-works.co.uk/logs/?l=" + logHash return IRCResponse(ResponseType.Say, output, message.ReplyTo)
def add(self, message): """add lat,lon - adds a nick to the chat map, or updates if already added""" coords = ''.join(message.ParameterList[1:]) if not ',' in coords: return 'lat,lon coords must be comma separated' (lat, lon) = coords.split(',') if not StringUtils.isNumber(lat) or not StringUtils.isNumber(lon): return 'latitude or longitude are not numeric' (lat, lon) = float(lat), float(lon) if not -90.0 < lat < 90.0: return 'latitude is outside valid range (-90 -> 90)' if not -180.0 < lon < 180.0: return 'longitude is outside valid range (-180 -> 180)' db = create_database("mysql://{0}:{1}@{2}:{3}/{4}".format(self.chatMapDB['User'], self.chatMapDB['Password'], self.chatMapDB['Host'], 3306, self.chatMapDB['DB'])) store = Store(db) result = store.execute("SELECT nick, latitude, longitude FROM " + self.chatMapDB['Table'] + " WHERE nick=%s", [message.User.Name]) response = 'There has been a fatal error updating your GPS coordinates. Please contact Emily to let her know.' if result.rowcount == 1: result = store.execute("UPDATE " + self.chatMapDB['Table'] + " SET latitude=%s, longitude=%s WHERE nick=%s", [lat, lon, message.User.Name]) if result: response = 'Your chatmap position has been updated with the new GPS coordinates!' elif result.rowcount == 0: result = store.execute( "INSERT INTO " + self.chatMapDB['Table'] + " (nick, latitude, longitude) VALUES(%s, %s, %s)", [message.User.Name, lat, lon]) if result: response = 'You are now on the chatmap at the specified GPS coordinates! ' \ 'Be sure to do an addYear to add the year you first started as a Survivor!' store.close() return response
def execute(self, message): """ @type message: IRCMessage """ # split on unescaped | chain = re.split(r'(?<!\\)\|', message.Parameters) response = None extraVars = {} for link in chain: link = link.strip() link = re.sub(r'\\\|', r'|', link) if response is not None: if hasattr(response, '__iter__'): return IRCResponse(ResponseType.Say, u"Chain Error: segment before '{}' returned a list".format(link), message.ReplyTo) link = link.replace('$output', response.Response) # replace $output with output of previous command extraVars.update(response.ExtraVars) for var, value in extraVars.iteritems(): link = re.sub(r'\$\b{}\b'.format(re.escape(var)), '{}'.format(value), link) else: # replace $output with empty string if previous command had no output # (or this is the first command in the chain, but for some reason has $output as a param) link = link.replace('$output', '') link = link.replace('$sender', message.User.Name) if message.Channel is not None: link = link.replace('$channel', message.Channel.Name) else: link = link.replace('$channel', message.User.Name) # build a new message out of this 'link' in the chain inputMessage = IRCMessage(message.Type, message.User.String, message.Channel, self.bot.commandChar + link.lstrip(), self.bot) inputMessage.chained = True # might be used at some point to tell commands they're being called from Chain if inputMessage.Command.lower() in self.bot.moduleHandler.mappedTriggers: response = self.bot.moduleHandler.mappedTriggers[inputMessage.Command.lower()].execute(inputMessage) else: return IRCResponse(ResponseType.Say, "'{0}' is not a recognized command trigger".format(inputMessage.Command), message.ReplyTo) if response.Response is not None: # limit response length (chains can get pretty large) response.Response = list(StringUtils.splitUTF8(response.Response.encode('utf-8'), 700))[0] response.Response = unicode(response.Response, 'utf-8') return response
def _stringifyTweet(self, tweet): """ turn a tweet object into a nice string for us to send to IRC @type tweet: dict[str, T/str] """ retweet = None # get the original tweet if this is a retweet if 'retweeted_status' in tweet: retweet = tweet tweet = retweet['retweeted_status'] tweetText = StringUtils.unescapeXHTML(tweet['text']) tweetText = re.sub('[\r\n]+', StringUtils.graySplitter, tweetText) for url in tweet['entities']['urls']: tweetText = tweetText.replace(url['url'], url['expanded_url']) timestamp = parser.parse(tweet['created_at']) timeString = timestamp.strftime('%A, %Y-%m-%d %H:%M:%S %Z') delta = datetime.datetime.utcnow() - timestamp.replace(tzinfo=None) deltaString = StringUtils.deltaTimeToString(delta) tweetText = u'{} (tweeted {}, {} ago)'.format(tweetText, timeString, deltaString) if retweet is None: user = tweet['user']['screen_name'] else: user = retweet['user']['screen_name'] tweetText = 'RT {}: {}'.format(tweet['user']['screen_name'], tweetText) link = u'https://twitter.com/{}/status/{}'.format( tweet['user']['screen_name'], tweet['id_str']) link = WebUtils.shortenGoogl(link) formatString = unicode( assembleFormattedText(A.normal[A.bold['@{0}>'], ' {1} {2}'])) newTweet = formatString.format(user, tweetText, link) return newTweet
def execute(self, message): """ @type message: IRCMessage """ match = re.search('^hango+?u?t$', message.Command, re.IGNORECASE) if match or ((message.Type == 'JOIN') and (message.User.Name == 'Emily[iOS]')): if message.ReplyTo not in self.hangoutDict: self.hangoutDict[message.ReplyTo] = None self._syncHangoutDict() if self.hangoutDict[message.ReplyTo] is None: return IRCResponse(ResponseType.Say, 'No hangouts posted here yet', message.ReplyTo) hangout = self.hangoutDict[message.ReplyTo] timeDiff = datetime.datetime.utcnow() - hangout.lastDate url = 'https://talkgadget.google.com/hangouts/_/{0}'.format( hangout.lastCode) byLine = 'first linked {0} ago'.format( StringUtils.deltaTimeToString(timeDiff)) if ((message.Type == 'JOIN') and (message.User.Name == 'Emily[iOS]')): response = 'Welcome Back, Lady Emily. Here\'s the hangout for your streaming pleasure: http://bit.ly/DBHangoutReloaded' else: response = 'Last hangout linked: {0} ({1})'.format(url, byLine) return IRCResponse(ResponseType.Say, response, message.ReplyTo) match = re.search(r'google\.com/hangouts/_/(?P<code>[^\?\s]+)', message.MessageString, re.IGNORECASE) if not match: return if message.ReplyTo not in self.hangoutDict or self.hangoutDict[ message.ReplyTo] is None: self.hangoutDict[message.ReplyTo] = Data() elif match.group('code') == self.hangoutDict[message.ReplyTo].lastCode: return self.hangoutDict[message.ReplyTo].lastCode = match.group('code') self.hangoutDict[message.ReplyTo].lastUser = message.User.Name self.hangoutDict[message.ReplyTo].lastDate = datetime.datetime.utcnow() self._syncHangoutDict() return
def execute(self, response): """ @type response: IRCResponse """ limit = 700 # chars expire = 10 # minutes if len(response.Response) > limit: replaced = WebUtils.pasteEE( StringUtils.stripFormatting(response.Response), u'Response longer than {0} chars intended for {1}'.format( limit, response.Target), expire) response.Response = u'Response too long, pasted here instead: {0} (Expires in {1} minutes)'.format( replaced, expire) return response
def execute(self, response): """ @type response: IRCResponse """ limit = 700 # chars expire = 10 # minutes if len(response.Response) > limit: replaced = WebUtils.pasteEE(StringUtils.stripFormatting(response.Response), u'Response longer than {0} chars intended for {1}'.format(limit, response.Target), expire) response.Response = u'Response too long, pasted here instead: {0} (Expires in {1} minutes)'.format(replaced, expire) return response
def execute(self, message): """ @type message: IRCMessage """ # TODO: maybe do this in the command handler? # map triggers to commands so we can call them via dict lookup mappedTriggers = {} for command in self.bot.moduleHandler.commands.values(): for trigger in command.triggers: mappedTriggers[trigger] = command # split on unescaped | chain = re.split(r'(?<!\\)\|', message.Parameters) # rebuild the user string... TODO: this should probably be part of the User class if message.User.User is not None: userString = '{0}!{1}@{2}'.format(message.User.Name, message.User.User, message.User.Hostmask) else: userString = message.User.Name response = None for link in chain: if response is not None: link = link.replace('%output%', response.Response) # replace %output% with output of previous command else: # replace %output% with empty string if previous command had no output # (or this is the first command in the chain, but for some reason has %output% as a param) link = link.replace('%output%', '') # build a new message out of this 'link' in the chain inputMessage = IRCMessage(message.Type, userString, message.Channel, self.bot.commandChar + link.lstrip(), self.bot) inputMessage.chained = True # might be used at some point to tell commands they're being called from Chain if inputMessage.Command.lower() in mappedTriggers: response = mappedTriggers[inputMessage.Command.lower()].execute(inputMessage) else: return IRCResponse(ResponseType.Say, "'{0}' is not a recognized command trigger".format(inputMessage.Command), message.ReplyTo) if response.Response is not None: # limit response length (chains can get pretty large) response.Response = list(StringUtils.splitUTF8(response.Response.encode('utf-8'), 700))[0] response.Response = unicode(response.Response, 'utf-8') return response
def execute(self, message): """ @type message: IRCMessage """ match = re.search('^hango+?u?t$', message.Command, re.IGNORECASE) if match or ((message.Type == 'JOIN') and (message.User.Name == 'Emily[iOS]')): if message.ReplyTo not in self.hangoutDict: self.hangoutDict[message.ReplyTo] = None self._syncHangoutDict() if self.hangoutDict[message.ReplyTo] is None: return IRCResponse(ResponseType.Say, 'No hangouts posted here yet', message.ReplyTo) hangout = self.hangoutDict[message.ReplyTo] timeDiff = datetime.datetime.utcnow() - hangout.lastDate url = 'https://talkgadget.google.com/hangouts/_/{0}'.format(hangout.lastCode) byLine = 'first linked {0} ago'.format(StringUtils.deltaTimeToString(timeDiff)) if ((message.Type == 'JOIN') and (message.User.Name == 'Emily[iOS]')): response = 'Welcome Back, Lady Emily. Here\'s the hangout for your streaming pleasure: http://bit.ly/DBHangoutReloaded' else: response = 'Last hangout linked: {0} ({1})'.format(url, byLine) return IRCResponse(ResponseType.Say, response, message.ReplyTo) match = re.search(r'google\.com/hangouts/_/(?P<code>[^\?\s]+)', message.MessageString, re.IGNORECASE) if not match: return if message.ReplyTo not in self.hangoutDict or self.hangoutDict[message.ReplyTo] is None: self.hangoutDict[message.ReplyTo] = Data() elif match.group('code') == self.hangoutDict[message.ReplyTo].lastCode: return self.hangoutDict[message.ReplyTo].lastCode = match.group('code') self.hangoutDict[message.ReplyTo].lastUser = message.User.Name self.hangoutDict[message.ReplyTo].lastDate = datetime.datetime.utcnow() self._syncHangoutDict() return
def _fetch(self, j, short, mode, label): r = j['modes'][mode] data = [] t = A.normal[A.bold['{} {}: '.format(label, r[0]['rule']['name'])], '/'.join(r[0]['maps'])] data.append(assembleFormattedText(t)) if not short: # include next maps now = int(time.time()) startTime = r[1]['startTime'] delta = startTime - now d = datetime.timedelta(seconds=delta) deltaStr = StringUtils.deltaTimeToString(d, resolution='m') t = A.normal[A.bold['{} {} in {}: '. format(label, r[1]['rule']['name'], deltaStr)], '/'.join(r[1]['maps'])] data.append(assembleFormattedText(t)) return ' | '.join(data)
def execute(self, message): """ @type message: IRCMessage """ if len(message.ParameterList) < 2: return IRCResponse(ResponseType.Say, self.help, message.ReplyTo) command = message.ParameterList[1].lower() delay = timeparse(message.ParameterList[0]) delayDelta = datetime.timedelta(seconds=delay) delayString = StringUtils.deltaTimeToString(delayDelta, 's') params = message.ParameterList[2:] commandString = u'{}{} {}'.format(self.bot.commandChar, command, u' '.join(params)) commandString = commandString.replace('$delayString', delayString) commandString = commandString.replace('$delay', str(delay)) newMessage = IRCMessage(message.Type, message.User.String, message.Channel, commandString, self.bot) moduleHandler = self.bot.moduleHandler if command in moduleHandler.mappedTriggers: d = task.deferLater(reactor, delay, moduleHandler.mappedTriggers[command].execute, newMessage) d.addCallback(self.bot.sendResponse) return IRCResponse(ResponseType.Say, "OK, I'll execute that in {}".format(delayString), message.ReplyTo, {'delay': delay, 'delayString': delayString}) else: if 'Alias' not in moduleHandler.commands: return IRCResponse(ResponseType.Say, "'{}' is not a recognized command".format(command), message.ReplyTo) if command not in moduleHandler.commands['Alias'].aliases: return IRCResponse(ResponseType.Say, "'{}' is not a recognized command or alias".format(command), message.ReplyTo) d = task.deferLater(reactor, delay, moduleHandler.commands['Alias'].execute, newMessage) d.addCallback(self.bot.sendResponse) return IRCResponse(ResponseType.Say, "OK, I'll execute that in {}".format(delayString), message.ReplyTo)
def execute(self, message): """ @type message: IRCMessage """ try: results = WebUtils.googleSearch(message.Parameters) firstResult = results['responseData']['results'][0] title = firstResult['titleNoFormatting'] content = firstResult['content'] content = re.sub(r'<.*?>', '', content) # strip html tags content = re.sub(r'\s+', ' ', content) # replace multiple spaces with single ones (includes newlines?) content = StringUtils.unescapeXHTML(content) url = firstResult['unescapedUrl'] replyText = u'{1}{0}{2}{0}{3}'.format(StringUtils.graySplitter, title, content, url) return IRCResponse(ResponseType.Say, replyText, message.ReplyTo) except Exception, x: print str(x) return IRCResponse(ResponseType.Say, x.args, message.ReplyTo)
def execute(self, message): """ @type message: IRCMessage """ match = re.search('^hango+?u?t$', message.Command, re.IGNORECASE) if match: if message.ReplyTo not in self.hangoutDict: self.hangoutDict[message.ReplyTo] = None if self.hangoutDict[message.ReplyTo] is None: return IRCResponse(ResponseType.Say, 'No hangouts posted here yet', message.ReplyTo) hangout = self.hangoutDict[message.ReplyTo] timeDiff = datetime.datetime.utcnow() - hangout.lastDate url = 'https://talkgadget.google.com/hangouts/_/{0}'.format(hangout.lastCode) byLine = 'first linked {0} ago by {1}'.format(StringUtils.deltaTimeToString(timeDiff), hangout.lastUser) response = 'Last hangout linked: {0} ({1})'.format(url, byLine) return IRCResponse(ResponseType.Say, response, message.ReplyTo) match = re.search(r'google\.com/hangouts/_/(?P<code>[^\?\s]+)', message.MessageString, re.IGNORECASE) if not match: return if message.ReplyTo not in self.hangoutDict or self.hangoutDict[message.ReplyTo] is None: self.hangoutDict[message.ReplyTo] = Data() elif match.group('code') == self.hangoutDict[message.ReplyTo].lastCode: return self.hangoutDict[message.ReplyTo].lastCode = match.group('code') self.hangoutDict[message.ReplyTo].lastUser = message.User.Name self.hangoutDict[message.ReplyTo].lastDate = datetime.datetime.utcnow() return
def addYear(self, message): """addYear - updates desert bus year for the user, (first surviving year)""" year = ''.join(message.ParameterList[1:]) if not StringUtils.isNumber(year): return 'the desert bus year should only be numeric (1-8)' year = int(year) if year >= 2010: year -= 2006 if not 4 <= year <= 8: return 'the desert bus year should only be for valid years (4 -> 8)' db = create_database("mysql://{0}:{1}@{2}:{3}/{4}".format( self.chatMapDB['User'], self.chatMapDB['Password'], self.chatMapDB['Host'], 3306, self.chatMapDB['DB'])) store = Store(db) result = store.execute( "SELECT nick, dbyear FROM " + self.chatMapDB['Table'] + " WHERE nick=%s", [message.User.Name]) response = 'There has been a fatal error updating your Desert Bus Year. Please contact Emily to let her know.' if result.rowcount == 1: result = store.execute( "UPDATE " + self.chatMapDB['Table'] + " SET dbyear=%s WHERE nick=%s", [year, message.User.Name]) if result: response = 'Your desert bus year has been updated with your information!' elif result.rowcount == 0: response = 'You do not currently have a chatmap record, please use add lat,lon first.' store.close() return response
def addYear(self, message): """addYear - updates desert bus year for the user, (first surviving year)""" year = ''.join(message.ParameterList[1:]) if not StringUtils.isNumber(year): return 'the desert bus year should only be numeric (1-8)' year = int(year) if year >= 2010: year -= 2006 if not 4 <= year <= 8: return 'the desert bus year should only be for valid years (4 -> 8)' db = create_database("mysql://{0}:{1}@{2}:{3}/{4}".format(self.chatMapDB['User'], self.chatMapDB['Password'], self.chatMapDB['Host'], 3306, self.chatMapDB['DB'])) store = Store(db) result = store.execute("SELECT nick, dbyear FROM " + self.chatMapDB['Table'] + " WHERE nick=%s", [message.User.Name]) response = 'There has been a fatal error updating your Desert Bus Year. Please contact Emily to let her know.' if result.rowcount == 1: result = store.execute("UPDATE " + self.chatMapDB['Table'] + " SET dbyear=%s WHERE nick=%s", [year, message.User.Name]) if result: response = 'Your desert bus year has been updated with your information!' elif result.rowcount == 0: response = 'You do not currently have a chatmap record, please use add lat,lon first.' store.close() return response
def execute(self, message): """ @type message: IRCMessage """ try: results = WebUtils.googleSearch(message.Parameters) firstResult = results[u'items'][0] title = firstResult[u'title'] title = re.sub(r'\s+', ' ', title) content = firstResult[u'snippet'] content = re.sub( r'\s+', ' ', content ) # replace multiple spaces with single ones (includes newlines?) content = StringUtils.unescapeXHTML(content) url = firstResult[u'link'] replyText = u'{1}{0}{2}{0}{3}'.format(StringUtils.graySplitter, title, content, url) return IRCResponse(ResponseType.Say, replyText, message.ReplyTo) except Exception, x: print str(x) return IRCResponse(ResponseType.Say, x.args, message.ReplyTo)
def _scanTwitter(self): for user, lastTweetTimestamp in self.follows.iteritems(): timeline = self.twitter.statuses.user_timeline(screen_name=user) newTweets = [] for tweet in timeline: tweetTimestamp = datetime.datetime.strptime(tweet['created_at'], '%a %b %d %H:%M:%S +0000 %Y') if tweetTimestamp > lastTweetTimestamp: newTweets.append(tweet) else: if len(newTweets) > 0: self.follows[user] = datetime.datetime.strptime(newTweets[0]['created_at'], '%a %b %d %H:%M:%S +0000 %Y') else: self.follows[user] = tweetTimestamp break if len(newTweets) > 0: newTweets = newTweets[::-1] # reverse the list so oldest tweets are first for tweet in newTweets: # skip replies if tweet['in_reply_to_screen_name'] is not None: continue tweetText = StringUtils.unescapeXHTML(tweet['text']) tweetText = re.sub('[\r\n]+', StringUtils.graySplitter, tweetText) for url in tweet['entities']['urls']: tweetText = tweetText.replace(url['url'], url['expanded_url']) formatString = unicode(assembleFormattedText(A.normal['Tweet! ', A.bold['@{0}>'], ' {1}'])) newTweet = formatString.format(tweet['user']['screen_name'], tweetText) for channel, _ in self.bot.channels.iteritems(): self.bot.sendResponse(IRCResponse(ResponseType.Say, newTweet, channel))
def execute(self, response): """ @type response: IRCResponse """ response.Response = StringUtils.stripFormatting(response.Response) return response
def execute(self, response): """ @type response: IRCResponse """ response.Response = StringUtils.stripColours(response.Response) return response
def FollowYouTube(self, videoID, message): if self.youtubeKey is None: return IRCResponse(ResponseType.Say, '[YouTube API key not found]', message.ReplyTo) fields = 'items(id,snippet(title,description,channelTitle,liveBroadcastContent),contentDetails(duration),statistics(viewCount),liveStreamingDetails(scheduledStartTime))' parts = 'snippet,contentDetails,statistics,liveStreamingDetails' url = 'https://www.googleapis.com/youtube/v3/videos?id={}&fields={}&part={}&key={}'.format( videoID, fields, parts, self.youtubeKey) webPage = WebUtils.fetchURL(url) webPage.body = webPage.body.decode('utf-8') j = json.loads(webPage.body) if 'items' not in j: return None data = [] vid = j['items'][0] title = vid['snippet']['title'] data.append(title) channel = vid['snippet']['channelTitle'] data.append(channel) if vid['snippet']['liveBroadcastContent'] == 'none': length = parse_duration( vid['contentDetails']['duration']).total_seconds() m, s = divmod(int(length), 60) h, m = divmod(m, 60) if h > 0: length = u'{0:02d}:{1:02d}:{2:02d}'.format(h, m, s) else: length = u'{0:02d}:{1:02d}'.format(m, s) data.append(length) elif vid['snippet']['liveBroadcastContent'] == 'upcoming': startTime = vid['liveStreamingDetails']['scheduledStartTime'] startDateTime = dateutil.parser.parse(startTime) now = datetime.datetime.now(dateutil.tz.tzutc()) delta = startDateTime - now timespan = StringUtils.deltaTimeToString(delta, 'm') timeString = assembleFormattedText( A.normal['Live in ', A.fg.cyan[A.bold[timespan]]]) data.append(timeString) pass # time till stream starts, indicate it's upcoming elif vid['snippet']['liveBroadcastContent'] == 'live': status = unicode( assembleFormattedText(A.normal[A.fg.red[A.bold['{} Live']]])) status = status.format(u'●') data.append(status) else: pass # if we're here, wat views = int(vid['statistics']['viewCount']) data.append('{:,}'.format(views)) description = vid['snippet']['description'] if not description: description = u'<no description available>' description = re.sub('(\n|\s)+', ' ', description) limit = 150 if len(description) > limit: description = u'{} ...'.format(description[:limit].rsplit(' ', 1)[0]) data.append(description) return IRCResponse( ResponseType.Say, self.graySplitter.join(data), message.ReplyTo, {'urlfollowURL': 'http://youtu.be/{}'.format(videoID)})