Initial commit
This commit is contained in:
commit
ee76802e74
|
@ -0,0 +1,39 @@
|
||||||
|
import socket;
|
||||||
|
|
||||||
|
class NotRunningException (Exception):
|
||||||
|
pass;
|
||||||
|
|
||||||
|
class IRCBot:
|
||||||
|
# The IRC bot class. This can be reused, and will be the superclass of the actual minerbot.
|
||||||
|
def __init__(self, name, user, realname, owner):
|
||||||
|
self.name = name;
|
||||||
|
self.owner = owner;
|
||||||
|
self.user = user;
|
||||||
|
self.realname = realname;
|
||||||
|
self.running = False;
|
||||||
|
|
||||||
|
def begin(self, server, port, channels):
|
||||||
|
self.irc = socket.socket();
|
||||||
|
self.running = True;
|
||||||
|
self.irc.connect((server, port));
|
||||||
|
self.irc.send("NICK " + self.name + "\r\n");
|
||||||
|
self.irc.send("USER " + self.user + " 8 * " + self.realname + "\r\n");
|
||||||
|
for chan in channels:
|
||||||
|
self.irc.send("JOIN " + chan + "\r\n");
|
||||||
|
while True:
|
||||||
|
data = self.irc.recv(4096);
|
||||||
|
#print data;
|
||||||
|
if data.find("PING") != -1:
|
||||||
|
self.irc.send("PONG " + data.split()[1] + "\r\n");
|
||||||
|
elif data.find("PRIVMSG") != -1:
|
||||||
|
self.spokento(data)
|
||||||
|
|
||||||
|
def spokento(self, data):
|
||||||
|
if not self.running:
|
||||||
|
raise Exception("spokento was prematurely called.");
|
||||||
|
data_parts = data.split(" ",3);
|
||||||
|
id = data_parts[0];
|
||||||
|
nick = id.split("!")[0][1:];
|
||||||
|
message = data_parts[3][1:];
|
||||||
|
print(nick + ": " + message);
|
||||||
|
self.irc.send("PRIVMSG " + data_parts[2] + " :" + nick + ": " + message + "\r\n");
|
Binary file not shown.
|
@ -0,0 +1,12 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
#programlines = sys.stdin.readlines()
|
||||||
|
|
||||||
|
symbols = ["<",">","+","-","[","]",",","."]
|
||||||
|
def clean(i):
|
||||||
|
cleanedChars = []
|
||||||
|
|
||||||
|
for char in i:
|
||||||
|
if char in symbols:
|
||||||
|
cleanedChars.append(char);
|
||||||
|
|
||||||
|
return "".join(cleanedChars)
|
|
@ -0,0 +1,16 @@
|
||||||
|
import minerbot
|
||||||
|
|
||||||
|
while(True):
|
||||||
|
bot = minerbot.minerbot("minerbot","minerbot","minerobber")
|
||||||
|
f = open("/home/minerobber/misc/mbchan.txt")
|
||||||
|
channels = f.read().split("\n")
|
||||||
|
f.close()
|
||||||
|
# try:
|
||||||
|
val = bot.begin("localhost",6667,channels)
|
||||||
|
if val == 0:
|
||||||
|
break
|
||||||
|
# except Exception as e:
|
||||||
|
# raise e
|
||||||
|
# bot.addNote("minerobber","Minerbot Crash","Crashed with {}: {}".format(type(e).__name__,str(e)))
|
||||||
|
# finally:
|
||||||
|
# reload(minerbot)
|
|
@ -0,0 +1,42 @@
|
||||||
|
import requests
|
||||||
|
|
||||||
|
class ChanInfoError(Exception):
|
||||||
|
pass;
|
||||||
|
|
||||||
|
class ChannelInfo:
|
||||||
|
"""A class for obtaining info for a Twitch Channel"""
|
||||||
|
def __init__(self,channel,client_id):
|
||||||
|
self.channel = channel;
|
||||||
|
self.client_id = client_id;
|
||||||
|
self.resp = requests.get("https://api.twitch.tv/kraken/streams/{!s}?client_id={!s}".format(channel,client_id));
|
||||||
|
if self.resp.json().get("error") != None:
|
||||||
|
raise ChanInfoError("{status} {error} - \"{message}\"".format(**self.resp.json()))
|
||||||
|
|
||||||
|
"""If the channel is online, returns true. Else, returns false."""
|
||||||
|
def isOnline(self):
|
||||||
|
return self.resp.json().get('stream') != None;
|
||||||
|
|
||||||
|
"""Get the status of the stream."""
|
||||||
|
def getStatus(self):
|
||||||
|
return self.resp.json()['stream']['channel']['status']
|
||||||
|
|
||||||
|
"""Get the game."""
|
||||||
|
def getGame(self):
|
||||||
|
return self.resp.json()['stream']['game']
|
||||||
|
|
||||||
|
"""Get whether to display "playing" or "being"."""
|
||||||
|
def getDisplay(self):
|
||||||
|
return self.getGame() == "Creative"
|
||||||
|
|
||||||
|
"""Get viewer count."""
|
||||||
|
def getViewers(self):
|
||||||
|
return self.resp.json()['stream']['viewers']
|
||||||
|
|
||||||
|
"""Get embed frame (for HTML)"""
|
||||||
|
def getEmbed(self, width=950, height=700, autoplay=False):
|
||||||
|
return "<iframe src='http://player.twitch.tv/?channel={}&autoplay={}' width='{!s}' height='{!s}' frameborder='0' scrolling='no' allowfullscreen='true'></iframe>".format(self.channel,str(autoplay).lower(),width,height)
|
||||||
|
|
||||||
|
|
||||||
|
"""Update data, just runs the init again."""
|
||||||
|
def update(self):
|
||||||
|
self.__init__(self.channel,self.client_id)
|
Binary file not shown.
|
@ -0,0 +1,27 @@
|
||||||
|
testString = 'say "Jasper Oxide" "Are you really that stupid?"'
|
||||||
|
def parse(text,debug=False):
|
||||||
|
lines = [text.rstrip()]
|
||||||
|
result = []
|
||||||
|
for line in lines:
|
||||||
|
linetable = []
|
||||||
|
words = line.split(" ")
|
||||||
|
i=0
|
||||||
|
while i < len(words):
|
||||||
|
if words[i].startswith('"'):
|
||||||
|
if words[i].endswith('"'):
|
||||||
|
linetable.append(words[i][1:-1])
|
||||||
|
i = i + 1
|
||||||
|
continue
|
||||||
|
part = words[i][1:]
|
||||||
|
i=i+1
|
||||||
|
while not words[i].endswith('"'):
|
||||||
|
part = part + " " + words[i]
|
||||||
|
i = i + 1
|
||||||
|
part = part + " " + words[i][:-1]
|
||||||
|
linetable.append(part)
|
||||||
|
else:
|
||||||
|
part = words[i]
|
||||||
|
linetable.append(part)
|
||||||
|
i = i + 1
|
||||||
|
result.append(linetable)
|
||||||
|
return result[0][1:]
|
Binary file not shown.
|
@ -0,0 +1,40 @@
|
||||||
|
import socket;
|
||||||
|
|
||||||
|
class NotRunningException (Exception):
|
||||||
|
pass;
|
||||||
|
|
||||||
|
class IRCBot:
|
||||||
|
# The IRC bot class. This can be reused, and will be the superclass of the actual minerbot.
|
||||||
|
def __init__(self, name, user, realname, owner):
|
||||||
|
self.name = name;
|
||||||
|
self.owner = owner;
|
||||||
|
self.user = user;
|
||||||
|
self.realname = realname;
|
||||||
|
self.running = False;
|
||||||
|
|
||||||
|
def begin(self, server, port, channels):
|
||||||
|
self.irc = socket.socket();
|
||||||
|
self.running = True;
|
||||||
|
self.irc.connect((server, port));
|
||||||
|
self.irc.send("NICK " + self.name + "\r\n");
|
||||||
|
self.irc.send("USER " + self.user + " 8 * " + self.realname + "\r\n");
|
||||||
|
for chan in channels:
|
||||||
|
self.irc.send("JOIN " + chan + "\r\n");
|
||||||
|
while True:
|
||||||
|
data = self.irc.recv(4096);
|
||||||
|
#print data;
|
||||||
|
if data.find("PING") != -1:
|
||||||
|
self.irc.send("PONG " + data.split()[1] + "\r\n");
|
||||||
|
elif data.find("PRIVMSG") != -1:
|
||||||
|
self.spokento(data)
|
||||||
|
|
||||||
|
def spokento(self, data):
|
||||||
|
if not self.running:
|
||||||
|
raise Exception("spokento was prematurely called.");
|
||||||
|
data_parts = data.split(" ",3);
|
||||||
|
id = data_parts[0];
|
||||||
|
nick = id.split("!")[0][1:];
|
||||||
|
message = data_parts[3][1:-2];
|
||||||
|
print(nick + ": " + message);
|
||||||
|
if nick == self.owner and message.find("!colortest") == 0:
|
||||||
|
self.irc.send("PRIVMSG "+data_parts[2]+" :\x034,1yo\x0f")
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,20 @@
|
||||||
|
import random
|
||||||
|
|
||||||
|
class KWAMPlugin:
|
||||||
|
def __init__(self,bot):
|
||||||
|
for i in "kwam":
|
||||||
|
with open("data/"+i+"-words.txt") as f:
|
||||||
|
setattr(self,i,[line.replace("\n","") for line in f.readlines()])
|
||||||
|
self.bot=bot
|
||||||
|
self.answerRequests = True
|
||||||
|
|
||||||
|
def answer(self,channel,nick,msg):
|
||||||
|
if not msg.startswith("!kwam"):
|
||||||
|
return
|
||||||
|
if nick==self.bot.owner:
|
||||||
|
if msg.startswith("!kwam "):
|
||||||
|
self.answerRequests = msg.endswith("on")
|
||||||
|
return
|
||||||
|
if self.answerRequests:
|
||||||
|
words = [random.choice(self.k),random.choice(self.w),random.choice(self.a),random.choice(self.m)]
|
||||||
|
self.bot.mention(channel,nick," ".join(words))
|
|
@ -0,0 +1,35 @@
|
||||||
|
from subapi import SubAPI
|
||||||
|
|
||||||
|
class LuaPlugin:
|
||||||
|
"""Handles lua execution"""
|
||||||
|
def __init__(self,bot):
|
||||||
|
self.bot = bot
|
||||||
|
self.channels = dict()
|
||||||
|
|
||||||
|
def addChannel(self,chan):
|
||||||
|
self.channels[chan]=SubAPI()
|
||||||
|
self.channels[chan].addListener(self.outWithIt(chan))
|
||||||
|
self.channels[chan].start(["/usr/bin/lua"])
|
||||||
|
|
||||||
|
def outWithIt(self,chan):
|
||||||
|
def handler(msg):
|
||||||
|
if msg.strip()=="Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio":
|
||||||
|
return
|
||||||
|
self.bot.say(chan,msg)
|
||||||
|
return handler
|
||||||
|
|
||||||
|
def handleCommand(self,chan,sender,cmd):
|
||||||
|
if cmd.strip()=="!lua":
|
||||||
|
self.bot.mention(chan,sender,"Use !lua <lua command> to execute lua.")
|
||||||
|
elif not cmd.startswith("!lua "):
|
||||||
|
return
|
||||||
|
elif cmd.strip()=="!lua start" and not self.channels[chan]:
|
||||||
|
self.addChannel(chan)
|
||||||
|
self.bot.say(chan,"Lua session started")
|
||||||
|
elif cmd.strip()=="!lua reset" and self.channels[chan]:
|
||||||
|
self.channels[chan].stop()
|
||||||
|
del self.channels[chan]
|
||||||
|
self.addChannel(chan)
|
||||||
|
self.bot.say(chan,"Lua session reset")
|
||||||
|
else:
|
||||||
|
self.channels[chan].sendInput(cmd.strip.split(" ",2)[1])
|
|
@ -0,0 +1,42 @@
|
||||||
|
import random,json
|
||||||
|
class Chain:
|
||||||
|
def __init__(self):
|
||||||
|
self.map = {}
|
||||||
|
|
||||||
|
def addWord(self,lastWord,word):
|
||||||
|
if lastWord in self.map and not word in self.map[lastWord]:
|
||||||
|
self.map[lastWord].append(word)
|
||||||
|
elif not lastWord in self.map:
|
||||||
|
self.map[lastWord] = [word]
|
||||||
|
|
||||||
|
def train(self,sentance):
|
||||||
|
words = sentance.split(" ")
|
||||||
|
lastWord = words.pop(0)
|
||||||
|
self.addWord("",lastWord)
|
||||||
|
for word in words:
|
||||||
|
self.addWord(lastWord,word)
|
||||||
|
lastWord = word
|
||||||
|
self.addWord(lastWord,"")
|
||||||
|
|
||||||
|
def generate(self):
|
||||||
|
lastWord = random.choice(self.map[""])
|
||||||
|
sentence = lastWord
|
||||||
|
while lastWord != "":
|
||||||
|
word = random.choice(self.map[lastWord])
|
||||||
|
sentence += " " + word
|
||||||
|
lastWord = word
|
||||||
|
return sentence[:-1]
|
||||||
|
|
||||||
|
def to_json(self):
|
||||||
|
return json.dumps(self.map)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls,jsonstr):
|
||||||
|
ret = cls()
|
||||||
|
ret.map = json.loads(jsonstr)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def addLinesFromFile(chain,filename):
|
||||||
|
with open(filename) as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
chain.train(line.rstrip())
|
Binary file not shown.
|
@ -0,0 +1,17 @@
|
||||||
|
import markov
|
||||||
|
|
||||||
|
def chainFromFile(filename):
|
||||||
|
with open(filename) as f:
|
||||||
|
return markov.Chain.from_json(f.read())
|
||||||
|
|
||||||
|
titles = chainFromFile("data/titles.json")
|
||||||
|
synopses = chainFromFile("data/synopses.json")
|
||||||
|
|
||||||
|
def new_episode():
|
||||||
|
title = titles.generate().encode("utf-8")
|
||||||
|
synopsis = synopses.generate().encode("utf-8")
|
||||||
|
return (title,synopsis)
|
||||||
|
|
||||||
|
if __name__=="__main__":
|
||||||
|
details = new_episode()
|
||||||
|
print "New episode:\n{} - {}".format(*details)
|
Binary file not shown.
|
@ -0,0 +1,86 @@
|
||||||
|
import sieve,plugin
|
||||||
|
class Solver(plugin.Plugin):
|
||||||
|
def __init__(self,bot):
|
||||||
|
plugin.Plugin.__init__(self,bot,"!mbtilde ([a-z]+) ([A-Za-z0-9]+)(?: (.+))?")
|
||||||
|
|
||||||
|
def answer(self,c,n,m):
|
||||||
|
if not self.cmd.search(m):
|
||||||
|
return
|
||||||
|
if n!=self.bot.owner:
|
||||||
|
self.bot.say(c,"Don't tell me what to do!")
|
||||||
|
return
|
||||||
|
if c!="#bots":
|
||||||
|
self.bot.say(c,"Remember: tildebot only awards tildes in \#bots.")
|
||||||
|
plugin.Plugin.answer(self,c,n,m) # call super method
|
||||||
|
|
||||||
|
def run(self,cmd):
|
||||||
|
if not cmd.startswith("!mbtilde"):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
parts = cmd.split()
|
||||||
|
parts.pop(0)
|
||||||
|
parts = [part.strip() for part in parts]
|
||||||
|
try:
|
||||||
|
return getattr(self,parts[0])(*parts[1:])
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def request(self,c,n,m):
|
||||||
|
self.bot.say(c,self._request())
|
||||||
|
|
||||||
|
def _request(self):
|
||||||
|
return "!tilde"
|
||||||
|
|
||||||
|
def add(self,c,n,m):
|
||||||
|
self.bot.say(c,self._add(m.group(2),m.group(3)))
|
||||||
|
|
||||||
|
def _add(self,num1,num2):
|
||||||
|
return int(num1)+int(num2)
|
||||||
|
|
||||||
|
def sub(self,c,n,m):
|
||||||
|
self.bot.say(c,self._sub(m.group(2),m.group(3)))
|
||||||
|
|
||||||
|
def _sub(self,num1,num2):
|
||||||
|
return int(num1)-int(num2)
|
||||||
|
|
||||||
|
def mult(self,c,n,m):
|
||||||
|
self.bot.say(c,self._mult(m.group(2),m.group(3)))
|
||||||
|
|
||||||
|
def _mult(self,num1,num2):
|
||||||
|
return int(num1)*int(num2)
|
||||||
|
|
||||||
|
def div(self,c,n,m):
|
||||||
|
self.bot.say(c,self._div(m.group(2),m.group(3)))
|
||||||
|
|
||||||
|
def _div(self,num1,num2):
|
||||||
|
return int(num1)/int(num2)
|
||||||
|
|
||||||
|
def pow(self,c,n,m):
|
||||||
|
self.bot.say(c,self._pow(m.group(2),m.group(3)))
|
||||||
|
|
||||||
|
def _pow(self,num1,num2):
|
||||||
|
return int(num1)**int(num2)
|
||||||
|
|
||||||
|
def mod(self,c,n,m):
|
||||||
|
self.bot.say(c,self._mod(m.group(2),m.group(3)))
|
||||||
|
|
||||||
|
def _mod(self,num1,num2):
|
||||||
|
return int(num1)%int(num2)
|
||||||
|
|
||||||
|
def primefac(self,c,n,m):
|
||||||
|
self.bot.say(c,self._primefac(m.group(2)))
|
||||||
|
|
||||||
|
def _primefac(self,num):
|
||||||
|
return sieve.primefactors(int(num))
|
||||||
|
|
||||||
|
def score(self,c,n,m):
|
||||||
|
self.bot.say(c,self._score())
|
||||||
|
|
||||||
|
def _score(self,d):
|
||||||
|
return "!tildescore"
|
||||||
|
|
||||||
|
def say(self,c,n,m):
|
||||||
|
self.bot.say(c,self._say(m.group(2)))
|
||||||
|
|
||||||
|
def _say(self,msg):
|
||||||
|
return msg
|
Binary file not shown.
|
@ -0,0 +1,27 @@
|
||||||
|
if message.find("!steven-universe") == 0:
|
||||||
|
elif message.find("!log") == 0:
|
||||||
|
if message.find("!quit") == 0 and nick == self.owner:
|
||||||
|
elif message.find("!rollcall") == 0:
|
||||||
|
elif message.find("!twitch ") == 0:
|
||||||
|
elif message.find("!choose ") == 0:
|
||||||
|
elif message.strip == "!last5said":
|
||||||
|
elif message.find("!dicegame") == 0:
|
||||||
|
elif message.find("!online") == 0:
|
||||||
|
elif message.find("!reload\r\n") == 0 and self.owner == nick:
|
||||||
|
# elif message.find("!shop") == 0:
|
||||||
|
elif message.find("!tbadmin") == 0 and self.owner == nick:
|
||||||
|
elif message.find("!announce ") == 0:
|
||||||
|
# elif message.find("!guessing_game") == 0 and self.gg_state == "not-active":
|
||||||
|
# elif message.find("!join_guessing_game") == 0 and self.gg_state == "player-wait":
|
||||||
|
elif message.find("!reloadchannels") == 0 and nick == self.owner:
|
||||||
|
elif message.find("!save") == 0 and nick == self.owner:
|
||||||
|
elif message.find("!load") == 0 and nick == self.owner:
|
||||||
|
#elif message.find("!money") == 0:
|
||||||
|
elif message.find("!update-qdb-commits") == 0 and self.owner == nick:
|
||||||
|
elif message.find("!run ") == 0 and self.owner == nick:
|
||||||
|
#elif message.find("!tell") == 0:
|
||||||
|
elif message.find("!note ") == 0:
|
||||||
|
# elif message.find("!get-gg-state") == 0 and self.owner == nick:
|
||||||
|
elif message.find("!getStock") == 0:
|
||||||
|
elif message.find("!mbtilde ") == 0:
|
||||||
|
# elif message.find("!helpme") == 0:
|
|
@ -0,0 +1,414 @@
|
||||||
|
import socket,random,subprocess,threading,time,cPickle,string,time,prss,randwords,pstocks,chaninfo,primefac,choose_parser,notes,mbtilde,kwam,lua,urn,scplugin,json,math;
|
||||||
|
import os.path as fs;
|
||||||
|
from email.mime.text import MIMEText;
|
||||||
|
import markovuniverse as mu;
|
||||||
|
zws = ""
|
||||||
|
class NotRunningException (Exception):
|
||||||
|
pass;
|
||||||
|
|
||||||
|
log_format = "{} [{}] {}: {}"
|
||||||
|
|
||||||
|
def loadLNR():
|
||||||
|
with open("/home/minerobber/lnr.txt") as f:
|
||||||
|
return [l.rstrip() for l in f if l.rstrip()]
|
||||||
|
|
||||||
|
def saveLNR(lnr):
|
||||||
|
with open("/home/minerobber/lnr.txt","w") as f:
|
||||||
|
f.write("\n".join(lnr))
|
||||||
|
|
||||||
|
def filterNick(nick):
|
||||||
|
if len(nick) == 1:
|
||||||
|
print "Either "+nick+" is not a nick, or the person who has that nick needs a longer nick."
|
||||||
|
return nick
|
||||||
|
s = nick[0]+zws+nick[1:]
|
||||||
|
return s.encode('utf-8')
|
||||||
|
|
||||||
|
def log(channel, nick, message):
|
||||||
|
with open("/home/minerobber/log.txt","ab") as fh:
|
||||||
|
fh.write(log_format.format(time.strftime("%Y-%m-%d %H:%M:%S"),channel,nick,message))
|
||||||
|
with open("/home/minerobber/logs/"+time.strftime("%Y-%m-%d")+".txt","ab") as fh:
|
||||||
|
fh.write(log_format.format(time.strftime("%Y-%m-%d %H:%M:%S"),channel,nick,message))
|
||||||
|
|
||||||
|
def announce(channel, nick, ann, prssfeed):
|
||||||
|
prssfeed.addItem("Announcement by {} in {}".format(channel, nick),"https://tilde.town/~{}".format(nick),ann)
|
||||||
|
with open(fs.expanduser("~/public_html/announcements/rss.xml"),"wb") as rss:
|
||||||
|
rss.write(prssfeed.make())
|
||||||
|
with open(fs.expanduser("~/public_html/announcements/index.text"),"ab") as html:
|
||||||
|
html.write('{}, while in {}, announced: "{}" \n'.format(nick, channel, ann));
|
||||||
|
subprocess.check_output(["make -C ~/public_html/announcements -B"],shell=True)
|
||||||
|
cPickle.dump(prssfeed,open("/home/minerobber/misc/annrss","wb"))
|
||||||
|
|
||||||
|
def logJoin(channel,nick):
|
||||||
|
with open("/home/minerobber/log.txt","ab") as fh:
|
||||||
|
fh.write(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())+" "+nick+" joined "+channel)
|
||||||
|
|
||||||
|
def logPart(channel,nick):
|
||||||
|
with open("/home/minerobber/log.txt","ab") as fh:
|
||||||
|
fh.write(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())+" "+nick+" left "+channel)
|
||||||
|
|
||||||
|
def getBotanyPlantPath(user,file="{0}_plant_data.json"):
|
||||||
|
return "/home/{{0}}/.botany/{}".format(file).format(user)
|
||||||
|
|
||||||
|
def hasBotanyPlant(user):
|
||||||
|
return fs.exists(getBotanyPlantPath(user))
|
||||||
|
|
||||||
|
def hasVisitors(user):
|
||||||
|
return fs.exists(getBotanyPlantPath(user,"visitors.json"))
|
||||||
|
|
||||||
|
def getBotanyPlant(user):
|
||||||
|
if not hasBotanyPlant(user):
|
||||||
|
return False, {}
|
||||||
|
else:
|
||||||
|
with open(getBotanyPlantPath(user)) as f:
|
||||||
|
data = json.load(f)
|
||||||
|
# if not hasVisitors(user): # TODO: fix this
|
||||||
|
return True, data
|
||||||
|
# else:
|
||||||
|
# with open(getBotanyPlantPath(user,"visitors.json")):
|
||||||
|
# return True, data, json.load(f)
|
||||||
|
|
||||||
|
#def getBotanyLastWatered(dlw,vt):
|
||||||
|
# rvt = []
|
||||||
|
# for t in vt:
|
||||||
|
# if t < time.time():
|
||||||
|
# rvt.append(t)
|
||||||
|
# if not rvt:
|
||||||
|
# return dlw
|
||||||
|
# allts = [dlw]+rvt
|
||||||
|
# allts.sort()
|
||||||
|
# diffs = [(j-i)/86400.0 for i, j in zip(allts[:-1], allts[1:])]
|
||||||
|
# lve = next((x for x in diffs if x > 5), None)
|
||||||
|
# if not lve:
|
||||||
|
# return allts[-1]
|
||||||
|
# return allts[:diffs.index(lve)+1][-1] #this should actually work, believe it or not
|
||||||
|
|
||||||
|
class minerbot:
|
||||||
|
def __init__(self, name, user, owner):
|
||||||
|
self.name = name;
|
||||||
|
self.owner = owner;
|
||||||
|
self.user = user;
|
||||||
|
self.running = False;
|
||||||
|
self.reload = 0;
|
||||||
|
|
||||||
|
def begin(self, server, port, channels):
|
||||||
|
# declare variables here
|
||||||
|
self.irc = socket.socket();
|
||||||
|
self.randWordsList = randwords.corpus;
|
||||||
|
self.userList = [];
|
||||||
|
self.running = True;
|
||||||
|
self.channels = channels;
|
||||||
|
self.kwam = kwam.KWAMPlugin(self)
|
||||||
|
self.lua = lua.LuaPlugin(self)
|
||||||
|
self.rss = prss.PageRSS("Announcements","https://tilde.town/~minerobber/announcements","Announcements made by tilde.town members in IRC.",time.localtime())
|
||||||
|
if fs.isfile("/home/minerobber/misc/annrss"):
|
||||||
|
self.rss = cPickle.load(open("/home/minerobber/misc/annrss"))
|
||||||
|
self.notebook = notes.DatedNotebook()
|
||||||
|
self.solver = mbtilde.Solver(self)
|
||||||
|
self.urn = urn.UrnPlugin(self)
|
||||||
|
if fs.isfile("/home/minerobber/lnr.txt"):
|
||||||
|
self.lnr = loadLNR()
|
||||||
|
else:
|
||||||
|
self.lnr = []
|
||||||
|
saveLNR([])
|
||||||
|
# self.xkcd = xkcdpl.XKCDPlugin(self)
|
||||||
|
# self.g7sc = scplugin.G7SCPlugin(self,"!shinycalc")
|
||||||
|
#self.quiz = quiz.QuizGame("/home/minerobber/quiz.txt")
|
||||||
|
# connecting, as well as main loop
|
||||||
|
self.irc.connect((server, port));
|
||||||
|
self.irc.send("NICK " + self.name + "\r\n");
|
||||||
|
self.irc.send("USER " + self.user + " 8 * Making an IRC bot is fun!\r\n");
|
||||||
|
self.irc.recv(4096)
|
||||||
|
for chan in channels:
|
||||||
|
self.irc.send("JOIN " + chan + "\r\n");
|
||||||
|
while self.running:
|
||||||
|
data = self.irc.recv(4096);
|
||||||
|
if data.find("PING") != -1:
|
||||||
|
self.irc.send("PONG " + data.split()[1] + "\r\n");
|
||||||
|
elif data.find("NAMES") != -1 and not fs.isfile("/home/minerobber/userList"):
|
||||||
|
users = data[5:-3]
|
||||||
|
for name in users.split(" "):
|
||||||
|
table = []
|
||||||
|
table.append(name)
|
||||||
|
table.append(0)
|
||||||
|
self.userList.append(table);
|
||||||
|
elif data.find("PART") != -1:
|
||||||
|
logPart(data.split(" ")[2],data.split(" ")[0].split("!")[0][1:])
|
||||||
|
elif data.find("PRIVMSG") != -1:
|
||||||
|
self.spokento(data)
|
||||||
|
self.save()
|
||||||
|
return self.reload;
|
||||||
|
|
||||||
|
def runCMD(self, cmd):
|
||||||
|
i = subprocess.check_output([cmd],shell=True)
|
||||||
|
if "\n" in i:
|
||||||
|
i.replace("\n","; ")
|
||||||
|
return i;
|
||||||
|
|
||||||
|
def addNote(self,touser,fromuser,msg):
|
||||||
|
# print "ADDNOTE: {} {} {}".format(touser,fromuser,msg)
|
||||||
|
self.notebook.addNote(touser,fromuser,msg)
|
||||||
|
|
||||||
|
def readNotes(self,user):
|
||||||
|
# print "READNOTES: {}".format(user)
|
||||||
|
for msg in self.notebook.readNotes(user):
|
||||||
|
self.say(user,msg)
|
||||||
|
|
||||||
|
def haveNotesFor(self,user):
|
||||||
|
# print "CHECK: {}".format(user)
|
||||||
|
return self.notebook.checkNotes(user)
|
||||||
|
|
||||||
|
def spokento(self, data):
|
||||||
|
if not self.running:
|
||||||
|
raise Exception("spokento was prematurely called.");
|
||||||
|
data_parts = data.split(" ",3);
|
||||||
|
id = data_parts[0];
|
||||||
|
nick = id.split("!")[0][1:];
|
||||||
|
message = data_parts[3][1:];
|
||||||
|
channel = data_parts[2];
|
||||||
|
if nick=="tilde.town":
|
||||||
|
return
|
||||||
|
print "[" + channel + "] " + nick + ": " + message;
|
||||||
|
log(channel, nick, message)
|
||||||
|
self.rss.pubDate = time.localtime()
|
||||||
|
if self.haveNotesFor(nick):
|
||||||
|
self.readNotes(nick)
|
||||||
|
if message.strip()=="!water minerbot":
|
||||||
|
self.mention(channel, nick, "BZZ-ZAP! Please don't water me! I'm not waterproofed yet!!!!! BZZ-BZZ-ZZZ-ZAP!")
|
||||||
|
# elif message.find("!urlme "):
|
||||||
|
# parts = message.split()
|
||||||
|
# if len(parts)>1:
|
||||||
|
# self.mention(channel,nick,"https://tilde.town/~{}/{}".format(nick,parts[1]))
|
||||||
|
# elif message.find("!talklikeme"):
|
||||||
|
# self.say(channel,"!talklike "+nick)
|
||||||
|
# elif message.strip()=="!lnrdebug":
|
||||||
|
# self.say(channel,"lnr = {!s}".format(self.lnr))
|
||||||
|
# return
|
||||||
|
elif message.find("!plant ")==0:
|
||||||
|
ok, data = getBotanyPlant(message.split(" ",1)[1].rstrip())
|
||||||
|
if not ok:
|
||||||
|
self.mention(channel,nick,"{} doesn't have a plant".format(message.split(" ",1)[1].rstrip()))
|
||||||
|
else:
|
||||||
|
# user requested does indeed have a plant, and data is the loaded JSON representation of said plant
|
||||||
|
msg = "{d[owner]}'s ".format(d=data)
|
||||||
|
status = data["description"]
|
||||||
|
if data["is_dead"]:
|
||||||
|
status = "dead "+status
|
||||||
|
status+=" was watered"
|
||||||
|
lastwatered = data["last_watered"] #,[x['timestamp'] for x in visitors])
|
||||||
|
if (lastwatered-time.time())<=(24*60*60):
|
||||||
|
status+=" today"
|
||||||
|
hours = str(int(math.floor((time.time()-lastwatered)/3600)))
|
||||||
|
if hours=='0':
|
||||||
|
seconds = str(int(math.floor((time.time()-lastwatered)/60)))
|
||||||
|
if seconds=='1':
|
||||||
|
status+=" (about a second ago)"
|
||||||
|
else:
|
||||||
|
status+=" (about {} seconds ago)".format(seconds)
|
||||||
|
elif hours=='1':
|
||||||
|
status+=" (about an hour ago)"
|
||||||
|
else:
|
||||||
|
status+=" (about {} hours ago)".format(hours)
|
||||||
|
self.mention(channel,nick,msg+status)
|
||||||
|
elif message.find("!steven-universe") == 0:
|
||||||
|
self.mention(channel, nick, "\"{}\" - {}".format(*mu.new_episode()))
|
||||||
|
elif message.find("!quit") == 0 and nick == self.owner:
|
||||||
|
self.irc.send("QUIT :beep boop I'm a bot.\r\n");
|
||||||
|
self.running = False;
|
||||||
|
elif message.find("!rollcall") == 0:
|
||||||
|
self.say(channel,"Hey! I'm " + self.name + "! I'm a mess of code. Ask my developer (my nick, but replace bot with \"obber\") about commands of mine!")
|
||||||
|
elif message.find("!twitch ") == 0:
|
||||||
|
mparts = message.split(" ")
|
||||||
|
if len(mparts) == 2:
|
||||||
|
c = chaninfo.ChannelInfo(mparts[1][:-2],"h7lvoe263k42haljbhlbv2ag1nzt5nd")
|
||||||
|
if not c.isOnline():
|
||||||
|
self.say(channel,"{} is not streaming.".format(c.channel))
|
||||||
|
verb = "playing"
|
||||||
|
if c.getDisplay():
|
||||||
|
verb = "being"
|
||||||
|
self.say(channel, '{} is {} {}. Status: "{}"; Viewers: {!s}'.format(c.channel,verb,c.getGame(),c.getStatus(),c.getViewers()))
|
||||||
|
elif message.find("!choose ") == 0:
|
||||||
|
self.say(channel,nick+": "+random.choice(choose_parser.parse(message)))
|
||||||
|
elif message.strip == "!last5said":
|
||||||
|
with open("/home/minerobber/log.txt") as f:
|
||||||
|
lines = []
|
||||||
|
for line in f:
|
||||||
|
lines.append(line.strip())
|
||||||
|
for line in lines[:-5]:
|
||||||
|
self.say(nick,line)
|
||||||
|
elif message.find("!dicegame") == 0:
|
||||||
|
message_parts = message.split(" ",2)
|
||||||
|
sides = 6
|
||||||
|
choice = int(random.uniform(1,sides))
|
||||||
|
b_choice = int(random.uniform(1,sides))
|
||||||
|
if b_choice > choice:
|
||||||
|
winMSG = "I win!"
|
||||||
|
else:
|
||||||
|
if b_choice == choice:
|
||||||
|
winMSG = "It's a tie!"
|
||||||
|
else:
|
||||||
|
winMSG = "You win!"
|
||||||
|
self.say(channel,"You rolled a " + str(choice) + ", and I rolled a " + str(b_choice) + ". " + winMSG)
|
||||||
|
elif channel == self.name and nick == self.owner:
|
||||||
|
# d = False
|
||||||
|
# if message.startwith("s "):
|
||||||
|
# d=True
|
||||||
|
# message=message.split(" ",2)[1]
|
||||||
|
print(self.owner + " used the global to say: \"" + message + "\"")
|
||||||
|
# if d:
|
||||||
|
self.globalmsg(message)
|
||||||
|
# else:
|
||||||
|
# self.globalmsg("[GLOBAL] "+message)
|
||||||
|
# self.globalmsg(("[GLOBAL] " if not d else "") + message)
|
||||||
|
elif message.find("!lnr") == 0:
|
||||||
|
if nick==self.owner and len(message.split(" "))>1:
|
||||||
|
self.lnr.append(message.split(" ",1)[1].rstrip())
|
||||||
|
saveLNR(self.lnr)
|
||||||
|
self.mention(channel,nick,"I'll remember that...")
|
||||||
|
return
|
||||||
|
for i in self.lnr:
|
||||||
|
self.mention(nick,nick,"Late night rambling: {}".format(i))
|
||||||
|
self.mention(channel,nick,"All late night ramblings have been PM'd to you.")
|
||||||
|
elif message.find("!online") == 0:
|
||||||
|
results = self.runCMD("onlinepeople4irc")
|
||||||
|
leet = string.maketrans("aelosiuUc","43105|Uu(")
|
||||||
|
self.say(channel, results.translate(leet))
|
||||||
|
elif message.find("!reload\r\n") == 0 and self.owner == nick:
|
||||||
|
self.irc.send("QUIT :Reloading bot code...\r\n");
|
||||||
|
self.reload = 1;
|
||||||
|
self.running = False;
|
||||||
|
elif message.find("!announce ") == 0:
|
||||||
|
announce(channel, nick, " ".join(message.split(" ")[1:]), self.rss)
|
||||||
|
elif message.find("!reloadchannels") == 0 and nick == self.owner:
|
||||||
|
channels = []
|
||||||
|
with open("/home/minerobber/misc/mbchan.txt") as f:
|
||||||
|
channels = f.readlines()
|
||||||
|
self.channels_2 = channels
|
||||||
|
for channel in self.channels_2:
|
||||||
|
if channel not in self.channels:
|
||||||
|
self.irc.send("JOIN {}\r\n".format(channel))
|
||||||
|
self.channels = self.channels_2
|
||||||
|
elif message.find("!save") == 0 and nick == self.owner:
|
||||||
|
self.save()
|
||||||
|
elif message.find("!load") == 0 and nick == self.owner:
|
||||||
|
self.load()
|
||||||
|
elif message.find("!update-qdb-commits") == 0 and self.owner == nick:
|
||||||
|
self.say(channel, self.runCMD("/home/minerobber/qdb-commits-gen.sh"))
|
||||||
|
elif message.find("!run ") == 0 and self.owner == nick:
|
||||||
|
prog = message.split(" ",1)[1]
|
||||||
|
nprog = which(prog.split(" ",1)[0])
|
||||||
|
if nprog is None:
|
||||||
|
self.say(channel,"Error: program does not exist!")
|
||||||
|
else:
|
||||||
|
self.say(channel,self.runCMD(prog.replace(prog.split(" ",1)[0],nprog)))
|
||||||
|
elif message.find("!tell") == 0:
|
||||||
|
self.say(nick,"DEPRECATED: Use new \"!note\" command (same syntax)")
|
||||||
|
elif message.find("!note ") == 0:
|
||||||
|
parts = message.split(" ",2)
|
||||||
|
if not len(parts) == 3:
|
||||||
|
self.mention(channel,nick,"usage: !note <user> <message>")
|
||||||
|
else:
|
||||||
|
self.addNote(parts[1],nick,parts[2])
|
||||||
|
self.mention(channel,nick,"Message sent for {}.".format(parts[1]))
|
||||||
|
elif message.find("!getStock") == 0:
|
||||||
|
self.mention(channel,nick,"This command is out-of-service while my developer figures out what's wrong with me.")
|
||||||
|
return
|
||||||
|
ticker = pstocks.StockTicker(format="{0} ({1}) is currently priced at {2}. (a change of {3})")
|
||||||
|
parts = message.split(" ")
|
||||||
|
if len(parts) < 2:
|
||||||
|
self.say(channel, "Usage: '!getStock <ticker>'")
|
||||||
|
return
|
||||||
|
for symbol in parts[1:]:
|
||||||
|
ticker.addSymbol(symbol)
|
||||||
|
for message in ticker.getTickerValues():
|
||||||
|
self.say(channel,message)
|
||||||
|
elif message.find("!mbtilde ") == 0:
|
||||||
|
if nick != self.owner:
|
||||||
|
self.say(channel,"Don't tell me what to do!")
|
||||||
|
return
|
||||||
|
if channel != "#bots":
|
||||||
|
self.say(channel,"Remember: tildebot only awards tildes in \#bots.")
|
||||||
|
result = self.solver.run(message)
|
||||||
|
if result:
|
||||||
|
if type(result)==str:
|
||||||
|
self.say(channel,result)
|
||||||
|
else:
|
||||||
|
self.say(channel,str(result))
|
||||||
|
elif message.strip()=="!discord":
|
||||||
|
self.mention(channel,nick,"The discord invite link is: https://discord.gg/RS8gJAV")
|
||||||
|
self.solver.answer(channel,nick,message)
|
||||||
|
#self.xkcd.answer(channel,nick,message)
|
||||||
|
#self.xkcd.check_for_new_xkcd(channel)
|
||||||
|
self.kwam.answer(channel,nick,message)
|
||||||
|
# self.g7sc.handleCommand(channel,nick,message)
|
||||||
|
# self.urn.onMessage(self,channel,nick,message)
|
||||||
|
# self.lua.handleCommand(channel,nick,message)
|
||||||
|
|
||||||
|
def globalmsg(self,message):
|
||||||
|
for chan in self.channels:
|
||||||
|
self.say(chan,message)
|
||||||
|
|
||||||
|
def say(self, chan, message):
|
||||||
|
try:
|
||||||
|
if type(message)!=str:
|
||||||
|
message = str(message)
|
||||||
|
message = message.replace("\n","")
|
||||||
|
self.irc.send("PRIVMSG " + chan + " :" + message + "\r\n")
|
||||||
|
if chan.find("#") == 0:
|
||||||
|
log(chan, self.name, message)
|
||||||
|
print("[{}] {}: {}".format(chan,self.name,message))
|
||||||
|
except:
|
||||||
|
self.say(chan,"Failed to send message, try again!")
|
||||||
|
|
||||||
|
def mention(self,chan,nick,message):
|
||||||
|
self.say(chan,nick+": "+message)
|
||||||
|
|
||||||
|
# def playQuizGame(self,channel,nick,message):
|
||||||
|
# if self.quiz.notPlaying(nick):
|
||||||
|
# self.quiz.addPlayer(nick)
|
||||||
|
# self.mention(channel,nick,self.quiz.getQuestion(nick)+" Use !a, !b, !c, or !d to answer.")
|
||||||
|
# else:
|
||||||
|
# if message.rstrip() not in ("!a","!b","!c","!d"):
|
||||||
|
# return
|
||||||
|
# if not self.quiz.answer(nick,message[1]):
|
||||||
|
# self.mention(channel,nick,"Close, but no dice! Try again!")
|
||||||
|
# else:
|
||||||
|
# self.mention(channel,nick,"Correct!")
|
||||||
|
# self.quiz.addPoint(nick)
|
||||||
|
# self.quiz.save()
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
# self.quiz.save()
|
||||||
|
saveLNR(self.lnr)
|
||||||
|
return
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
# self.quiz.load()
|
||||||
|
return
|
||||||
|
|
||||||
|
def num(s):
|
||||||
|
try:
|
||||||
|
int(s)
|
||||||
|
except ValueError:
|
||||||
|
float(s)
|
||||||
|
|
||||||
|
def wait(s, minutes):
|
||||||
|
if minutes:
|
||||||
|
time.sleep(s * 60)
|
||||||
|
else:
|
||||||
|
time.sleep(s)
|
||||||
|
|
||||||
|
def which(s):
|
||||||
|
import os
|
||||||
|
def is_exe(fpath):
|
||||||
|
return fs.isfile(fpath) and os.access(fpath, os.X_OK)
|
||||||
|
fpath, fname = fs.split(s)
|
||||||
|
if fpath:
|
||||||
|
if is_exe(program):
|
||||||
|
return program
|
||||||
|
else:
|
||||||
|
for path in os.environ["PATH"].split(os.pathsep):
|
||||||
|
path = path.strip('"')
|
||||||
|
exe_file = os.path.join(path, s)
|
||||||
|
if is_exe(exe_file):
|
||||||
|
return exe_file
|
||||||
|
return None;
|
|
@ -0,0 +1,380 @@
|
||||||
|
import socket,random,subprocess,threading,time,cPickle,string,time,prss,randwords,pstocks,chaninfo,primefac,re;
|
||||||
|
import os.path as fs;
|
||||||
|
from email.mime.text import MIMEText;
|
||||||
|
#with open("zws.txt","rb") as f:
|
||||||
|
# zws = f.readAll()
|
||||||
|
zws = ""
|
||||||
|
class NotRunningException (Exception):
|
||||||
|
pass;
|
||||||
|
|
||||||
|
log_format = "{} [{}] {}: {}"
|
||||||
|
|
||||||
|
def filterNick(nick):
|
||||||
|
if len(nick) == 1:
|
||||||
|
print "Either "+nick+" is not a nick, or the person who has that nick needs a longer nick."
|
||||||
|
return nick
|
||||||
|
s = nick[0]+zws+nick[1:]
|
||||||
|
return s.encode('utf-8')
|
||||||
|
|
||||||
|
def log(channel, nick, message):
|
||||||
|
with open("/home/minerobber/log.txt","ab") as fh:
|
||||||
|
fh.write(log_format.format(time.strftime("%Y-%m-%d %H:%M:%S"),channel,nick,message))
|
||||||
|
with open("/home/minerobber/logs/"+time.strftime("%Y-%m-%d")+".txt","ab") as fh:
|
||||||
|
fh.write(log_format.format(time.strftime("%Y-%m-%d %H:%M:%S"),channel,nick,message))
|
||||||
|
|
||||||
|
def logPublic(channel, nick, message):
|
||||||
|
with open("/home/minerobber/public_html/public_msgs.txt","ab") as fh:
|
||||||
|
fh.write(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())+" ["+channel+"] "+nick+": "+message)
|
||||||
|
|
||||||
|
def announce(channel, nick, ann, prssfeed):
|
||||||
|
prssfeed.addItem("Announcement by {} in {}".format(channel, nick),"https://tilde.town/~{}".format(nick),ann)
|
||||||
|
with open(fs.expanduser("~/public_html/announcements/rss.xml"),"wb") as rss:
|
||||||
|
rss.write(prssfeed.make())
|
||||||
|
with open(fs.expanduser("~/public_html/announcements/index.text"),"ab") as html:
|
||||||
|
html.write('{}, while in {}, announced: "{}" \n'.format(nick, channel, ann));
|
||||||
|
subprocess.check_output(["make -C ~/public_html/announcements -B"],shell=True)
|
||||||
|
cPickle.dump(prssfeed,open("/home/minerobber/misc/annrss","wb"))
|
||||||
|
|
||||||
|
def logJoin(channel,nick):
|
||||||
|
with open("/home/minerobber/log.txt","ab") as fh:
|
||||||
|
fh.write(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())+" "+nick+" joined "+channel)
|
||||||
|
|
||||||
|
def logPart(channel,nick):
|
||||||
|
with open("/home/minerobber/log.txt","ab") as fh:
|
||||||
|
fh.write(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())+" "+nick+" left "+channel)
|
||||||
|
|
||||||
|
class minerbot:
|
||||||
|
def __init__(self, name, user, owner):
|
||||||
|
self.name = name;
|
||||||
|
self.owner = owner;
|
||||||
|
self.user = user;
|
||||||
|
self.running = False;
|
||||||
|
self.reload = 0;
|
||||||
|
|
||||||
|
def begin(self, server, port, channels):
|
||||||
|
# declare variables here
|
||||||
|
self.irc = socket.socket();
|
||||||
|
self.randWordsList = randwords.corpus;
|
||||||
|
self.userList = [];
|
||||||
|
if fs.isfile("/home/minerobber/userList"):
|
||||||
|
self.load();
|
||||||
|
self.running = True;
|
||||||
|
self.channels = channels;
|
||||||
|
self.emailTemplate = ["~{0} wanted me to tell you:\n"]
|
||||||
|
self.rss = prss.PageRSS("Announcements","https://tilde.town/~minerobber/announcements","Announcements made by tilde.town members in IRC.",time.localtime())
|
||||||
|
if fs.isfile("/home/minerobber/misc/annrss"):
|
||||||
|
self.rss = cPickle.load(open("/home/minerobber/misc/annrss"))
|
||||||
|
# self.guessgameplaying = False;
|
||||||
|
# self.gg_players = {};
|
||||||
|
# self.gg_state = "not-active";
|
||||||
|
# self.gg_votes = {}
|
||||||
|
# connecting, as well as main loop
|
||||||
|
self.irc.connect((server, port));
|
||||||
|
self.irc.send("NICK " + self.name + "\r\n");
|
||||||
|
self.irc.send("USER " + self.user + " 8 * Making an IRC bot is fun!\r\n");
|
||||||
|
for chan in channels:
|
||||||
|
self.irc.send("JOIN " + chan + "\r\n");
|
||||||
|
while self.running:
|
||||||
|
data = self.irc.recv(4096);
|
||||||
|
#print data;
|
||||||
|
if data.find("PING") != -1:
|
||||||
|
self.irc.send("PONG " + data.split()[1] + "\r\n");
|
||||||
|
elif data.find("NAMES") != -1 and not fs.isfile("/home/minerobber/userList"):
|
||||||
|
users = data[5:-3]
|
||||||
|
for name in users.split(" "):
|
||||||
|
table = []
|
||||||
|
table.append(name)
|
||||||
|
table.append(0)
|
||||||
|
self.userList.append(table);
|
||||||
|
elif data.find("JOIN") != -1:
|
||||||
|
logJoin(data.split(" ")[2],data.split(" ")[0].split("!")[0][1:])
|
||||||
|
if data.split(" ")[2] == "#music" and data.split(" ")[0].split("!")[0][1:] != self.nick:
|
||||||
|
self.say(data.split(" ")[2],"Hello, "+data.split(" ")[0].split("!")[0][1:]+"! If you want to listen along, the URL is: https://tilde.town/~kc/jukebot/listen")
|
||||||
|
elif data.find("PART") != -1:
|
||||||
|
logPart(data.split(" ")[2],data.split(" ")[0].split("!")[0][1:])
|
||||||
|
elif data.find("PRIVMSG") != -1:
|
||||||
|
self.spokento(data)
|
||||||
|
self.save()
|
||||||
|
return self.reload;
|
||||||
|
|
||||||
|
def runCMD(self, cmd):
|
||||||
|
i = subprocess.check_output([cmd],shell=True)
|
||||||
|
if "\n" in i:
|
||||||
|
i.replace("\n","; ")
|
||||||
|
return i;
|
||||||
|
|
||||||
|
def sendEmail(self, channel, sender, recipient, text):
|
||||||
|
msg = MIMEText("~{0} wanted me to tell you:\n> {1}".format(sender,text))
|
||||||
|
msg["From"] = "minerbot-messages@tilde.town"
|
||||||
|
msg["To"] = "{0}@tilde.town".format(recipient)
|
||||||
|
msg["Subject"] = "Message from ~{0}".format(sender)
|
||||||
|
msg["Cc"] = "{0}@tilde.town".format(sender)
|
||||||
|
mail = subprocess.Popen("{0} -t -oi".format(which("sendmail")).split(" "),stdin=subprocess.PIPE)
|
||||||
|
mail.communicate(msg.as_string())
|
||||||
|
self.say(channel,"Mail sent!")
|
||||||
|
# mail.close()
|
||||||
|
|
||||||
|
def spokento(self, data):
|
||||||
|
if not self.running:
|
||||||
|
raise Exception("spokento was prematurely called.");
|
||||||
|
data_parts = data.split(" ",3);
|
||||||
|
id = data_parts[0];
|
||||||
|
nick = id.split("!")[0][1:];
|
||||||
|
message = data_parts[3][1:];
|
||||||
|
channel = data_parts[2];
|
||||||
|
print "[" + channel + "] " + nick + ": " + message;
|
||||||
|
log(channel, nick, message)
|
||||||
|
self.rss.pubDate = time.localtime()
|
||||||
|
if message.find(self.owner) != -1:
|
||||||
|
logPublic(channel,nick,message)
|
||||||
|
elif message.find("!log") == 0:
|
||||||
|
logPublic(channel,nick,message.split(" ",2)[1])
|
||||||
|
if message.find("!quit") == 0 and nick == self.owner:
|
||||||
|
self.irc.send("QUIT :beep boop I'm a bot.\r\n");
|
||||||
|
self.running = False;
|
||||||
|
elif message.find("!rollcall") == 0:
|
||||||
|
self.say(channel,"Hey! I'm " + self.name + "! Use '!help' to see a list of my commands.")
|
||||||
|
elif message.find("!twitch ") == 0:
|
||||||
|
mparts = message.split(" ")
|
||||||
|
if len(mparts) == 2:
|
||||||
|
c = chaninfo.ChannelInfo(mparts[1][:-2],"h7lvoe263k42haljbhlbv2ag1nzt5nd")
|
||||||
|
if not c.isOnline():
|
||||||
|
return
|
||||||
|
verb = "playing"
|
||||||
|
if c.getDisplay():
|
||||||
|
verb = "being"
|
||||||
|
self.say(channel, '{} is {} {}. Status: "{}"; Viewers: {!s}'.format(c.channel,verb,c.getGame(),c.getStatus(),c.getViewers()))
|
||||||
|
elif message.strip == "!last5said":
|
||||||
|
with open("/home/minerobber/log.txt") as f:
|
||||||
|
lines = []
|
||||||
|
for line in f:
|
||||||
|
lines.append(line.strip())
|
||||||
|
for line in lines[:-5]:
|
||||||
|
self.say(nick,line)
|
||||||
|
elif message.find("!dicegame") == 0:
|
||||||
|
message_parts = message.split(" ",2)
|
||||||
|
sides = 6
|
||||||
|
choice = int(random.uniform(1,sides))
|
||||||
|
b_choice = int(random.uniform(1,sides))
|
||||||
|
if b_choice > choice:
|
||||||
|
winMSG = "I win!"
|
||||||
|
else:
|
||||||
|
if b_choice == choice:
|
||||||
|
winMSG = "It's a tie!"
|
||||||
|
else:
|
||||||
|
winMSG = "You win!"
|
||||||
|
self.say(channel,"You rolled a " + str(choice) + ", and I rolled a " + str(b_choice) + ". " + winMSG)
|
||||||
|
elif channel == self.name and nick == self.owner:
|
||||||
|
print(self.owner + " used the global to say: \"" + message + "\"")
|
||||||
|
for chan in self.channels:
|
||||||
|
self.say(chan,"[GLOBAL] " + message)
|
||||||
|
elif message.find("!online") == 0:
|
||||||
|
results = self.runCMD("onlinepeople4irc")
|
||||||
|
leet = string.maketrans("aelosiuUc","43105|Uu(")
|
||||||
|
self.say(channel, results.translate(leet))
|
||||||
|
elif message.find("!reload") == 0 and self.owner == nick:
|
||||||
|
self.irc.send("QUIT :Reloading bot code...\r\n");
|
||||||
|
self.reload = 1;
|
||||||
|
self.running = False;
|
||||||
|
# elif message.find("!shop") == 0:
|
||||||
|
#nyi
|
||||||
|
elif message.find("!tbadmin") == 0 and self.owner == nick:
|
||||||
|
message_parts = message.split(" ")
|
||||||
|
if message_parts[1] == "add":
|
||||||
|
for i in self.userList:
|
||||||
|
if message_parts[2] == i[0]:
|
||||||
|
i[1] += int(message_parts[3])
|
||||||
|
self.save()
|
||||||
|
elif message_parts[1] == "rm":
|
||||||
|
for i in self.userList:
|
||||||
|
if message_parts[2] == i[0]:
|
||||||
|
i[1] += int(message_parts[3])
|
||||||
|
self.save()
|
||||||
|
elif message_parts[1] == "view":
|
||||||
|
for i in self.userList:
|
||||||
|
if message_parts[2] == i[0]:
|
||||||
|
self.say(channel,i[0] + " has " + str(i[1]) + " tildebucks.")
|
||||||
|
elif message.find("!announce ") == 0:
|
||||||
|
announce(channel, nick, " ".join(message.split(" ")[1:]), self.rss)
|
||||||
|
# elif message.find("!guessing_game") == 0 and self.gg_state == "not-active":
|
||||||
|
# thread = threading.Thread(target=self.playGuessingGame, args=(channel));
|
||||||
|
# elif message.find("!join_guessing_game") == 0 and self.gg_state == "player-wait":
|
||||||
|
# self.gg_players.append(nick);
|
||||||
|
elif message.find("!save") == 0 and nick == self.owner:
|
||||||
|
self.save()
|
||||||
|
elif message.find("!load") == 0 and nick == self.owner:
|
||||||
|
self.load()
|
||||||
|
#elif message.find("!money") == 0:
|
||||||
|
# for i in self.userList:
|
||||||
|
# if i[0] == nick:
|
||||||
|
# self.say(channel,(nick + " has " + str(i[1]) + " tildebucks."))
|
||||||
|
elif message.find("!update-qdb-commits") == 0 and self.owner == nick:
|
||||||
|
self.say(channel, self.runCMD("/home/minerobber/qdb-commits-gen.sh"))
|
||||||
|
elif message.find("!run ") == 0 and self.owner == nick:
|
||||||
|
prog = message.split(" ",1)[1]
|
||||||
|
nprog = which(prog.split(" ",1)[0])
|
||||||
|
if nprog is None:
|
||||||
|
self.say(channel,"Error: program does not exist!")
|
||||||
|
else:
|
||||||
|
self.say(channel,self.runCMD(prog.replace(prog.split(" ",1)[0],nprog)))
|
||||||
|
elif message.find("!tell") == 0:
|
||||||
|
parts = message.split(" ",2)
|
||||||
|
if not len(parts) == 3:
|
||||||
|
self.say(channel,"Usage: !tell <user> <message>")
|
||||||
|
else:
|
||||||
|
self.sendEmail(channel,nick,parts[1],parts[2][:-2])
|
||||||
|
# elif message.find("!get-gg-state") == 0 and self.owner == nick:
|
||||||
|
# self.say(channel, "GG-State: " + self.gg_state)
|
||||||
|
elif message.find("!getStock") == 0:
|
||||||
|
ticker = pstocks.StockTicker(format="{0} ({1}) is currently priced at {2}. (a change of {3})")
|
||||||
|
parts = message.split(" ")
|
||||||
|
if len(parts) < 2:
|
||||||
|
self.say(channel, "Usage: '!getStock <ticker>'")
|
||||||
|
return
|
||||||
|
for symbol in parts[1:]:
|
||||||
|
ticker.addSymbol(symbol)
|
||||||
|
for message in ticker.getTickerValues():
|
||||||
|
self.say(channel,message)
|
||||||
|
elif message.find("!mbtilde ") == 0:
|
||||||
|
if nick != self.owner:
|
||||||
|
self.say(channel,"Don't tell me what to do!")
|
||||||
|
return
|
||||||
|
if channel != "#bots":
|
||||||
|
self.say(channel,"Remember: tildebot only awards tildes in \#bots.")
|
||||||
|
parts = message.split(" ",2)
|
||||||
|
parts = [s.rstrip() for s in parts]
|
||||||
|
if parts[1] == "request":
|
||||||
|
self.say("#bots","!tilde")
|
||||||
|
if parts[1] == "add":
|
||||||
|
nums = [int(s) for s in parts[2].split(" ")]
|
||||||
|
self.say(channel,"{!s}".format(sum(nums)))
|
||||||
|
if parts[1] == "sub":
|
||||||
|
nums = [int(s) for s in parts[2].split(" ",1)]
|
||||||
|
self.say(channel,"{!s}".format(nums[1]-nums[0]))
|
||||||
|
if parts[1] == "mult":
|
||||||
|
nums = [int(s) for s in parts[2].split(" ",1)]
|
||||||
|
self.say(channel,"{!s}".format(nums[1]*nums[0]))
|
||||||
|
if parts[1] == "divide":
|
||||||
|
nums = [int(s) for s in parts[2].split(" ",1)]
|
||||||
|
try:
|
||||||
|
self.say(channel,"{!s}".format(nums[0]/nums[1]))
|
||||||
|
except ZeroDivisionError:
|
||||||
|
self.say(channel,"Bugger off!")
|
||||||
|
if parts[1] == "mod":
|
||||||
|
nums = [int(s) for s in parts[2].split(" ",1)]
|
||||||
|
self.say(channel,"{!s}".format(nums[0]%nums[1]))
|
||||||
|
if parts[1] == "factor":
|
||||||
|
self.say(channel,"{!s},{!s}".format(*list(primefac.primefac(int(parts[2]))))
|
||||||
|
elif message.find("!rpg") and channel=="#rpg":
|
||||||
|
parts = message.split(" ")
|
||||||
|
if len(parts) < 2:
|
||||||
|
self.say(channel,"Usage: !rpg <action> [parameters]")
|
||||||
|
if parts[1]=="roll" and len(parts)==3:
|
||||||
|
descriptor = parts[2].rstrip()
|
||||||
|
t = re.match(descriptor,r"^(\d+)d(\d+)$")
|
||||||
|
if not t:
|
||||||
|
self.say(channel,"Usage: !rpg roll <amount of dice>d<number of sides on each>")
|
||||||
|
self.say(channel,"Example: !rpg roll 1d100")
|
||||||
|
number = t.match(0)
|
||||||
|
sides =
|
||||||
|
# elif message.find("!helpme") == 0:
|
||||||
|
# help_parts = message.split(" ",2)
|
||||||
|
# if len(help_parts) < 2:
|
||||||
|
# self.say(channel,"Commands: 'dicegame', 'online', 'tell';")
|
||||||
|
# else:
|
||||||
|
# if help_parts[1] == "dicegame":
|
||||||
|
# self.say(channel,"Play a dice game against " + self.name + ". Usage: '!dicegame'")
|
||||||
|
# elif help_parts[1] == "online":
|
||||||
|
# self.say(channel,"Returns a list of online users, as well as a user count. Usage: '!online'")
|
||||||
|
# elif help_parts[1] == "tell":
|
||||||
|
# self.say(channel,"Sends a user an email to let them know of something. Usage: '!tell <user> <thing to tell them>'")
|
||||||
|
# elif help_parts[1] == "words":
|
||||||
|
# self.say(channel,"Generates a random string of words. Usage: '!words'")
|
||||||
|
# elif help_parts[1] == "getStock":
|
||||||
|
# self.say(channel,"Gets stock info for a specific ticker. Usage: '!getStock <ticker>'")
|
||||||
|
# elif self.gg_state == "player-wait-vote" and message.find("!guess"):
|
||||||
|
# if nick in self.gg_players:
|
||||||
|
# for i in self.gg_votes:
|
||||||
|
# if i[0] == nick:
|
||||||
|
# return;
|
||||||
|
# self.gg_votes.append({nick,int(message.split(" ")[1])})
|
||||||
|
# if self.gg_state == "player-wait-vote":
|
||||||
|
# playerDouble = {};
|
||||||
|
# for i in self.gg_votes:
|
||||||
|
# if i[0] in self.gg_players:
|
||||||
|
# playerDouble.append(i[0])
|
||||||
|
# if self.gg_players == playerDouble:
|
||||||
|
# self.gg_state = "all-voted"
|
||||||
|
# self.randWordsList.append(message)
|
||||||
|
|
||||||
|
def say(self, chan, message):
|
||||||
|
self.irc.send("PRIVMSG " + chan + " :" + message + "\r\n")
|
||||||
|
if chan.find("#") == 0:
|
||||||
|
log(chan, self.name, message)
|
||||||
|
|
||||||
|
def playGuessingGame(self,chan):
|
||||||
|
self.gg_players = []
|
||||||
|
self.say(chan, "Generating number to guess...")
|
||||||
|
gg_number = random.uniform(1,100)
|
||||||
|
self.gg_state = "player-wait"
|
||||||
|
self.say(chan, "Game will start soon! To join, type \"!join_guessing_game\"")
|
||||||
|
wait(15, True)
|
||||||
|
self.gg_state = "started"
|
||||||
|
self.say(chan, "The game has started!")
|
||||||
|
playerString = "Players: "
|
||||||
|
for player in self.gg_players:
|
||||||
|
playerString += player + " "
|
||||||
|
self.say(chan, playerString)
|
||||||
|
self.say(chan,"How to play: guess a number between 1 and 100.")
|
||||||
|
self.gg_state = "player-wait-vote"
|
||||||
|
while not self.gg_state == "all-voted":
|
||||||
|
wait(5,False)
|
||||||
|
correct_players = [];
|
||||||
|
for i in self.gg_votes:
|
||||||
|
if gg_number == i[1]:
|
||||||
|
correct_players.append(i[0])
|
||||||
|
correctVoteString = "Winners: "
|
||||||
|
for player in correct_players:
|
||||||
|
correctVoteString += player + " "
|
||||||
|
self.say(chan, correctVoteString)
|
||||||
|
self.say(chan, "All of the winners get 3 tildebucks!")
|
||||||
|
for user in self.userList:
|
||||||
|
if user[0] in correct_players:
|
||||||
|
user[1] += 3;
|
||||||
|
self.save()
|
||||||
|
self.gg_state = "not-active"
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
cPickle.dump(self.userList, open("/home/minerobber/userList","wb"))
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
cPickle.load(open("/home/minerobber/userList","rb"))
|
||||||
|
|
||||||
|
def num(s):
|
||||||
|
try:
|
||||||
|
int(s)
|
||||||
|
except ValueError:
|
||||||
|
float(s)
|
||||||
|
|
||||||
|
def wait(s, minutes):
|
||||||
|
if minutes:
|
||||||
|
time.sleep(s * 60)
|
||||||
|
else:
|
||||||
|
time.sleep(s)
|
||||||
|
|
||||||
|
def which(s):
|
||||||
|
import os
|
||||||
|
def is_exe(fpath):
|
||||||
|
return fs.isfile(fpath) and os.access(fpath, os.X_OK)
|
||||||
|
|
||||||
|
fpath, fname = fs.split(s)
|
||||||
|
if fpath:
|
||||||
|
if is_exe(program):
|
||||||
|
return program
|
||||||
|
else:
|
||||||
|
for path in os.environ["PATH"].split(os.pathsep):
|
||||||
|
path = path.strip('"')
|
||||||
|
exe_file = os.path.join(path, s)
|
||||||
|
if is_exe(exe_file):
|
||||||
|
return exe_file
|
||||||
|
return None;
|
Binary file not shown.
|
@ -0,0 +1,35 @@
|
||||||
|
import time
|
||||||
|
class BasicNotebook:
|
||||||
|
def __init__(self):
|
||||||
|
self.messages = {}
|
||||||
|
|
||||||
|
def _addToNotes(self,touser,msgformat):
|
||||||
|
if touser in self.messages:
|
||||||
|
self.messages[touser].append(msgformat)
|
||||||
|
else:
|
||||||
|
self.messages[touser]=[msgformat]
|
||||||
|
|
||||||
|
def addNote(self,touser,fromuser,msg):
|
||||||
|
self._addToNotes(touser,[fromuser,msg])
|
||||||
|
|
||||||
|
def _readNotes(self,user,fmtstr):
|
||||||
|
if not self.checkNotes(user):
|
||||||
|
return []
|
||||||
|
ret = []
|
||||||
|
for messageI in self.messages[user]:
|
||||||
|
ret.append(fmtstr.format(*messageI))
|
||||||
|
del self.messages[user]
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def readNotes(self,user):
|
||||||
|
return self._readNotes(user,"{0} left a message: {1}")
|
||||||
|
|
||||||
|
def checkNotes(self,user):
|
||||||
|
return user in self.messages.keys()
|
||||||
|
|
||||||
|
class DatedNotebook(BasicNotebook):
|
||||||
|
def addNote(self,touser,fromuser,msg):
|
||||||
|
self._addToNotes(touser,[fromuser,msg,time.strftime("%H:%M:%S"),time.strftime("%A, %B %d, %Y")])
|
||||||
|
|
||||||
|
def readNotes(self,user):
|
||||||
|
return self._readNotes(user,"{0} left a message at {2} on {3}: {1}")
|
|
@ -0,0 +1,8 @@
|
||||||
|
if not table.pack then table.pack = function(...) return { n = select("#", ...), ... } end end
|
||||||
|
if not table.unpack then table.unpack = unpack end
|
||||||
|
local load = load if _VERSION:find("5.1") then load = function(x, n, _, env) local f, e = loadstring(x, n) if not f then return f, e end if env then setfenv(f, env) end return f end end
|
||||||
|
local _select, _unpack, _pack, _error = select, table.unpack, table.pack, error
|
||||||
|
local _libs = {}
|
||||||
|
local print1
|
||||||
|
print1 = print
|
||||||
|
return print1("lua")
|
|
@ -0,0 +1,25 @@
|
||||||
|
import re
|
||||||
|
|
||||||
|
class Plugin:
|
||||||
|
def __init__(self,bot,command_format):
|
||||||
|
self.bot = bot
|
||||||
|
self.cmd = re.compile(command_format)
|
||||||
|
|
||||||
|
def answer(self,channel,nick,message):
|
||||||
|
m = self.cmd.search(message)
|
||||||
|
if m and hasattr(self,m.group(1).replace(" ","_")):
|
||||||
|
getattr(self,m.group(1).replace(" ","_"))(channel,nick,message)
|
||||||
|
|
||||||
|
class TestPlugin(Plugin):
|
||||||
|
def __init__(self,bot):
|
||||||
|
Plugin.__init__(self,bot,"!test ([A-Za-z]+)(?: (.+))?")
|
||||||
|
self.is_bot=True
|
||||||
|
|
||||||
|
# def is_not_a_bot(self):
|
||||||
|
# self.is_bot=False
|
||||||
|
|
||||||
|
def say(self,c,n,m):
|
||||||
|
if self.is_bot:
|
||||||
|
self.bot.mention(c,n,m)
|
||||||
|
else:
|
||||||
|
print(m)
|
Binary file not shown.
|
@ -0,0 +1,54 @@
|
||||||
|
import json,os.path,copy
|
||||||
|
class Pokemon:
|
||||||
|
def __init__(self):
|
||||||
|
self.pkmns = dict()
|
||||||
|
def __getitem__(self,k):
|
||||||
|
return self.pkmns[k]
|
||||||
|
def add(self,**kwargs):
|
||||||
|
self.pkmns[kwargs["name"]] = kwargs
|
||||||
|
|
||||||
|
class PCBox:
|
||||||
|
"""Pokemon box"""
|
||||||
|
def __init__(self):
|
||||||
|
self.pokemon = []
|
||||||
|
|
||||||
|
def move(self,pkmn):
|
||||||
|
self.pokemon.append(pkmn)
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.pokemon
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fromList(cls,l):
|
||||||
|
ret = cls()
|
||||||
|
ret.pokemon = l
|
||||||
|
return ret
|
||||||
|
|
||||||
|
class PokemonGame:
|
||||||
|
"""A game of Pokemon. Up to 6 mons, 300000 pokeyen, and 4 moves per Pokemon."""
|
||||||
|
def __init__(self,owner,prompt):
|
||||||
|
self.setupPKMNList()
|
||||||
|
try:
|
||||||
|
with open(os.path.join("/home/minerobber/.pkmn/",owner+".json"),"r") as f:
|
||||||
|
self.data = json.load(f)
|
||||||
|
self.name = self.data["name"]
|
||||||
|
self.pokeyen = self.data["pokeyen"]
|
||||||
|
self.pkmn = self.data["pkmn"]
|
||||||
|
self.pc = []
|
||||||
|
for item in self.data["boxes"]:
|
||||||
|
self.pc.append(PCBox.fromList(item))
|
||||||
|
except IOError as e:
|
||||||
|
self.name = prompt()
|
||||||
|
self.pokeyen = 3000
|
||||||
|
self.pkmn = []
|
||||||
|
self.pc = [PCBox()]*20
|
||||||
|
|
||||||
|
def addPKMN(self,type):
|
||||||
|
if len(self.pkmn)==6:
|
||||||
|
return False
|
||||||
|
self.pkmn.append(copy.copy(self.pkmnl[type]))
|
||||||
|
|
||||||
|
def setupPKMNList(self):
|
||||||
|
self.pkmnl = Pokemon()
|
||||||
|
self.pkmnl.add(name="Charmander",maxhp=39,atk=52,dfn=43,spa=60,sde=50,speed=65,evolves=dict(at=16,to="Charmeleon"))
|
||||||
|
self.pkmnl.add(name="Charmeleon")
|
|
@ -0,0 +1,3 @@
|
||||||
|
from minerbot import minerbot;
|
||||||
|
bot = minerbot("minerbot", "minerbot","minerobber");
|
||||||
|
bot.begin("localhost",6667,["#bots","#minerobber","#tildetown"]);
|
|
@ -0,0 +1,26 @@
|
||||||
|
"""A python module for writing RSS."""
|
||||||
|
import time
|
||||||
|
class PageRSS:
|
||||||
|
"""A helper class for creating a page's RSS."""
|
||||||
|
def __init__(self, title, description, link, date):
|
||||||
|
self.items = []
|
||||||
|
self.title = title
|
||||||
|
self.description = description
|
||||||
|
self.link = link
|
||||||
|
self.pubDate = date
|
||||||
|
|
||||||
|
"""Add items to RSS feed."""
|
||||||
|
def addItem(self, title, link, desc):
|
||||||
|
item = {}
|
||||||
|
item['title'] = title
|
||||||
|
item['link'] = link
|
||||||
|
item['desc'] = desc
|
||||||
|
self.items.append(item)
|
||||||
|
|
||||||
|
"""Generates RSS feed."""
|
||||||
|
def make(self):
|
||||||
|
contents = "<?xml version='1.0' ?><rss version='2.0'><channel><title>{}</title><link>{}</link><description>{}</description><pubDate>{}</pubDate>".format(self.title,self.link,self.description,time.strftime("%a, %d %b %Y %H:%M:%S %z",self.pubDate))
|
||||||
|
for i in self.items:
|
||||||
|
contents += "<item><title>{}</title><link>{}</link><description>{}</description></item>".format(i['title'],i['link'],i['desc'])
|
||||||
|
contents += "</channel></rss>"
|
||||||
|
return contents
|
|
@ -0,0 +1,20 @@
|
||||||
|
import getters
|
||||||
|
class StockTicker:
|
||||||
|
"""A stock ticker to track certain stocks with."""
|
||||||
|
def __init__(self, data=["s","n","l1","c1"], format="{1} ({0}) {2} ({3})"):
|
||||||
|
self.symbols = []
|
||||||
|
self.data = data
|
||||||
|
self.format = format
|
||||||
|
|
||||||
|
def addSymbol(self,symbol):
|
||||||
|
self.symbols.append(symbol)
|
||||||
|
|
||||||
|
def removeSymbol(self,symbol):
|
||||||
|
self.symbols = [x for x in self.symbols if x != symbol]
|
||||||
|
|
||||||
|
def getTickerValues(self):
|
||||||
|
reader = getters.getStocks(self.symbols,"".join(self.data))
|
||||||
|
ret = []
|
||||||
|
for row in reader:
|
||||||
|
ret.append(self.format.format(*row))
|
||||||
|
return ret
|
Binary file not shown.
|
@ -0,0 +1,19 @@
|
||||||
|
import csv,requests;
|
||||||
|
from urllib import quote_plus as urlencode;
|
||||||
|
|
||||||
|
def generatorFromText(text):
|
||||||
|
for line in text.splitlines():
|
||||||
|
yield line
|
||||||
|
|
||||||
|
def getCSVFile(url):
|
||||||
|
r = requests.get(url)
|
||||||
|
reader = csv.reader(generatorFromText(r.text))
|
||||||
|
return reader
|
||||||
|
|
||||||
|
def getStocks(symbols,data):
|
||||||
|
symbol_string = ""
|
||||||
|
if type(symbols) is str:
|
||||||
|
symbol_string = symbols
|
||||||
|
else:
|
||||||
|
symbol_string = "+".join(symbols)
|
||||||
|
return getCSVFile("http://finance.yahoo.com/d/quotes.csv?s="+urlencode(symbol_string)+"&f="+data)
|
Binary file not shown.
|
@ -0,0 +1,32 @@
|
||||||
|
import wordfreq,string,random
|
||||||
|
corpus = open("corpus").read().split("\n")
|
||||||
|
strs = corpus
|
||||||
|
filter = ""
|
||||||
|
for c in string.punctuation:
|
||||||
|
if c != "'":
|
||||||
|
filter += c
|
||||||
|
def getListFreqDict(list):
|
||||||
|
nl = []
|
||||||
|
for s in list:
|
||||||
|
ls = s.split(" ")
|
||||||
|
filter(ls,None)
|
||||||
|
lsc = ls[:]
|
||||||
|
for word in ls:
|
||||||
|
if word.find("http://") != -1 or word.find("https://") != -1:
|
||||||
|
lsc.remove(word);
|
||||||
|
s = " ".join(lsc)
|
||||||
|
nl.add(s)
|
||||||
|
ret = wordfreq.getFreqDict(" ".join(nl),filterchars=filter)
|
||||||
|
return ret
|
||||||
|
def getRandomWords(freqDict):
|
||||||
|
t = ""
|
||||||
|
for s in freqDict:
|
||||||
|
t += "{} ".format(s) * freqDict[s]
|
||||||
|
listW = [x for x in t.split(" ") if x != ""]
|
||||||
|
len = random.randint(1,20)
|
||||||
|
ret = ""
|
||||||
|
while len != 0:
|
||||||
|
ret += random.choice(listW)
|
||||||
|
ret += " "
|
||||||
|
len -= 1
|
||||||
|
return ret[:-1]+random.choice(".!?;")
|
Binary file not shown.
|
@ -0,0 +1,45 @@
|
||||||
|
import shinycalc
|
||||||
|
|
||||||
|
class G7SCPlugin:
|
||||||
|
|
||||||
|
help = "Generates shiny chances for pokemon generation 7 shiny hunting! Subcommands: shiny, hidden_ability, perfect_ivs"
|
||||||
|
|
||||||
|
"""Handles lua execution"""
|
||||||
|
def __init__(self,bot,prefix):
|
||||||
|
self.bot = bot
|
||||||
|
self.prefix = prefix
|
||||||
|
|
||||||
|
def handleCommand(self,chan,sender,cmd):
|
||||||
|
if cmd.strip()==prefix:
|
||||||
|
self.bot.mention(chan,sender,G7SCPlugin.help)
|
||||||
|
elif not cmd.startswith(prefix+" "):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
parts = cmd.strip().split()
|
||||||
|
if not hasattr(self,parts[1]):
|
||||||
|
self.bot.mention(chan,sender,G7SCPlugin.help)
|
||||||
|
raise Exception()
|
||||||
|
args = parts[2:]
|
||||||
|
# args.insert(0,self)
|
||||||
|
self.bot.mention(chan,sender,getattr(self,parts[1])(*args))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def shiny(self,*args):
|
||||||
|
shinycalc.setChain(int(args[0]))
|
||||||
|
shiny = shinycalc.generateShiny()
|
||||||
|
ret = "1/{!s} chance of the pokemon being shiny.".format(shiny[0])
|
||||||
|
if shiny[1]:
|
||||||
|
ret += " (Or not. Shiny values from 1-69 aren't known yet.)"
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def hidden_ability(self,*args):
|
||||||
|
shinycalc.setChain(int(args[0]))
|
||||||
|
ha = shinycalc.generateHA()
|
||||||
|
return "{!s}% chance of a hidden ability.".format(ha)
|
||||||
|
|
||||||
|
def perfect_ivs(self,*args):
|
||||||
|
shinycalc.setChain(int(args[0]))
|
||||||
|
ivs = shinycalc.generateIVs()
|
||||||
|
return "{!s} guaranteed perfect IV(s).".format(ivs)
|
Binary file not shown.
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
chain = 0
|
||||||
|
|
||||||
|
def setChain(c):
|
||||||
|
global chain
|
||||||
|
chain = (c%256)
|
||||||
|
|
||||||
|
def generateShiny():
|
||||||
|
if chain<70:
|
||||||
|
return (4096,chain!=0)
|
||||||
|
else:
|
||||||
|
return (1024,False)
|
||||||
|
|
||||||
|
def generateIVs():
|
||||||
|
if chain<=4:
|
||||||
|
return 0
|
||||||
|
elif chain<=9:
|
||||||
|
return 1
|
||||||
|
elif chain<=19:
|
||||||
|
return 2
|
||||||
|
elif chain<=29:
|
||||||
|
return 3
|
||||||
|
else:
|
||||||
|
return 4
|
||||||
|
|
||||||
|
def generateHA():
|
||||||
|
if chain<10:
|
||||||
|
return 0
|
||||||
|
elif chain<20:
|
||||||
|
return 5
|
||||||
|
elif chain<30:
|
||||||
|
return 10
|
||||||
|
else:
|
||||||
|
return 15
|
||||||
|
|
||||||
|
if __name__=="__main__":
|
||||||
|
parser = argparse.ArgumentParser(description="Calculates shiny chance and IVs for SOS battles in generation 7.")
|
||||||
|
parser.add_argument("chain",type=int,help="Chain value. Due to overflow bug, will not be calculated hgher than 255 (handled automatically)")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
setChain(args.chain)
|
||||||
|
|
||||||
|
shiny = generateShiny()
|
||||||
|
iv = generateIVs()
|
||||||
|
ha = generateHA()
|
||||||
|
|
||||||
|
print "Shiny chance: 1/"+str(shiny[0])+("*" if shiny[1] else "")
|
||||||
|
print str(iv)+" guaranteed perfect IV(s)"
|
||||||
|
print "Hidden Ability chance: "+str(ha)+"%"
|
||||||
|
if shiny[1]:
|
||||||
|
print "* Shiny chances for chain values below 70 are not known."
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
from minerbot import minerbot;
|
||||||
|
bot = minerbot("minerbot", "minerbot","minerobber");
|
||||||
|
bot.begin("irc.badnik.net",6667,["#ImANoob"]);
|
|
@ -0,0 +1,19 @@
|
||||||
|
def primes(n):
|
||||||
|
if n<=2:
|
||||||
|
return []
|
||||||
|
sieve=[True]*(n+1)
|
||||||
|
for x in range(3,int(n**0.5)+1,2):
|
||||||
|
for y in range(3,(n//x)+1,2):
|
||||||
|
sieve[(x*y)]=False
|
||||||
|
|
||||||
|
return [2]+[i for i in range(3,n,2) if sieve[i]]
|
||||||
|
|
||||||
|
def primefactors(n):
|
||||||
|
primelist = primes(100)
|
||||||
|
lpf = 2
|
||||||
|
for prime in primelist:
|
||||||
|
print "Checking prime: "+str(prime)
|
||||||
|
if n%prime == 0 and prime > lpf:
|
||||||
|
print "Better prime found: "+str(prime)
|
||||||
|
lpf = prime
|
||||||
|
return "{!s},{!s}".format(lpf,n/lpf)
|
|
@ -0,0 +1,35 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import subprocess as sp
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
|
class SubAPI:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.outputListeners = set()
|
||||||
|
|
||||||
|
|
||||||
|
def start(self, args, listenDaemon=True):
|
||||||
|
self.program = sp.Popen(args, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.STDOUT, universal_newlines=True)
|
||||||
|
|
||||||
|
self.t = Thread(target=self.listen, daemon=listenDaemon)
|
||||||
|
self.t.start()
|
||||||
|
|
||||||
|
|
||||||
|
def listen(self):
|
||||||
|
while self.program.stdout.readable():
|
||||||
|
outputLine = self.program.stdout.readline()[:-1]
|
||||||
|
for listener in self.outputListeners:
|
||||||
|
listener(outputLine)
|
||||||
|
|
||||||
|
def sendInput(self, command):
|
||||||
|
self.program.stdin.write(command+"\n")
|
||||||
|
self.program.stdin.flush()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.program.terminate()
|
||||||
|
self.program.stdout.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
||||||
|
import requests
|
||||||
|
|
||||||
|
def doMethod(m):
|
||||||
|
return requests.get("https://api.sug.rocks/{}.json".format(m)).json()
|
||||||
|
|
||||||
|
def schedule():
|
||||||
|
return doMethod("schedule")
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
||||||
|
def BLANK(self,c,n,m):
|
||||||
|
self.bot.say(c,self._BLANK(m.group(2),m.group(3)))
|
|
@ -0,0 +1,3 @@
|
||||||
|
from minerbot import minerbot;
|
||||||
|
bot = minerbot("minerbot", "testuser","minerobber");
|
||||||
|
bot.begin("localhost",6667,["#minerobber"]);
|
|
@ -0,0 +1,5 @@
|
||||||
|
import urn
|
||||||
|
|
||||||
|
bot = urn.TestBot()
|
||||||
|
urnp = urn.UrnPlugin(bot)
|
||||||
|
urnp.onMessage("#tildetown","minerobber","!urn (print! \"lua\")")
|
|
@ -0,0 +1,32 @@
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
class TestBot:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
def say(self,chan,message):
|
||||||
|
print(message)
|
||||||
|
|
||||||
|
class NFile:
|
||||||
|
def __init__(self,bot,chan):
|
||||||
|
self.bot = bot
|
||||||
|
self.chan = chan
|
||||||
|
def write(self,c):
|
||||||
|
self.bot.say(self.chan,c)
|
||||||
|
|
||||||
|
class UrnPlugin:
|
||||||
|
def __init__(self,bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
def onMessage(self,chan,nick,message):
|
||||||
|
parts = message.strip().split()
|
||||||
|
if parts[0]!="!urn":
|
||||||
|
return
|
||||||
|
with open("te.urn","w") as f:
|
||||||
|
f.write(" ".join(parts[1:]))
|
||||||
|
subprocess.call("urn te.urn",shell=True)
|
||||||
|
t = subprocess.Popen("lua out.lua",shell=True,stdout=subprocess.PIPE)
|
||||||
|
out = t.communicate()[0]
|
||||||
|
lines = [l.strip() for l in out.strip().split("\n")]
|
||||||
|
for line in lines:
|
||||||
|
if line:
|
||||||
|
self.bot.say(chan,line)
|
|
@ -0,0 +1,14 @@
|
||||||
|
import string
|
||||||
|
def getFreqDict(corpus, filterchars=string.punctuation):
|
||||||
|
corpus = corpus.lower()
|
||||||
|
for c in filterchars:
|
||||||
|
corpus = corpus.replace(c,"")
|
||||||
|
words = corpus.split()
|
||||||
|
words = filter(None,words)
|
||||||
|
freq = {}
|
||||||
|
for word in words:
|
||||||
|
if word in freq:
|
||||||
|
freq[word] += 1
|
||||||
|
else:
|
||||||
|
freq.update({word: 1})
|
||||||
|
return freq
|
Binary file not shown.
|
@ -0,0 +1,37 @@
|
||||||
|
import requests
|
||||||
|
|
||||||
|
class InvalidComic(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Comic(object):
|
||||||
|
def __init__(self,num=None,donterror=False):
|
||||||
|
if num:
|
||||||
|
r = requests.get("https://xkcd.com/{!s}/info.0.json".format(num))
|
||||||
|
if r.status_code!=200:
|
||||||
|
if donterror:
|
||||||
|
self.num = num
|
||||||
|
self.fakeit = True
|
||||||
|
else:
|
||||||
|
raise InvalidComic("Invalid XKCD comic \""+str(num)+"\"")
|
||||||
|
else:
|
||||||
|
self.__dict__.update(r.json())
|
||||||
|
self.fakeit = False
|
||||||
|
else:
|
||||||
|
r = requests.get("https://xkcd.com/info.0.json")
|
||||||
|
if r.status_code!=200:
|
||||||
|
if donterror:
|
||||||
|
self.num = 0
|
||||||
|
self.fakeit = True
|
||||||
|
else:
|
||||||
|
raise InvalidComic("Cannot locate latest comic.")
|
||||||
|
else:
|
||||||
|
self.__dict__.update(r.json())
|
||||||
|
self.fakeit = False
|
||||||
|
|
||||||
|
def __getattr__(self,k):
|
||||||
|
if k=="fakeit" or k=="num":
|
||||||
|
return object.__getattr__(self,k)
|
||||||
|
if self.fakeit:
|
||||||
|
return ""
|
||||||
|
else:
|
||||||
|
return object.__getattr__(self,k)
|
Loading…
Reference in New Issue