示例#1
0
 def urbandictionary_lookup(self, channel, nick, msg, args):
     query = args['query']
     try:
         r = requests.get(API_URL % query)
         r.raise_for_status()
     except requests.exceptions.HTTPError:
         self.bot.msg(channel, 'No results for %s' % query)
         return False
     data = r.json()
     if 'result_type' in data:
         if data['result_type'] == "no_results":
             self.bot.msg('No results for %s' % query)
             return False
         else:
             definition = data['list'][0]
             word = definition['word'].encode('UTF-8')
             def_text = definition['definition'].encode('UTF-8')
             permalink = definition['permalink'].encode('UTF-8')
             formatted_msg = assembleFormattedText(A.bold[word])
             formatted_msg += assembleFormattedText(A.normal[": "])
             formatted_msg += def_text.split('\r\n')[0]
             formatted_msg += assembleFormattedText(A.bold[" See more: "])
             formatted_msg += assembleFormattedText(A.normal[permalink])
             self.bot.msg(channel, formatted_msg)
     else:
         self.bot.msg(channel, 'No results for %s' % query)
         return False
示例#2
0
    def execute(self, message):
        """
        @type message: IRCMessage
        """

        subString = self._mangleEscapes(message.Parameters)

        try:
            segments = list(self._parseSubcommandTree(subString))
        except UnbalancedBracesException as e:
            red = assembleFormattedText(A.bold[A.fg.lightRed['']])
            normal = assembleFormattedText(A.normal[''])
            error = subString[:e.column] + red + subString[e.column] + normal + subString[e.column+1:]
            error = self._unmangleEscapes(error, False)
            return [IRCResponse(ResponseType.Say, u"Sub Error: {}".format(e.message), message.ReplyTo),
                    IRCResponse(ResponseType.Say, error, message.ReplyTo)]

        prevLevel = -1
        responseStack = []
        extraVars = {}
        metadata = {}

        for segment in segments:
            (level, command, start, end) = segment

            # We've finished executing subcommands at the previous depth,
            # so replace subcommands with their output at the current depth
            if level < prevLevel:
                command = self._substituteResponses(command, responseStack, level, extraVars, start)

            # Replace any extraVars in the command
            for var, value in iteritems(extraVars):
                command = re.sub(r'\$\b{}\b'.format(re.escape(var)), u'{}'.format(value), command)

            # Build a new message out of this segment
            inputMessage = IRCMessage(message.Type, message.User.String, message.Channel,
                                      self.bot.commandChar + command.lstrip(),
                                      self.bot,
                                      metadata=metadata)

            # Execute the constructed message
            if inputMessage.Command.lower() in self.bot.moduleHandler.mappedTriggers:
                response = self.bot.moduleHandler.mappedTriggers[inputMessage.Command.lower()].execute(inputMessage)
                """@type : IRCResponse"""
            else:
                return IRCResponse(ResponseType.Say,
                                   u"'{}' is not a recognized command trigger".format(inputMessage.Command),
                                   message.ReplyTo)

            # Push the response onto the stack
            responseStack.append((level, response.Response, start, end))
            # Update the extraVars dict
            extraVars.update(response.ExtraVars)
            metadata = self._recursiveMerge(metadata, response.Metadata)

            prevLevel = level

        responseString = self._substituteResponses(subString, responseStack, -1, extraVars, -1)
        responseString = self._unmangleEscapes(responseString)
        return IRCResponse(ResponseType.Say, responseString, message.ReplyTo, extraVars=extraVars, metadata=metadata)
示例#3
0
    def _guess(self, message):
        """
        @type message: IRCMessage
        @rtype: IRCResponse
        """
        channel = message.ReplyTo.lower()
        if channel not in self.gameStates:
            return IRCResponse(ResponseType.Say,
                               u'[Hangman] no game running, use {}hangman start to begin!'.format(self.bot.commandChar),
                               message.ReplyTo)

        responses = []
        gs = self.gameStates[channel]

        guess = message.Parameters.lower()
        # single letter
        if len(guess) == 1:
            try:
                correct = gs.guessLetter(guess)
            except (AlreadyGuessedException,
                    InvalidCharacterException) as e:
                return self._exceptionFormatter(e, message.ReplyTo)
        # whole phrase
        else:
            try:
                correct = gs.guessPhrase(guess)
            except (WrongPhraseLengthException,
                    PhraseMismatchesGuessesException,
                    PhraseUsesKnownBadLettersException) as e:
                return self._exceptionFormatter(e, message.ReplyTo)

        user = message.User.Name
        # split the username with a zero-width space
        # hopefully this kills client highlighting on nick mentions
        #user = user[:1] + u'\u200b' + user[1:]
        # try a tiny arrow instead, some clients actually render zero-width spaces
        colUser = user[:1] + u'\u034e' + user[1:]
        if correct:
            colUser = assembleFormattedText(A.normal[A.fg.green[colUser]])
        else:
            colUser = assembleFormattedText(A.normal[A.fg.red[colUser]])
        responses.append(IRCResponse(ResponseType.Say,
                                     u'{} - {}'.format(gs.render(), colUser),
                                     message.ReplyTo))

        if gs.finished:
            if correct:
                responses.append(IRCResponse(ResponseType.Say,
                                             u'[Hangman] Congratulations {}!'.format(user),
                                             message.ReplyTo))
            else:
                responses.append(IRCResponse(ResponseType.Say,
                                             u'[Hangman] {} blew up the bomb! The {} was {}'.format(user,
                                                                                                    gs.wOrP(),
                                                                                                    gs.phrase),
                                             message.ReplyTo))
            self._stop(message, suppressMessage=True)

        return responses
示例#4
0
 def _renderGuesses(self):
     colouredGuesses = []
     for g in self.guesses:
         if g in self.phrase:
             colouredGuesses.append(assembleFormattedText(A.bold[A.fg.green[g]]))
         else:
             colouredGuesses.append(assembleFormattedText(A.fg.red[g]))
     reset = assembleFormattedText(A.normal[''])
     return u'[{}{}]'.format(u''.join(colouredGuesses), reset)
示例#5
0
    def whoresponse(self, channel):
        who_users = communicator.handleWho(self, channel)

        if len(who_users) > 0:
            return [irc.assembleFormattedText(
                irc.attributes.bold[irc.attributes.underline["List of relayed users on ", channel]]),
                "  ".join(who_users),
                irc.assembleFormattedText(irc.attributes.bold[irc.attributes.underline[
                    "END List of relayed users on ", channel]])]
        return None
示例#6
0
    def FollowKickstarter(self, ksID, message):
        webPage = WebUtils.fetchURL('https://www.kickstarter.com/projects/{0}/'.format(ksID))

        soup = BeautifulSoup(webPage.body)

        data = []

        title = soup.find(class_='title')
        if title is not None:
            creator = soup.find(id='name')
            if creator is not None:
                data.append(assembleFormattedText(A.normal['{0}', A.fg.gray[' by '], '{1}']).format(title.h2.text.strip(), creator.text.strip()))
            else:
                data.append(title.h2.text.strip())

        stats = soup.find(id='stats')

        backerCount = stats.find(id='backers_count')
        if backerCount is not None:
            data.append('Backers: {0:,}'.format(int(backerCount['data-backers-count'])))

        pledged = stats.find(id='pledged')
        if pledged is not None:
            if float(pledged['data-percent-raised']) >= 1.0:
                percentageString = A.fg.green['({3:,.0f}% funded)']
            else:
                percentageString = A.fg.red['({3:,.0f}% funded)']
                
            pledgedString = assembleFormattedText(A.normal['Pledged: {0:,.0f}', A.fg.gray['/'], '{1:,.0f} {2} ', percentageString])
            data.append(pledgedString.format(float(pledged['data-pledged']),
                                             float(pledged['data-goal']),
                                             pledged.data['data-currency'],
                                             float(pledged['data-percent-raised']) * 100))

        findState = soup.find(id='main_content')
        if 'Project-state-canceled' in findState['class']:
            data.append(assembleFormattedText(A.normal[A.fg.red['Cancelled']]))
            
        elif 'Project-state-failed' in findState['class']:
            data.append(assembleFormattedText(A.normal[A.fg.red['Failed']]))

        elif 'Project-state-successful' in findState['class']:
                data.append(assembleFormattedText(A.normal[A.fg.green['Successful']]))

        elif 'Project-state-live' in findState['class']:
            duration = stats.find(id='project_duration_data')

            if duration is not None:
                remaining = float(duration['data-hours-remaining'])
                days = math.floor(remaining/24)
                hours = remaining/24 - days

                data.append('Duration: {0:.0f} days {1:.1f} hours to go'.format(days, hours))

        return IRCResponse(ResponseType.Say, self.graySplitter.join(data), message.ReplyTo)
示例#7
0
def stock(bot, args, sender, source):
    try:
        resp = yql(args[0])
    except:
        bot.reply(source, sender,
                  "Couldn't get stock data: {}".format(sys.exc_info()[0]))
        raise

    if resp["count"] == 0:
        bot.reply(
            source, sender,
            assembleFormattedText(A.normal["Couldn't find the ticker symbol ",
                                           A.bold[args[0]]]))
        return

    quote = resp["results"]["quote"]

    if quote["LastTradePriceOnly"] is None:
        bot.reply(
            source, sender,
            assembleFormattedText(A.normal["Couldn't find the ticker symbol ",
                                           A.bold[args[0]]]))
        return

    change = float(quote["Change"])
    price = float(quote["LastTradePriceOnly"])
    name = quote["Name"]

    if price == 0 and change == 0:
        # Company is dead
        bot.reply(
            source, sender,
            assembleFormattedText(A.normal[A.bold[name],
                                           " is no longer trading."]))
        return

    color = A.fg.gray

    percent = (change / (price - change)) * 100

    if change > 0:
        color = A.fg.green
        change = "+{}".format(change)
    elif change < 0:
        color = A.fg.lightRed

    bot.reply(
        source, sender,
        assembleFormattedText(
            A.normal[A.bold[name], " (", A.bold[quote["Symbol"]], "): ",
                     str(price), " ",
                     color["{} ({:.2f}%)".format(change, percent)]]))
示例#8
0
    def FollowTwitch(self, channel, message):
        # Heavily based on Didero's DideRobot code for the same
        # https://github.com/Didero/DideRobot/blob/06629fc3c8bddf8f729ce2d27742ff999dfdd1f6/commands/urlTitleFinder.py#L37
        # TODO: other stats?
        if self.twitchClientID is None:
            return IRCResponse(ResponseType.Say,
                               '[Twitch Client ID not found]', message.ReplyTo)

        chanData = {}
        channelOnline = False
        twitchHeaders = [('Accept', 'application/vnd.twitchtv.v3+json'),
                         ('Client-ID', self.twitchClientID)]
        webPage = WebUtils.fetchURL(
            u'https://api.twitch.tv/kraken/streams/{}'.format(channel),
            twitchHeaders)

        streamData = json.loads(webPage.body)

        if 'stream' in streamData and streamData['stream'] is not None:
            chanData = streamData['stream']['channel']
            channelOnline = True
        elif 'error' not in streamData:
            webPage = WebUtils.fetchURL(
                u'https://api.twitch.tv/kraken/channels/{}'.format(channel),
                twitchHeaders)
            chanData = json.loads(webPage.body)

        if len(chanData) > 0:
            if channelOnline:
                channelInfo = assembleFormattedText(
                    A.fg.green['']) + u'{}'.format(
                        chanData['display_name']) + assembleFormattedText(
                            A.normal[''])
            else:
                channelInfo = assembleFormattedText(
                    A.fg.red['']) + u'{}'.format(
                        chanData['display_name']) + assembleFormattedText(
                            A.normal[''])
            channelInfo += u' "{}"'.format(
                re.sub(r'[\r\n]+', self.graySplitter,
                       chanData['status'].strip()))
            if chanData['game'] is not None:
                channelInfo += assembleFormattedText(
                    A.normal[A.fg.gray[', playing '],
                             u'{}'.format(chanData['game'])])
            if chanData['mature']:
                channelInfo += assembleFormattedText(
                    A.normal[A.fg.lightRed[' [Mature]']])
            if channelOnline:
                channelInfo += assembleFormattedText(
                    A.normal[A.fg.green[' (Live with {0:,d} viewers)'.format(
                        streamData['stream']['viewers'])]])
            else:
                channelInfo += assembleFormattedText(
                    A.normal[A.fg.red[' (Offline)']])

            return IRCResponse(
                ResponseType.Say, channelInfo, message.ReplyTo,
                {'urlfollowURL': 'https://twitch.tv/{}'.format(channel)})
示例#9
0
文件: stock.py 项目: w4/belle
def stock(bot, args, sender, source):
    try:
        resp = yql(args[0])
    except:
        bot.reply(source, sender, "Couldn't get stock data: {}".format(sys.exc_info()[0]))
        raise

    if resp["count"] == 0:
        bot.reply(source, sender, assembleFormattedText(
            A.normal["Couldn't find the ticker symbol ", A.bold[args[0]]]
        ))
        return

    quote = resp["results"]["quote"]

    if quote["LastTradePriceOnly"] is None:
        bot.reply(source, sender, assembleFormattedText(
            A.normal["Couldn't find the ticker symbol ", A.bold[args[0]]]
        ))
        return

    change = float(quote["Change"])
    price = float(quote["LastTradePriceOnly"])
    name = quote["Name"]

    if price == 0 and change == 0:
        # Company is dead
        bot.reply(source, sender, assembleFormattedText(
            A.normal[A.bold[name], " is no longer trading."]
        ))
        return

    color = A.fg.gray

    percent = (change / (price - change)) * 100

    if change > 0:
        color = A.fg.green
        change = "+{}".format(change)
    elif change < 0:
        color = A.fg.lightRed

    bot.reply(source, sender, assembleFormattedText(
        A.normal[
            A.bold[name], " (",  A.bold[quote["Symbol"]], "): ",
            str(price), " ", color["{} ({:.2f}%)".format(change, percent)]
        ]
    ))
示例#10
0
文件: wolfram.py 项目: kekles/dave
def wolfram(bot, args, sender, source):
    query = args[0].strip()

    key = "wolfram:{}".format(query.lower())

    if dave.config.redis.exists(key):
        bot.reply(source, sender, dave.config.redis.get(key).decode('utf-8'))
        dave.config.redis.setex(key, 60, dave.config.redis.get(key))
        return

    if query:
        client = wolframalpha.Client(dave.config.config["api_keys"]["wolfram"])
        res = client.query(query)

        pods = list(res.pods)

        if len(pods) > 0:
            resultpod = next(res.results)
            result = resultpod.text

            if "image" in pods[0].text:
                result = resultpod.img

            if len(result) > 500:
                result = result[:497] + "..."

            res = assembleFormattedText(A.normal[A.bold[pods[0].text],
                                                 ": {}".format(result)])
            dave.config.redis.setex(key, 60, res)
            bot.reply(source, sender, res)
示例#11
0
    def execute(self, message):
        """
        @type message: IRCMessage
        """
        if len(message.ParameterList) != 1:
            return IRCResponse(ResponseType.Say, self.help, message.ReplyTo)

        subreddit = message.ParameterList[0].lower()

        url = "https://api.imgur.com/3/gallery/r/{}/time/all/{}"
        url = url.format(subreddit, random.randint(0, 100))
        response = WebUtils.fetchURL(url, self.headers)
        jsonResponse = json.loads(response.body)
        images = jsonResponse['data']

        if not images:
            return IRCResponse(ResponseType.Say,
                               "The subreddit '{}' doesn't seem to have any images posted to it (or it doesn't exist!)"
                               .format(subreddit),
                               message.ReplyTo)

        image = random.choice(images)

        data = []
        if image['title'] is not None:
            data.append(image['title'])
        if image['nsfw']:
            data.append(u'\x034\x02NSFW!\x0F')
        if image['animated']:
            data.append(u'\x032\x02Animated!\x0F')
        data.append(image['link'])

        graySplitter = assembleFormattedText(A.normal[' ', A.fg.gray['|'], ' '])
        return IRCResponse(ResponseType.Say, graySplitter.join(data), message.ReplyTo)
示例#12
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)})
示例#13
0
文件: wolfram.py 项目: w4/belle
def wolfram(bot, args, sender, source):
    query = args[0].strip()

    key = "wolfram:{}".format(query.lower())

    if dave.config.redis.exists(key):
        bot.reply(source, sender, dave.config.redis.get(key).decode('utf-8'))
        dave.config.redis.setex(key, 60, dave.config.redis.get(key))
        return

    if query:
        client = wolframalpha.Client(dave.config.config["api_keys"]["wolfram"])
        res = client.query(query)

        pods = list(res.pods)

        if len(pods) > 0:
            resultpod = next(res.results)
            result = resultpod.text

            if "image" in pods[0].text:
                result = resultpod.img

            if len(result) > 500:
                result = result[:497] + "..."

            res = assembleFormattedText(A.normal[A.bold[pods[0].text],
                                        ": {}".format(result)])
            dave.config.redis.setex(key, 60, res)
            bot.reply(source, sender, res)
示例#14
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)})
示例#15
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)
示例#16
0
 def _renderGuesses(self):
     colouredGuesses = []
     for g in self.guesses:
         if g in self.phrase:
             g = g.encode('utf-8')
             colouredGuesses.append(
                 assembleFormattedText(A.bold[A.fg.green[g]]))
         else:
             g = g.encode('utf-8')
             colouredGuesses.append(assembleFormattedText(A.fg.red[g]))
     reset = assembleFormattedText(A.normal[''])
     colouredGuesses = [
         c.decode(encoding='utf-8', errors='ignore')
         for c in colouredGuesses
     ]
     return u'[{}{}]'.format(u''.join(colouredGuesses), reset)
示例#17
0
文件: poep.py 项目: trirpi/irc-poep
    def privmsg(self, user, channel, msg, color=None):
        """This will get called when the bot receives a message."""
        user = user.split('!', 1)[0]

        # Check to see if they're sending me a private message
        if channel == self.nickname:
            print("[*] info: received a private message: " + msg)
            msg = "Wat zit je nu weer te ratelen. Gooi het in de groep!"
            self.msg(user, irc.assembleFormattedText(irc.attributes.normal[irc.attributes.fg.magenta[msg]]))

        # Otherwise check to see if it is a message directed at me
        elif msg.startswith(settings.control_char) or msg.endswith(settings.nickname):
            if user not in settings.banned:

                # look for control_char or nick and remove it from the message
                if msg[0] == settings.control_char:
                    msg = msg[1:]
                elif msg[-5:] == " " + settings.nickname:
                    msg = msg[:-5]

                command = msg.split()[0]  # filter command from message
                try:
                    arg = msg.split(' ', 1)[1]  # the stuff after the command
                except IndexError:
                    arg = ''

                response = controllers.message.handle_message(command, arg, user)
                if response is not None:
                    self.msg(channel, response)
示例#18
0
    def execute(self, message):
        """
        @type message: IRCMessage
        """
        if len(message.ParameterList) < 3:
            return IRCResponse(ResponseType.Say, self.help, message.ReplyTo)

        try:
            amount = float(message.ParameterList[0])
            offset = 1
        except ValueError:
            amount = 1.0
            offset = 0

        ccFrom = message.ParameterList[offset]
        ccTo   = message.ParameterList[offset+2:]
        ccTo   = ",".join(ccTo)

        url = "https://api.fixer.io/latest?base={}&symbols={}"
        url = url.format(ccFrom, ccTo)
        response = WebUtils.fetchURL(url)
        jsonResponse = json.loads(response.body)
        rates = jsonResponse['rates']

        if not rates:
            return IRCResponse(ResponseType.Say,
                               "Some or all of those currencies weren't recognized!",
                               message.ReplyTo)

        data = []
        for curr,rate in rates.iteritems():
            data.append("{} {}".format(rate*amount, curr))

        graySplitter = assembleFormattedText(A.normal[' ', A.fg.gray['|'], ' '])
        return IRCResponse(ResponseType.Say, graySplitter.join(data), message.ReplyTo)
示例#19
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
示例#20
0
 def applyColorFormat(self, *msg, **kwargs):
     """put some nice colors on the message"""
     colors = kwargs.get('colors')
     toAssemble = []
     log.debug(msg)
     log.debug(colors)
     msg = [m.encode('utf-8') for m in msg]
     if not colors or len(colors) != len(msg):
         log.debug("no colors")
         for m in msg:
             log.debug(m)
             log.debug(type(m))
             toAssemble.append(irc.attributes.fg.gray[m])
     else:
         log.debug("colors!")
         for m, c in zip(msg, colors):
             log.debug(m)
             log.debug(c)
             if not c:
                 log.debug("no c")
                 toAssemble.append(irc.attributes.fg.gray[m])
             else:
                 log.debug("using special color")
                 log.debug(c)
                 toAssemble.append(c[m])
     return irc.assembleFormattedText(irc.attributes.normal[toAssemble])
示例#21
0
    def execute(self, message):
        """
        @type message: IRCMessage
        """
        if len(message.ParameterList) == 0 or len(message.ParameterList) > 2:
            return IRCResponse(ResponseType.Say, self.help(None), message.ReplyTo)

        if not self.imgurClientID:
            return IRCResponse(ResponseType.Say,
                               u'[imgur client ID not found]',
                               message.ReplyTo)

        subreddit = message.ParameterList[0].lower()
        if len(message.ParameterList) == 2:
            try:
                if len(message.ParameterList[1]) < 20:
                    topRange = int(message.ParameterList[1])
                else:
                    raise ValueError
                if topRange < 0:
                    raise ValueError
            except ValueError:
                return IRCResponse(ResponseType.Say, "The range should be a positive integer!", message.ReplyTo)
        else:
            topRange = 100

        url = "https://api.imgur.com/3/gallery/r/{}/time/all/{}"
        url = url.format(subreddit, random.randint(0, topRange))
        try:
            response = self.bot.moduleHandler.runActionUntilValue('fetch-url', url, extraHeaders=self.headers)
            jsonResponse = json.loads(response.body)
        except json.JSONDecodeError:
            return IRCResponse(ResponseType.Say,
                               "[The imgur API doesn't appear to be responding correctly]",
                               message.ReplyTo)

        images = jsonResponse['data']

        if not images:
            return IRCResponse(ResponseType.Say,
                               "The subreddit '{}' doesn't seem to have any images posted to it (or it doesn't exist!)"
                               .format(subreddit),
                               message.ReplyTo)

        image = random.choice(images)

        data = []
        if 'title' in image and image['title'] is not None:
            data.append(image['title'])
        if 'nsfw' in image and image['nsfw']:
            data.append(u'\x034\x02NSFW!\x0F')
        if 'animated' in image and image['animated']:
            data.append(u'\x032\x02Animated!\x0F')
        if 'gifv' in image:
            data.append(image['gifv'])
        else:
            data.append(image['link'])

        graySplitter = assembleFormattedText(A.normal[' ', A.fg.gray['|'], ' '])
        return IRCResponse(ResponseType.Say, graySplitter.join(data), message.ReplyTo)
示例#22
0
def pollen(bot, args, sender, source):
    postcode = args[0].lower()

    text = None

    if not dave.config.redis.exists("pollen:{}".format(postcode)):
        res = get("https://www.bbc.co.uk/weather/{}".format(postcode))

        soup = BeautifulSoup(res.text, "html.parser")
        element = soup.find_all("div",
                                class_="environmental-index pollen-index")

        if element:
            pollen = element[0].find("span")

            if pollen:
                text = pollen.text
                dave.config.redis.setex("pollen:{}".format(postcode), 1800,
                                        text)
    else:
        text = dave.config.redis.get("pollen:{}".format(postcode))

    if text:
        bot.reply(
            source, sender,
            assembleFormattedText(A.normal["The pollen count is currently ",
                                           A.bold[str(text)], " in ",
                                           postcode.upper()]))
示例#23
0
    def FollowTwitter(self, tweeter, tweetID):
        url = 'https://twitter.com/{}/status/{}'.format(tweeter, tweetID)
        webPage = self.bot.moduleHandler.runActionUntilValue('fetch-url', url)

        soup = BeautifulSoup(webPage.body, 'lxml')

        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
        tweetTimeText = re.sub(r'[\r\n\s]+', u' ', tweetTimeText)

        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 = string.unescapeXHTML(tweetText.text)
        text = re.sub('[\r\n]+', self.graySplitter, text)

        formatString = str(assembleFormattedText(A.normal[A.fg.gray['[{0}]'], A.bold[' {1}:'], ' {2}']))

        return formatString.format(tweetTimeText, user, text), url
示例#24
0
文件: boxbot.py 项目: aa-m-sa/boxbot
 def applyColorFormat(self, *msg, **kwargs):
     """put some nice colors on the message"""
     colors = kwargs.get('colors')
     toAssemble = []
     log.debug(msg)
     log.debug(colors)
     msg = [m.encode('utf-8') for m in msg]
     if not colors or len(colors) != len(msg):
         log.debug("no colors")
         for m in msg:
             log.debug(m)
             log.debug(type(m))
             toAssemble.append(irc.attributes.fg.gray[m])
     else:
         log.debug("colors!")
         for m, c in zip(msg, colors):
             log.debug(m)
             log.debug(c)
             if not c:
                 log.debug("no c")
                 toAssemble.append(irc.attributes.fg.gray[m])
             else:
                 log.debug("using special color")
                 log.debug(c)
                 toAssemble.append(c[m])
     return irc.assembleFormattedText(irc.attributes.normal[toAssemble])
示例#25
0
文件: title.py 项目: w4/belle
def link_parse(bot, args, sender, source):
    matches = parse.findall(args[0])

    titles = []

    for match in matches:
        if "gfycat" in match or ".webm" in match:
            continue

        if not dave.config.redis.exists("site:{}".format(match)):
            try:
                res = get(match, timeout=3,
                          headers={'user-agent': 'irc bot (https://github.com/w4)'})
            except BaseException as e:
                log.msg("Couldn't connect to host.", e)
                return

            # sometimes requests guesses the charset wrong
            if res.encoding == 'ISO-8859-1' and not 'ISO-8859-1' in \
                    res.headers.get('Content-Type', ''):
                res.encoding = res.apparent_encoding

            try:
                soup = BeautifulSoup(res.text, "html.parser")
                title = soup.title.string

                if title is not None:
                    title = re.sub(r"(\r?\n|\r| )+",
                                   " ",
                                   title.strip())
                    title = title[:140] + (title[140:] and '...')
                    dave.config.redis.setex("site:{}".format(match), 300, title)
            except BaseException as e:
                log.msg("Failed to grab title", e)
                return
        else:
            title = str(dave.config.redis.get("site:{}".format(match)), 'utf8')

        if title is not None:
            titles.append(assembleFormattedText(A.normal[title]))

    if titles:
        # remove duplicates
        titles = list(set(titles))

        bot.msg(source, "Title: {}".format(
                        assembleFormattedText(A.normal[", "]).join(titles)))
示例#26
0
	def test(self, bot, nick, channel, message):
		price = 0.00000000001212
		dict_ = {}
		print price
		print type(price)
		dict_["hi"] = assembleFormattedText(A.fg.green[str(price)])
		#dict_["hi"] = str(price)
		bot.sendMsg(channel, dict_["hi"])
示例#27
0
 def _fetch(self, j, short, mode, label):
     r = j[mode]
     data = []
     t = A.normal[A.bold['{} {}: '.format(label, r[0]['rule']['name'])],
                  '/'.join([r[0]['stage_a']['name'], r[0]['stage_b']['name']])]
     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 = string.deltaTimeToString(d, resolution='m')
         t = A.normal[A.bold['{} {} in {}: '.format(label, r[1]['rule']['name'], deltaStr)],
                      '/'.join([r[1]['stage_a']['name'], r[1]['stage_b']['name']])]
         data.append(assembleFormattedText(t))
     return ' | '.join(data)
示例#28
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)
示例#29
0
	def get_price(self, bot, nick, channel, msg):
		coin = msg.split(" ", 1)[0]
		try:
			message = {}
			for x in self.coin_data[coin]:
				r = requests.get("http://pubapi2.cryptsy.com/api.php?method=singlemarketdata&marketid={}".format(x)).json()
				label = r["return"]["markets"][coin.upper()]["label"].encode("utf-8")
				price = r["return"]["markets"][coin.upper()]["lasttradeprice"]
				try:
					if price > self.coin_data[label]["last"]:
						message[label] = assembleFormattedText(A.fg.green["".encode("utf-8")+str(price)])
					else:
						message[label] = assembleFormattedText(A.fg.red[""+str(price)])
				except Exception as e:
					self.coin_data[label] = {}
					message[label] = assembleFormattedText(A.fg.red[""+str(price)])
				self.coin_data[label]["last"] = price				
			bot.sendMsg(channel, ("(Cryptsy) "+"".join([(assembleFormattedText(A.bold["["])+"%s] %s " % (k,v)) for k,v in message.iteritems()])).encode("utf-8"))
		except Exception as e:
			return
示例#30
0
    def privmsg(self, user, channel, message):
        # If someone addresses the bot directly, respond in the same way.
        if channel == self.nickname:
            if message.lower().startswith("who ") and len(message.split(" ")) > 1:
                who_channel = message.split(" ")[1]
                if ("#" + who_channel) in self.ircUsers.users and who_channel not in self.ircUsers.users:
                    who_channel = "#" + who_channel
                self.sendWhoToUser(who_channel, user)
            elif (message.lower().startswith("msg ") or message.lower().startswith("m ")) and len(
                    message.split(" ")) > 2:
                msg_user = message.split(" ", 2)[1]
                msg_message = message.split(" ", 2)[2]

                if not communicator.sendmessage(self, formatUsername(msg_user),
                                                "[%s] %s" % (formatUsername(user), msg_message.strip())):
                    self.sendToUser(user, irc.assembleFormattedText(
                        irc.attributes.normal["Unable to find user ", irc.attributes.bold[
                            msg_user], " on any relayed channel."]))
            else:
                self.sendToUser(user, self.privMsgResponse)
                self.sendToUser(user, irc.assembleFormattedText(irc.attributes.normal["Say ", irc.attributes.bold[
                    "WHO ", irc.attributes.underline["#channel"]], " to see who is on ", irc.attributes.underline[
                                                                                          "#channel"], " via a separate network."]))
                self.sendToUser(user, irc.assembleFormattedText(irc.attributes.normal["Say ", irc.attributes.bold[
                    "MSG ", irc.attributes.underline["user"], " ", irc.attributes.underline[
                        "message"]], " to send a private ", irc.attributes.underline[
                                                                                          "message"], " to ",
                                                                                      irc.attributes.underline[
                                                                                          "user"], "."]))
        elif channel in self.channels:
            if message.lower().strip() in [".who", "!who", "?who", ".names", "!names", "?names", ".users", "!users",
                                           "?users"]:
                self.sendWhoToUser(channel, user)
            else:
                self.relay(channel, "[%s] %s" % (formatUsername(user), message))
                if message.startswith(self.nickname + ':'):
                    self.sayToChannel(channel,
                                      self.privMsgResponse + " -- Send a private message for more information.")
                    # For consistency, if anyone responds to the bot's response:
                    self.relay(channel, "[%s] %s" % (formatUsername(self.nickname),
                                                     self.privMsgResponse + " -- Send a private message for more information."))
示例#31
0
文件: title.py 项目: kekles/dave
def link_parse(bot, args, sender, source):
    matches = parse.findall(args[0])

    titles = []

    for match in matches:
        if not dave.config.redis.exists("site:{}".format(match)):
            try:
                res = get(
                    match,
                    timeout=3,
                    headers={'user-agent': 'irc bot (https://github.com/w4)'})
            except BaseException as e:
                log.msg("Couldn't connect to host.", e)
                return

            # sometimes requests guesses the charset wrong
            if res.encoding == 'ISO-8859-1' and not 'ISO-8859-1' in \
                    res.headers.get('Content-Type', ''):
                res.encoding = res.apparent_encoding

            soup = BeautifulSoup(res.text, "html.parser")
            title = soup.title.string

            if title is not None:
                title = re.sub(r"(\r?\n|\r| )+", " ", title.strip())
                title = title[:140] + (title[140:] and '...')
                dave.config.redis.setex("site:{}".format(match), 300, title)
        else:
            title = str(dave.config.redis.get("site:{}".format(match)), 'utf8')

        if title is not None:
            titles.append(assembleFormattedText(A.bold[title]))

    if titles:
        # remove duplicates
        titles = list(set(titles))

        bot.msg(
            source, "Title: {}".format(
                assembleFormattedText(A.normal[", "]).join(titles)))
示例#32
0
    def FollowTwitch(self, channel, message):
        # Heavily based on Didero's DideRobot code for the same
        # https://github.com/Didero/DideRobot/blob/06629fc3c8bddf8f729ce2d27742ff999dfdd1f6/commands/urlTitleFinder.py#L37
        # TODO: other stats?
        chanData = {}
        channelOnline = False
        twitchHeaders = [('Accept', 'application/vnd.twitchtv.v2+json')]
        webPage = WebUtils.fetchURL(u'https://api.twitch.tv/kraken/streams/{0}'.format(channel), twitchHeaders)

        streamData = json.loads(webPage.body)

        if 'stream' in streamData and streamData['stream'] is not None:
            chanData = streamData['stream']['channel']
            channelOnline = True
        elif 'error' not in streamData:
            webPage = WebUtils.fetchURL(u'https://api.twitch.tv/kraken/channels/{0}'.format(channel), twitchHeaders)
            chanData = json.loads(webPage.body)

        if len(chanData) > 0:
            if channelOnline:
                channelInfo = assembleFormattedText(A.fg.green['']) + '{0}'.format(chanData['display_name']) + assembleFormattedText(A.normal[''])
            else:
                channelInfo = assembleFormattedText(A.fg.red['']) + '{0}'.format(chanData['display_name']) + assembleFormattedText(A.normal[''])
            channelInfo += u' "{0}"'.format(re.sub('[\r\n]+', self.graySplitter, chanData['status'].strip()))
            if chanData['game'] is not None:
                channelInfo += assembleFormattedText(A.normal[A.fg.gray[', playing '], '{0}'.format(chanData['game'])])
            if chanData['mature']:
                channelInfo += assembleFormattedText(A.normal[A.fg.lightRed[' [Mature]']])
            if channelOnline:
                channelInfo += assembleFormattedText(A.normal[A.fg.green[' (Live with {0:,d} viewers)'.format(streamData['stream']['viewers'])]])
            else:
                channelInfo += assembleFormattedText(A.normal[A.fg.red[' (Offline)']])

            return IRCResponse(ResponseType.Say, channelInfo, message.ReplyTo)
示例#33
0
def quote(bot, args, sender, source):
    query = dave.config.session.query(Quote)

    if not query.count():
        bot.reply(source, sender, "No quotes found.")
        return

    row = query.offset(random.randrange(query.count())).first()

    bot.reply(
        source, sender,
        assembleFormattedText(A.normal[A.bold[row.quote], " by ",
                                       (row.attributed or row.added_by)]))
示例#34
0
 def current_conditions(self, channel, nick, msg, args):
     query = ' '.join(args['query'].split('  ')).lstrip()
     if 'wunderground_key' not in self.bot.plugin_config:
         logging.debug('configure weather plugin')
         self.bot.msg(channel,
                      'Weather plugin not configured')
         return False
     try:
         args = {'key': self.bot.plugin_config['wunderground_key'],
                 'query': query}
         r = requests.get(API_URL % args)
         r.raise_for_status()
         data = r.json()['current_observation']
     except:
         logging.exception('Caught exception while searching for weather')
         self.bot.msg(channel,
                      'Cannot find weather for %s' % query)
         return False
     response = assembleFormattedText(A.bold[data['display_location']['full'].encode('UTF-8')])
     response += assembleFormattedText(A.normal[" (%s): " % query])
     response += "%(weather)s, %(temperature_string)s, Humidity: %(relative_humidity)s, %(observation_time)s" % data
     self.bot.msg(channel, response.encode('UTF-8'))
示例#35
0
 def last_tweet(self, channel, nick, msg, args):
     if 'twitter_api' not in self.bot.plugin_config:
         logging.debug('configure twitter plugin')
         self.bot.msg(channel,
                      'Twitter plugin not configured')
         return False
     creds = self.bot.plugin_config['twitter_api']
     auth = twitter_oauth(creds['access_token'],
                          creds['access_token_secret'],
                          creds['consumer_key'],
                          creds['consumer_secret'])
     t = twitter_api(auth=auth)
     try:
         user = t.users.lookup(screen_name=args['user'])[0]
     except TwitterHTTPError:
         logging.exception('Caught twitter api exception:')
         self.bot.msg('Error retreiving tweet from %s' % args['user'])
         return
     text = user['status']['text'].encode('UTF-8')
     screen_name = args['user'].encode('UTF-8')
     formatted_msg = assembleFormattedText(A.bold[screen_name])
     formatted_msg += assembleFormattedText(A.normal[" tweets: "]) + text
     self.bot.msg(channel, formatted_msg)
示例#36
0
    def execute(self, message):
        """
        @type message: IRCMessage
        """
        if len(message.ParameterList) == 0 or len(message.ParameterList) > 2:
            return IRCResponse(ResponseType.Say, self.help, message.ReplyTo)

        subreddit = message.ParameterList[0].lower()
        if len(message.ParameterList) == 2:
            try:
                topRange = int(message.ParameterList[1])
                if topRange < 0:
                    return IRCResponse(ResponseType.Say, "The range should be a positive integer!", message.ReplyTo)
            except ValueError:
                return IRCResponse(ResponseType.Say, "The range should be a positive integer!", message.ReplyTo)
        else:
            topRange = 100

        url = "https://api.imgur.com/3/gallery/r/{}/time/all/{}"
        url = url.format(subreddit, random.randint(0, topRange))
        response = WebUtils.fetchURL(url, self.headers)
        jsonResponse = json.loads(response.body)
        images = jsonResponse["data"]

        if not images:
            return IRCResponse(
                ResponseType.Say,
                "The subreddit '{}' doesn't seem to have any images posted to it (or it doesn't exist!)".format(
                    subreddit
                ),
                message.ReplyTo,
            )

        image = random.choice(images)

        data = []
        if image["title"] is not None:
            data.append(image["title"])
        if image["nsfw"]:
            data.append(u"\x034\x02NSFW!\x0F")
        if image["animated"]:
            data.append(u"\x032\x02Animated!\x0F")
        if "gifv" in image:
            data.append(image["gifv"])
        else:
            data.append(image["link"])

        graySplitter = assembleFormattedText(A.normal[" ", A.fg.gray["|"], " "])
        return IRCResponse(ResponseType.Say, graySplitter.join(data), message.ReplyTo)
示例#37
0
    def execute(self, message):
        """
        @type message: IRCMessage
        """
        if len(message.ParameterList) == 0 or len(message.ParameterList) > 2:
            return IRCResponse(ResponseType.Say, self.help, message.ReplyTo)

        subreddit = message.ParameterList[0].lower()
        if len(message.ParameterList) == 2:
            try:
                if len(message.ParameterList[1]) < 20:
                    topRange = int(message.ParameterList[1])
                else:
                    raise ValueError
                if topRange < 0:
                    raise ValueError
            except ValueError:
                return IRCResponse(ResponseType.Say, "The range should be a positive integer!", message.ReplyTo)
        else:
            topRange = 100

        url = "https://api.imgur.com/3/gallery/r/{}/time/all/{}"
        url = url.format(subreddit, random.randint(0, topRange))
        response = WebUtils.fetchURL(url, self.headers)
        jsonResponse = json.loads(response.body)
        images = jsonResponse['data']

        if not images:
            return IRCResponse(ResponseType.Say,
                               "The subreddit '{}' doesn't seem to have any images posted to it (or it doesn't exist!)"
                               .format(subreddit),
                               message.ReplyTo)

        image = random.choice(images)

        data = []
        if 'title' in image and image['title'] is not None:
            data.append(image['title'])
        if 'nsfw' in image and image['nsfw']:
            data.append(u'\x034\x02NSFW!\x0F')
        if 'animated' in image and image['animated']:
            data.append(u'\x032\x02Animated!\x0F')
        if 'gifv' in image:
            data.append(image['gifv'])
        else:
            data.append(image['link'])

        graySplitter = assembleFormattedText(A.normal[' ', A.fg.gray['|'], ' '])
        return IRCResponse(ResponseType.Say, graySplitter.join(data), message.ReplyTo)
示例#38
0
def crypto(bot, args, sender, source):
    cryptocurrency = args[0].upper()
    cryptoKey = cryptocurrency.lower()

    currency = (args[1] or 'usd').upper()
    currencyKey = currency.lower()

    p = preev(cryptocurrency, currency)

    if p == 'Not found.':
        # Invalid currency.
        bot.reply(source, sender, "Preev doesn't support that currency.")
        return

    if 'usd' in p[cryptoKey] \
            and currencyKey not in p[cryptoKey] and 'usd' in p[currencyKey]:
        # We were given the exchange rate for currency -> usd but not currency -> crypto
        multiplier = 1 / decimal.Decimal(list(p[currencyKey]['usd'].values())[0]['last'])
        currencyKey = 'usd'
    else:
        multiplier = decimal.Decimal(1)

    total_volume = sum(
        float(market['volume']) for market in p[cryptoKey][currencyKey].values()
    )

    avg = sum(
        float(market['last']) * float(market['volume']) / total_volume
            for market in p[cryptoKey][currencyKey].values()
    )

    prices = assembleFormattedText(A.normal[
        A.bold['{} -> {}'.format(cryptocurrency, currency)],
        ': ',
        ', '.join([
            u'{}: {}'.format(
                market,
                babel.numbers.format_currency(decimal.Decimal(data['last']) * multiplier,
                                              currency)
            ) for market, data in p[cryptoKey][currencyKey].items()
        ])
    ])

    prices += u'. average: {}'.format(
        babel.numbers.format_currency(decimal.Decimal(avg) * multiplier,
                                      currency)
    )

    bot.reply(source, sender, prices)
示例#39
0
    def execute(self, message):
        """
        @type message: IRCMessage
        """
        if len(message.ParameterList) == 0:
            return IRCResponse(ResponseType.Say, "You didn't give me any text to rainbow!", message.ReplyTo)

        outputMessage = ''

        for i, c in enumerate(message.Parameters):
            outputMessage += self.colours[i % len(self.colours)] + c

        outputMessage += assembleFormattedText(A.normal[''])

        return IRCResponse(ResponseType.Say, outputMessage, message.ReplyTo)
示例#40
0
文件: speedtest.py 项目: w4/belle
def speedtest(bot, args, sender, source):
    res = get("http://www.speedtest.net/result/{}".format(args[0]), timeout=3)

    soup = BeautifulSoup(res.text, "html.parser")
    download = soup.select(".share-speed.share-download p")[0].text
    upload = soup.select(".share-speed.share-upload p")[0].text
    ping = soup.select(".share-data.share-ping p")[0].text
    isp = soup.select(".share-data.share-isp p")[0].text

    bot.msg(source, assembleFormattedText(A.normal[
        A.bold[str(isp)], ": "
        "Download: ", A.bold[str(download)], " ",
        "Upload: ", A.bold[str(upload)], " ",
        "Ping: ", A.bold[str(ping)]
    ]))
示例#41
0
文件: speedtest.py 项目: kekles/dave
def speedtest(bot, args, sender, source):
    res = get("http://www.speedtest.net/result/{}".format(args[0]), timeout=3)

    soup = BeautifulSoup(res.text, "html.parser")
    download = soup.select(".share-speed.share-download p")[0].text
    upload = soup.select(".share-speed.share-upload p")[0].text
    ping = soup.select(".share-data.share-ping p")[0].text
    isp = soup.select(".share-data.share-isp p")[0].text

    bot.msg(
        source,
        assembleFormattedText(A.normal[A.bold[str(isp)], ": "
                                       "Download: ", A.bold[str(download)],
                                       " ", "Upload: ", A.bold[str(upload)],
                                       " ", "Ping: ", A.bold[str(ping)]]))
示例#42
0
 def first_google_result(self, channel, nick, msg, args):
     if 'google_apis' not in self.bot.plugin_config:
         logging.error('Google apis not configured')
         self.bot.msg('Google search plugin not configured')
     headers = {'Referer': self.bot.plugin_config['google_apis']['referer']}
     try:
         r = requests.get(API_URL % args['query'].replace('  ', ' '),
                          headers=headers)
         r.raise_for_status()
     except requests.exceptions.HTTPError:
         logging.exception("google search httperror: ")
     result = r.json()['responseData']['results'][0]
     title = result['titleNoFormatting'].encode('UTF-8')
     formatted_msg = assembleFormattedText(A.bold[title]) + ": "
     formatted_msg += result['url'].encode('UTF-8')
     self.bot.msg(channel, formatted_msg)
示例#43
0
def add_quote(bot, args, sender, source):
    generated_uuid = str(uuid.uuid4())
    quote = Quote(id=generated_uuid,
                  quote=args[0],
                  attributed=args[1],
                  added_by=sender)
    dave.config.session.add(quote)

    bot.reply(
        source, sender,
        assembleFormattedText(A.normal["Successfully added quote: ",
                                       A.bold[args[0]], " by ",
                                       (args[1] or sender)]))

    bot.msg(
        sender, "You can remove this quote later using \"dave dq {}\"".format(
            generated_uuid))
示例#44
0
def urbandictionary(bot, args, sender, source):
    result = int(args[0].strip()) - 1 if args[0] else 0
    query = args[1].strip().lower()

    key = "urban:{}:{}".format(query, result)

    if dave.config.redis.exists(key):
        bot.reply(source, sender, dave.config.redis.get(key).decode('utf-8'))
        return

    if not dave.config.redis.exists("urban_query:{}".format(query)):
        url = "https://mashape-community-urban-dictionary.p.mashape.com/define?term={}".format(quote_plus(query))
        r = requests.get(url, headers={
            "X-Mashape-Key": dave.config.config["api_keys"]["mashape"],
            "Accept": "text/plain"
        })

        resp = r.json()
        dave.config.redis.setex("urban_query:{}".format(query), 86400, pickle.dumps(resp))
    else:
        resp = pickle.loads(dave.config.redis.get("urban_query:{}".format(query)))

    print(resp)

    if len(resp["list"]) > result:
        res = resp["list"][result]
        definition = re.sub(r"\r?\n|\r", "", res["definition"].strip())

        if len(definition) > 200:
            definition = definition[:197] + "..."

        definition = assembleFormattedText(A.normal[A.bold[str(res["word"])], ": {} [by {}, +{}/-{}] [more at {}]".format(
            definition,
            res["author"],
            res["thumbs_up"],
            res["thumbs_down"],
            res["permalink"]
        )])

        dave.config.redis.setex(key, 86400, definition)
        bot.reply(source, sender, definition)
    else:
        bot.reply(source, sender, "There are no entries for: {} at position {}".format(
            query,
            result
        ))
示例#45
0
文件: reddit.py 项目: kekles/dave
def subreddit(bot, args, sender, source):
    """Ran whenever a subreddit is mentioned"""
    if dave.config.redis.exists("reddit:subreddit:mentioned:{}:{}".format(
            args[0], source)):
        # if this subreddit was mentioned in the last x seconds (see the setex below),
        # don't spam info about it
        return

    if not dave.config.redis.exists("reddit:subreddit:{}".format(args[0])):
        req = get("https://reddit.com/r/{}/about.json".format(args[0]),
                  headers={'user-agent': 'irc bot (https://github.com/w4)'})

        if req.status_code != 200:
            return

        if "/search.json" in req.url:
            # 404'd, reddit redirected us to the search page because they couldn't find
            # the user.
            return

        req = req.json()

        dave.config.redis.setex("reddit:subreddit:{}".format(args[0]), 600,
                                pickle.dumps(req))
    else:
        req = pickle.loads(
            dave.config.redis.get("reddit:subreddit:{}".format(args[0])))

    resp = req["data"]

    # don't give info about this user again in this channel for 300 seconds
    dave.config.redis.setex(
        "reddit:subreddit:mentioned:{}:{}".format(args[0], source), 300, 1)

    bot.msg(
        source,
        assembleFormattedText(A.normal[
            A.bold[A.fg.lightRed["[NSFW] "]] if resp["over18"] else "",
            A.bold[resp["title"]],
            " ({}), a community for {}. {} subscribers, {} browsing right now."
            .format(
                resp["display_name_prefixed"],
                naturaldelta(datetime.utcnow().timestamp() -
                             resp["created"]), intcomma(resp["subscribers"]),
                intcomma(resp["accounts_active"]))]))
示例#46
0
文件: reddit.py 项目: w4/belle
def subreddit(bot, args, sender, source):
    """Ran whenever a subreddit is mentioned"""
    if dave.config.redis.exists("reddit:subreddit:mentioned:{}:{}".format(args[0], source)):
        # if this subreddit was mentioned in the last x seconds (see the setex below),
        # don't spam info about it
        return

    if not dave.config.redis.exists("reddit:subreddit:{}".format(args[0])):
        req = get("https://reddit.com/r/{}/about.json".format(args[0]),
                  headers={'user-agent': 'irc bot (https://github.com/w4)'})

        if req.status_code != 200:
            return

        if "/search.json" in req.url:
            # 404'd, reddit redirected us to the search page because they couldn't find
            # the user.
            return

        req = req.json()

        dave.config.redis.setex("reddit:subreddit:{}".format(args[0]), 600,
                                pickle.dumps(req))
    else:
        req = pickle.loads(dave.config.redis.get("reddit:subreddit:{}".format(args[0])))

    resp = req["data"]

    # don't give info about this user again in this channel for 300 seconds
    dave.config.redis.setex("reddit:subreddit:mentioned:{}:{}".format(args[0], source),
                            300, 1)

    bot.msg(source, assembleFormattedText(
        A.normal[
            A.bold[A.fg.lightRed["[NSFW] "]] if resp["over18"] else "",
            A.normal[resp["title"]],
            " ({}), a community for {}. {} subscribers, {} browsing right now.".format(
                resp["display_name_prefixed"],
                naturaldelta(datetime.utcnow().timestamp() - resp["created"]),
                intcomma(resp["subscribers"]),
                intcomma(resp["accounts_active"])
            )
        ]
    ))
示例#47
0
    def execute(self, message):
        """
        @type message: IRCMessage
        """
        if len(message.ParameterList) == 0:
            return IRCResponse(ResponseType.Say,
                               "You didn't give me any text to rainbow!",
                               message.ReplyTo)

        outputMessage = u''

        if message.Command == 'rainbow':
            for i, c in enumerate(message.Parameters):
                outputMessage += self.colours[i % len(self.colours)] + c
        else:
            for i, c in enumerate(message.Parameters):
                outputMessage += self.bgcolours[i % len(self.bgcolours)] + c

        outputMessage += assembleFormattedText(A.normal[''])

        return IRCResponse(ResponseType.Say, outputMessage, message.ReplyTo)
示例#48
0
文件: reddit.py 项目: kekles/dave
def post(bot, args, sender, source):
    """Ran whenever a reddit post is sent"""
    if dave.config.redis.exists("reddit:post:mentioned:{}:{}".format(
            args[0], source)):
        # if this post was mentioned in the last x seconds (see the setex below),
        # don't spam info about it
        return

    if not dave.config.redis.exists("reddit:post:{}".format(args[0])):
        req = get("https://reddit.com/{}.json?limit=1".format(args[0]),
                  headers={'user-agent': 'irc bot (https://github.com/w4)'})

        if req.status_code != 200:
            return

        req = req.json()

        dave.config.redis.setex("reddit:post:{}".format(args[0]), 200,
                                pickle.dumps(req))
    else:
        req = pickle.loads(
            dave.config.redis.get("reddit:post:{}".format(args[0])))

    resp = req[0]["data"]["children"][0]["data"]

    dave.config.redis.setex(
        "reddit:post:mentioned:{}:{}".format(args[0], source), 300, 1)

    bot.msg(
        source,
        assembleFormattedText(A.normal[
            A.bold[A.fg.lightRed["[NSFW] "]] if resp["over_18"] else "",
            A.bold[resp["title"][:75] + (resp["title"][75:] and '...')],
            " by ", A.bold[resp["author"]],
            " (/r/{}) {} comments, {} points, posted {}".format(
                resp["subreddit"], intcomma(resp["num_comments"]
                                            ), intcomma(resp["score"]),
                naturaltime(datetime.utcnow().timestamp() -
                            resp["created_utc"])), ]))
示例#49
0
文件: youtube.py 项目: w4/belle
def youtubevideo(bot, args, sender, source):
    """Ran whenever a YouTube video is sent"""
    if not dave.config.redis.exists("youtube:{}".format(args[0])):
        req = get("{}&id={}".format(BASE_URL, args[0]),
                  headers={'user-agent': 'irc bot (https://github.com/w4)'})

        if req.status_code != 200:
            print("{} from YouTube API: {}", req.status_code, req.json())
            return

        req = req.json()

        if not req["pageInfo"]["totalResults"]:
            bot.msg(source, "That video doesn't exist.")
            return

        dave.config.redis.setex("youtube:{}".format(args[0]), 400,
                                pickle.dumps(req))
    else:
        req = pickle.loads(dave.config.redis.get("youtube:{}".format(args[0])))

    resp = req["items"][0]

    bot.msg(source, assembleFormattedText(
        A.normal[
            A.bold[resp["snippet"]["title"]],
            " ({}) by {} uploaded {}. {} views, +{}/-{}.".format(
                str(isodate.parse_duration(resp["contentDetails"]["duration"])),
                resp["snippet"]["channelTitle"],
                naturaltime(
                    datetime.now(timezone.utc)
                        - isodate.parse_datetime(resp["snippet"]["publishedAt"])
                ),
                intcomma(resp["statistics"]["viewCount"]),
                intcomma(resp["statistics"]["likeCount"]),
                intcomma(resp["statistics"]["dislikeCount"])
            )
        ]
    ))
示例#50
0
文件: youtube.py 项目: kekles/dave
def youtubevideo(bot, args, sender, source):
    """Ran whenever a YouTube video is sent"""
    if not dave.config.redis.exists("youtube:{}".format(args[0])):
        req = get("{}&id={}".format(BASE_URL, args[0]),
                  headers={'user-agent': 'irc bot (https://github.com/w4)'})

        if req.status_code != 200:
            bot.msg(
                source,
                "Bad response from YouTube API: {}".format(req.status_code))
            return

        req = req.json()

        if not req["pageInfo"]["totalResults"]:
            bot.msg(source, "That video doesn't exist.")
            return

        dave.config.redis.setex("youtube:{}".format(args[0]), 400,
                                pickle.dumps(req))
    else:
        req = pickle.loads(dave.config.redis.get("youtube:{}".format(args[0])))

    resp = req["items"][0]

    bot.msg(
        source,
        assembleFormattedText(A.normal[
            A.bold[resp["snippet"]["title"]],
            " ({}) by {} uploaded {}. {} views, +{}/-{}.".format(
                str(isodate.parse_duration(resp["contentDetails"]["duration"])
                    ), resp["snippet"]["channelTitle"],
                naturaltime(
                    datetime.now(timezone.utc) -
                    isodate.parse_datetime(resp["snippet"]["publishedAt"])
                ), intcomma(resp["statistics"]["viewCount"]
                            ), intcomma(resp["statistics"]["likeCount"]),
                intcomma(resp["statistics"]["dislikeCount"]))]))
示例#51
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
示例#52
0
文件: reddit.py 项目: kekles/dave
def user(bot, args, sender, source):
    if dave.config.redis.exists("reddit:user:mentioned:{}:{}".format(
            args[0], source)):
        # if this user was mentioned in the last x seconds (see the setex below), don't
        # spam info about them
        return

    if not dave.config.redis.exists("reddit:user:{}".format(args[0])):
        req = get("https://reddit.com/u/{}/about.json".format(args[0]),
                  headers={'user-agent': 'irc bot (https://github.com/w4)'})

        if req.status_code != 200:
            return

        req = req.json()

        dave.config.redis.setex("reddit:user:{}".format(args[0]), 600,
                                pickle.dumps(req))
    else:
        req = pickle.loads(
            dave.config.redis.get("reddit:user:{}".format(args[0])))

    resp = req["data"]

    # don't give info about this user again in this channel for 300 seconds
    dave.config.redis.setex(
        "reddit:user:mentioned:{}:{}".format(args[0], source), 300, 1)

    bot.msg(
        source,
        assembleFormattedText(A.normal[
            A.bold[resp["name"]],
            ", a redditor for {}. {} link karma, {} comment karma.".format(
                naturaldelta(datetime.utcnow().timestamp() - resp["created"]),
                intcomma(resp["link_karma"]), intcomma(resp["comment_karma"])),
            " Verified user." if resp["verified"] else "",
            " Reddit employee." if resp["is_employee"] else ""]))
示例#53
0
    def execute(self, message):
        """
        @type message: IRCMessage
        """
        if len(message.ParameterList) != 1:
            return IRCResponse(ResponseType.Say, self.help, message.ReplyTo)

        subreddit = message.ParameterList[0].lower()

        url = "https://api.imgur.com/3/gallery/r/{}/time/all/{}"
        url = url.format(subreddit, random.randint(0, 100))
        response = WebUtils.fetchURL(url, self.headers)
        jsonResponse = json.loads(response.body)
        images = jsonResponse['data']

        if not images:
            return IRCResponse(
                ResponseType.Say,
                "The subreddit '{}' doesn't seem to have any images posted to it (or it doesn't exist!)"
                .format(subreddit), message.ReplyTo)

        image = random.choice(images)

        data = []
        if image['title'] is not None:
            data.append(image['title'])
        if image['nsfw']:
            data.append(u'\x034\x02NSFW!\x0F')
        if image['animated']:
            data.append(u'\x032\x02Animated!\x0F')
        data.append(image['link'])

        graySplitter = assembleFormattedText(A.normal[' ', A.fg.gray['|'],
                                                      ' '])
        return IRCResponse(ResponseType.Say, graySplitter.join(data),
                           message.ReplyTo)
示例#54
0
def find_quote(bot, args, sender, source):
    try:
        quotes = dave.config.session.query(
            Quote).filter((Quote.quote.op("~")(args[0]))
                          | (Quote.attributed.op("~")(args[0]))
                          | (Quote.added_by.op("~")(args[0]))).all()
    except SQLAlchemyError as e:
        bot.reply(source, sender, SQLAlchemyError.__str__(e))
        return

    if len(quotes) == 0:
        bot.reply(source, sender, "No results for query.")

    if len(quotes) > 3:
        bot.reply(source, sender, "Your query yielded too many results ({}), here's a " \
                                  "random sample:".format(len(quotes)))
        quotes = random.sample(quotes, 3)

    for quote in quotes:
        bot.reply(
            source, sender,
            assembleFormattedText(
                A.normal[A.bold[quote.quote], " by ",
                         (quote.attributed or quote.added_by)]))
示例#55
0
    def execute(self, message):
        """
        @type message: IRCMessage
        """
        if len(message.ParameterList) < 3:
            return IRCResponse(ResponseType.Say, self.help, message.ReplyTo)

        try:
            amount = float(message.ParameterList[0])
            offset = 1
        except ValueError:
            amount = 1.0
            offset = 0

        ccFrom = message.ParameterList[offset].upper()
        ccTo   = message.ParameterList[offset+2:]
        ccTo   = ",".join(ccTo)
        ccTo   = ccTo.upper()

        url = "https://api.fixer.io/latest?base={}&symbols={}"
        url = url.format(ccFrom, ccTo)
        response = WebUtils.fetchURL(url)
        jsonResponse = json.loads(response.body)
        rates = jsonResponse['rates']

        if not rates:
            return IRCResponse(ResponseType.Say,
                               "Some or all of those currencies weren't recognized!",
                               message.ReplyTo)

        data = []
        for curr,rate in rates.iteritems():
            data.append("{} {}".format(rate*amount, curr))

        graySplitter = assembleFormattedText(A.normal[' ', A.fg.gray['|'], ' '])
        return IRCResponse(ResponseType.Say, graySplitter.join(data), message.ReplyTo)
示例#56
0
class Splatoon(BotCommand):
    def triggers(self):
        return ['splat']

    def help(self, query):
        return "splat [regular/ranked/league/fest]"

    graySplitter = assembleFormattedText(A.normal[' ', A.fg.gray['|'], ' '])

    def _fetch(self, j, short, mode, label):
        r = j[mode]
        data = []
        t = A.normal[
            A.bold['{} {}: '.format(label, r[0]['rule']['name'])],
            '/'.join([r[0]['stage_a']['name'], r[0]['stage_b']['name']])]
        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 = string.deltaTimeToString(d, resolution='m')
            t = A.normal[
                A.bold['{} {} in {}: '.
                       format(label, r[1]['rule']['name'], deltaStr)],
                '/'.join([r[1]['stage_a']['name'], r[1]['stage_b']['name']])]
            data.append(assembleFormattedText(t))
        return ' | '.join(data)

    def _regular(self, j, short):
        return self._fetch(j, short, 'regular', 'Regular')

    def _ranked(self, j, short):
        return self._fetch(j, short, 'gachi', 'Ranked')

    def _league(self, j, short):
        return self._fetch(j, short, 'league', 'League')

    def _fest(self, j, short):
        if j['splatfests']:
            pass
        elif not short:
            return 'No SplatFest is currently scheduled'

    def execute(self, message: IRCMessage):
        url = "https://splatoon2.ink/data/schedules.json"
        response = self.bot.moduleHandler.runActionUntilValue('fetch-url', url)
        j = response.json()

        if len(message.parameterList) < 1:
            # do everything
            data = []
            data += filter(None, [self._regular(j, short=True)])
            data += filter(None, [self._ranked(j, short=True)])
            data += filter(None, [self._league(j, short=True)])
            data += filter(None, [self._fest(j, short=True)])
            return IRCResponse(ResponseType.Say, self.graySplitter.join(data),
                               message.replyTo)
        else:
            subCommands = {
                'regular': self._regular,
                'ranked': self._ranked,
                'league': self._league,
                'fest': self._fest
            }
            subCommand = message.parameterList[0].lower()
            if subCommand in subCommands:
                return IRCResponse(ResponseType.Say,
                                   subCommands[subCommand](j, short=False),
                                   message.replyTo)
            else:
                return IRCResponse(ResponseType.Say, self.help(None),
                                   message.replyTo)
示例#57
0
def spell(bot, user, channel, args):
    # msg = 'This is an example.'
    # bot.send_msg(channel, msg, length = 450)

    s = {
        'Q': 0,
        'W': 1,
        'E': 2,
        'R': 3,
    }

    scalings = {
        'bonusattackdamage': 'Bonus AD',
        'spelldamage': 'AP',
        'attackdamage': 'AD',
        '@stacks': 'per Stack',
        '@dynamic.attackdamage': 'Dyn. AD',
        '@special.dariusr3': '+ 32/50/68 per Stack',
        'health': 'HP',
        'abilitypower': 'AP',
    }

    # easteregg
    if len(args) < 1:
        return

    if args[0].lower() in ['riottriggs', 'triggs', 'triggs390']:
        bot.send_msg(channel, 'Triggs has no skill.')
        return
    # /easteregg

    if len(args) < 2:
        return

    args[0] = lol_ddragon.normalize_name(args[0])

    data = lol_ddragon.get_champion(args[0])['data'][args[0]]
    passive = data['passive']
    data = data['spells'][s[args[1].upper()]]

    cost = data['resource']
    text = data['tooltip']
    effects = data['effectBurn']

    for i, e in enumerate(effects):

        cost = cost.replace('{{ e' + str(i) + ' }}', str(e))
        text = text.replace('{{ e' + str(i) + ' }}', str(e))

    cost = cost.replace('{{ cost }}', data['costBurn'])
    cd = data['cooldownBurn']
    range_ = data['rangeBurn']

    for i, a in enumerate(data['vars']):
        scale = ''
        if a['link'] in scalings:
            scale = ' ' + scalings[a['link']]
        text = text.replace('{{ ' + a['key'] + ' }}', str(a['coeff']) + scale)
    text = strip_tags(text)

    # msg  = '[' + args[0] + ' | ' + args[1].upper() + ' | ' + data['name'] + '] '
    # msg += '[Cost: ' + cost + '] [CD: ' + cd + '] [Range: ' + range_ + '] '
    # msg += '[' + text + ']'

    msg = assembleFormattedText(
        A.normal['[', A.bold[args[0]], ' | ', A.bold[args[1].upper()], ' | ',
                 A.bold[str(data['name'])], '] [', A.bold['Cost: '],
                 cost + '] [', A.bold['CD: '], cd + '] [', A.bold['Range: '],
                 range_ + '] [' + text + ']'])

    bot.send_msg(channel, str(msg))
示例#58
0
class Rainbow(CommandInterface):
    triggers = ['rainbow', 'rrainbow']
    help = 'rainbow <text> - outputs the specified text with rainbow colours; rrainbow uses background colours'

    colours = [
        assembleFormattedText(A.fg.lightRed['']),
        #assembleFormattedText(A.fg.orange['']),
        assembleFormattedText(A.fg.yellow['']),
        assembleFormattedText(A.fg.lightGreen['']),
        assembleFormattedText(A.fg.lightCyan['']),
        assembleFormattedText(A.fg.lightBlue['']),
        assembleFormattedText(A.fg.lightMagenta['']),
    ]

    bgcolours = [
        assembleFormattedText(A.bg.red['']),
        assembleFormattedText(A.bg.orange['']),
        assembleFormattedText(A.bg.yellow['']),
        assembleFormattedText(A.bg.green['']),
        assembleFormattedText(A.bg.cyan['']),
        assembleFormattedText(A.bg.blue['']),
        assembleFormattedText(A.bg.magenta['']),
    ]

    def execute(self, message):
        """
        @type message: IRCMessage
        """
        if len(message.ParameterList) == 0:
            return IRCResponse(ResponseType.Say,
                               "You didn't give me any text to rainbow!",
                               message.ReplyTo)

        outputMessage = u''

        if message.Command == 'rainbow':
            for i, c in enumerate(message.Parameters):
                outputMessage += self.colours[i % len(self.colours)] + c
        else:
            for i, c in enumerate(message.Parameters):
                outputMessage += self.bgcolours[i % len(self.bgcolours)] + c

        outputMessage += assembleFormattedText(A.normal[''])

        return IRCResponse(ResponseType.Say, outputMessage, message.ReplyTo)
示例#59
0
    def execute(self, message):
        """
        @type message: IRCMessage
        """

        subString = self._mangleEscapes(message.Parameters)

        try:
            segments = list(self._parseSubcommandTree(subString))
        except UnbalancedBracesException as e:
            red = assembleFormattedText(A.fg.lightRed[''])
            normal = assembleFormattedText(A.normal[''])
            error = subString[:e.column] + red + subString[
                e.column] + normal + subString[e.column + 1:]
            error = self._unmangleEscapes(error, False)
            return [
                IRCResponse(ResponseType.Say,
                            u"Sub Error: {}".format(e.message),
                            message.ReplyTo),
                IRCResponse(ResponseType.Say, error, message.ReplyTo)
            ]

        prevLevel = -1
        responseStack = []
        extraVars = {}
        metadata = {}

        for segment in segments:
            (level, command, start, end) = segment

            # We've finished executing subcommands at the previous depth,
            # so replace subcommands with their output at the current depth
            if level < prevLevel:
                command = self._substituteResponses(command, responseStack,
                                                    level, extraVars, start)

            # Build a new message out of this segment
            inputMessage = IRCMessage(message.Type,
                                      message.User.String,
                                      message.Channel,
                                      self.bot.commandChar + command.lstrip(),
                                      self.bot,
                                      metadata=metadata)

            # Execute the constructed message
            if inputMessage.Command.lower(
            ) in self.bot.moduleHandler.mappedTriggers:
                response = self.bot.moduleHandler.mappedTriggers[
                    inputMessage.Command.lower()].execute(inputMessage)
                """@type : IRCResponse"""
            else:
                return IRCResponse(
                    ResponseType.Say,
                    u"'{}' is not a recognized command trigger".format(
                        inputMessage.Command), message.ReplyTo)

            # Push the response onto the stack
            responseStack.append((level, response.Response, start, end))
            # Update the extraVars dict
            extraVars.update(response.ExtraVars)
            metadata = self._recursiveMerge(metadata, response.Metadata)

            prevLevel = level

        responseString = self._substituteResponses(subString, responseStack,
                                                   -1, extraVars, -1)
        responseString = self._unmangleEscapes(responseString)
        return IRCResponse(ResponseType.Say,
                           responseString,
                           message.ReplyTo,
                           extraVars=extraVars,
                           metadata=metadata)
示例#60
0
文件: Urban.py 项目: LBbot/PyMoronBot
    def execute(self, message):
        """
        @type message: IRCMessage
        """
        if len(message.ParameterList) == 0:
            return IRCResponse(
                ResponseType.Say,
                "You didn't give a word! Usage: {0}".format(self.help),
                message.ReplyTo)

        search = urllib.quote(message.Parameters)

        url = 'http://api.urbandictionary.com/v0/define?term={0}'.format(
            search)

        webPage = WebUtils.fetchURL(url)

        response = json.loads(webPage.body)

        if len(response['list']) == 0:
            return IRCResponse(
                ResponseType.Say,
                "No entry found for '{0}'".format(message.Parameters),
                message.ReplyTo)

        graySplitter = assembleFormattedText(A.normal[' ', A.fg.gray['|'],
                                                      ' '])

        defn = response['list'][0]

        word = defn['word']

        definition = defn['definition']
        definition = graySplitter.join(
            [s.strip() for s in definition.strip().splitlines() if s])

        example = defn['example']
        example = graySplitter.join(
            [s.strip() for s in example.strip().splitlines() if s])

        author = defn['author']

        up = defn['thumbs_up']
        down = defn['thumbs_down']

        more = 'http://{}.urbanup.com/'.format(word.replace(' ', '-'))

        if word.lower() != message.Parameters.lower():
            word = "{0} (Contains '{1}')".format(word, message.Parameters)

        defFormatString = unicode(
            assembleFormattedText(A.normal[A.bold["{0}:"], " {1}"]))
        exampleFormatString = unicode(
            assembleFormattedText(A.normal[A.bold["Example(s):"], " {0}"]))
        byFormatString = unicode(
            assembleFormattedText(A.normal["{0}", graySplitter,
                                           A.fg.lightGreen["+{1}"],
                                           A.fg.gray["/"],
                                           A.fg.lightRed["-{2}"], graySplitter,
                                           "More defs: {3}"]))
        responses = [
            IRCResponse(ResponseType.Say,
                        defFormatString.format(word, definition),
                        message.ReplyTo),
            IRCResponse(ResponseType.Say, exampleFormatString.format(example),
                        message.ReplyTo),
            IRCResponse(ResponseType.Say,
                        byFormatString.format(author, up, down, more),
                        message.ReplyTo)
        ]

        return responses