From ee76802e7407cb6e0f5cda4c43a990232b2e5eed Mon Sep 17 00:00:00 2001 From: khuxkm Date: Tue, 26 Jun 2018 00:12:53 +0000 Subject: [PATCH] Initial commit --- NormalBot.py | 39 + NormalBot.pyc | Bin 0 -> 2063 bytes bfc.py | 12 + bfc.pyc | Bin 0 -> 509 bytes bot_runner.py | 16 + chaninfo.py | 42 + chaninfo.pyc | Bin 0 -> 2813 bytes choose_parser.py | 27 + choose_parser.pyc | Bin 0 -> 867 bytes colorbot.py | 40 + colorbot.pyc | Bin 0 -> 1862 bytes corpus | 2 + data/a-words.txt | 10531 +++++++++++++++++++++++++++++++++++++++++ data/k-words.txt | 2111 +++++++++ data/m-words.txt | 9584 +++++++++++++++++++++++++++++++++++++ data/synopses.json | 1 + data/titles.json | 1 + data/w-words.txt | 3927 +++++++++++++++ key.ps | 1 + kwam.py | 20 + kwam.pyc | Bin 0 -> 1352 bytes lua.py | 35 + lua.pyc | Bin 0 -> 2138 bytes markov.py | 42 + markov.pyc | Bin 0 -> 2282 bytes markovuniverse.py | 17 + markovuniverse.pyc | Bin 0 -> 956 bytes mbtilde.py | 86 + mbtilde.pyc | Bin 0 -> 5779 bytes minerbot.commands | 27 + minerbot.py | 414 ++ minerbot.py.save | 380 ++ minerbot.pyc | Bin 0 -> 17052 bytes notes.py | 35 + notes.pyc | Bin 0 -> 2419 bytes out.lua | 8 + plugin.py | 25 + plugin.pyc | Bin 0 -> 1675 bytes pokemon.py | 54 + prod.py | 3 + prss.py | 26 + prss.pyc | Bin 0 -> 1684 bytes pstocks/__init__.py | 20 + pstocks/__init__.pyc | Bin 0 -> 1572 bytes pstocks/getters.py | 19 + pstocks/getters.pyc | Bin 0 -> 1155 bytes randwords.py | 32 + randwords.pyc | Bin 0 -> 1504 bytes scplugin.py | 45 + scplugin.pyc | Bin 0 -> 2354 bytes shinycalc.py | 53 + shinycalc.pyc | Bin 0 -> 1918 bytes show.py | 3 + sieve.py | 19 + sieve.pyc | Bin 0 -> 999 bytes subapi.py | 35 + subapi.pyc | Bin 0 -> 1862 bytes sugrocks.py | 7 + sugrocks.pyc | Bin 0 -> 457 bytes t.tt | 2 + te.urn | 1 + test.py | 3 + testurn.py | 5 + urn.py | 32 + urn.pyc | Bin 0 -> 2363 bytes wordfreq.py | 14 + wordfreq.pyc | Bin 0 -> 657 bytes xkcd.py | 37 + zws.txt | 1 + 69 files changed, 27834 insertions(+) create mode 100644 NormalBot.py create mode 100644 NormalBot.pyc create mode 100755 bfc.py create mode 100644 bfc.pyc create mode 100644 bot_runner.py create mode 100644 chaninfo.py create mode 100644 chaninfo.pyc create mode 100644 choose_parser.py create mode 100644 choose_parser.pyc create mode 100644 colorbot.py create mode 100644 colorbot.pyc create mode 100644 corpus create mode 100644 data/a-words.txt create mode 100644 data/k-words.txt create mode 100644 data/m-words.txt create mode 100644 data/synopses.json create mode 100644 data/titles.json create mode 100644 data/w-words.txt create mode 100644 key.ps create mode 100644 kwam.py create mode 100644 kwam.pyc create mode 100644 lua.py create mode 100644 lua.pyc create mode 100644 markov.py create mode 100644 markov.pyc create mode 100644 markovuniverse.py create mode 100644 markovuniverse.pyc create mode 100644 mbtilde.py create mode 100644 mbtilde.pyc create mode 100644 minerbot.commands create mode 100644 minerbot.py create mode 100644 minerbot.py.save create mode 100644 minerbot.pyc create mode 100644 notes.py create mode 100644 notes.pyc create mode 100644 out.lua create mode 100644 plugin.py create mode 100644 plugin.pyc create mode 100644 pokemon.py create mode 100644 prod.py create mode 100644 prss.py create mode 100644 prss.pyc create mode 100644 pstocks/__init__.py create mode 100644 pstocks/__init__.pyc create mode 100644 pstocks/getters.py create mode 100644 pstocks/getters.pyc create mode 100644 randwords.py create mode 100644 randwords.pyc create mode 100644 scplugin.py create mode 100644 scplugin.pyc create mode 100755 shinycalc.py create mode 100644 shinycalc.pyc create mode 100644 show.py create mode 100644 sieve.py create mode 100644 sieve.pyc create mode 100644 subapi.py create mode 100644 subapi.pyc create mode 100644 sugrocks.py create mode 100644 sugrocks.pyc create mode 100644 t.tt create mode 100644 te.urn create mode 100644 test.py create mode 100644 testurn.py create mode 100644 urn.py create mode 100644 urn.pyc create mode 100644 wordfreq.py create mode 100644 wordfreq.pyc create mode 100644 xkcd.py create mode 100644 zws.txt diff --git a/NormalBot.py b/NormalBot.py new file mode 100644 index 0000000..e21cdce --- /dev/null +++ b/NormalBot.py @@ -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"); diff --git a/NormalBot.pyc b/NormalBot.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61da76a655a4644ed39c08d099faa9cf7bbb2c49 GIT binary patch literal 2063 zcmb_d&2HO95S}G1*^=!zaAB)Xf`mcQKQ~B!@~9AA~C(NC?`>Nzi@Y_FE!7?o3~uFsazAUzTSoR z{gr+KU$s&o1TYu~B?`9hiL%6-;Q8VP1V23QE*|?i#4AOwuq`M{qG0HW0_lt5ldD_} zZo{CrxU)!&#ab76i9FxRk0M>H08F+7S~g^EBjRx}1A0@aa6 z=ZX}9*b0aQ&vBDFz`yfG7pm#I`*mjhg(?B)slc!J~2s~b{4a~zQ}}co(Ur|*Vx6o zc>bF3J4l!TYrrYA+@P?(`%@r9U2luw$>4zwL<_zQKC84JAN9i^rK@$b_xs_VoJa}V ze-!QoDRWAwv9J3-KOF3J*V({5u|<4roMQr~Wh`uYT+WPcU1Y>Xo}1X!Jj#=IcqI1H z#3!O0rFkM`wbLwhLJT`Cj!o_gVYFsuRCP^xQqy@_lvQZ_EJCf!%2YfMC5c>gNknBx z56vjeH=x*S5TrK1(rtBJ-BIi62J}sDOMR-gR4ms6BId093j^*MQa>h#Mk?;yABu80 z=40Fq`1y41(HYn*cjnF+Na+*%q|adH4)}D7Nhrb9NN5ORb-;$s-Va;_Nw{)XB&@}3 zYQxK1t)r6FivIs$On?Pmz#Y7ZY%nd&ByzLTWG{m_$}*GO#kz@tRQe5#_d#@92qHYY z7s&No^CUuprHg~#Gx$ZfQtHdR}7)D?8P+63=i^Gft8iyJIBZLtE;KIC%L tjI`Uw{##N*je!6F literal 0 HcmV?d00001 diff --git a/bfc.py b/bfc.py new file mode 100755 index 0000000..3fa100c --- /dev/null +++ b/bfc.py @@ -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) diff --git a/bfc.pyc b/bfc.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55e3823ac51c51f3d308604a8d3a9f31acce4c8d GIT binary patch literal 509 zcmbu5!B4_46vn>}7=y5Q@obEzMU>q<5ki7z4sg(5IBablAY12J6G^s{{>R=t`C2gk z0XFTgU*7xj-fLT5VZZsleB?N-fbJnk)KY7Yi@@ll1S8FtJ@ zJ{Z_*2-*)c<&Ip;#+H#sMdsuOB3s;a3Hp$yYOjq?Iw?z82-7CHQ`_QbvZHLxfXMeU zDWsTfl1e)hClyfw4*HH%yivJ~^KBt3m8P;Hsd-#hDyx#5!r3vGDid=hWSl&+&EX_Z7(PG)!P2h1^WRL6k+cG literal 0 HcmV?d00001 diff --git a/bot_runner.py b/bot_runner.py new file mode 100644 index 0000000..5962c27 --- /dev/null +++ b/bot_runner.py @@ -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) diff --git a/chaninfo.py b/chaninfo.py new file mode 100644 index 0000000..1ee3339 --- /dev/null +++ b/chaninfo.py @@ -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 "".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) diff --git a/chaninfo.pyc b/chaninfo.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de375fdc63105f34429d9db501c78ae61ec26ed4 GIT binary patch literal 2813 zcmcgu%W@k<6z$O~mYoDD1u0CW!jK9`Eby@8VL5;?6dO@BqNt$FFq&yeV~=J;cgrSa zYeTYS&lm6stoSQF0M5B1*+HCD&m=rBDX0Ivoc-ec&t`oNQq@XgB486 znGR-Ip-nj&X#>+H!Q7M+6VEU_spdwd3z9O`K>|=2K<&(*g?tlTw>-Gzxh?zL#41cly0lEtzOjCa8sq5 zGPOk}2*L*FzVMSgw$>k)#xF-M&VYO36T1w>{`V)DOQ!w`aY9en8fg1y)}lM})EW4M zQ4_;cuBHwpUWW~tt*PhuR?C`PbJ$deEry!QWGYqasIE-O;J`s{ytM2$=)zOKda4lZ z47vo+w;!XQIybkU20=W}cATKyamT@tiH~#EYb zjeQ8~)VkO$?9xA#v8Df^|LAn4t&Jyo`Ka5*5=ZSZwuqhM!1)VBP)7f}(AHT;f+pIz z7JfnOEOw4?jka?!4sBV8(Ju=v0_k##3|XCzLm~^g`$CLY)!|C=h_8zx%HLA<%4_5E z5TAr8!$z4(WFNp_2=MhJQX)k}p^DT%GN~_4RxC?QLcTVnzCxZ7-bUBudqZaHHT#p< z?}{8*`8r-L`K4as$2KM}`+*>i1gmT z!+(15CMI9z#XzLf7Y{^06BM;q0iC%3=-=SDxBd?}V^aY~wuAel8j3hY))z_cBR^es ztSfp+!Hp12RRZl-nVskHvj=#(8q@UtIMXNEyb_(P;Qvsa=wHCk{zT=-{sNx~OAH%j zED8J`3=ob4CjU~D&+06rsJVy*t2QccV;v6rJJ#=JV_a$4w6 zygV5%@*Lw@7rl-%3*Fh<4Jtf)Rc&FqRA~yY6{?QZaO~8kTEH43V}eAIxq=~DTVuWE zDg<2}%tktWOiWbvr7A?65{$QDRB2EJgT35}9?I!JG~bt04)0>+r5oTTYA3Ij#XOCj z{s7hrbC;z$l;h}xTy{~EmPr&Nu)DWM<0ceDF)6=PoM?xnboE*NjR;wOjq;xJTkF5!|lb Gum1}?NMe}) literal 0 HcmV?d00001 diff --git a/choose_parser.py b/choose_parser.py new file mode 100644 index 0000000..d1fc5f4 --- /dev/null +++ b/choose_parser.py @@ -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:] diff --git a/choose_parser.pyc b/choose_parser.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8af462c12ac9dfbbbb60123df07e3f9eae93526c GIT binary patch literal 867 zcmah{O>fgc5PfSWX^7O)@{v#psV1k0143}&fS?G(fkTmqL{TM#-0Ui`F}Ab2Q4`5N zm0!Rw;D5kh;>3v)%uM1!Ppq}Gvv1zaKF@CWbGv81e1A8=W(2ez(sX??8aM%rf>!vf za1uZV7>`1Z-)9rAqT#F9mBvP|mx(sRX!y*UXjLpCYvL?hMSd3h$oWN?=%>R8SHD8D zP4hVyc&mU4NP%-;s!#`*0(FSx162ih@&2x=TLQIFwUCOGbK-SaO1*{UFH~Fb0jdrN z{|MMeihKh1(-1mj)ZVy&S`G9SRU0W)U2`=B+PFhxMX9tKQ1SU8a?*FfIHAo)#02%cHid7G4;FU6Hv;yqt*W^&(S#K+dVv&7GQ zm$oL?>kTKyWl8%H->7e~F-tFHv^iZ&#mkc1xb-QAxMzjcPGlxR zE9vABu^`6nk~f(Zg)<*0;*7mlt|U)({IujzLS0oIwM~=Po9a4!w^Wb(9kP9Ojn=-} x4SK}cQG4o0-n0CxC#hrVMZVVlGR~ZNv)2gtpA>G-<4=WNWabHX*|DUK`U4`uq%Qyf literal 0 HcmV?d00001 diff --git a/colorbot.py b/colorbot.py new file mode 100644 index 0000000..a052285 --- /dev/null +++ b/colorbot.py @@ -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") diff --git a/colorbot.pyc b/colorbot.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e75adcbe399237f020f8ae4e38cc64a00322fd10 GIT binary patch literal 1862 zcmah~-)|d55T5lVPV6S6geD3!#ciJV1pi)KEe|xX}iPsD!NR-6ouKxpQwf zX`(hSg#V&{0}uRRJi#;YeRGZ@f}plMg zMhcO~U|Qmg>>9};`B~&lbV3!i>?18lzv_OLATa_`}B z>P8{2%1K58{R2FH7Q`W!5xd<3FTEB>pm;DSlLI#xgsv_Qs_d}9vay0ll=D}>rBzYY zPpWWdbYiJtL7suyCbaR|wCfM5@bBzzL)Tq2x zd12%QwhCrS87y1MfJVwh5*pPsTf5z3>HQve1-S@o3=CU6D_yOkLl1@>s9jP_^q(h% zcY!^wo38fgr4HT|yOzN$!&=%{Dlb}fxl7{)=VcxS1E%t9vY5{Jn=%@M@vX&P$G(He zP*K2=jfAFBEpupOh%&YO-IkmgF)*SOWowUyZCOE2SN^GLoM)h#k`;Q)URWL9W)DC6 z;Vn7U4vwQuv)7YQPmg5h_&N7dFP*3C5TD3%3e#yBb|stPGMknCNb27>mT|0(8eAc= zv#zXOM16Vg3EjjKLU_(m#VVe@6#RBFPIV4_>U%c5zq$TZtl*pPs^Hu0hc;F&{wRL0 z;l6yd*^hI%Iv(KGW`9FZj+$*f>Tkq3aiZhivYX$1y}i+!r+_o@Rl4s&ASm-XRRnxf zA3EDP_eiUYp}0^cOG5HL;A5MfxV^kw0OPNNh*<#gmdy=w+svDr;1^p<=3TR7Qa#47 zppzo;S1_CdT;G&{;TTTiCnKdE$05!zevzEDW+e9>RgD;0A>i#mEnvAY|AS4M37)p3J_jX zeIJ9KcQ<~P_;^&igCrc*t~iO)q$pf=2PKKbxsDecOB7jCJmi1kc2#WMi}l2=>CG3M z5B?gg#!!i$e{dS#i#~k+?n$-K@>6#VuI!6DF(QD1J zX3O}Njk7mN=y(xVxy$#OW!LnKkhEK!nafgc5S_K%q)A(l3Q`fLA}+qr9Fb7PN9hf<0vD+zQZcT*Bu?yg>fI={d4DP4Vh{JzGrPhm2A6%|B%I38sI zWj=i)S`dBeE6yE+OE{PR!Druf;l4Y3v-iH34s!Faq{8+NmVFGPQ4BYU%k)uFiQ`jr z5PC?bY`Eka)>|xl4s-T}5AGfx(S=7&W|@1mfnhcliY~Y5!Y8L_PK50NtWP74r`$b$ zL>B?g0~+}<{t_)b`s~r^3tIT34l&4wqtiAW&gFU>kXzz9af@d>2wUjB?*iEIEGaEd zmL)FfS$^xYSyg9t%bhvPZ|q_+qOc7kH>!y?jw7pG;#}=I@N1o9MQ*f}OsywHl4|E8 zb5c3E_OYI7cMlthu`^vq`gDrZR)CfRRu^9*>B3!eJe=sOWVmpMh{V|E@Os0l)V&gk zx;i=0HC&taCUrHalM>s5CWq#|w90gkpSd+TcgwgN$GOQ}3{da}elV#uwV__Aj!Jot z(cmRK{er`|10Y3U#Xb-OK?vX+DJEp>QN4G42>ht)5Zw42GVstCfHx?HYXQ|inUPUT z!Zshe372n&o!eoT!$BbYHxsN7vn)Cut+FU^fK`BI+*1(V7ml9@+f2TAn~r5!8G(8; zWNnJrtxIZWXSo|Td@vZ*3{VSv+GI_Rd3Ri_PE1yn;-j>%Df{f@Z^maSK!%o7*h9Dpw?m6RU2~H zQ6W!xr5clzI*tXQI4-MfS|E&A($OZ&%~<~}(+K5=|2&r4w^XOy6lc1khitI!vZ1_i OyLr<~CeL!KRqrpMh!n&C literal 0 HcmV?d00001 diff --git a/lua.py b/lua.py new file mode 100644 index 0000000..e5cad11 --- /dev/null +++ b/lua.py @@ -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 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]) diff --git a/lua.pyc b/lua.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c2a72991ebcf76742a579872d9c1192e965a056 GIT binary patch literal 2138 zcmb_d-EQ1O6rNdcHrde7HWd*;LYNzB1lesvi&QB@z}_@c6h)3I)ZAEJd%E$mwpX69 zAShg*RL}?GDY)PzcmVjmGn-^VToG2D<1;hI=l45jgFiObgCBle>jUzQ(eeE2M5}EG8*eR@b<)o+LlW2wCz60_+t@4?%;jB$V^S#Mh zSJYM3!OhhgQFI&RLaPg<61b=7J9*fHqvG>X6hOw2jBDq*c;`jt+!~ndEUhXtvk`U5 zl{K?hF?SJ`C-!r2!?U_H!?LJMQ;)}{0c*42ys0NmTH<)(?_gn=)wvnM?ZNz9j3h}> z6)s66G@4hsudgGaUn4C09K=cT5x^87X|;FFZBILlYZ~zQQXai@iDYUu@y8N4BRH~m zK!>euhU225N0QwbhbpEY?k$is&kqah3<8sq)~)-daAyb3iN7vwoMb2FR#L>I{Xf}R z_x4A=3IvoTz?8nH-}f0}b{Grab_?VeJX*aHJpHWHk4Q@gg_d|Tf{%;R53uYG2-75K zMT)-dsAfx`@kTSp$m$!Bxa^<>h!~%^&+r|v9X=iG4xWVJsGgrU#pKL|(dgsw@v~=7 zc6J{f^CetcGP8{boHBvVq65oyWN+n-F)4ZTK*(oci9x%cN)K2S+vNaKc+qIG22+; z>h+QXJyG%dl8R<|GhO8{5iMfi3j*oil|z!sA1XifVOwlAy+xe513vbro$)BVuZiwS5r4F{H`5;4nadX9Z+iTOi(X^pj*mZ9aT z$#29OV~w--{~;!)n4L<61p!fzjRYy2ARfkqSZOLwVaF@cZNI~)kXaHloOlDok5O08 zWt>=3-qhRr zF4`m18+uEBpzrH-a-E1_E~a*smL^Fg*d!_Iyq$4Nfh5W6EJ=)rEs`da^n^rNFMfl`nzW|rJ BvMvAs literal 0 HcmV?d00001 diff --git a/markov.py b/markov.py new file mode 100644 index 0000000..a43090c --- /dev/null +++ b/markov.py @@ -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()) diff --git a/markov.pyc b/markov.pyc new file mode 100644 index 0000000000000000000000000000000000000000..93008de035fb003cc82b9aa75637d407db5c960a GIT binary patch literal 2282 zcmb_dOK%iM5U$=?)~pj_gayPA3J-zU6BY-=LnuNq;uKlRaIjf~M&p^bJ@(A>c)Cf9 zWKPbVAH`4N2PEHDGwU^HcC}qw-CbReuO1tHTUl=G*PTrIPlVrBSpFGEj<1nYWO~jU znHtFll3$WMl7B_cMBYuYA96E|_~7kigvZ5y_-utsU^fraqCPh*^R2GZR>V-Z41_C8%^u>+qA;*es{O)!bawDNT%(P`}wH3AV&167W$MGWYx6)n{sFTvJeFuO c& zJ@FB9&)hVtCZl~;39Tw9NE%}UA}9yM`Wc7}1fiquxQ!Gb6bqP0&IV#m?o;CRhgP8W|M>9YI7WVS8KlWk5%KlsHjAvT3FIqY{4Zo_8ZvQ5TU2^i1dHl~N#gE3nmzDB~thMzz(%r9TraNzRzSM29LEB9j~ zJ%&O>+_M8mW*m)2V}2r?Uu-?Xwu$9QkOs67YUj&iX658zKf=xgV`_aq!_ZTQ7)JVM zW{z*k_BMvnUppYPoKdwFox{iugs8P?UgBTLD+=0PEpk;f+F6>~jQ_X_fgc5S_L2K|%@$!4WA(Us_){AcPR8QsESd&6+jUy z%0v31=q&KK=W$4R-*4y<_bDIHML^vrVnp%Rfbt<#L*fB_BYO8<`^1ar9*UH|am_LX zD8&a@$5=LoaYQ#H`M*D-tsv=Kb*oWB1tlf`toNF#)nI@^M(SC2oX&wmyC!~t9W}P;Siuj0N$Q%0>C_Xn0$4#lZGs`7+ zfHsTU&aAq$fqS)!EscvalVhi^zSiZ2JIhDyl{-L|Oo*I-!wG7Ia9E*C>Y=ia@Xk}0 z#;$ZV+an=qAKyCdl{T&2yZzvVwk)sPa{%a8DN!DBVS-R;3upMBQ;EC~vj`xbWSCje zXzhx_7m?8M>g`x~T~>^yQ^(%VTH5peTTVL#{Q!jeKe5u@xr+BeQ1fNNZD~Pdj87}m zCiN7zubm_fR8A861nwDMPWO9Xj<2`V!|CJMT7+b#eA literal 0 HcmV?d00001 diff --git a/mbtilde.py b/mbtilde.py new file mode 100644 index 0000000..f905c44 --- /dev/null +++ b/mbtilde.py @@ -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 diff --git a/mbtilde.pyc b/mbtilde.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f405150340cf2c92734c361413bca2f99921da6e GIT binary patch literal 5779 zcmcgw?QYye6utItKAX@sNz;_CY+9h3R!v$8LR3HtsVX6%fF?q~Lb043cjINf-g>-^ zf>QpJpZwqrcq|@-2Y_>~<76qQieTlmbN6^Wp1Jp&x#Jnv{+OTr_4aSAwjBM{@Oux% zy$fUU-;lk~|^2GWQdD8Xe5pYd@7I`M}O{>P%JIy+tjQ_;nc0LKXllGoO+3^4# zsy;z+zr#f68eIsxX!(4c0R8w1>PNk|CdAgYW>V~gf+?|+3Z}(QDVPyEtzcH{jDj;_ zXBEteJ)>Y=?3{v^#Lg=?EA}M?=fs{>a9->=1q))&D_9h}pkPVtqJj%zmlQ0Ey`bQt z*kuJPVs@Gr5nJ1bVIdz|DDGvLT%@bi9f}+xbWfhu!~+96O}5>3*I?I@-8}BusL}j3 zyz%41>+1j?-)I5fyzxFRn|JRtnj6>G*Y7r|m(o1w4LfmP;THv*#;qWT`*9uw+Idb- zT-1A%^Qql5Z{kPPxH~|bdubAFCUHN?(%s!C19a`pL6&y1FhO;vxQ7Qf+o?s%!pn`p zfnkR%jzNgm=143PC|fA*Cm4j>)$k8%^2`$l@(}l-uQz<@*5rqpWOvKUdP$I95Jb9s zZ4&;y33@}5K8To*?xb|5cpI(RGw#)o_@zJF?h@?%w0|{kxe5KFHM;E<7;I1w+QPZP<7FQKso*=xff~ZMA*1$@uh|Mb}JDcMe9p1+R{>2s`I3 zdpdLJ0gI}4002Uv9w#iMTcme8tn!)rPr!7(W_a83E(;7AC*4gTNUmo9P z+k;iIL6MO2zFdNQL^WCc1ry?{{8aQ{NQDibuxRG{Fj2*j5u@Y@Qje$Ezr% zOZ0$+L#s=C+x?SZ&Rl(|VNM@mo!?;nn0RWm9W#=cu%Maqr;vc71fjJ$?>bpJ98@3# z9l@BF@l!_3s!g15(~5f|n+ zQA&?1*2oQa4PVd|$%ElYT^VdC4S!!C&&sGghDmm!jo~6;US}Q3cwXzwnd>N}o7HK; z3<{EAFRw}zhQ{$WM#4R%DoYisvIZA#jksBzDjX@W@sp}Vp#T`}osnQqsmXXELN-u-zFc9xLL6#NouRq1jF4M3HFqlELW__Rk*k{ z;%2D{*L$sB2YB&L4EvSi-Iwklb@%oB#)})^V35U0^eAjsrNcA^EysKSTqX$JWT7Y; zFMYigO~HV^cQ1*FH7)6s2^( z6zSOg|9BqZb~|wGG>ajj?&C|mblLNh~{qTOOzv`n>=e2 zr{ka>CQ%UR7la_d8anLZQom;zepN8bG%GYbM4DG<__%4%aD!|v({NK}-k`Zc^A-(X zK!#BmE_>!04RgzE(op?^DY|zOtRnY6Kggj+U2z;one=9AGqW>uu&4M} 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 ") + 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 '") + 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; diff --git a/minerbot.py.save b/minerbot.py.save new file mode 100644 index 0000000..e61d779 --- /dev/null +++ b/minerbot.py.save @@ -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 ") + 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 '") + 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 [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 d") + 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 '") +# 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 '") +# 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; diff --git a/minerbot.pyc b/minerbot.pyc new file mode 100644 index 0000000000000000000000000000000000000000..59e4faa139d916d0dedc41e064b83e89ff568a14 GIT binary patch literal 17052 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 d>h28Ge$_sGzPiYB7_e*qg57gzuQ literal 0 HcmV?d00001 diff --git a/notes.py b/notes.py new file mode 100644 index 0000000..c66ab88 --- /dev/null +++ b/notes.py @@ -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}") diff --git a/notes.pyc b/notes.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8be8924ad4ef536978b97f608bf4f0186c7a57af GIT binary patch literal 2419 zcmcgtU2hvj6uskh+&Z+hG^K@7!3xP>iK>S30#T`;^Z|tM!?;xyOK7#(9lK7l-mo*3 zs1iS=kNuPV4g7%ioV)&r+QLf=QSR*Bnen~%ocpoS-xoJuUiob&llfnS=Z_HoJ(e8* zMh--VP#TiAB#-2|$cf0#&`91CXJiCrW4Vi4Mh4w;`1Rx!{`%n})cdKQWc@O@-Ll+Y z`Z7F$_Dc*tr^(;AgHabx(ZzoUt@orXT(6i+T~+Sxx(ce#dWTgxuF?YA z8#N=BT)p8pezv}KYmNbNC#vV$zNaT8K5DB5B|6*vnC<# z0cb<^A~|l#3v?2)`sbJOm}d0q54f{PC>@1OEZGy6?JKLAU#kZsc%DH^BfKn9zW~6e0@#AW zvekw~=1#P27m4Gwx)Yg?efP}&HvwDr+$WHEoZa)#=Tm2z7A{G&e3GOn^QQ-RwGl38 zKUro@xwKcP(b9@W)y_2gEbM8{JzJ<{+EKd&X}2T&AUsHe)0%nr2Z6KUpFRi}_T+at zP}r@SlRHqBMO6=!VAyahFe7taC+WDk8Z@M&@5x-}m+j8)+ns@aHab7uiaYn?PL9V; zJx1v%Xzxu5r!=FzMgcExOeafgmesVP^lWT0Tc1JREJy~g;QytgI=J(8N5yG~kM7Lk zavC3fJNsYyODpa36^fd*tJts~a?z4xHLh4w?QGOtgTYTBo|$7I*4D|K<*?C8wY;@X Uw^|-|>%P0kub8^OV76|)1}Z+~1poj5 literal 0 HcmV?d00001 diff --git a/out.lua b/out.lua new file mode 100644 index 0000000..2bf60bc --- /dev/null +++ b/out.lua @@ -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") diff --git a/plugin.py b/plugin.py new file mode 100644 index 0000000..b41d4b1 --- /dev/null +++ b/plugin.py @@ -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) diff --git a/plugin.pyc b/plugin.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e3bf8d0d2a514146594d257d5f167aaff99842e GIT binary patch literal 1675 zcmb_cO>Yx15FPKPEv+br77$+&fzy_%%^8F!9|t%^XwwTpXtmvSlMTDxU^_xZ;Z*MY z9DW!-0N#v4qnr}?{ zgXo;-!%$J#A+6{X%G$*$tP~BB4V`` zk%;3vx}Q~4~Dpe#sjs)CiZ#gJ6LV1hg+_>f-ANq+Cp zyhFAjB!n&K6XdLTYtoS_!3=OjVzc%i8^#fSa3m&Wq~ZgCtzQWYEV{rLH%_>aDPK`a z>U3_4vA{XbUGBa0eD#rSXH!|VdRpg20DPo9TO@3evIu1u=f>z-kT+HFSr!}ZTn>AV z*{lq6zI$%mS8W-6$5T=}>WK;*2_-RkqqEF!VK2*?ww%?Nrc9W07h-uC(XPgV6b^;f zjuBl~n;nUJtew9~voOhduv1}B7m5$`k*;B;pwxjp*`izcMBm+qeB^O~Zu0Tf!7xAg z_Gy1FIeOMj4)^!=jsz*Wwm>3PJGL_|Y^YoYrc1+0eWi((fL#$QE&(^BU`1*-bPDHq zk>@@pp;PQ*QNp`$iQZ_2nBKlCmk$ItetL(6u$|*H+W4w9AzPs;ZxzBvlkPxYRa)}= zxcuxEd@dNdsqRK0@=YwJyc78M;8NUG@b5M}Ze#r8-$qDF5Me%qO0(56-xb7_*Y9~~ Ot{04~#J?WxZv6$%{ZIh_ literal 0 HcmV?d00001 diff --git a/pokemon.py b/pokemon.py new file mode 100644 index 0000000..217fcff --- /dev/null +++ b/pokemon.py @@ -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") diff --git a/prod.py b/prod.py new file mode 100644 index 0000000..9c3ef5d --- /dev/null +++ b/prod.py @@ -0,0 +1,3 @@ +from minerbot import minerbot; +bot = minerbot("minerbot", "minerbot","minerobber"); +bot.begin("localhost",6667,["#bots","#minerobber","#tildetown"]); diff --git a/prss.py b/prss.py new file mode 100644 index 0000000..b95b232 --- /dev/null +++ b/prss.py @@ -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 = "{}{}{}{}".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 += "{}{}{}".format(i['title'],i['link'],i['desc']) + contents += "" + return contents diff --git a/prss.pyc b/prss.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa238f14d70f316b62765fd35658f8d0b3350c6e GIT binary patch literal 1684 zcmb_cOHbQC5S~p!ASqO+Ql)b9B_gO5p*@rexuLWi+DeTo=YT+}EXQ6F2R~BpQs^V6 z@Jsp^`vcl<#(|(-AsRTe)1VB~=K-L5x0YcH7aIei9Sr)O?sS#vj zn`rw0x=5R_h$lAAGs}r4adsxfPtFI2fz_qAl%SJSj}!9v2s~DaN5oc`kO;F2)EVWe z?xb<1i+nK91)vE#lOi7$K??P-TpQ%J6Xub|iZRwHgdo+JKOx6t zJtrV-c?A#?O;I(vfvOd`+!UY+kn{sb;i7M2{KaObNJZQo-mOHm zT$UM7zs={>GgpxA{$-jt-*jO>q}Q9zw|6$3{jQ61T_|5b*>%HFkYzgQy28Qk&#Buf zk;~MRxd8VTGevuQ?#|gM3)k2@K_ac-nbV4#*1%~UJFWM7txtQczSH_)K5~|PPIrvl zkv;w+fm!F>J2$m;PhS%-u9N(~t3yH!`K>L0PV BbAkW> literal 0 HcmV?d00001 diff --git a/pstocks/__init__.py b/pstocks/__init__.py new file mode 100644 index 0000000..af1369a --- /dev/null +++ b/pstocks/__init__.py @@ -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 diff --git a/pstocks/__init__.pyc b/pstocks/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2607fc438f2af0e996ca38c9f6efc74cdfcdd1fc GIT binary patch literal 1572 zcmcIk&2G~`5T3OYw<#?kfe;cxHR6CPp@hN}A%1%9!2v2Fm6c;}Q>Ss9dbhMyn^Sw_ z!kh6fJOF$%OG_VsB;N72v%53%&CELdwYJj!`C})izrPUgw;1**M1e=qglGT|P|>0y zq)Va;qAvr*YyG5+edTZbw%skjzN_I8< ziij=)8bGtejs{RJ3&2uGKtyRjSz&9>A>PH79mY;P#;%TClVP5l#%1NyuiE&ybo*VW z_>{=03xFq^^2#^uJpdZmP`rO}t>uWH04~l#e7BURd_p+pjCrtIDZq z>fz8dfHv>VntIe^71SfYHmqGQuM5+gNlt7}>vCE;t-G^Rw+uU1b8*PdNOkbfncdY8 zmiM6m#W5a`Q*@z7-Jr&MQ?9#E$!0S%EfP_(7g2iB3*ga#hpZ_2l2o2pc1)fG=bXt2 zi5`G26?kmzKBPISgh$aqNX-i4uK^tbNHK5l;{pmlsZYwJQtoYOos$KST7~h(RP{IG zdGY*;7YDLQ@IV&b5C@{H+j?XJ@tI|3TFWnV<&h|WX$ zj+>0i9(HL5i+w5KHcX@UxC^CwN5(nRSjVXbmg{YO@j0S#T~2-9@|E<>%X&$gbV6gY z0+*3X)4-Oz>*EC^@eVv7LjUdgoK235WtHW?NIg-JT2qgeXT~MfdYV;6YsVY3uIl1w z!c(TMby4S9r_4I#YNWSWJb?HYxuE}bK~tEPODOS1i1tyt6Lv!HPA=D74uQ8VCalLJ!R`2wJF0ggBraTvd@G6)Cm1i9=#1yBi2< zatdd}k=NiEIPf?ecmVj%xGe{cV0p*0v*X?Q_-*!QxwN_VqZ!cElg0N4!+wGY@ha*Q zwQh7pEp=_rP%A?^OJRoQih4Pk6ZP^GW_jB3NPE;OP?)1uktTbj;j=*Xvu$dXNS7$g z)7vbWQ_@AA*5EZd<+mAn^bv6 z%~S6>S>%Y=?cmyo+))-WnnRlAxEk<>QH>4>Zxb1yHdx`)a5$zOhafIxYPtgTikv5V zDcLU1G0l~l!O=thoODBy+_9Ws*SX=7YE?>Nxj1aFu((A`E~38ECg`?}tt?>fxE^-c zkDOF5U3NJb8%eB1xrpLW7L6Vx?^0VYiDJi8w8PNxA@36tUKl-+Lps{MgkFyVSK*Lk zn|@@S%U~AwC0Z+!zLjnIHV`M?Mhr%~3Vca~J%Cp2CIej^M6ou>`MEYwZBQMWq+{9x zm^