<commit_before>#!/usr/bin/env python3
# coding: utf-8

from wxpy import *
import re

'''
使用 cache 来缓存登陆信息，同时使用控制台登陆
'''
bot = Bot('bot.pkl', console_qr=True)

'''
开启 PUID 用于后续的控制
'''
bot.enable_puid('wxpy_puid.pkl')

'''
邀请信息处理
'''
rp_new_member_name = (
    re.compile(r'^"(.+)"通过'),
    re.compile(r'邀请"(.+)"加入'),
)

'''
为保证兼容，在下方admins中使用标准用法
在 admin_puids 中确保将机器人的puid 加入
机器人的puid 可以通过 bot.self.puid 获得
其他用户的PUID 可以通过 执行 export_puid.py 生成 data 文件，在data 文件中获取
'''
admin_puids = (
    '8b8b7560',
    '69f27236'
)

'''
定义需要管理的群
群的PUID 可以通过 执行 export_puid.py 生成 data 文件，在data 文件中获取
'''
group_puids = (
     '6a698e9c',
 )

# 格式化 Group
groups = list(map(lambda x: bot.groups().search(puid=x)[0], group_puids))
# 格式化 Admin
admins = list(map(lambda x: bot.friends().search(puid=x)[0], admin_puids))

# 新人入群的欢迎语
welcome_text = '''🎉 欢迎 @{} 的加入！
😃 有问题请私聊 @Linux中国
'''

invite_text = """欢迎您，我是 Linux 中国 微信群助手，
请输入如下关键字加入群：
运维 开发 嵌入式  运维密码 学生 机器人 安全
DBA PHP Python Golang Docker LFS
进群四件事：
1、阅读群公告，
2、修改群名片，
3、做自我介绍，
4、发个总计一元、一百份的红包
请言行遵守群内规定，违规者将受到处罚，拉入黑名单。"""

'''
设置群组关键词和对应群名
* 关键词必须为小写，查询时会做相应的小写处理
'''
keyword_of_group = {
    "lfs":"Linux中国◆LFS群",
    "dba":"Linux中国◆DBA群"
}

# 远程踢人命令: 移出 @<需要被移出的人>
rp_kick = re.compile(r'^移出\s*@(.+?)(?:\u2005?\s*$)')

'''
地区群
'''
city_group = {
    "北京":"Linux中国◆北京群",
    "上海":"Linux中国◆上海群",
    "广州":"Linux中国◆广州群",
}

female_group="Linux中国◆技术美女群"

# 下方为函数定义

'''
条件邀请
'''
def condition_invite(user):
    if user.sex == 2:
        female_groups = bot.groups().search(female_group)[0]
        try:
            female_groups.add_members(user, use_invitation=True)
            pass
        except:
            pass
    if (user.province in city_group.keys() or user.city in city_group.keys()):
        try:
            target_city_group = bot.groups().search(city_group[user.province])[0]
            pass
        except:
            target_city_group = bot.groups().search(city_group[user.city])[0]
            pass
        try:
            if user not in target_city_group:
                target_city_group.add_members(user, use_invitation=True)
        except:
            pass

'''
判断消息发送者是否在管理员列表
'''
def from_admin(msg):
    """
    判断 msg 中的发送用户是否为管理员
    :param msg:
    :return:
    """
    if not isinstance(msg, Message):
        raise TypeError('expected Message, got {}'.format(type(msg)))
    from_user = msg.member if isinstance(msg.chat, Group) else msg.sender
    print(admins)
    return from_user in admins

'''
远程踢人命令
'''
def remote_kick(msg):
    if msg.type is TEXT:
        match = rp_kick.search(msg.text)
        if match:
            name_to_kick = match.group(1)

            if not from_admin(msg):
                return '感觉有点不对劲… @{}'.format(msg.member.name)

            member_to_kick = ensure_one(list(filter(
                lambda x: x.name == name_to_kick, msg.chat)))
            if member_to_kick  == bot.self:
                return '无法移出 @{}'.format(member_to_kick.name)
            if member_to_kick in admins:
                return '无法移出 @{}'.format(member_to_kick.name)

            member_to_kick.remove()
            return '成功移出 @{}'.format(member_to_kick.name)

'''
邀请消息处理
'''
def get_new_member_name(msg):
    # itchat 1.2.32 版本未格式化群中的 Note 消息
    from itchat.utils import msg_formatter
    msg_formatter(msg.raw, 'Text')

    for rp in rp_new_member_name:
        match = rp.search(msg.text)
        if match:
            return match.group(1)

'''
定义邀请用户的方法。
按关键字搜索相应的群，如果存在相应的群，就向用户发起邀请。
'''
def invite(user, keyword):
    group = bot.groups().search(keyword_of_group[keyword])
    print(len(group))
    if len(group) > 0:
        target_group = ensure_one(group)
        if user in target_group:
            content = "您已经加入了{} [微笑]".format(target_group.nick_name)
            user.send(content)
        else:
            try:
                target_group.add_members(user, use_invitation=True)
            except:
                user.send("邀请错误！机器人邀请好友进群以达当日限制。请您明日再试")
    else:
        user.send("该群状态有误，您换个关键词试试？")

# 下方为消息处理

'''
处理加好友请求信息。
如果验证信息文本是字典的键值之一，则尝试拉群。
'''
@bot.register(msg_types=FRIENDS)
def new_friends(msg):
    user = msg.card.accept()
    if msg.text.lower() in keyword_of_group.keys():
        invite(user, msg.text.lower())
    else:
        return invite_text

@bot.register(Friend, msg_types=TEXT)
def exist_friends(msg):
    if msg.text.lower() in keyword_of_group.keys():
        invite(msg.sender, msg.text.lower())
    else:
        return invite_text

# 管理群内的消息处理
@bot.register(groups, except_self=False)
def wxpy_group(msg):
    ret_msg = remote_kick(msg)
    if ret_msg:
        return ret_msg
    elif msg.is_at:
        pass

@bot.register(groups, NOTE)
def welcome(msg):
    name = get_new_member_name(msg)
    if name:
        return welcome_text.format(name)

embed()
<commit_msg>修改部分文案<commit_after>#!/usr/bin/env python3
# coding: utf-8

from wxpy import *
import re

'''
使用 cache 来缓存登陆信息，同时使用控制台登陆
'''
bot = Bot('bot.pkl', console_qr=True)

'''
开启 PUID 用于后续的控制
'''
bot.enable_puid('wxpy_puid.pkl')

'''
邀请信息处理
'''
rp_new_member_name = (
    re.compile(r'^"(.+)"通过'),
    re.compile(r'邀请"(.+)"加入'),
)

'''
为保证兼容，在下方admins中使用标准用法
在 admin_puids 中确保将机器人的puid 加入
机器人的puid 可以通过 bot.self.puid 获得
其他用户的PUID 可以通过 执行 export_puid.py 生成 data 文件，在data 文件中获取
'''
admin_puids = (
    '8b8b7560',
    '69f27236'
)

'''
定义需要管理的群
群的PUID 可以通过 执行 export_puid.py 生成 data 文件，在data 文件中获取
'''
group_puids = (
     '6a698e9c',
 )

# 格式化 Group
groups = list(map(lambda x: bot.groups().search(puid=x)[0], group_puids))
# 格式化 Admin
admins = list(map(lambda x: bot.friends().search(puid=x)[0], admin_puids))

# 新人入群的欢迎语
welcome_text = '''🎉 欢迎 @{} 的加入！
😃 有问题请私聊我。
'''

invite_text = """欢迎您，我是「Linux 中国」微信群助手，
请输入如下关键字加入群：
- 运维 开发 安全 嵌入式 学生
- 运维密码  机器人
- DBA PHP Python Golang Docker LFS
进群四件事：
1、阅读群公告，
2、修改群名片，
3、做自我介绍，
4、发个总计一元、一百份的红包
请言行遵守群内规定，违规者将受到处罚，拉入黑名单。"""

'''
设置群组关键词和对应群名
* 关键词必须为小写，查询时会做相应的小写处理
'''
keyword_of_group = {
    "lfs":"Linux中国◆LFS群",
    "dba":"Linux中国◆DBA群"
}

# 远程踢人命令: 移出 @<需要被移出的人>
rp_kick = re.compile(r'^[移出|移除|踢出|拉黑]\s*@(.+?)(?:\u2005?\s*$)')

'''
地区群
'''
city_group = {
    "北京":"Linux中国◆北京群",
    "上海":"Linux中国◆上海群",
    "广州":"Linux中国◆广州群",
}

female_group="Linux中国◆技术美女群"

# 下方为函数定义

'''
条件邀请
'''
def condition_invite(user):
    if user.sex == 2:
        female_groups = bot.groups().search(female_group)[0]
        try:
            female_groups.add_members(user, use_invitation=True)
            pass
        except:
            pass
    if (user.province in city_group.keys() or user.city in city_group.keys()):
        try:
            target_city_group = bot.groups().search(city_group[user.province])[0]
            pass
        except:
            target_city_group = bot.groups().search(city_group[user.city])[0]
            pass
        try:
            if user not in target_city_group:
                target_city_group.add_members(user, use_invitation=True)
        except:
            pass

'''
判断消息发送者是否在管理员列表
'''
def from_admin(msg):
    """
    判断 msg 中的发送用户是否为管理员
    :param msg:
    :return:
    """
    if not isinstance(msg, Message):
        raise TypeError('expected Message, got {}'.format(type(msg)))
    from_user = msg.member if isinstance(msg.chat, Group) else msg.sender
    print(admins)
    return from_user in admins

'''
远程踢人命令
'''
def remote_kick(msg):
    if msg.type is TEXT:
        match = rp_kick.search(msg.text)
        if match:
            name_to_kick = match.group(1)

            if not from_admin(msg):
                return '感觉有点不对劲… @{}'.format(msg.member.name)

            member_to_kick = ensure_one(list(filter(
                lambda x: x.name == name_to_kick, msg.chat)))
            if member_to_kick  == bot.self:
                return '无法移出 @{}'.format(member_to_kick.name)
            if member_to_kick in admins:
                return '无法移出 @{}'.format(member_to_kick.name)

            member_to_kick.remove()
            return '成功移出 @{}'.format(member_to_kick.name)

'''
邀请消息处理
'''
def get_new_member_name(msg):
    # itchat 1.2.32 版本未格式化群中的 Note 消息
    from itchat.utils import msg_formatter
    msg_formatter(msg.raw, 'Text')

    for rp in rp_new_member_name:
        match = rp.search(msg.text)
        if match:
            return match.group(1)

'''
定义邀请用户的方法。
按关键字搜索相应的群，如果存在相应的群，就向用户发起邀请。
'''
def invite(user, keyword):
    group = bot.groups().search(keyword_of_group[keyword])
    print(len(group))
    if len(group) > 0:
        target_group = ensure_one(group)
        if user in target_group:
            content = "您已经加入了 {} [微笑]".format(target_group.nick_name)
            user.send(content)
        else:
            try:
                target_group.add_members(user, use_invitation=True)
            except:
                user.send("邀请错误！机器人邀请好友进群已达当日限制。请您明日再试")
    else:
        user.send("该群状态有误，您换个关键词试试？")

# 下方为消息处理

'''
处理加好友请求信息。
如果验证信息文本是字典的键值之一，则尝试拉群。
'''
@bot.register(msg_types=FRIENDS)
def new_friends(msg):
    user = msg.card.accept()
    if msg.text.lower() in keyword_of_group.keys():
        invite(user, msg.text.lower())
    else:
        return invite_text

@bot.register(Friend, msg_types=TEXT)
def exist_friends(msg):
    if msg.text.lower() in keyword_of_group.keys():
        invite(msg.sender, msg.text.lower())
    else:
        return invite_text

# 管理群内的消息处理
@bot.register(groups, except_self=False)
def wxpy_group(msg):
    ret_msg = remote_kick(msg)
    if ret_msg:
        return ret_msg
    elif msg.is_at:
        pass

@bot.register(groups, NOTE)
def welcome(msg):
    name = get_new_member_name(msg)
    if name:
        return welcome_text.format(name)

embed()
<|endoftext|>


<commit_before>import praw, time
from Search&Respond.py import words, response
import sqlite3

#Building up the framework, still a work in progress

r = praw.Reddit("HelpfulBot by /u/UnknownDeveloper and /u/___NOT_A_BOT___")
o = OAuth2Util.OAuth2Util(r)
o.refresh(force=True)

print("Database opening")
found = sqlite3.connect('answered.db') #create a database w/SQLite3 python library
x = found.cursor()
x.execute('CREATE TABLE IF NOT EXISTS answered(COMMENT ID TEXT, SUBMISSION ID TEXT)')
found.commit()

print("Starting up and loggin in to Reddit")
sub = 'test'

def comment_reply():
	subreddit = r.get_subreddit(sub)
	comments = subreddit.get_comments(limit=100)
	for comment in comments:
	    x.execute('SELECT * FROM answered WHERE ID=?', [comment.id])
	    if not x.fetchone():
	    	try:
    		    author = comment.author.name
    		    if author.lower() != username.lower():
    		        comment_text = comment.body.lower()
    		        r.send_message("___NOT_A_BOT___", "Response", "Comment answered")
    	    	    match = any(string in comment_text for string in words)
    		        if match:
    				print("Replying to " + author)
      			    comment.reply(response)
      	    	except AttributeError:
      		    	pass

      		x.execute('INSERT INTO answered VALUES(?)', [commend.id])
      		found.commit()

def submission_reply():
	submissions = r.get_subreddit(sub).get_new(limit=50)
	for submission in submissions:
		x.execute('SELECT * FROM answered WHERE ID=?,' [submission.id]
		if not x.fetchone():
			try:
				author = submission.author.name
				if author.lower() != username.lower():
					submission_text = submission.text.lower()
					r.send_message("___NOT_A_BOT___", "Response", "Submission answered")
					match = any(string in submission_text for string in words)
					if match:
						print("Replying to " + author)
						comment.reply(response)
			except AttributeError:
				pass
			x.execute('INSERT INTO answered VALUES(?)', [submission.id])
			found.commit()

while True:
  	comment_reply()
  	submission_reply()
  	time.sleep(10)

<commit_msg>Fixed starting message<commit_after>import praw, time
from Search&Respond.py import words, response
import sqlite3

#Building up the framework, still a work in progress
print("Starting up and loggin in to Reddit...")
r = praw.Reddit("HelpfulBot by /u/UnknownDeveloper and /u/___NOT_A_BOT___")
o = OAuth2Util.OAuth2Util(r)
o.refresh(force=True)

print("Database opening")
found = sqlite3.connect('answered.db') #create a database w/SQLite3 python library
x = found.cursor()
x.execute('CREATE TABLE IF NOT EXISTS answered(COMMENT ID TEXT, SUBMISSION ID TEXT)')
found.commit()

sub = 'test'

def comment_reply():
	subreddit = r.get_subreddit(sub)
	comments = subreddit.get_comments(limit=100)
	for comment in comments:
	    x.execute('SELECT * FROM answered WHERE ID=?', [comment.id])
	    if not x.fetchone():
	    	try:
    		    author = comment.author.name
    		    if author.lower() != username.lower():
    		        comment_text = comment.body.lower()
    		        r.send_message("___NOT_A_BOT___", "Response", "Comment answered")
    	    	    match = any(string in comment_text for string in words)
    		        if match:
    				print("Replying to " + author)
      			    comment.reply(response)
      	    	except AttributeError:
      		    	pass

      		x.execute('INSERT INTO answered VALUES(?)', [commend.id])
      		found.commit()

def submission_reply():
	submissions = r.get_subreddit(sub).get_new(limit=50)
	for submission in submissions:
		x.execute('SELECT * FROM answered WHERE ID=?,' [submission.id]
		if not x.fetchone():
			try:
				author = submission.author.name
				if author.lower() != username.lower():
					submission_text = submission.text.lower()
					r.send_message("___NOT_A_BOT___", "Response", "Submission answered")
					match = any(string in submission_text for string in words)
					if match:
						print("Replying to " + author)
						comment.reply(response)
			except AttributeError:
				pass
			x.execute('INSERT INTO answered VALUES(?)', [submission.id])
			found.commit()

while True:
  	comment_reply()
  	submission_reply()
  	time.sleep(10)

<|endoftext|>


<commit_before>from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, InlineQueryHandler, Job
import telegram
from telegram import InlineQueryResultArticle, ParseMode, \
    InputTextMessageContent
import urllib2
import os
import keys
import random
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick2_ochl
import json
import matplotlib.ticker as ticker
import datetime as datetime
from pytz import timezone
import pytz

import logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)

def get_coin_list():
    response = urllib2.urlopen('https://www.cryptocompare.com/api/data/coinlist/')
    coin_list = json.load(response)['Data']

    coin_dict = {}

    for sym, coin in coin_list.iteritems():
        coin_dict[coin['Name'].strip().lower()] = sym
        coin_dict[coin['CoinName'].strip().lower()] = sym

    return coin_dict

# def price(bot, update):
#     # TODO catch error and tell user they fucked up
#     coin = coin_list[update.message.text[3:].lower()]
#     usd, btc, day = get_price(coin)

#     bot.send_message(chat_id=update.message.chat_id,
#                      text="""
# {}:
# USD: {}
# BTC: {}
# 24h: {}%
#                           """.format(coin, usd, btc, day),
#                      parse_mode=telegram.ParseMode.HTML)
def price(bot, update):
    coin = update.message.text[3:]

    name, symbol, usd, btc, hour, day = get_price(coin)

    bot.send_message(chat_id=update.message.chat_id,
                     text="""
{} ({}):
USD: ${}
BTC: {}
1h: {}%
24h: {}%
                          """.format(name, symbol, usd, btc, hour, day),
                          parse_mode=telegram.ParseMode.HTML)

def get_price(coin):
    response = urllib2.urlopen('https://api.coinmarketcap.com/v1/ticker/')
    price_data = json.load(response)

    coin = coin.lower()

    for data in price_data:
        if data['name'].lower() == coin or \
           data['id'].lower() == coin or \
           data['symbol'].lower() == coin:
            return data['name'], \
                   data['symbol'], \
                   data['price_usd'], \
                   data['price_btc'], \
                   data['percent_change_1h'], \
                   data['percent_change_24h']

def cap(bot,update):
    coin = coin_list[update.message.text[5:].lower()]

    response = urllib2.urlopen('https://min-api.cryptocompare.com/data/pricemultifull?fsyms={}&tsyms=BTC,USD'.format(coin))
    cap = json.load(response)['DISPLAY'][coin]['USD']['MKTCAP']

    bot.send_message(chat_id=update.message.chat_id,
                     text="Market Cap ({})\n{}".format(coin, cap),
                     parse_mode=telegram.ParseMode.HTML)

# huhlol this doesnt even need to be a method, it was originally to clean it up
# but this is fine
# def get_price(coin):
#     response = urllib2.urlopen('https://min-api.cryptocompare.com/data/pricemultifull?fsyms={}&tsyms=BTC,USD'.format(coin))

#     price_data = json.load(response)
#     usd_price_data = price_data['DISPLAY'][coin]['USD']
#     btc_price_data = price_data['RAW'][coin]['BTC']

#     return usd_price_data['PRICE'].replace(' ',''), \
#            btc_price_data['PRICE'], \
#            usd_price_data['CHANGEPCT24HOUR']

def three_chart(bot,update):
    coin = coin_list[update.message.text[4:].lower()]

    response = urllib2.urlopen('https://min-api.cryptocompare.com/data/histohour?fsym={}&tsym=USD&limit=72&aggregate=3&e=CCCAGG'.format(coin))
    data = json.load(response)['Data']

    chart = gen_chart(data, coin, 6)

    bot.send_photo(chat_id=update.message.chat_id,
                   photo=open('tmp.png'))

def sixty_chart(bot,update):
    coin = coin_list[update.message.text[5:].lower()]
    response = urllib2.urlopen('https://min-api.cryptocompare.com/data/histoday?fsym={}&tsym=USD&limit=60&aggregate=3&e=CCCAGG'.format(coin))
    data = json.load(response)['Data']
    chart = gen_chart(data, coin, 10)

    bot.send_photo(chat_id=update.message.chat_id,
                   photo=open('tmp.png'))

def day_chart(bot,update):
    coin = coin_list[update.message.text[3:].lower()]
    response = urllib2.urlopen('https://min-api.cryptocompare.com/data/histohour?fsym={}&tsym=USD&limit=24&aggregate=3&e=CCCAGG'.format(coin))
    data = json.load(response)['Data']
    chart = gen_chart(data, coin, 12)

    bot.send_photo(chat_id=update.message.chat_id,
                   photo=open('tmp.png'))

def tracker_callback(bot, job):
    now_resp = urllib2.urlopen('https://min-api.cryptocompare.com/data/pricemultifull?fsyms={}&tsyms=BTC,USD'.format(job.context["coin"]))
    now_data = json.load(now_resp)['RAW'][job.context['coin']]['USD']
    now_price = now_data['PRICE']
    now_time = now_data['LASTUPDATE']

    hour_time = now_time - 3600
    hour_resp = urllib2.urlopen('https://min-api.cryptocompare.com/data/pricehistorical?fsym={}&tsyms=BTC,USD&ts={}'.format(job.context["coin"], hour_time))
    hour_price = json.load(hour_resp)[job.context['coin']]['USD']
    #hour_price = json.load(hour_resp)
    print hour_price

    difference = now_price - hour_price
    percent = difference / hour_price
    print "percent {}, coin {}".format(percent, job.context['coin'])

    if percent < .05 and percent > -.05:
        jobs[job.context["coin"]] = jq.run_once(tracker_callback, 300, job.context)
    elif (percent > .05 and percent < .1) or (percent < -.05 and percent > -.1):
        jobs[job.context["coin"]] = jq.run_once(tracker_callback, 7200, job.context)
        track_response(bot, job.context["update"], job.context["coin"], percent, difference)
    elif percent > .1 or percent < -.1:
        jobs[job.context["coin"]] = jq.run_once(tracker_callback, 7200, job.context)
        track_response(bot, job.context["update"], job.context["coin"], percent, difference)

def track(bot, update):
    coin = coin_list[update.message.text[3:].lower()]
    try:
        job = jobs[coin]
    except KeyError:
        jobs[coin] = jq.run_once(tracker_callback, 0, context={"coin": coin, "update": update})
        bot.send_message(chat_id=update.message.chat_id,
                         text="Now tracking {}".format(coin))

def track_response(bot, update, coin, percent, difference):
    print "track response called for coin {} with 1hr change of {}%".format(coin, percent)
    response = "up"
    if percent < 0:
        response = "down"

    bot.send_message(chat_id=update.message.chat_id,
                    text="{} Has gone {} {:.2%} (${:.2}) in the last 1hr".format(coin,response,percent, difference))

def gen_chart(data, coin, numdisp):
    close = [d['close'] for d in data]
    opens = [d['open'] for d in data]
    high = [d['high'] for d in data]
    low = [d['low'] for d in data]
    dates = [d['time'] for d in data]

    fig, ax = plt.subplots()

    fig.patch.set_facecolor('#2f3d45')

    ax.set_facecolor('#2f3d45')
    ax.xaxis.label.set_color('white')
    ax.yaxis.label.set_color('white')

    ax.spines['top'].set_alpha(0)
    ax.spines['right'].set_alpha(0)
    ax.spines['bottom'].set_color('w')
    ax.spines['left'].set_color('w')

    plt.ylabel('Price of {} in USD'.format(coin))

    ax.tick_params(axis='x', colors='white')
    ax.tick_params(axis='y', colors='white')

    def mydate(x,pos):
        try:
            return xdate[int(x)]
        except IndexError:
            print "error"
            return ''

    candlestick2_ochl(ax, opens, close, high, low, width=.7, colordown='#f22800', colorup='#00ce03', alpha=.75)

    xdate = [datetime.datetime.fromtimestamp(d, tz=pytz.utc).astimezone(timezone('US/Pacific')).strftime("%d/%m/%y %I:%M%p GMT") for d in dates]

    ax.xaxis.set_major_locator(ticker.MaxNLocator(numdisp))
    ax.xaxis.set_major_formatter(ticker.FuncFormatter(mydate))
    fig.autofmt_xdate()
    fig.tight_layout()

    fig.savefig('tmp.png', facecolor='#2f3d45')

updater = Updater(keys.bot_key)

jobs = {}
coin_list = get_coin_list()
print "built coin list"

jq = updater.job_queue
dp = updater.dispatcher

# Crypto Handlers
dp.add_handler(CommandHandler('p', price))
dp.add_handler(CommandHandler('cap', cap))
dp.add_handler(CommandHandler('c', day_chart))
dp.add_handler(CommandHandler('c3', three_chart))
dp.add_handler(CommandHandler('c60', sixty_chart))
dp.add_handler(CommandHandler('t', track))

updater.start_polling()
updater.idle()
<commit_msg>price: bitcoin symbol. Bold symbol name and rounded bitcoin<commit_after>from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, InlineQueryHandler, Job
import telegram
from telegram import InlineQueryResultArticle, ParseMode, \
    InputTextMessageContent
import urllib2
import os
import keys
import random
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick2_ochl
import json
import matplotlib.ticker as ticker
import datetime as datetime
from pytz import timezone
import pytz

import logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)

def get_coin_list():
    response = urllib2.urlopen('https://www.cryptocompare.com/api/data/coinlist/')
    coin_list = json.load(response)['Data']

    coin_dict = {}

    for sym, coin in coin_list.iteritems():
        coin_dict[coin['Name'].strip().lower()] = sym
        coin_dict[coin['CoinName'].strip().lower()] = sym

    return coin_dict

# def price(bot, update):
#     # TODO catch error and tell user they fucked up
#     coin = coin_list[update.message.text[3:].lower()]
#     usd, btc, day = get_price(coin)

#     bot.send_message(chat_id=update.message.chat_id,
#                      text="""
# {}:
# USD: {}
# BTC: {}
# 24h: {}%
#                           """.format(coin, usd, btc, day),
#                      parse_mode=telegram.ParseMode.HTML)
def price(bot, update):
    coin = update.message.text[3:]

    name, symbol, usd, btc, hour, day = get_price(coin)
    # TODO MAKE THIS BETTER
    btc = round(float(btc),6)

    prices = u"""
{} ({}):
USD: ${}
BTC: \u0243{}
1h: {}%
24h: {}%
                          """.format(name, symbol, usd, btc, hour, day)

    bot.send_message(chat_id=update.message.chat_id,
                     text=prices,
                     parse_mode=telegram.ParseMode.HTML)

def get_price(coin):
    response = urllib2.urlopen('https://api.coinmarketcap.com/v1/ticker/')
    price_data = json.load(response)

    coin = coin.lower()

    for data in price_data:
        if data['name'].lower() == coin or \
           data['id'].lower() == coin or \
           data['symbol'].lower() == coin:
            return data['name'], \
                   data['symbol'], \
                   data['price_usd'], \
                   data['price_btc'], \
                   data['percent_change_1h'], \
                   data['percent_change_24h']

def cap(bot,update):
    coin = coin_list[update.message.text[5:].lower()]

    response = urllib2.urlopen('https://min-api.cryptocompare.com/data/pricemultifull?fsyms={}&tsyms=BTC,USD'.format(coin))
    cap = json.load(response)['DISPLAY'][coin]['USD']['MKTCAP']

    bot.send_message(chat_id=update.message.chat_id,
                     text="Market Cap ({})\n{}".format(coin, cap),
                     parse_mode=telegram.ParseMode.HTML)

# huhlol this doesnt even need to be a method, it was originally to clean it up
# but this is fine
def get_price(coin):
    response = urllib2.urlopen('https://min-api.cryptocompare.com/data/pricemultifull?fsyms={}&tsyms=BTC,USD'.format(coin))

    price_data = json.load(response)
    usd_price_data = price_data['DISPLAY'][coin]['USD']
    btc_price_data = price_data['RAW'][coin]['BTC']

    return usd_price_data['PRICE'].replace(' ',''), \
           btc_price_data['PRICE'], \
           usd_price_data['CHANGEPCT24HOUR']

def three_chart(bot,update):
    coin = coin_list[update.message.text[4:].lower()]

    response = urllib2.urlopen('https://min-api.cryptocompare.com/data/histohour?fsym={}&tsym=USD&limit=72&aggregate=3&e=CCCAGG'.format(coin))
    data = json.load(response)['Data']

    chart = gen_chart(data, coin, 6)

    bot.send_photo(chat_id=update.message.chat_id,
                   photo=open('tmp.png'))

def sixty_chart(bot,update):
    coin = coin_list[update.message.text[5:].lower()]
    response = urllib2.urlopen('https://min-api.cryptocompare.com/data/histoday?fsym={}&tsym=USD&limit=60&aggregate=3&e=CCCAGG'.format(coin))
    data = json.load(response)['Data']
    chart = gen_chart(data, coin, 10)

    bot.send_photo(chat_id=update.message.chat_id,
                   photo=open('tmp.png'))

def day_chart(bot,update):
    coin = coin_list[update.message.text[3:].lower()]
    response = urllib2.urlopen('https://min-api.cryptocompare.com/data/histohour?fsym={}&tsym=USD&limit=24&aggregate=3&e=CCCAGG'.format(coin))
    data = json.load(response)['Data']
    chart = gen_chart(data, coin, 12)

    bot.send_photo(chat_id=update.message.chat_id,
                   photo=open('tmp.png'))

def tracker_callback(bot, job):
    now_resp = urllib2.urlopen('https://min-api.cryptocompare.com/data/pricemultifull?fsyms={}&tsyms=BTC,USD'.format(job.context["coin"]))
    now_data = json.load(now_resp)['RAW'][job.context['coin']]['USD']
    now_price = now_data['PRICE']
    now_time = now_data['LASTUPDATE']

    hour_time = now_time - 3600
    hour_resp = urllib2.urlopen('https://min-api.cryptocompare.com/data/pricehistorical?fsym={}&tsyms=BTC,USD&ts={}'.format(job.context["coin"], hour_time))
    hour_price = json.load(hour_resp)[job.context['coin']]['USD']
    #hour_price = json.load(hour_resp)
    print hour_price

    difference = now_price - hour_price
    percent = difference / hour_price
    print "percent {}, coin {}".format(percent, job.context['coin'])

    if percent < .05 and percent > -.05:
        jobs[job.context["coin"]] = jq.run_once(tracker_callback, 300, job.context)
    elif (percent > .05 and percent < .1) or (percent < -.05 and percent > -.1):
        jobs[job.context["coin"]] = jq.run_once(tracker_callback, 7200, job.context)
        track_response(bot, job.context["update"], job.context["coin"], percent, difference)
    elif percent > .1 or percent < -.1:
        jobs[job.context["coin"]] = jq.run_once(tracker_callback, 7200, job.context)
        track_response(bot, job.context["update"], job.context["coin"], percent, difference)

def track(bot, update):
    coin = coin_list[update.message.text[3:].lower()]
    try:
        job = jobs[coin]
    except KeyError:
        jobs[coin] = jq.run_once(tracker_callback, 0, context={"coin": coin, "update": update})
        bot.send_message(chat_id=update.message.chat_id,
                         text="Now tracking {}".format(coin))

def track_response(bot, update, coin, percent, difference):
    print "track response called for coin {} with 1hr change of {}%".format(coin, percent)
    response = "up"
    if percent < 0:
        response = "down"

    bot.send_message(chat_id=update.message.chat_id,
                    text="{} Has gone {} {:.2%} (${:.2}) in the last 1hr".format(coin,response,percent, difference))

def gen_chart(data, coin, numdisp):
    """
        A helper function to generate a chart from the data returned from
    """
    close = [d['close'] for d in data]
    opens = [d['open'] for d in data]
    high = [d['high'] for d in data]
    low = [d['low'] for d in data]
    dates = [d['time'] for d in data]

    fig, ax = plt.subplots()

    fig.patch.set_facecolor('#2f3d45')

    ax.set_facecolor('#2f3d45')
    ax.xaxis.label.set_color('white')
    ax.yaxis.label.set_color('white')

    ax.spines['top'].set_alpha(0)
    ax.spines['right'].set_alpha(0)
    ax.spines['bottom'].set_color('w')
    ax.spines['left'].set_color('w')

    plt.ylabel('Price of {} in USD'.format(coin))

    ax.tick_params(axis='x', colors='white')
    ax.tick_params(axis='y', colors='white')

    def mydate(x,pos):
        try:
            return xdate[int(x)]
        except IndexError:
            print "error"
            return ''

    candlestick2_ochl(ax, opens, close, high, low, width=.7, colordown='#f22800', colorup='#00ce03', alpha=.75)

    xdate = [datetime.datetime.fromtimestamp(d, tz=pytz.utc).astimezone(timezone('US/Pacific')).strftime("%d/%m/%y %I:%M%p GMT") for d in dates]

    ax.xaxis.set_major_locator(ticker.MaxNLocator(numdisp))
    ax.xaxis.set_major_formatter(ticker.FuncFormatter(mydate))
    fig.autofmt_xdate()
    fig.tight_layout()

    fig.savefig('tmp.png', facecolor='#2f3d45')

updater = Updater(keys.bot_key)

jobs = {}
coin_list = get_coin_list()
print "built coin list"

jq = updater.job_queue
dp = updater.dispatcher

# Crypto Handlers
dp.add_handler(CommandHandler('p', price))
dp.add_handler(CommandHandler('cap', cap))
# dp.add_handler(CommandHandler('c', day_chart))
# dp.add_handler(CommandHandler('c3', three_chart))
# dp.add_handler(CommandHandler('c60', sixty_chart))
# dp.add_handler(CommandHandler('t', track))

updater.start_polling()
updater.idle()
<|endoftext|>


<commit_before>#!/usr/bin/python

import asyncio, json, urllib3, datetime, discord, dateutil
from apiclient.discovery import build
from datetime import date
from datetime import timedelta
from threading import Timer
import dateutil.parser
import dateutil.relativedelta

with open( './settings.json' ) as f:
    data = json.load( f )

client = discord.Client()
discord_token = data["discord"]["token"]
youtube_token = data["youtube"]["token"]
prefix = data["bot"]["prefix"]
me = "BeeStingBot"
searched = False
videos = {}
timer = None
search_time = datetime.datetime.now() - datetime.timedelta( days=90 )

def write_log( log ):
    logfile = open( data["bot"]["logfile"], "a" )
    time_format = "%m/%d/%Y %H:%M:%S"
    now = date.today()
    time = now.strftime( time_format )
    logfile.seek( 0, 2 ) #EOF
    logfile.write( time+" :: "+log+"\n" )
    logfile.close()
    return

def search_helper():
    global searched
    global videos
    global timer
    global search_time
    search_time = None
    searched = False
    videos = {}
    timer = None
    print( "timeout!" )
    return

class yt_video:
    """simple container for yt video data"""
    title = ""
    video_id = -1

    def __init__(self,t,i):
        self.title = str(t)
        self.video_id = str(i)

    def set_title( self, t ):
        self.title = t

    def set_id( self, i ):
        self.video_id = i

def youtube_search( term ):
    global searched
    global timer
    global videos
    global search_time

    if( searched == True ):
        if( datetime.datetime.now() > search_time + timedelta( seconds=15 ) ):
            search_helper( msg )
            return "Timeout!"
        else:
            return "Search in progress still!"
    else:
        videos = {}
        timer = None
        searched = False
        search_time  = None

    youtube = build( "youtube", "v3", developerKey=youtube_token )
    resp = youtube.search().list(
        q=term,
        part="id,snippet",
        maxResults=50
    ).execute()

    count = 0
    res_str = ""
    for res in resp.get( "items", [] ):
        if( res["id"]["kind"] == "youtube#video" ):
            count+=1
            res_str += str(count)+". "+res["snippet"]["title"]+"\n"
            title = res["snippet"]["title"]
            video_id = res["id"]["videoId"]
            vid = yt_video( title, video_id )
            videos[count] = vid
            if( count >= 10 ):
                break
        else:
            continue
    searched = True
    search_time = datetime.datetime.now()
    print( search_time )
    return res_str

def get_got_time():
    cur = datetime.datetime.now()
    uri = "http://api.tvmaze.com/shows/82?embed=nextepisode"
    http = urllib3.PoolManager()
    response = http.request( 'GET', uri )
    data = json.loads( response.data.decode( 'utf-8' ) )
    next_ep = dateutil.parser.parse( data["_embedded"]["nextepisode"]["airstamp"] )
    next_ep = next_ep.replace( tzinfo=None )
    diff = dateutil.relativedelta.relativedelta( next_ep, cur )
    print_str = "```css\nThere are ---\n"
    if( diff.months > 0 ):
        print_str+=str(diff.months)+" Months\n"
    if( diff.days > 0 ):
        print_str+=str(diff.days)+" Days\n"
    if( diff.minutes > 0 ):
        print_str+=str(diff.minutes)+" Minutes and\n"
    if( diff.seconds > 0 ):
        print_str+=str(diff.seconds)+" Seconds\n"
    print_str+="until the next Game of Thrones airs!\n\n```"
    return print_str

@client.event
async def on_ready():
    write_log( "bot started!" )
    write_log( "user: "+client.user.name )
    write_log( "id: "+client.user.id )
    write_log( "----------------------" )

@client.event
async def on_message( msg ):
    if( msg.author.name.find( me ) >= 0 ):
        return

    # check for prefix
    if( msg.content[:len(prefix)].find( prefix ) >= 0 ):
        cmd = msg.content[len(prefix):]
        args = cmd.split()
        if( args[0] == "yt" ):
            search_str = ""
            for i in args[1:]:
                search_str+=i+" "
            print( search_str )
            search_results = youtube_search( search_str )
            write_log( "Got results string: "+search_results )
            await client.send_message( msg.channel, "```css\n"+search_results+"\n```" )
            return
        elif( datetime.datetime.now() < (search_time + timedelta( seconds=15 )) and searched == True ):
            val = int( args[0] )
            if( val > 10 or val < 0 ):
                await client.send_message( msg.channel, "Invalid selection!" )
            else:
                await client.send_message( msg.channel, videos[i].title )
        elif( args[0] == "got" ):
            await client.send_message( msg.channel, get_got_time() )
        else:
            write_log( "caught unknown cmd" )
            return

client.run( discord_token )
<commit_msg>slowly getting closer to working youtube search -- timeout (hopefully) works -- searches dont interrupt each other -- correctly returns the video TITLE the user specified ---- need to build URI and return that instead -- need to set up bot to edit message instead of posting a new one as well<commit_after>#!/usr/bin/python

import asyncio, json, urllib3, datetime, discord, dateutil
from apiclient.discovery import build
from datetime import date
from datetime import timedelta
from threading import Timer
import dateutil.parser
import dateutil.relativedelta

with open( './settings.json' ) as f:
    data = json.load( f )

client = discord.Client()
discord_token = data["discord"]["token"]
youtube_token = data["youtube"]["token"]
prefix = data["bot"]["prefix"]
me = "BeeStingBot"
searched = False
videos = {}
timer = None
search_time = datetime.datetime.now() - datetime.timedelta( days=90 )

def write_log( log ):
    logfile = open( data["bot"]["logfile"], "a" )
    time_format = "%m/%d/%Y %H:%M:%S"
    now = date.today()
    time = now.strftime( time_format )
    logfile.seek( 0, 2 ) #EOF
    logfile.write( time+" :: "+log+"\n" )
    logfile.close()
    return

def search_helper():
    global searched
    global videos
    global timer
    global search_time
    search_time = None
    searched = False
    videos = {}
    timer = None
    print( "timeout!" )
    return

class yt_video:
    """simple container for yt video data"""
    title = ""
    video_id = -1

    def __init__(self,t,i):
        self.title = str(t)
        self.video_id = str(i)

    def set_title( self, t ):
        self.title = t

    def set_id( self, i ):
        self.video_id = i

def youtube_search( term ):
    global searched
    global timer
    global videos
    global search_time

    if( searched == True ):
        if( datetime.datetime.now() > search_time + timedelta( seconds=15 ) ):
            search_helper()
            return "Timeout!"
        else:
            return "Search in progress still!"
    else:
        videos = {}
        timer = None
        searched = False
        search_time  = None

    youtube = build( "youtube", "v3", developerKey=youtube_token )
    resp = youtube.search().list(
        q=term,
        part="id,snippet",
        maxResults=50
    ).execute()

    count = 0
    res_str = "```css\n"
    for res in resp.get( "items", [] ):
        if( res["id"]["kind"] == "youtube#video" ):
            count+=1
            res_str += str(count)+". "+res["snippet"]["title"]+"\n"
            title = res["snippet"]["title"]
            video_id = res["id"]["videoId"]
            vid = yt_video( title, video_id )
            videos[count] = vid
            if( count >= 10 ):
                break
        else:
            continue
    searched = True
    search_time = datetime.datetime.now()
    res_str+="\n```"
    return res_str

def get_got_time():
    cur = datetime.datetime.now()
    uri = "http://api.tvmaze.com/shows/82?embed=nextepisode"
    http = urllib3.PoolManager()
    response = http.request( 'GET', uri )
    data = json.loads( response.data.decode( 'utf-8' ) )
    next_ep = dateutil.parser.parse( data["_embedded"]["nextepisode"]["airstamp"] )
    next_ep = next_ep.replace( tzinfo=None )
    diff = dateutil.relativedelta.relativedelta( next_ep, cur )
    print_str = "```css\nThere are ---\n"
    if( diff.months > 0 ):
        print_str+=str(diff.months)+" Months\n"
    if( diff.days > 0 ):
        print_str+=str(diff.days)+" Days\n"
    if( diff.minutes > 0 ):
        print_str+=str(diff.minutes)+" Minutes and\n"
    if( diff.seconds > 0 ):
        print_str+=str(diff.seconds)+" Seconds\n"
    print_str+="until the next Game of Thrones airs!\n\n```"
    return print_str

@client.event
async def on_ready():
    write_log( "bot started!" )
    write_log( "user: "+client.user.name )
    write_log( "id: "+client.user.id )
    write_log( "----------------------" )

@client.event
async def on_message( msg ):
    global searched
    if( msg.author.name.find( me ) >= 0 ):
        return

        # check for prefix
    if( searched == True ):
        cur = datetime.datetime.now()
        if( cur > (search_time + timedelta( seconds=15 ) )):
            print("timeout")
            search_helper()
            return
        if ( msg.content.isdigit() == False ):
            await client.send_message( msg.channel, "Invalid selection!" )
            return
        val = int( msg.content )
        if( val > 10 or val < 0 ):
            await client.send_message( msg.channel, "Invalid selection!" )
            return
        await client.send_message( msg.channel, videos[val].title )
        search_helper()

    if( msg.content[:len(prefix)].find( prefix ) >= 0 ):
        cmd = msg.content[len(prefix):]
        args = cmd.split()
        if( args[0] == "yt" ):
            search_str = ""
            for i in args[1:]:
                search_str+=i+" "
            await client.send_message( msg.channel, youtube_search( search_str ) )
            return
        elif( args[0] == "got" ):
            await client.send_message( msg.channel, get_got_time() )
        else:
            write_log( "caught unknown cmd" )
            return

client.run( discord_token )
<|endoftext|>


<commit_before>import discord, sqlite3
from discord.ext.commands import Bot
import secrets

statbot = Bot(command_prefix='!')
startup_extensions = ['cogs.pubg', 'cogs.mattbeer', 'cogs.wow']

conn = sqlite3.connect('db/statbot.db')
cur = conn.cursor()

@statbot.event
async def on_ready():
    print('Client logged in.')
    print(statbot.user.id)
    print('-----')
    await statbot.change_presence(game=discord.Game(name="Stats"))

    for extension in startup_extensions:
        try:
            statbot.load_extension(extension)
        except Exception as e:
            exc = '{}: {}'.format(type(e).__name__, e)
            print('Failed to load extensions {}\n {}'.format(extension, exc))

statbot.run(secrets.BOT_TOKEN)
<commit_msg>Add d3 cog<commit_after>import discord, sqlite3
from discord.ext.commands import Bot
import secrets

statbot = Bot(command_prefix='!')
startup_extensions = ['cogs.pubg', 'cogs.mattbeer', 'cogs.wow', 'cogs.d3']

conn = sqlite3.connect('db/statbot.db')
cur = conn.cursor()

@statbot.event
async def on_ready():
    print('Client logged in.')
    print(statbot.user.id)
    print('-----')
    await statbot.change_presence(game=discord.Game(name="Stats"))

    for extension in startup_extensions:
        try:
            statbot.load_extension(extension)
        except Exception as e:
            exc = '{}: {}'.format(type(e).__name__, e)
            print('Failed to load extensions {}\n {}'.format(extension, exc))

statbot.run(secrets.BOT_TOKEN)
<|endoftext|>


<commit_before>import settings
import threading
import Queue
import socket
import logging

from irc import IRCBot, run_bot, DisconnectedException

class TwitchBot(IRCBot, threading.Thread):
    """
    A threaded IRC bot that automatically reconnects and rejoins channels if
    disconnected. Communication happens over the queue command_queue. The
    accepted commands through the queue are 'join' and 'part'.
    """

    def __init__(self, name, conn, chat_logger, command_queue, log_filename=None, *args, **kwargs):
        super(TwitchBot, self).__init__(conn, *args, **kwargs)

        self.name = name
        self.chat_logger = chat_logger
        self.command_queue = command_queue
        self.disconnect = threading.Event()

        self.logger = self.conn.get_logger(name, log_filename)

    def run(self):
        """
        Receives data in a loop until the event for disconnecting is set.
        Checks the command queue for actions to be taken (joining or leaving
        channels).
        """
        patterns = self.conn.dispatch_patterns()

        while not self.disconnect.is_set():
            try:
                data = self.conn.get_data()  # returns empty string if times out
            except DisconnectedException:
                self.logger.info('Disconnected from server. Reconnecting.')
                self.conn.close()
                self.connect_and_join_channels(self.channels)
                continue

            if data:
                self.conn.dispatch_data(data, patterns)

            try:
                command = self.command_queue.get_nowait()
                self.process_command(command)
            except Queue.Empty:
                continue

    def join(self, timeout=None):
        """
        Forces the bot to disconnect, close its socket and database
        connection.
        """
        self.conn.close()
        self.chat_logger.close()
        self.logger.info('Closed connection.')
        self.disconnect.set()
        super(TwitchBot, self).join(timeout)

    def connect_and_join_channels(self, channels):
        if not self.conn.connect():
            raise RuntimeError("Failed to connect to IRC channel.")

        for channel in channels:
            self.conn.join(channel)
        self.channels = channels

    def process_command(self, command):
        """
        Processes a command, either joining or leaving channels.
        command is expected to be a tuple of a string and a list.
        Valid commands are 'join' and 'part'.
        """
        if not (type(command) is tuple and len(command) == 2):
            raise ValueError("Expected command to be a tuple of a string and a list")

        action, channels = command
        self.logger.info("Received command %s (%s)" % (action, ','.join(channels)))
        if action == 'join':
            for channel in channels:
                self.conn.join(channel)
            self.channels += channels
        elif action == 'part':
            for channel in channels:
                self.conn.part(channel)
            self.channels = [c for c in self.channels if c not in channels]

    def log(self, sender, message, channel):
        if sender == settings.IRC['NICK']:
            self.logger.info("%s, %s: %s " % (channel, sender, message))

        self.chat_logger.log_chat(sender, message, channel)

    def command_patterns(self):
        return (
            ('.*', self.log),
        )
<commit_msg>Do not log the bots own messages (typically join and part).<commit_after>import settings
import threading
import Queue
import socket
import logging

from irc import IRCBot, run_bot, DisconnectedException

class TwitchBot(IRCBot, threading.Thread):
    """
    A threaded IRC bot that automatically reconnects and rejoins channels if
    disconnected. Communication happens over the queue command_queue. The
    accepted commands through the queue are 'join' and 'part'.
    """

    def __init__(self, name, conn, chat_logger, command_queue, log_filename=None, *args, **kwargs):
        super(TwitchBot, self).__init__(conn, *args, **kwargs)

        self.name = name
        self.chat_logger = chat_logger
        self.command_queue = command_queue
        self.disconnect = threading.Event()

        self.logger = self.conn.get_logger(name, log_filename)

    def run(self):
        """
        Receives data in a loop until the event for disconnecting is set.
        Checks the command queue for actions to be taken (joining or leaving
        channels).
        """
        patterns = self.conn.dispatch_patterns()

        while not self.disconnect.is_set():
            try:
                data = self.conn.get_data()  # returns empty string if times out
            except DisconnectedException:
                self.logger.info('Disconnected from server. Reconnecting.')
                self.conn.close()
                self.connect_and_join_channels(self.channels)
                continue

            if data:
                self.conn.dispatch_data(data, patterns)

            try:
                command = self.command_queue.get_nowait()
                self.process_command(command)
            except Queue.Empty:
                continue

    def join(self, timeout=None):
        """
        Forces the bot to disconnect, close its socket and database
        connection.
        """
        self.conn.close()
        self.chat_logger.close()
        self.logger.info('Closed connection.')
        self.disconnect.set()
        super(TwitchBot, self).join(timeout)

    def connect_and_join_channels(self, channels):
        if not self.conn.connect():
            raise RuntimeError("Failed to connect to IRC channel.")

        for channel in channels:
            self.conn.join(channel)
        self.channels = channels

    def process_command(self, command):
        """
        Processes a command, either joining or leaving channels.
        command is expected to be a tuple of a string and a list.
        Valid commands are 'join' and 'part'.
        """
        if not (type(command) is tuple and len(command) == 2):
            raise ValueError("Expected command to be a tuple of a string and a list")

        action, channels = command
        self.logger.info("Received command %s (%s)" % (action, ','.join(channels)))
        if action == 'join':
            for channel in channels:
                self.conn.join(channel)
            self.channels += channels
        elif action == 'part':
            for channel in channels:
                self.conn.part(channel)
            self.channels = [c for c in self.channels if c not in channels]

    def log(self, sender, message, channel):
        if sender == settings.IRC['NICK']:
            self.logger.info("%s, %s: %s " % (channel, sender, message))
            return

        self.chat_logger.log_chat(sender, message, channel)

    def command_patterns(self):
        return (
            ('.*', self.log),
        )
<|endoftext|>


<commit_before>import discord
from discord.ext import commands
import SelfIDs
import cogs.utils.prefix as Prefix
import cogs.emojis as Emojis
import os.path
import json
import datetime

startup_extensions = [
    "cogs.fun",
    "cogs.eval",
    "cogs.gens",
    "cogs.botinfos",
    "cogs.hepbot",
    "cogs.ack",
    "cogs.bgt",
    "cogs.clear",
    "cogs.serverinfo",
    "cogs.count",
    "cogs.mute",
    "cogs.discrim",
    "cogs.guildlogs"
]

cDir = os.path.dirname(os.path.abspath(__file__))
muteListDir = f"{cDir}/muteList.json"

try:
    with open(muteListDir, "r") as f:
        pass
except FileNotFoundError:
    print("Mute List not made. Creating...")
    with open(muteListDir, "a+") as f:
        json.dump({}, f)
    print("muteList.json created.")

bot = commands.Bot(command_prefix=Prefix.prefixes, description="A Self Bot", max_messages=1000, self_bot=True)
bot.remove_command("help")
bot.blank = "\u200B"
bot.muteListDir = muteListDir
bot.ready = False

# bot.muteList = muteList
# bot.muteListFile = muteListFile

def emojireplacetext(message):
    if not message: return
    try:
        output = message.content
    except AttributeError:
        print(f"discord.Message obj needed. {type(message)} was given.")
        return

    for emoji in Emojis.emojis:
        if f"[{emoji}]" in output.lower():
            fEmoji = Emojis.emojis[emoji]
            output = output.replace(f"[{emoji}]", fEmoji)

    return output

@bot.event
async def on_ready():
    gamename = "with Orangutans \U0001f435"
    await bot.change_presence(game=discord.Game(name=gamename))
    print("Logged in as:")
    print("Name: " + str(bot.user))
    print("ID: " + str(bot.user.id))
    print("Playing", gamename)
    print("Prefixes: " + Prefix.Prefix())
    bot.ready = True

@bot.event
async def on_message(message):
    if message.author.id != bot.user.id:
        return
    if not bot.ready:
        # await message.channel.send("I'm still loading")
        return
    if "[" in message.content:
        if "`" not in message.content and "\u200B" not in message.content:
            await message.edit(content=(emojireplacetext(message)))
    if "Nihaal" in message.content:
        await message.edit(content=message.content.replace("Nihaal", "*****"))
    await bot.process_commands(message)

@bot.event
async def on_message_edit(before, after):
    if after.author.id != bot.user.id:
        return
    if "[" in after.content:
        if not "```" in after.content:
            await after.edit(content=(emojireplacetext(after)))
    await bot.process_commands(after)

@bot.event
async def on_guild_remove(guild):
    embed = discord.Embed(description=f"<@{bot.user.id}> left the guild {guild.name}")
    embed.add_field(name="Owner", value=f"{str(guild.owner)} ({guild.owner.id}) <@{guild.owner.id}>")
    embed.set_footer(text=("Server left on " + datetime.datetime.utcnow().strftime("%A %d %B %Y at %H:%M:%S")))

    if guild.icon_url:
        embed.set_image(url=guild.icon_url)
        embed.add_field(name="Server Icon URL", value=guild.icon_url)

    await bot.get_channel(304597561615056899).send(embed=embed)

@bot.command()
async def load(ctx, extension_name: str):
    """Loads a module."""
    try:
        bot.load_extension(extension_name)
    except (AttributeError, ImportError) as e:
        await ctx.send(bot.blank + "```py\n{}: {}\n```".format(type(e).__name__, str(e)), delete_after=3)
        return
    await ctx.send(bot.blank + "{} loaded.".format(extension_name), delete_after=3)

@bot.command()
async def unload(ctx, extension_name: str):
    """Unloads a module"""
    bot.unload_extension(extension_name)
    await ctx.send(bot.blank + "{} unloaded.".format(extension_name), delete_after=3)

@bot.command(name="reload")
async def _reload(ctx, *, module: str):
    """Reloads a module."""
    try:
        bot.unload_extension(module)
        bot.load_extension(module)
    except Exception as e:
        await ctx.send("{}: {}".format(type(e).__name__, e))
    else:
        await ctx.send(":thumbsup:")

@bot.command()
async def shutdown(ctx):
    """Shutdown"""
    try:
        await ctx.send("System Shutting down.")
        await bot.logout()
        await bot.close()
    except:
        await ctx.send("Error!")

@bot.command()
async def shutdownall(ctx):
    prefixes = [
        "o!",
        "q!",
        "t!",
        "v!",
        "s."
    ]
    for bot in prefixes:
        await ctx.send(f"{bot}shutdown")

if __name__ == "__main__":
    for extension in startup_extensions:
        try:
            bot.load_extension(extension)
        except Exception as e:
            exc = "{}: {}".format(type(e).__name__, e)
            print("Failed to load extension {}\n{}".format(extension, exc))

@bot.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.MissingRequiredArgument):
        print(error)
    elif isinstance(error, commands.errors.CommandNotFound):
        await ctx.send("`{}` is not a valid command".format(ctx.invoked_with))
    elif isinstance(error, commands.errors.CommandInvokeError):
        print(error)
    else:
        print(error)

bot.run(SelfIDs.token, bot=False)
<commit_msg>Added check for not ready message<commit_after>import discord
from discord.ext import commands
import SelfIDs
import cogs.utils.prefix as Prefix
import cogs.emojis as Emojis
import os.path
import json
import datetime

startup_extensions = [
    "cogs.fun",
    "cogs.eval",
    "cogs.gens",
    "cogs.botinfos",
    "cogs.hepbot",
    "cogs.ack",
    "cogs.bgt",
    "cogs.clear",
    "cogs.serverinfo",
    "cogs.count",
    "cogs.mute",
    "cogs.discrim",
    "cogs.guildlogs"
]

cDir = os.path.dirname(os.path.abspath(__file__))
muteListDir = f"{cDir}/muteList.json"

try:
    with open(muteListDir, "r") as f:
        pass
except FileNotFoundError:
    print("Mute List not made. Creating...")
    with open(muteListDir, "a+") as f:
        json.dump({}, f)
    print("muteList.json created.")

bot = commands.Bot(command_prefix=Prefix.prefixes, description="A Self Bot", max_messages=1000, self_bot=True)
bot.remove_command("help")
bot.blank = "\u200B"
bot.muteListDir = muteListDir
bot.ready = False

# bot.muteList = muteList
# bot.muteListFile = muteListFile

def emojireplacetext(message):
    if not message: return
    try:
        output = message.content
    except AttributeError:
        print(f"discord.Message obj needed. {type(message)} was given.")
        return

    for emoji in Emojis.emojis:
        if f"[{emoji}]" in output.lower():
            fEmoji = Emojis.emojis[emoji]
            output = output.replace(f"[{emoji}]", fEmoji)

    return output

@bot.event
async def on_ready():
    gamename = "with Orangutans \U0001f435"
    await bot.change_presence(game=discord.Game(name=gamename))
    print("Logged in as:")
    print("Name: " + str(bot.user))
    print("ID: " + str(bot.user.id))
    print("Playing", gamename)
    print("Prefixes: " + Prefix.Prefix())
    bot.ready = True

@bot.event
async def on_message(message):
    if message.author.id != bot.user.id:
        return
    if not bot.ready:
        for prefix in prefixes:
            if message.content.startswith(prefix):
                await message.channel.send("I am still loading.")
                return
    if "[" in message.content:
        if "`" not in message.content and "\u200B" not in message.content:
            await message.edit(content=(emojireplacetext(message)))
    if "Nihaal" in message.content:
        await message.edit(content=message.content.replace("Nihaal", "*****"))
    await bot.process_commands(message)

@bot.event
async def on_message_edit(before, after):
    if after.author.id != bot.user.id:
        return
    if "[" in after.content:
        if not "```" in after.content:
            await after.edit(content=(emojireplacetext(after)))
    await bot.process_commands(after)

@bot.event
async def on_guild_remove(guild):
    embed = discord.Embed(description=f"<@{bot.user.id}> left the guild {guild.name}")
    embed.add_field(name="Owner", value=f"{str(guild.owner)} ({guild.owner.id}) <@{guild.owner.id}>")
    embed.set_footer(text=("Server left on " + datetime.datetime.utcnow().strftime("%A %d %B %Y at %H:%M:%S")))

    if guild.icon_url:
        embed.set_image(url=guild.icon_url)
        embed.add_field(name="Server Icon URL", value=guild.icon_url)

    await bot.get_channel(304597561615056899).send(embed=embed)

@bot.command()
async def load(ctx, extension_name: str):
    """Loads a module."""
    try:
        bot.load_extension(extension_name)
    except (AttributeError, ImportError) as e:
        await ctx.send(bot.blank + "```py\n{}: {}\n```".format(type(e).__name__, str(e)), delete_after=3)
        return
    await ctx.send(bot.blank + "{} loaded.".format(extension_name), delete_after=3)

@bot.command()
async def unload(ctx, extension_name: str):
    """Unloads a module"""
    bot.unload_extension(extension_name)
    await ctx.send(bot.blank + "{} unloaded.".format(extension_name), delete_after=3)

@bot.command(name="reload")
async def _reload(ctx, *, module: str):
    """Reloads a module."""
    try:
        bot.unload_extension(module)
        bot.load_extension(module)
    except Exception as e:
        await ctx.send("{}: {}".format(type(e).__name__, e))
    else:
        await ctx.send(":thumbsup:")

@bot.command()
async def shutdown(ctx):
    """Shutdown"""
    try:
        await ctx.send("System Shutting down.")
        await bot.logout()
        await bot.close()
    except:
        await ctx.send("Error!")

@bot.command()
async def shutdownall(ctx):
    prefixes = [
        "o!",
        "q!",
        "t!",
        "v!",
        "s."
    ]
    for bot in prefixes:
        await ctx.send(f"{bot}shutdown")

if __name__ == "__main__":
    for extension in startup_extensions:
        try:
            bot.load_extension(extension)
        except Exception as e:
            exc = "{}: {}".format(type(e).__name__, e)
            print("Failed to load extension {}\n{}".format(extension, exc))

@bot.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.MissingRequiredArgument):
        print(error)
    elif isinstance(error, commands.errors.CommandNotFound):
        await ctx.send("`{}` is not a valid command".format(ctx.invoked_with))
    elif isinstance(error, commands.errors.CommandInvokeError):
        print(error)
    else:
        print(error)

bot.run(SelfIDs.token, bot=False)
<|endoftext|>


<commit_before>import tweepy
import os
from time import sleep
from random import randrange

def file_to_dict(file_name):
	"""opens a file and put tab separated values in a dict"""
	f = open(file_name, 'r')
	d_keys = {}
	for i in f.readlines():
		i = i[:len(i) - 1]		#Removing the \n char
		j = i.split('\t')
		d_keys[j[0]] = j[1]
	return d_keys

def twitter_authentification(keys_file):
	"""return a tweepy.api object connected to your account"""
	d_keys = file_to_dict(keys_file)
	auth = tweepy.OAuthHandler(d_keys["consumer_key"],
		d_keys["consumer_secret"])
	auth.set_access_token(d_keys["access_token"],
		d_keys["access_secret"])
	api = tweepy.API(auth)
	return api

def daemonize():
    try:
        pid = os.fork()
    except OSError, e:
        raise Exception, "%s [%d]" % (e.argsstrerror, e.argserrno)
    if (pid == 0):      # Ayanami Rei
        os.setsid()
        try:
            pid = os.fork()
        except OSError, e:
            raise Exception, "%s [%d]" % (e.argsstrerror, e.argserrno)
        if (pid == 0):      # Langley Soryu Asuka
            os.chdir("/")
            os.umask(0)
        else:
            os._exit(0)
    else:
        os._exit(0)
    os.open("/dev/null",os.O_RDWR)
    os.dup2(0,1)
    os.dup2(0,2)
    print pid
    return(0)

if __name__ == "__main__":
	#retCode = daemonize()
	cur_dir = os.path.dirname(os.path.realpath(__file__))

	api = twitter_authentification(cur_dir + "/keys.conf")
	dms = api.direct_messages()
	first_dm_id = dms[0].id
	start = 0
	while 1:
		try:
			followers = api.followers()
			for follower in followers:
				if not follower.following:
					follower.follow()

			if len(dms) > 0:
				print "picking dm"
				picked_dm = dms[randrange(len(dms))]
				dms.remove(picked_dm)
				api.destroy_direct_message(picked_dm.id)
				print picked_dm.text
				api.update_status(picked_dm.text)

				last_dm_id = dms[len(dms) - 1]
				first_dm_id = last_dm_id

			print "sleeping"
			sleep(3600)

			try:
				dms = api.direct_messages(first_dm_id)
			except tweepy.error.TweepError:pass
		except IndexError:pass

<commit_msg>Repartition of sleeping times<commit_after>import tweepy
import os
from time import sleep
from random import randrange

def file_to_dict(file_name):
	"""opens a file and put tab separated values in a dict"""
	f = open(file_name, 'r')
	d_keys = {}
	for i in f.readlines():
		i = i[:len(i) - 1]		#Removing the \n char
		j = i.split('\t')
		d_keys[j[0]] = j[1]
	return d_keys

def twitter_authentification(keys_file):
	"""return a tweepy.api object connected to your account"""
	d_keys = file_to_dict(keys_file)
	auth = tweepy.OAuthHandler(d_keys["consumer_key"],
		d_keys["consumer_secret"])
	auth.set_access_token(d_keys["access_token"],
		d_keys["access_secret"])
	api = tweepy.API(auth)
	return api

def daemonize():
    try:
        pid = os.fork()
    except OSError, e:
        raise Exception, "%s [%d]" % (e.argsstrerror, e.argserrno)
    if (pid == 0):      # Ayanami Rei
        os.setsid()
        try:
            pid = os.fork()
        except OSError, e:
            raise Exception, "%s [%d]" % (e.argsstrerror, e.argserrno)
        if (pid == 0):      # Langley Soryu Asuka
            os.chdir("/")
            os.umask(0)
        else:
            os._exit(0)
    else:
        os._exit(0)
    os.open("/dev/null",os.O_RDWR)
    os.dup2(0,1)
    os.dup2(0,2)
    print pid
    return(0)

if __name__ == "__main__":
	#retCode = daemonize()
	cur_dir = os.path.dirname(os.path.realpath(__file__))

	api = twitter_authentification(cur_dir + "/keys.conf")
	dms = api.direct_messages()
	first_dm_id = dms[0].id
	start = 0
	while 1:
		try:
			print "Follow back"
			followers = api.followers()
			for follower in followers:
				if not follower.following:
					follower.follow()

			print "sleeping"
			sleep(1800)

			if len(dms) > 0:
				print "Picking dm"
				picked_dm = dms[randrange(len(dms))]
				dms.remove(picked_dm)
				api.destroy_direct_message(picked_dm.id)
				print picked_dm.text
				api.update_status(picked_dm.text)

				last_dm_id = dms[len(dms) - 1]
				first_dm_id = last_dm_id

			print "sleeping"
			sleep(1800)

			try:
				dms = api.direct_messages(first_dm_id)
			except tweepy.error.TweepError:pass
		except IndexError:pass

<|endoftext|>


<commit_before>import logging
import select
import socket
from config import settings as defaultsettings
from errno import WSAEWOULDBLOCK#EINPROGRESS
from strings import encode, decode

# flood control setting
RECEIVE_QUEUE_SIZE = 1024

class Bot(object):
    def __init__(self, settings):
        self.settings = settings

        self.s = None

        self.buffer_in = b""
        self.buffer_out = b""
        self.send_queue = []

        self.allow_send = True
        self.bytes_buffered = 0

    def process_timers(self):
        # temp
        return None

    def split_received(self, data):
        self.buffer_in += data
        encoded_lines = self.buffer_in.split(b"\r\n")
        # leave incomplete lines in buffer
        self.buffer_in = encoded_lines.pop(-1)

        for encoded_line in encoded_lines:
            line = decode(encoded_line)
            self.handle_line(line)

    def handle_line(self, line):
        logging.info("<- {}".format(line))

        # split up line in prefix, command, args
        prefix = ''
        trailing = []

        if line[0] == ':':
            prefix, line = line[1:].split(' ', 1)

        if line.find(' :') != -1:
            line, trailing = line.split(' :', 1)
            args = line.split()
            args.append(trailing)

        else:
            args = line.split()

        command = args.pop(0)

        # deal with response to anti-flood check
        if len(args) == 3 and (command, args[1]) == ("421", "SPLIDGEPLOIT"):
            self.bytes_buffered = 0
            self.allow_send = True
            return

        # respond to ping
        if command == "PING":
            self.send("PONG :{}".format(args[0]))

    def send_lines(self):
        while self.send_queue and self.allow_send:
            encoded_line = encode("%s\r\n" % self.send_queue[0])

            # wait for my commands to be processed after I have sent a critical amount of bytes
            # note: I do not control the amount of bytes the server separately queues up to send me
            if self.bytes_buffered + len(encoded_line) > RECEIVE_QUEUE_SIZE:
                self.allow_send = False
                logging.info("-> SPLIDGEPLOIT")
                self.buffer_out += encode("SPLIDGEPLOIT\r\n")

            else:
                logging.info("-> {}".format(self.send_queue.pop(0)))
                self.buffer_out += encoded_line
                self.bytes_buffered += len(encoded_line)

        # send as much of buffer as possible
        sent = self.s.send(self.buffer_out)
        self.buffer_out = self.buffer_out[sent:]

    def send(self, line):
        self.send_queue.append(line)

    def connect(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.setblocking(0)

        try:
            self.s.connect((self.settings['server'], int(self.settings['port'])))

        except socket.error as e:
            message = e.args[0]
            if message != WSAEWOULDBLOCK:
                logging.critical("Could not make connection: {}".format(message))
                return

        self.send("USER {} * * :{}".format(self.settings['username'], self.settings['realname']))
        self.send("NICK {}".format(self.settings['desired_nick']))

    def loop(self):
        inputtest = [self.s]
        excepttest = inputtest

        # the main loop
        while True:
            outputtest = [self.s] if self.send_queue else []
            timeout = self.process_timers()

            inputready, outputready, exceptready = select.select(inputtest, outputtest, excepttest, timeout)

            if exceptready:
                # assume fatal error
                logging.critical("Fatal error returned by select().")
                self.s.close()
                break

            if inputready:
                received = self.s.recv(8192)

                if not received:
                    # assume disconnect
                    logging.critical("Disconnected.")
                    self.s.close()
                    break

                self.split_received(received)

            if outputready:
                self.send_lines()

def runbot(settings):
    bot = Bot(settings)
    bot.connect()
    bot.loop()

if __name__ == "__main__":
    runbot(defaultsettings)
<commit_msg>split out basic responses and ensure nickname<commit_after>import logging
import select
import socket
from config import settings as defaultsettings
from errno import WSAEWOULDBLOCK#EINPROGRESS
from strings import encode, decode

# flood control setting
RECEIVE_QUEUE_SIZE = 1024

class Bot(object):
    def __init__(self, settings):
        self.settings = settings
        self.state = {}

        self.s = None

        self.buffer_in = b""
        self.buffer_out = b""
        self.send_queue = []

        self.allow_send = True
        self.bytes_buffered = 0

    def process_timers(self):
        # temp
        return None

    def split_received(self, data):
        self.buffer_in += data
        encoded_lines = self.buffer_in.split(b"\r\n")
        # leave incomplete lines in buffer
        self.buffer_in = encoded_lines.pop(-1)

        for encoded_line in encoded_lines:
            line = decode(encoded_line)
            self.handle_line(line)

    def handle_line(self, line):
        logging.info("<- {}".format(line))

        # split up line in prefix, command, args
        prefix = ''
        trailing = []

        if line[0] == ':':
            prefix, line = line[1:].split(' ', 1)

        if line.find(' :') != -1:
            line, trailing = line.split(' :', 1)
            args = line.split()
            args.append(trailing)

        else:
            args = line.split()

        command = args.pop(0)

        self.basic_responses(command, args)
        # module responses

    def basic_responses(self, command, args):
        # deal with response to anti-flood check
        if len(args) == 3 and (command, args[1]) == ("421", "SPLIDGEPLOIT"):
            self.bytes_buffered = 0
            self.allow_send = True
            return

        # respond to ping
        if command == "PING":
            self.send("PONG :{}".format(args[0]))
            return

        # make sure initial nickname is obtained
        if "obtaining_nick" not in self.state:
            return

        if command == "001":
            del self.state["obtaining_nick"]
            return

        if command == "433":
            self.send("NICK {}".format(args[1] + "`"))
            return

    def send_lines(self):
        while self.send_queue and self.allow_send:
            encoded_line = encode("%s\r\n" % self.send_queue[0])

            # wait for my commands to be processed after I have sent a critical amount of bytes
            # note: I do not control the amount of bytes the server separately queues up to send me
            if self.bytes_buffered + len(encoded_line) > RECEIVE_QUEUE_SIZE:
                self.allow_send = False
                logging.info("-> SPLIDGEPLOIT")
                self.buffer_out += encode("SPLIDGEPLOIT\r\n")

            else:
                logging.info("-> {}".format(self.send_queue.pop(0)))
                self.buffer_out += encoded_line
                self.bytes_buffered += len(encoded_line)

        # send as much of buffer as possible
        sent = self.s.send(self.buffer_out)
        self.buffer_out = self.buffer_out[sent:]

    def send(self, line):
        self.send_queue.append(line)

    def connect(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.setblocking(0)

        try:
            self.s.connect((self.settings['server'], int(self.settings['port'])))

        except socket.error as e:
            message = e.args[0]
            if message != WSAEWOULDBLOCK:
                logging.critical("Could not make connection: {}".format(message))
                return

        self.send("USER {} * * :{}".format(self.settings['username'], self.settings['realname']))
        self.state["obtaining_nick"] = True
        self.send("NICK {}".format(self.settings['desired_nick']))

    def loop(self):
        inputtest = [self.s]
        excepttest = inputtest

        # the main loop
        while True:
            outputtest = [self.s] if self.send_queue else []
            timeout = self.process_timers()

            inputready, outputready, exceptready = select.select(inputtest, outputtest, excepttest, timeout)

            if exceptready:
                # assume fatal error
                logging.critical("Fatal error returned by select().")
                self.s.close()
                break

            if inputready:
                received = self.s.recv(8192)

                if not received:
                    # assume disconnect
                    logging.critical("Disconnected.")
                    self.s.close()
                    break

                self.split_received(received)

            if outputready:
                self.send_lines()

def runbot(settings):
    bot = Bot(settings)
    bot.connect()
    bot.loop()

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    runbot(defaultsettings)
<|endoftext|>


<commit_before>'''
    Title: Basic IRC bot
    Author: Andrés Villagra de la Fuente
    Creation date: 23:11 28/12/2015 (GMT-3)
    Last edit: 16:14 29/12/2015 (GMT-3)
    Version: 1.1

    Description:
        This is a simple IRC bot made to work whenever the normal bot collapses
    also to perform other sort of stuff such as a personal archive for me cause
    I really never set that up.

    Finished features:
        * Rolling
        * Joining channels
        * Tarot spreading
    '''

import socket
import sys
import random

def getCommand(text):
    '''
        Paramenters:
            text: String. Raw entry right out of the IRC protocol.

        Returns the command sent, which is the following:
            "!command <extra>"
    '''
    parts = text.split(":")
    return parts[len(parts)-1]

def makeDeck(deck):
    '''
        Paramenters:
            deck: string of the location fo the file with the cards saved
                as a line each.

        Returns a deck array containing the cards located in the file deck.
    '''
    deckFile = open(deck, "r")
    baseDeck = deckFile.readlines()
    for index in range(0, len(baseDeck)):
        baseDeck[index] = baseDeck[index][:-1]
    return baseDeck
    deckFile.close()

def canRoll(irc, channel):
    '''
        Paramenters:
            channel: string with the following format:
                #<CHANNEL_NAME>
            irc: connection socket.
        Returns:
            Boolean. True if can roll, false if not.
            Come one guys it's straight forward.
    '''
    irc.send(("NAMES "+channel+"\r\n").encode("utf-8"))
    if irc.recv(2040).decode("utf-8").find("Tyche[Dice]") != -1:
        Roll = False
    else:
        Roll = True
    irc.recv(2040)
    return Roll

def roll(pararelRolls, diceAmmount, diceSize):
    rolledArray = []
    for time in range(0, pararelRolls):
        rollSum = 0
        for time in range(0, diceAmmount):
            roll = random.randint(1, diceSize)
            rollSum = rollSum + roll
        rolledArray.append(rollSum)
    return rolledArray

def getRolledNumbers(command):
    '''
        parameters:
            command: String with the following format:
                !roll a#xdy+z
        Returns an array where the indexes give:
            0: pararelRolls -> default: 1
            1: diceAmmount  -> default: 1
            2: diceSize     -> default: 20
            3: modifier     -> default: 0
    '''
    rollNumbers = [1, 1, 20, 0]
    try:
        numbers = command.split()[1] #Will always be 1 because of space locations.
    except:
        numbers = ''
    if numbers.find("#") != -1:
        try:
            rollNumbers[0] = int(numbers.split("#")[0])
        except:
            rollNumbers[0] = 1
        numbers = numbers.split("#")[1]
    if numbers.find("D") != -1:
        try:
            rollNumbers[1] = int(numbers.split("D")[0])
        except:
            rollNumbers[1] = 1
        try:
            rollNumbers[2] = int(numbers.split("D")[1])
        except:
            rollNumbers[2] = 20
        numbers = numbers.split("D")[1]
    if numbers.find("+") != -1:
        try:
            rollNumbers[2] = int(numbers.split("+")[0])
        except:
            rollNumbers[2] = 20
        try:
            rollNumbers[3] = int(numbers.split("+")[1])
        except:
            rollNumbers[3] = 0
        numbers = ""
    if numbers.find("-") != -1:
        try:
            rollNumbers[2] = int(numbers.split("-")[0])
        except:
            rollNumbers[2]
        try:
            rollNumbers[3] = int(numbers.split("-")[1])*(-1)
        except:
            rollNumbers[3] = 0
        numbers = ""
    return rollNumbers

server = "irc.esper.net"
channel = "#RPGSTUCK"
botnick = "KaiserBot"

user = "USER "+ botnick +" "+ botnick +" "+ botnick +" :This is the KaiserBot!\n"
nick = "NICK "+ botnick +"\n"
join = "JOIN "+ channel +"\n"

irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("connecting to:"+server)
irc.connect((server, 6667))
irc.send(user.encode("utf-8"))
irc.send(nick.encode("utf-8"))
irc.send("PRIVMSG nickserv :iNOOPE\r\n".encode("utf-8"))

while 1:
    text=irc.recv(2040)
    text = text.decode("utf-8").upper()
    print(text)

    if text.find("End of /MOTD command.".upper()) != -1:
        irc.send(join.encode("utf-8"))      #Used to join the channel, this is specific to
                                            #esper, stupid motd...

    if text.find('PING') != -1:
        pong = 'PONG ' + text.split() [1] + '\r\n'
        irc.send(pong.encode("utf-8"))

    # All checking code goes here
    if text.find("!ROLL") != -1:
        '''
            A !roll comand has the following structure:
                !roll diceAmount+d+diceSize+"+"+modifier

            * Dice amount is an integer up to 20000
            * Dice Size is an integer
            * Modifier is an integer that is added onto the roll after

            The !Roll command can also have this structure:
                !!roll d+diceAmount+d+diceSize+"+"+modifier

            * Dice amount is the result of a roll of said size and then proceeds
                to roll that many of the following dice
            * Dice Size is an integer
            * Modifier is an integer that is added onto the roll after
        '''

        command = getCommand(text)
        if command[0] == "!":
            chann = (text.split(":")[1]).split(" ")[2]
            if canRoll(irc, chann):
                diceNumbers = getRolledNumbers(command)
                messageToSend = ''

                if diceNumbers[0] > 10:
                    diceNumbers[0] = 10

                if diceNumbers[1] > 2000:
                    diceNumbers[1] = 2000

                rolledArray = roll(diceNumbers[0], diceNumbers[1], diceNumbers[2])

                for rollNum in rolledArray:
                    messageToSend = messageToSend + "("+str(diceNumbers[1])+"d"+str(diceNumbers[2])+"+"+str(diceNumbers[3])+") = ["+str(rollNum)+"+"+str(diceNumbers[3])+"] ==> {"+str(rollNum+diceNumbers[3])+"}. "
                message = "PRIVMSG "+chann+" :"+messageToSend+"\r\n"
                irc.send(message.encode("utf-8"))
                print(text)

    if text.find("!JOIN") != -1 :
        '''
            A join command has the following structure:
                !JOIN #CHANNEL
            A message is sent to the irc server requesting to join #CHANNEL
        '''
        command = getCommand(text)
        if command[0] == "!":
            chann = ""
            foundLink = False
            for char in command:
                if char == "#":
                    foundLink = True
                if foundLink:
                    chann = chann + char
            if chann != "":
                joinMessage = "JOIN "+ chann +"\n"
                irc.send(joinMessage.encode("utf-8"))
            else:
                chann = (text.split(":")[1]).split(" ")[2]
                message = "PRIVMSG "+chann+" :"+"Error 02: bad channel."+"\r\n"
                irc.send(message.encode("utf-8"))

    if text.find("!TAROT") != -1:
        command = getCommand(text)
        if command[0] == "!" and text.find("PRIVMSG") != -1:
            '''
                Tarot command asks for the number of cards to be drawed and returns them.
                A tarot command has the following structure:
                    !tarot <NUMBER OF CARDS>
                Thre are 5 types:
                    * Major arcana
                    * Swords
                    * Wands
                    * Pentacles
                    * Cups
                The minor arcana have the following cards:
                    * 1
                    * 2
                    * 3
                    * 4
                    * 5
                    * 6
                    * 7
                    * 8
                    * 9
                    * 10
                    * page
                    * queen
                    * king
                Major arcana have 22 cards.
            '''
            localDeck = makeDeck("deck")
            numberBuffer = ""
            numberEnd = 9

            for characterIndex in range(0, len(command)):
                try:
                    int(command[characterIndex])
                    if characterIndex < numberEnd:
                        numberBuffer = numberBuffer + command[characterIndex]
                except ValueError:
                    continue

            try:
                amountOfCards = int(numberBuffer)
            except ValueError:
                amountOfCards = 1

            cardsSpreaded = []

            if amountOfCards > 15:
                amountOfCards = 15

            for time in range(0, amountOfCards):
                cardIndex = random.randint(0, len(localDeck)-1)
                reversedOrNot = random.randint(0,1)
                if reversedOrNot == 1:
                    if time != 0:
                        cardsSpreaded.append("||"+localDeck[cardIndex]+"(reversed)")
                    else:
                        cardsSpreaded.append(localDeck[cardIndex]+"(reversed)")

                elif reversedOrNot != 1:
                    if time != 0:
                        cardsSpreaded.append("||"+localDeck[cardIndex])
                    else:
                        cardsSpreaded.append(localDeck[cardIndex])
                localDeck.remove(localDeck[cardIndex]) # Eliminates the card from the deck so it doesn't come twice

            chann = (text.split(":")[1]).split(" ")[2]
            messageToSend = "You got these cards: "

            for card in cardsSpreaded:
                messageToSend = messageToSend + card

            message = "PRIVMSG "+chann+" :"+messageToSend+"\r\n"
            irc.send(message.encode("utf-8"))

    if text.find("!HELP") != -1:
        '''
            Help command, displays a string with help info.
                * What the bot is
                * How to use the commands
                * Where do download the bot
        '''
        command = getCommand(text)
        if command[0] == "!":
            chann = (text.split(":")[1]).split(" ")[2]
            message = "PRIVMSG "+chann+" :"+"Hello! I am KaiserBot, I am a tiny bot made my KaiserA, you can run the following commands on me: !roll, !join !help.!Roll uses the following parameters: !Roll <TIMES>#<AMOUNT OF DICE>d<MAX DIE>+<MOD> AMOUNT OF DIE and MAX DIE are obligatory.!Join takes the following parameters: !Join #<CHANNELNAME>. I am version 1.0 and I can be downloaded at the following adress: https://github.com/KaiserAndres/kaiserBot. I run on python 3.x so anyone who wants can host me!\r\n"
            irc.send(message.encode("utf-8"))

    if text.find("!LEAVE") != -1:
        command = getCommand(text)
        if command[0] == "!":
            chann = (text.split(":")[1]).split(" ")[2]
            if chann != channel:
                message = "PART "+chann+"\r\n"
                irc.send(message.encode("utf-8"))<commit_msg>Changed to tyche, removed roll, edited roll()<commit_after>'''
    Title: Basic IRC bot
    Author: Andrés Villagra de la Fuente
    Creation date: 23:11 28/12/2015 (GMT-3)
    Last edit: 16:14 29/12/2015 (GMT-3)
    Version: 1.1

    Description:
        This is a simple IRC bot made to work whenever the normal bot collapses
    also to perform other sort of stuff such as a personal archive for me cause
    I really never set that up.

    Finished features:
        * Rolling
        * Joining channels
        * Tarot spreading
    '''

import socket
import sys
import random
import roller

def getCommand(text):
    '''
        Paramenters:
            text: String. Raw entry right out of the IRC protocol.

        Returns the command sent, which is the following:
            "!command <extra>"
    '''
    parts = text.split(":")
    return parts[len(parts)-1]

def makeDeck(deck):
    '''
        Paramenters:
            deck: string of the location fo the file with the cards saved
                as a line each.

        Returns a deck array containing the cards located in the file deck.
    '''
    deckFile = open(deck, "r")
    baseDeck = deckFile.readlines()
    for index in range(0, len(baseDeck)):
        baseDeck[index] = baseDeck[index][:-1]
    return baseDeck
    deckFile.close()

def canRoll(irc, channel):
    '''
        Paramenters:
            channel: string with the following format:
                #<CHANNEL_NAME>
            irc: connection socket.
        Returns:
            Boolean. True if can roll, false if not.
            Come one guys it's straight forward.
    '''
    irc.send(("NAMES "+channel+"\r\n").encode("utf-8"))
    if irc.recv(2040).decode("utf-8").find("Tyche[Dice]") != -1:
        Roll = True #As I am the true tyche!
    else:
        Roll = True
    irc.recv(2040)
    return Roll

server = "irc.esper.net"
channel = "#RPGSTUCK"
botnick = "Tyche[Dice]"

user = "USER "+ botnick +" "+ botnick +" "+ botnick +" :This is Tyche!\n"
nick = "NICK "+ botnick +"\n"
join = "JOIN "+ channel +"\n"

irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("connecting to:"+server)
irc.connect((server, 6667))
irc.send(user.encode("utf-8"))
irc.send(nick.encode("utf-8"))
irc.send("PRIVMSG nickserv :iNOOPE\r\n".encode("utf-8"))

while 1:
    text=irc.recv(2040)
    text = text.decode("utf-8").upper()
    print(text)

    if text.find("End of /MOTD command.".upper()) != -1:
        irc.send(join.encode("utf-8"))      #Used to join the channel, this is specific to
                                            #esper, stupid motd...

    if text.find('PING') != -1:
        pong = 'PONG ' + text.split() [1] + '\r\n'
        irc.send(pong.encode("utf-8"))

    # All checking code goes here
    if text.find("!ROLL") != -1:
        '''
            A !roll comand has the following structure:
                !roll diceAmount+d+diceSize+"+"+modifier

            * Dice amount is an integer up to 20000
            * Dice Size is an integer
            * Modifier is an integer that is added onto the roll after

            The !Roll command can also have this structure:
                !!roll d+diceAmount+d+diceSize+"+"+modifier

            * Dice amount is the result of a roll of said size and then proceeds
                to roll that many of the following dice
            * Dice Size is an integer
            * Modifier is an integer that is added onto the roll after
        '''

        command = getCommand(text)
        if command[0] == "!":
            chann = (text.split(":")[len(text)-2]).split(" ")[2]
            if canRoll(irc, chann):
                diceNumbers = roller.getRolledNumbers(command)
                messageToSend = ''

                if diceNumbers[0] > 10:
                    diceNumbers[0] = 10

                if diceNumbers[1] > 2000:
                    diceNumbers[1] = 2000

                rolledArray = roller.roll(diceNumbers[0], diceNumbers[1], diceNumbers[2])

                for rollNum in rolledArray:
                    messageToSend = messageToSend + "("+str(diceNumbers[1])+"d"+str(diceNumbers[2])+"+"+str(diceNumbers[3])+") = ["+str(rollNum)+"+"+str(diceNumbers[3])+"] ==> {"+str(rollNum+diceNumbers[3])+"}. "
                message = "PRIVMSG "+chann+" :"+messageToSend+"\r\n"
                irc.send(message.encode("utf-8"))
                print(text)

    if text.find("!JOIN") != -1 :
        '''
            A join command has the following structure:
                !JOIN #CHANNEL
            A message is sent to the irc server requesting to join #CHANNEL
        '''
        command = getCommand(text)
        if command[0] == "!":
            chann = ""
            foundLink = False
            for char in command:
                if char == "#":
                    foundLink = True
                if foundLink:
                    chann = chann + char
            if chann != "":
                joinMessage = "JOIN "+ chann +"\n"
                irc.send(joinMessage.encode("utf-8"))
            else:
                chann = (text.split(":")[len(text)-2]).split(" ")[2]
                message = "PRIVMSG "+chann+" :"+"Error 02: bad channel."+"\r\n"
                irc.send(message.encode("utf-8"))

    if text.find("!TAROT") != -1:
        command = getCommand(text)
        if command[0] == "!" and text.find("PRIVMSG") != -1:
            '''
                Tarot command asks for the number of cards to be drawed and returns them.
                A tarot command has the following structure:
                    !tarot <NUMBER OF CARDS>
                Thre are 5 types:
                    * Major arcana
                    * Swords
                    * Wands
                    * Pentacles
                    * Cups
                The minor arcana have the following cards:
                    * 1
                    * 2
                    * 3
                    * 4
                    * 5
                    * 6
                    * 7
                    * 8
                    * 9
                    * 10
                    * page
                    * queen
                    * king
                Major arcana have 22 cards.
            '''
            localDeck = makeDeck("deck")
            numberBuffer = ""
            numberEnd = 9

            for characterIndex in range(0, len(command)):
                try:
                    int(command[characterIndex])
                    if characterIndex < numberEnd:
                        numberBuffer = numberBuffer + command[characterIndex]
                except ValueError:
                    continue

            try:
                amountOfCards = int(numberBuffer)
            except ValueError:
                amountOfCards = 1

            cardsSpreaded = []

            if amountOfCards > 15:
                amountOfCards = 15

            for time in range(0, amountOfCards):
                cardIndex = random.randint(0, len(localDeck)-1)
                reversedOrNot = random.randint(0,1)
                if reversedOrNot == 1:
                    if time != 0:
                        cardsSpreaded.append("||"+localDeck[cardIndex]+"(reversed)")
                    else:
                        cardsSpreaded.append(localDeck[cardIndex]+"(reversed)")

                elif reversedOrNot != 1:
                    if time != 0:
                        cardsSpreaded.append("||"+localDeck[cardIndex])
                    else:
                        cardsSpreaded.append(localDeck[cardIndex])
                localDeck.remove(localDeck[cardIndex]) # Eliminates the card from the deck so it doesn't come twice

            chann = (text.split(":")[1]).split(" ")[2]
            messageToSend = "You got these cards: "

            for card in cardsSpreaded:
                messageToSend = messageToSend + card

            message = "PRIVMSG "+chann+" :"+messageToSend+"\r\n"
            irc.send(message.encode("utf-8"))

    if text.find("!HELP") != -1:
        '''
            Help command, displays a string with help info.
                * What the bot is
                * How to use the commands
                * Where do download the bot
        '''
        command = getCommand(text)
        if command[0] == "!":
            chann = (text.split(":")[1]).split(" ")[2]
            message = "PRIVMSG "+chann+" :"+"Hello! I am Tyche, I am a tiny bot made my KaiserA, you can run the following commands on me: !roll, !join !help.!Roll uses the following parameters: !Roll <TIMES>#<AMOUNT OF DICE>d<MAX DIE>+<MOD> AMOUNT OF DIE and MAX DIE are obligatory.!Join takes the following parameters: !Join #<CHANNELNAME>. I am version 1.0 and I can be downloaded at the following adress: https://github.com/KaiserAndres/kaiserBot. I run on python 3.x so anyone who wants can host me!\r\n"
            irc.send(message.encode("utf-8"))

    if text.find("!LEAVE") != -1:
        command = getCommand(text)
        if command[0] == "!":
            chann = (text.split(":")[1]).split(" ")[2]
            if chann != channel:
                message = "PART "+chann+"\r\n"
                irc.send(message.encode("utf-8"))
<|endoftext|>


<commit_before>import zirc, ssl, socket

class Bot(zirc.Client):
    def __init__(self):
        self.connection = zirc.Socket(family=socket.AF_INET6, wrapper=ssl.wrap_socket)
        self.config = zirc.IRCConfig(host="irc.freenode.net",
            port=6697,
            nickname="wolfyzIRCBot",
            ident="zirc",
            realname="A zIRC bot",
            channels=["##wolfy1339"],
            sasl_user="BigWolfy1339",
            sasl_pass=""
        )

        self.connect(self.config)
        self.start()

    def on_privmsg(bot, event, irc):
        irc.reply(event, "It works!")
        #Or alternatively:
        #irc.privmsg(event.target, "It works!")

    def on_all(irc, raw):
        print(raw)

Bot()
<commit_msg>Move imports to their own line<commit_after>import zirc
import ssl
import socket

class Bot(zirc.Client):
    def __init__(self):
        self.connection = zirc.Socket(family=socket.AF_INET6, wrapper=ssl.wrap_socket)
        self.config = zirc.IRCConfig(host="irc.freenode.net",
            port=6697,
            nickname="wolfyzIRCBot",
            ident="zirc",
            realname="A zIRC bot",
            channels=["##wolfy1339"],
            sasl_user="BigWolfy1339",
            sasl_pass=""
        )

        self.connect(self.config)
        self.start()

    def on_privmsg(bot, event, irc):
        irc.reply(event, "It works!")
        #Or alternatively:
        #irc.privmsg(event.target, "It works!")

    def on_all(irc, raw):
        print(raw)

Bot()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

class BinarySearchTree(object):
  """Implements a basic binary search tree in Python.

  This BST does not do any kind of balancing, and thus can degenerate into a
  linked list in the worst case.
  """

  class _Node(object):
    """Represents a node in the binary search tree."""

    value = None
    left = None
    right = None

  size = 0

  _root = None

  def __init__(self, data=None):
    """Creates a new binary search tree.

    Args:
      data: An optional tuple or list containing data to be inserted IN ORDER
      into the BST.  If not supplied, the BST is created empty.
    """
    for datum in (data or []):
      self.insert(datum)
<commit_msg>root node property<commit_after># -*- coding: utf-8 -*-

class BinarySearchTree(object):
  """Implements a basic binary search tree in Python.

  This BST does not do any kind of balancing, and thus can degenerate into a
  linked list in the worst case.
  """

  class _Node(object):
    """Represents a node in the binary search tree."""

    value = None
    left = None
    right = None

  size = 0

  _root = None

  def __init__(self, data=None):
    """Creates a new binary search tree.

    Args:
      data: An optional tuple or list containing data to be inserted IN ORDER
      into the BST.  If not supplied, the BST is created empty.
    """
    for datum in (data or []):
      self.insert(datum)

  @property
  def root(self):
    """Returns the value of the root node.

    If BST is empty, raises a ValueError (i.e., there's no root node to query).
    """
    try:
      return self._root.value
    except AttributeError:
      raise ValueError('Tree is empty; no root node to query.')
<|endoftext|>