Exemple #1
0
    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
Exemple #2
0
    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
Exemple #3
0
    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)
Exemple #4
0
    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)})
Exemple #5
0
    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)})
Exemple #6
0
    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)
Exemple #7
0
    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)
Exemple #8
0
    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
Exemple #9
0
    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
Exemple #10
0
    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
Exemple #11
0
    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
Exemple #12
0
    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
Exemple #13
0
    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
Exemple #14
0
    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
Exemple #16
0
 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)
Exemple #17
0
    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)
Exemple #18
0
    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
Exemple #20
0
    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
Exemple #21
0
    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
Exemple #22
0
    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)
Exemple #23
0
    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))
Exemple #24
0
 def execute(self, response):
     """
     @type response: IRCResponse
     """
     response.Response = StringUtils.stripFormatting(response.Response)
     return response
Exemple #25
0
 def execute(self, response):
     """
     @type response: IRCResponse
     """
     response.Response = StringUtils.stripColours(response.Response)
     return response
Exemple #26
0
    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)})
Exemple #27
0
 def execute(self, response):
     """
     @type response: IRCResponse
     """
     response.Response = StringUtils.stripFormatting(response.Response)
     return response