Example #1
0
def getFromRelay(bot):
	#global logger
	if not "#crimbogrotto" in bot.channels:
		return
	sid = bot.getForumSID()
	if not 'lastMChatID' in bot.memory.keys():
			text = web.post( 'http://www.crimbogrotto.com/mchat.php','mode=read&room_id=0&sid={0}'.format(sid) )
			messageList = re.findall( mchatPattern, text )
			bot.memory['lastMChatID'] = int( messageList[-1].group(1) )

	text = web.post( 'http://www.crimbogrotto.com/mchat.php','mode=read&room_id=0&message_last_id={0!s}&sid={1}'.format( bot.memory['lastMChatID'], sid ) )
	messageIter = re.finditer( mchatPattern, text )
	parser = HTMLParser.HTMLParser()
	for messageMatch in messageIter:
		if messageMatch.group(2) != 'CGIRC':
			sender = messageMatch.group(2)
			message = messageMatch.group(3)
			message = re.sub( smiliesPattern, r'\1', message ) #Replace smilies from forum
			message = re.sub( linkPattern, r'\1', message ) #Replace links with just url
			message = re.sub( tagPattern, '', message ) #Remove all other tags
			openBracket = '{'
			closeBracket = '}'
			if sender == 'CGBot':
				nameMatch = re.match( CGBotMessagePattern, message )
				sender = nameMatch.group(1)
				message = nameMatch.group(2)
				openBracket = '['
				closeBracket = ']'
			if message == '':
				return
			bot.msg( '#crimbogrotto', u'{0}{1}{2}: {3}'.format( openBracket, sender, closeBracket, parser.unescape(message) ), 10, False )
			bot.memory['lastMChatID'] = int( messageMatch.group(1) )
	return
Example #2
0
def getFromRelay(bot):
    #global logger
    if not "#crimbogrotto" in bot.channels:
        return
    sid = bot.getForumSID()
    if not 'lastMChatID' in bot.memory.keys():
        text = web.post('http://www.crimbogrotto.com/mchat.php', 'mode=read&room_id=0&sid={0}'.format(sid))
        lastIDSoup = BeautifulSoup(text)
        bot.memory['lastMChatID'] = int(lastIDSoup.find_all('div', class_='mChatHover')[-1]['id'][4:])

    params = 'mode=read&room_id=0&message_last_id={0!s}&sid={1}'.format(bot.memory['lastMChatID'], sid)
    text = web.post('http://www.crimbogrotto.com/mchat.php', params)
    mchatSoup = BeautifulSoup(text)
    # Each message is contained in div with class mChatHover
    for messageDiv in mchatSoup.find_all('div', class_='mChatHover'):
        sender = messageDiv.find('a', href=memberlistPattern).string
        bot.memory['lastMChatID'] = int(messageDiv['id'][4:])

        if sender == 'CGIRC':
            continue

        message = messageDiv.find('div', class_='mChatMessage')

        # Replace smilies with text of smilie (images are disallowed, so all images should be smilies)
        imgs = message.find_all('img')
        for img in imgs:
            new_tag = mchatSoup.new_tag('div')
            new_tag.string = img['alt']
            img.replace_with(new_tag)

        links = message.find_all('a')
        for link in links:
            new_tag = mchatSoup.new_tag('div')
            if link.string != link['href']:
                new_tag.string = '{} ({})'.format(link['href'], link.string)
            else:
                new_tag.string = link.string
            link.replace_with(new_tag)

        # Collapse message to only plain text and adjust for correct bracketing based on message source
        messageText = message.get_text()
        openBracket = '['
        closeBracket = ']'

        if sender == 'CGBot':
            KoLMessageMatch = re.match(KoLMessagePattern, messageText)
            sender = KoLMessageMatch.group(1)
            messageText = KoLMessageMatch.group(2)
            openBracket = '{'
            closeBracket = '}'
        if message == '':
            return
        parser = HTMLParser.HTMLParser()
        toSend = u'{0}{1}{2}: {3}'.format(openBracket, sender, closeBracket, parser.unescape(messageText))
        bot.msg('#crimbogrotto', toSend, 10, False)
        bot.memory['lastMChatID'] = int(KoLMessageMatch.group(1))
    return
Example #3
0
def relay(bot, trigger):
    #global logger
    sid = bot.getForumSID()
    message = re.sub(actionPattern, '', trigger.group(0))  #Remove ACTION from /me messages
    message = re.sub(colorPattern, '', message)  # Remove color codes
    message = re.sub(nonAsciiPattern, '', message)  #remove non-ascii characters 'cause forum chat and kol chat are dumb
    message = re.sub(hiddenPattern, '', message)  #messages starting with "irc:" are hidden from kol chat
    if message == '':
        return
    toPost = web.quote(u'[b]{0}:[/b] {1}'.format(trigger.nick, message))
    web.post('http://www.crimbogrotto.com/mchat.php',
             'room_id=0&mode=add&sid={0}&message={1}'.format(sid, toPost))
    return
Example #4
0
def issue(bot, trigger):
    """Create a GitHub issue, also known as a bug report. Syntax: .makeissue Title of the bug report"""
    # check input
    if not trigger.group(2):
        return bot.say('Please title the issue')

    # Is the Oauth token and repo available?
    gitAPI = checkConfig(bot)
    if not gitAPI:
        return bot.say('Git module not configured, make sure github.oauth_token and github.repo are defined')

    # parse input
    now = ' '.join(str(datetime.utcnow()).split(' ')).split('.')[0] + ' UTC'
    body = 'Submitted by: %s\nFrom channel: %s\nAt %s' % (trigger.nick, trigger.sender, now)
    data = {"title": trigger.group(2), "body": body}
    # submit
    try:
        raw = web.post('https://api.github.com/repos/' + gitAPI[1] + '/issues?access_token=' + gitAPI[0], json.dumps(data))
    except HTTPError:
        bot.say('The GitHub API returned an error.')
        return NOLIMIT

    data = json.loads(raw)
    bot.say('Issue #%s posted. %s' % (data['number'], data['html_url']))
    bot.debug(__file__, 'Issue #%s created in %s' % (data['number'], trigger.sender), 'warning')
Example #5
0
def who(bot, trigger):
	sid = bot.getForumSID()
	whoText = web.post( 'http://www.crimbogrotto.com/mchat.php','mode=read&room_id=6&sid={0}'.format(sid) )
	lastWhoID = 0
	messageList = re.findall( whoPattern, whoText )
	messageMatch = messageList[-1]
	bot.reply( messageMatch.group(3) )
Example #6
0
def issue(bot, trigger):
    """Create a GitHub issue, also known as a bug report. Syntax: .makeissue Title of the bug report"""
    # check input
    if not trigger.group(2):
        return bot.say('Please title the issue')

    # Is the Oauth token and repo available?
    gitAPI = checkConfig(bot)
    if gitAPI == False:
        return bot.say(
            'Git module not configured, make sure github.oauth_token and github.repo are defined'
        )

    # parse input
    now = ' '.join(str(datetime.utcnow()).split(' ')).split('.')[0] + ' UTC'
    body = 'Submitted by: %s\nFrom channel: %s\nAt %s' % (trigger.nick,
                                                          trigger.sender, now)
    data = {"title": trigger.group(2).encode('utf-8'), "body": body}
    # submit
    try:
        raw = web.post(
            'https://api.github.com/repos/' + gitAPI[1] +
            '/issues?access_token=' + gitAPI[0], json.dumps(data))
    except HTTPError:
        return bot.say('The GitHub API returned an error.')

    data = json.loads(raw)
    bot.say('Issue #%s posted. %s' % (data['number'], data['html_url']))
    bot.debug(__file__,
              'Issue #%s created in %s' % (data['number'], trigger.sender),
              'warning')
Example #7
0
    def think(self, thought):
        self.svars['stimulus'] = thought
        postdata = web.urlencode(self.svars)
        postdata += '&icognocheck=' + md5(postdata[9:29]).hexdigest()
        response = web.post('http://www.cleverbot.com/webservicemin', postdata).read().split('\r')

        self.svars['sessionid'] = response[1]
        self.svars['logurl'] = response[2]
        self.svars['vText8'] = response[3]
        self.svars['vText7'] = response[4]
        self.svars['vText6'] = response[5]
        self.svars['vText5'] = response[6]
        self.svars['vText4'] = response[7]
        self.svars['vText3'] = response[8]
        self.svars['vText2'] = response[9]
        self.svars['prevref'] = response[10]
        self.svars['emotionalhistory'] = response[12]
        self.svars['ttsLocMP3'] = response[13]
        self.svars['ttsLocTXT'] = response[14]
        self.svars['ttsLocTXT3'] = response[15]
        self.svars['ttsText'] = response[16]
        self.svars['lineRef'] = response[17]
        self.svars['lineURL'] = response[18]
        self.svars['linePOST'] = response[19]
        self.svars['lineChoices'] = response[20]
        self.svars['lineChoicesAbbrev'] = response[21]
        self.svars['typingData'] = response[22]
        self.svars['divert'] = response[23]

        return self.svars['ttsText']
Example #8
0
def shindan(bot, trigger):
    """
    .shindan <id> [name] - Do the shindanmaker thing! Will automatically translate japanese shindans to english. (Waifu id: 215100 | Teh_Colt's Drama Gen id: 490953)
    """
    if not trigger.group(3) or not trigger.group(3).isdigit() or int(trigger.group(3).strip()) < 2000:
        bot.say('You must specify a shindanmaker ID (Waifu id: 215100 | Teh_Colt\'s Drama Gen id: 490953)')
        return
    
    name = trigger.nick    
    if (trigger.group(4)):
        name = trigger.group(4)
    data = web.urlencode({'u': name, 'from': ''}).encode('ascii')
    url = follow_redirects('http://en.shindanmaker.com/'+trigger.group(3).strip())
    try:
        soup = get_soup(web.post(url, data))
        shindan = soup.find(attrs={'class':re.compile("result")})
        if 'en' in url:
            bot.say(shindan.text.strip())
        else:
            msg, in_lang = translate.translate(shindan.text.strip())
            if in_lang == 'ja':
                in_lang = 'Japanese'
            bot.say('%s (Translated from %s)' % (msg, in_lang))
    except Exception as e:
        bot.say('418 I\'m a teapot')
Example #9
0
def shindan(bot, trigger):
    """
    .shindan <id> [name] - Do the shindanmaker thing! Will automatically translate japanese shindans to english. (Waifu id: 215100 | Teh_Colt's Drama Gen id: 490953)
    """
    if not trigger.group(3) or not trigger.group(3).isdigit() or int(
            trigger.group(3).strip()) < 2000:
        return bot.say(
            u'You must specify a shindanmaker ID (Waifu id: 215100 | T\u0081eh_Colt\'s Drama Gen id: 490953)'
        )

    name = trigger.nick
    if (trigger.group(4)):
        name = trigger.group(4)
    data = web.urlencode({'u': name, 'from': ''}).encode('ascii')
    url = follow_redirects('http://en.shindanmaker.com/' +
                           trigger.group(3).strip())
    try:
        soup = get_soup(web.post(url, data))
        shindan = soup.find(class_='result')
        if shindan is None:
            bot.say('The shindanmaker ID %s does not exist!' %
                    (trigger.group(3).strip(), ))
        else:
            bot.say(shindan.text.strip())
    except Exception as e:
        bot.say('418 I\'m a teapot')
Example #10
0
def shorten_url(url):
    try:
        res, headers = web.post('http://git.io',
                                'url=' + web.quote(url),
                                return_headers=True)
        return headers['location']
    except:
        return url
Example #11
0
def add_traceback(bot, trigger):
    """Add a traceback to a GitHub issue.

    This pulls the traceback from the exceptions log file. To use, put .addtrace
    followed by the issue number to add the comment to, then the signature of
    the error (the message shown to the channel when the error occured). This
    command will only work for errors from unhandled exceptions."""
    # Make sure the API is set up
    gitAPI = checkConfig(bot)
    if not gitAPI:
        return bot.say('Git module not configured, make sure github.oauth_token and github.repo are defined')

    # Make sure the input is valid
    args = trigger.group(2).split(None, 1)
    if len(args) != 2:
        bot.say('Please give both the issue number and the error message.')
        return
    number, trace = args

    # Make sure the given issue number exists
    issue_data = web.get('https://api.github.com/repos/%s/issues/%s' % (gitAPI[1], number))
    issue_data = json.loads(issue_data)
    if 'message' in issue_data and issue_data['message'] == 'Not Found':
        return bot.say("That issue doesn't exist.")

    # Find the relevant lines from the log file
    post = ''
    logfile = os.path.join(bot.config.logdir, 'exceptions.log')
    with open(logfile) as log:
        in_trace = False
        for data in log:
            if data == 'Signature: ' + trace + '\n':
                post = data
                in_trace = True
            elif data == '----------------------------------------\n':
                in_trace = False
            elif in_trace:
                post += data

    # Give an error if we didn't find the traceback
    if not post:
        return bot.say("I don't remember getting that error. Please post it "
                       "yourself at https://github.com/%s/issues/%s"
                       % (gitAPI[1], number))

    # Make the comment
    try:
        raw = web.post('https://api.github.com/repos/' + gitAPI[1] + '/issues/'
                       + number + '/comments?access_token=' + gitAPI[0],
                       json.dumps({'body': '``\n' + post + '``'}))
    except OSError:  # HTTPError:
        bot.say('The GitHub API returned an error.')
        return NOLIMIT

    data = json.loads(raw)
    bot.say('Added traceback to issue #%s. %s' % (number, data['html_url']))
    bot.debug(__file__, 'Traceback added to #%s in %s.' % (number, trigger.sender), 'warning')
Example #12
0
def paste(text, title="", format='text'):
   global pastebin_key

   response = web.post("http://pastebin.com/api/api_post.php", {
      'api_option': 'paste',
      'api_dev_key': pastebin_key,
      'api_paste_code': text.encode('utf-8'),
      'api_paste_private': '0',
      'api_paste_name': title.encode('utf-8'),
      'api_paste_expire_date': '1D',
      'api_paste_format': format
   })

   if len(response) > 200: raise IOError("Pastebin is not responding correctly")

   return response
Example #13
0
def latex(bot, trigger):
    #Request Body
    # formula=<FORMULA>&fsize=17px&fcolor=000000&mode=0&out=1&remhost=quicklatex.com&preamble=\usepackage{amsmath}\usepackage{amsfonts}\usepackage{amssymb}
    data = web.urlencode({
        'formula':
        trigger.group(2),
        'fsize':
        '25px',
        'fcolor':
        '000000',
        'mode':
        '0',
        'out':
        '1',
        'remhost':
        'quicklatex.com',
        'preamble':
        '\\usepackage{amsmath}\\usepackage{amsfonts}\\usepackage{amssymb}'
    }).encode('ascii')
    url = web.post('http://quicklatex.com/latex3.f', data).split()[1]
    bot.reply(web.get('http://is.gd/create.php?format=simple&url=' + url))
def shindan(bot, trigger):
    """
    .shindan <id> [name] - Do the shindanmaker thing! Will automatically translate japanese shindans to english. (Waifu id: 215100 | Teh_Colt's Drama Gen id: 490953)
    """
    if not trigger.group(3) or not trigger.group(3).isdigit() or int(trigger.group(3).strip()) < 2000:
        return bot.say(u'You must specify a shindanmaker ID (Waifu id: 215100 | T\u0081eh_Colt\'s Drama Gen id: 490953)')

    name = trigger.nick
    if (trigger.group(4)):
        name = trigger.group(4)
    data = web.urlencode({'u': name, 'from': ''}).encode('ascii')
    url = follow_redirects('http://en.shindanmaker.com/' + trigger.group(3).strip())
    try:
        soup = get_soup(web.post(url, data))
        shindan = soup.find(class_='result')
        if shindan is None:
            bot.say('The shindanmaker ID %s does not exist!' % (trigger.group(3).strip(), ))
        else:
            bot.say(shindan.text.strip())
    except Exception as e:
        bot.say('418 I\'m a teapot')
Example #15
0
def url_handler(bot, trigger):
    """ Check for malicious URLs """
    check = True  # Enable URL checking
    strict = False  # Strict mode: kick on malicious URL
    positives = 0  # Number of engines saying it's malicious
    total = 0  # Number of total engines
    use_vt = True  # Use VirusTotal
    if bot.config.has_section('safety'):
        check = bot.config.safety.enabled_by_default
        if check is None:
            # If not set, assume default
            check = True
        else:
            check = bool(check)
    # DB overrides config:
    setting = bot.db.get_channel_value(trigger.sender, 'safety')
    if setting is not None:
        if setting == 'off':
            return  # Not checking
        elif setting in ['on', 'strict', 'local', 'local strict']:
            check = True
        if setting == 'strict' or setting == 'local strict':
            strict = True
        if setting == 'local' or setting == 'local strict':
            use_vt = False

    if not check:
        return  # Not overriden by DB, configured default off

    netloc = urlparse(trigger).netloc
    if any(regex.search(netloc) for regex in known_good):
        return  # Whitelisted

    apikey = bot.config.safety.vt_api_key
    try:
        if apikey is not None and use_vt:
            payload = {
                'resource': unicode(trigger),
                'apikey': apikey,
                'scan': '1'
            }

            if trigger not in bot.memory['safety_cache']:
                result = web.post(vt_base_api_url + 'report', payload)
                if sys.version_info.major > 2:
                    result = result.decode('utf-8')
                result = json.loads(result)
                age = time.time()
                data = {
                    'positives': result['positives'],
                    'total': result['total'],
                    'age': age
                }
                bot.memory['safety_cache'][trigger] = data
                if len(bot.memory['safety_cache']) > 1024:
                    _clean_cache(bot)
            else:
                print('using cache')
                result = bot.memory['safety_cache'][trigger]
            positives = result['positives']
            total = result['total']
    except Exception as e:
        LOGGER.debug('Error from checking URL with VT.', exc_info=True)
        pass  # Ignoring exceptions with VT so MalwareDomains will always work

    if unicode(netloc).lower() in malware_domains:
        # malwaredomains is more trustworthy than some VT engines
        # therefor it gets a weight of 10 engines when calculating confidence
        positives += 10
        total += 10

    if positives > 1:
        # Possibly malicious URL detected!
        confidence = '{}%'.format(round((positives / total) * 100))
        msg = 'link posted by %s is possibliy malicious ' % bold(trigger.nick)
        msg += '(confidence %s - %s/%s)' % (confidence, positives, total)
        bot.say('[' + bold(color('WARNING', 'red')) + '] ' + msg)
        if strict:
            bot.write([
                'KICK', trigger.sender, trigger.nick, 'Posted a malicious link'
            ])
Example #16
0
def handle_auth_response():
    code = bottle.request.query.code
    state = bottle.request.query.state

    repo = state.split(":")[0]
    channel = state.split(":")[1]

    data = {
        "client_id": willie_instance.config.github.client_id,
        "client_secret": willie_instance.config.github.secret,
        "code": code,
    }
    raw = web.post("https://github.com/login/oauth/access_token", data, headers={"Accept": "application/json"})
    try:
        res = json.loads(raw)

        if "scope" not in res:
            raise ValueError("You've already completed authorization on this repo")
        if "write:repo_hook" not in res["scope"]:
            raise ValueError("You didn't allow read/write on repo hooks!")

        access_token = res["access_token"]

        data = {
            "name": "web",
            "active": "true",
            "events": ["*"],
            "config": {"url": "http://xpw.us/webhook", "content_type": "json"},
        }

        raw = web.post(
            "https://api.github.com/repos/{}/hooks?access_token={}".format(repo, access_token), json.dumps(data)
        )
        res = json.loads(raw)

        if "ping_url" not in res:
            if "errors" in res:
                raise ValueError(", ".join([error["message"] for error in res["errors"]]))
            else:
                raise ValueError("Webhook creation failed, try again.")

        raw, headers = web.get(res["ping_url"] + "?access_token={}".format(access_token), return_headers=True)

        title = "Done!"
        header = "Webhook setup complete!"
        body = "That was simple, right?! You should be seeing a completion message in {} any second now".format(channel)
        flair = "There's no way it was that easy... things are never this easy..."
    except Exception as e:
        title = "Error!"
        header = "Webhook setup failed!"
        body = "Please try using the link in {} again, something went wrong!".format(channel)
        flair = str(e)

    page = """
<!DOCTYPE html>
<html>
  <head>
    <title>{title}</title>
    <style>
      body {{
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
      }}
    </style>
  </head>
  <body>
    <h1>{header}</h1>
    <p>{body}</p>
    <small><em>{flair}</em></small>
  </body>
</html>
    """

    return page.format(title=title, header=header, body=body, flair=flair)
Example #17
0
def shorten_url(url):
    try:
        res, headers = web.post("http://git.io", "url=" + web.quote(url), return_headers=True)
        return headers["location"]
    except:
        return url
Example #18
0
def shorten_url(url):
    try:
        res, headers = web.post('http://git.io', 'url=' + web.quote(url), return_headers=True)
        return headers['location']
    except:
        return url
Example #19
0
def handle_auth_response():
    code = bottle.request.query.code
    state = bottle.request.query.state

    repo = state.split(':')[0]
    channel = state.split(':')[1]

    data = {'client_id': willie_instance.config.github.client_id,
             'client_secret': willie_instance.config.github.secret,
             'code': code}
    raw = web.post('https://github.com/login/oauth/access_token', data, headers={'Accept': 'application/json'})
    try:
        res = json.loads(raw)

        if 'scope' not in res:
            raise ValueError('You\'ve already completed authorization on this repo')
        if 'write:repo_hook' not in res['scope']:
            raise ValueError('You didn\'t allow read/write on repo hooks!')

        access_token = res['access_token']

        data = {
            "name": "web",
            "active": True,
            "events": ["*"],
            "config": {
                "url": "http://xpw.us/webhook",
                "content_type": "json"
            }
        }

        raw = web.post('https://api.github.com/repos/{}/hooks?access_token={}'.format(repo, access_token), json.dumps(data))
        res = json.loads(raw)

        if 'ping_url' not in res:
            if 'errors' in res:
                raise ValueError(', '.join([error['message'] for error in res['errors']]))
            else:
                raise ValueError('Webhook creation failed. If you\'re creating a webhook on an organization repo, please ensure you\'ve granted Inumuta IRC Bot access to the organization at https://github.com/settings/applications')

        raw, headers = web.get(res['ping_url'] + '?access_token={}'.format(access_token), return_headers=True)

        title = 'Done!'
        header = 'Webhook setup complete!'
        body = 'That was simple, right?! You should be seeing a completion message in {} any second now'.format(channel)
        flair = 'There\'s no way it was that easy... things are never this easy...'
    except Exception as e:
        title = 'Error!'
        header = 'Webhook setup failed!'
        body = 'Please try using the link in {} again, something went wrong!'.format(channel)
        flair = str(e)

    page = '''
<!DOCTYPE html>
<html>
  <head>
    <title>{title}</title>
    <style>
      body {{
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
      }}
    </style>
  </head>
  <body>
    <h1>{header}</h1>
    <p>{body}</p>
    <small><em>{flair}</em></small>
  </body>
</html>
    '''

    return page.format(title=title, header=header, body=body, flair=flair)
Example #20
0
def who(bot, trigger):
    sid = bot.getForumSID()
    whoText = web.post('http://www.crimbogrotto.com/mchat.php', 'mode=read&room_id=6&sid={0}'.format(sid))
    lastIDSoup = BeautifulSoup(whoText)
    whoMessage = lastIDSoup.find_all('div', class_='mChatHover')[-1].text
    bot.msg(trigger.nick, whoMessage.decode('utf-8'), relay=False)
Example #21
0
def url_handler(bot, trigger):
    """ Check for malicious URLs """
    check = True    # Enable URL checking
    strict = False  # Strict mode: kick on malicious URL
    positives = 0   # Number of engines saying it's malicious
    total = 0       # Number of total engines
    use_vt = True   # Use VirusTotal
    if bot.config.has_section('safety'):
        check = bot.config.safety.enabled_by_default
        if check is None:
            # If not set, assume default
            check = True
        else:
            check = bool(check)
    # DB overrides config:
    setting = bot.db.get_channel_value(trigger.sender, 'safety')
    if setting is not None:
        if setting == 'off':
            return  # Not checking
        elif setting in ['on', 'strict', 'local', 'local strict']:
            check = True
        if setting == 'strict' or setting == 'local strict':
            strict = True
        if setting == 'local' or setting == 'local strict':
            use_vt = False

    if not check:
        return  # Not overriden by DB, configured default off

    netloc = urlparse(trigger).netloc
    if any(regex.search(netloc) for regex in known_good):
        return  # Whitelisted

    apikey = bot.config.safety.vt_api_key
    try:
        if apikey is not None and use_vt:
            payload = {'resource': unicode(trigger),
                       'apikey': apikey,
                       'scan': '1'}

            if trigger not in bot.memory['safety_cache']:
                result = web.post(vt_base_api_url + 'report', payload)
                if sys.version_info.major > 2:
                    result = result.decode('utf-8')
                result = json.loads(result)
                age = time.time()
                data = {'positives': result['positives'],
                        'total': result['total'],
                        'age': age}
                bot.memory['safety_cache'][trigger] = data
                if len(bot.memory['safety_cache']) > 1024:
                    _clean_cache(bot)
            else:
                print('using cache')
                result = bot.memory['safety_cache'][trigger]
            positives = result['positives']
            total = result['total']
    except Exception as e:
        LOGGER.debug('Error from checking URL with VT.', exc_info=True)
        pass  # Ignoring exceptions with VT so MalwareDomains will always work

    if unicode(netloc).lower() in malware_domains:
        # malwaredomains is more trustworthy than some VT engines
        # therefor it gets a weight of 10 engines when calculating confidence
        positives += 10
        total += 10

    if positives > 1:
        # Possibly malicious URL detected!
        confidence = '{}%'.format(round((positives / total) * 100))
        msg = 'link posted by %s is possibliy malicious ' % bold(trigger.nick)
        msg += '(confidence %s - %s/%s)' % (confidence, positives, total)
        bot.say('[' + bold(color('WARNING', 'red')) + '] ' + msg)
        if strict:
            bot.write(['KICK', trigger.sender, trigger.nick,
                       'Posted a malicious link'])
Example #22
0
def postIRCWho(bot, trigger=None):
    sid = bot.getForumSID()
    users = bot.privileges['#crimbogrotto'].keys()
    web.post('http://www.crimbogrotto.com/mchat.php',
             'room_id=7&mode=add&sid={0}&message={1}'.format(sid, ', '.join(users)))
Example #23
0
def latex(bot, trigger):
    #Request Body
    # formula=<FORMULA>&fsize=17px&fcolor=000000&mode=0&out=1&remhost=quicklatex.com&preamble=\usepackage{amsmath}\usepackage{amsfonts}\usepackage{amssymb}
    data = web.urlencode({'formula': trigger.group(2), 'fsize': '25px', 'fcolor': '000000', 'mode': '0', 'out': '1', 'remhost': 'quicklatex.com', 'preamble': '\\usepackage{amsmath}\\usepackage{amsfonts}\\usepackage{amssymb}'}).encode('ascii')
    url = web.post('http://quicklatex.com/latex3.f', data).split()[1]
    bot.reply(web.get('http://is.gd/create.php?format=simple&url=' + url))
Example #24
0
    def msg(self, recipient, text, max_messages=1, relay=True):
        # We're arbitrarily saying that the max is 400 bytes of text when
        # messages will be split. Otherwise, we'd have to acocunt for the bot's
        # hostmask, which is hard.
        max_text_length = 400
        # Encode to bytes, for propper length calculation
        if isinstance(text, unicode):
            encoded_text = text.encode('utf-8')
        else:
            encoded_text = text
        excess = ''
        if max_messages > 1 and len(encoded_text) > max_text_length:
            last_space = encoded_text.rfind(' ', 0, max_text_length)
            if last_space == -1:
                excess = encoded_text[max_text_length:]
                encoded_text = encoded_text[:max_text_length]
            else:
                excess = encoded_text[last_space + 1:]
                encoded_text = encoded_text[:last_space]
        # We'll then send the excess at the end
        # Back to unicode again, so we don't screw things up later.
        text = encoded_text.decode('utf-8')
        try:
            self.sending.acquire()

            # No messages within the last 3 seconds? Go ahead!
            # Otherwise, wait so it's been at least 0.8 seconds + penalty

            recipient_id = Nick(recipient)

            if recipient_id not in self.stack:
                self.stack[recipient_id] = []
            elif self.stack[recipient_id]:
                elapsed = time.time() - self.stack[recipient_id][-1][0]
                if elapsed < 3:
                    penalty = float(max(0, len(text) - 50)) / 70
                    wait = 0.7 + penalty
                    if elapsed < wait:
                        time.sleep(wait - elapsed)

                # Loop detection
                messages = [m[1] for m in self.stack[recipient_id][-8:]]

                # If what we about to send repeated at least 5 times in the
                # last 2 minutes, replace with '...'
                if messages.count(text) >= 5 and elapsed < 120:
                    text = '...'
                    if messages.count('...') >= 3:
                        # If we said '...' 3 times, discard message
                        return

            self.write(('PRIVMSG', recipient), text)
            self.stack[recipient_id].append((time.time(), self.safe(text)))
            self.stack[recipient_id] = self.stack[recipient_id][-10:]
        finally:
            self.sending.release()
        if recipient == "#crimbogrotto" and relay:
                forumsid = self.getForumSID()
                mchatmessage = web.quote("[b]CGBot:[/b] "+text)
                web.post("http://www.crimbogrotto.com/mchat.php","room_id=0&mode=add&sid="+forumsid+"&message="+mchatmessage)
        # Now that we've sent the first part, we need to send the rest. Doing
        # this recursively seems easier to me than iteratively
        if excess:
            self.msg(recipient, excess, max_messages - 1, relay)
Example #25
0
 def forumLogin(bot):
     text = web.post( "http://www.crimbogrotto.com/ucp.php?","mode=login&username=CGIRC&password="******"&redirect=./ucp.php?mode=login&redirect=index.php&login=Login");
     SIDMatch = re.search( r'\?sid=([^"]+)"',text )
     bot.cachedSID = SIDMatch.group(1)
     bot.lastSIDUpdate = datetime.now()
     return bot.cachedSID
Example #26
0
def handle_auth_response():
    code = bottle.request.query.code
    state = bottle.request.query.state

    repo = state.split(':')[0]
    channel = state.split(':')[1]

    data = {
        'client_id': willie_instance.config.github.client_id,
        'client_secret': willie_instance.config.github.secret,
        'code': code
    }
    raw = web.post('https://github.com/login/oauth/access_token',
                   data,
                   headers={'Accept': 'application/json'})
    try:
        res = json.loads(raw)

        if 'scope' not in res:
            raise ValueError(
                'You\'ve already completed authorization on this repo')
        if 'write:repo_hook' not in res['scope']:
            raise ValueError('You didn\'t allow read/write on repo hooks!')

        access_token = res['access_token']

        data = {
            "name": "web",
            "active": "true",
            "events": ["*"],
            "config": {
                "url": "http://xpw.us/webhook",
                "content_type": "json"
            }
        }

        raw = web.post(
            'https://api.github.com/repos/{}/hooks?access_token={}'.format(
                repo, access_token), json.dumps(data))
        res = json.loads(raw)

        if 'ping_url' not in res:
            if 'errors' in res:
                raise ValueError(', '.join(
                    [error['message'] for error in res['errors']]))
            else:
                raise ValueError('Webhook creation failed, try again.')

        raw, headers = web.get(res['ping_url'] +
                               '?access_token={}'.format(access_token),
                               return_headers=True)

        title = 'Done!'
        header = 'Webhook setup complete!'
        body = 'That was simple, right?! You should be seeing a completion message in {} any second now'.format(
            channel)
        flair = 'There\'s no way it was that easy... things are never this easy...'
    except Exception as e:
        title = 'Error!'
        header = 'Webhook setup failed!'
        body = 'Please try using the link in {} again, something went wrong!'.format(
            channel)
        flair = str(e)

    page = '''
<!DOCTYPE html>
<html>
  <head>
    <title>{title}</title>
    <style>
      body {{
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
      }}
    </style>
  </head>
  <body>
    <h1>{header}</h1>
    <p>{body}</p>
    <small><em>{flair}</em></small>
  </body>
</html>
    '''

    return page.format(title=title, header=header, body=body, flair=flair)
Example #27
0
def hastebin_it(text):
    raw = web.post('http://hastebin.com/documents', text)
    return u'http://hastebin.com/raw/' + json.loads(raw)['key']