forked from zgrep/happybot
The happybot revolves around the Earth.
The Earth revolves around the God. The God gives you a world full of viral diseases. You curse God. You revolve around God. God revolves around a door. The door opens. This is going nowhere, you can stop reading now. I said you could stop. Okay, that's it, I'm really ending it now.
This commit is contained in:
parent
499ddbdf28
commit
8b6c9697e0
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
special = {
|
||||
'heart': '\u2764',
|
||||
'zwsp': '\u200b',
|
||||
}
|
||||
|
||||
colors = {name: code for code, *names in map(str.split, '''
|
||||
00 white w
|
||||
01 black b
|
||||
02 blue navy navyblue
|
||||
03 green
|
||||
04 red 05 brown maroon
|
||||
06 purple
|
||||
07 orange olive
|
||||
08 yellow
|
||||
09 lightgreen lime
|
||||
10 teal greenbluecyan
|
||||
11 lightcyan cyan aqua
|
||||
12 lightblue royalblue royal
|
||||
13 pink lightpurple fuchsia
|
||||
14 grey gray
|
||||
15 lightgrey lightgray silver
|
||||
99 default
|
||||
'''.strip().split('\n')) for name in names}
|
||||
|
||||
from sys import argv
|
||||
chan = argv[1]
|
||||
output = ''
|
||||
for arg in argv[2:]:
|
||||
try:
|
||||
if arg[0] == '-':
|
||||
arg = arg[1:]
|
||||
if arg[0] == '-':
|
||||
output += arg
|
||||
elif arg in special:
|
||||
output += special[arg]
|
||||
elif arg[0] == 'x':
|
||||
output += chr(int(arg[1:]))
|
||||
elif ',' in arg:
|
||||
a, b = arg.split(',')
|
||||
output += '\x03' + colors[a] + ',' + colors[b]
|
||||
else:
|
||||
output += '\x03' + colors[arg]
|
||||
else:
|
||||
output += arg
|
||||
except:
|
||||
continue
|
||||
|
||||
with open('/home/zgrep/offtopiabday/irc.freenode.net/' + chan + '/in', 'w') as fh:
|
||||
fh.write(output + '\n')
|
|
@ -0,0 +1,259 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
from urllib.request import urlopen, quote, Request
|
||||
from json import loads as dejson
|
||||
from re import compile as regex
|
||||
|
||||
def cmd(args):
|
||||
proc = Popen(args, stdout=PIPE)
|
||||
while True:
|
||||
line = proc.stdout.readline()
|
||||
if line:
|
||||
line = line[:-1]
|
||||
yield str(line, 'utf-8', 'ignore')
|
||||
else:
|
||||
break
|
||||
|
||||
# Imports are finished, as is the preparation for things later.
|
||||
# Time to implement the searchers!
|
||||
|
||||
def relevantxkcd(query):
|
||||
try:
|
||||
url = "https://relevantxkcd.appspot.com/process?action=xkcd&query=" + quote(query)
|
||||
req = urlopen(url)
|
||||
if req.code != 200:
|
||||
return None
|
||||
res = req.read().split()
|
||||
sure = float(res[0])
|
||||
if sure < 0.07:
|
||||
return None
|
||||
num = int(res[2])
|
||||
return 'https://xkcd.com/' + str(num)
|
||||
except:
|
||||
return None
|
||||
|
||||
def explainxkcd(query):
|
||||
try:
|
||||
url = "https://explainxkcd.com/wiki/api.php?action=query&list=search&srwhat=text&format=json&srsearch=" + quote(query)
|
||||
url = Request(url, headers={'User-Agent': 'Mozilla'})
|
||||
req = urlopen(url)
|
||||
if req.code != 200:
|
||||
return None
|
||||
res = dejson(req.read().decode())
|
||||
for item in res['query']['search']:
|
||||
try:
|
||||
num = int(item['title'].split(':')[0])
|
||||
return 'https://xkcd.com/' + str(num)
|
||||
except:
|
||||
pass
|
||||
return None
|
||||
except:
|
||||
return None
|
||||
|
||||
googleapi = 'AIzaSyDr1gkHH-18QheEJpdGwUMmhYYvtlIJ3bA'
|
||||
googlecse = '017423361205507730360:p6-h8trjn5c'
|
||||
googlereg = regex(r'xkcd\.com/(\d+)')
|
||||
|
||||
def googlexkcd(query):
|
||||
try:
|
||||
url = 'https://www.googleapis.com/customsearch/v1?key=' + googleapi + '&cx=' + googlecse + '&q=' + quote(query)
|
||||
req = urlopen(url)
|
||||
if req.code != 200:
|
||||
return None
|
||||
print('| | Opened URL, status code 200.')
|
||||
res = dejson(req.read().decode())
|
||||
print('| | Decoded JSON.')
|
||||
for item in res['items']:
|
||||
print('| | Checking:', item['link'])
|
||||
match = googlereg.search(item['link'])
|
||||
try:
|
||||
num = int(match.group(1))
|
||||
print('| | Found a match:', num)
|
||||
return 'https://xkcd.com/' + str(num)
|
||||
except:
|
||||
pass
|
||||
return None
|
||||
except:
|
||||
return None
|
||||
|
||||
tvtropesapi = 'AIzaSyCVAXiUzRYsML1Pv6RwSG1gunmMikTzQqY'
|
||||
tvtropescse = '006443654034974345143:kc4pt9dnkle'
|
||||
def googletvtropes(query):
|
||||
try:
|
||||
url = 'https://www.googleapis.com/customsearch/v1element?key=' + tvtropesapi + '&cx=' + tvtropescse + '&q=' + quote(query)
|
||||
req = urlopen(url)
|
||||
if req.code != 200:
|
||||
return None
|
||||
print('| | Opened URL, status code 200.')
|
||||
res = dejson(req.read().decode())
|
||||
print('| | Decoded JSON.')
|
||||
if 'results' in res.keys() and res['results']:
|
||||
return(res['results'][0]['url'])
|
||||
print('| | No results.')
|
||||
return None
|
||||
except:
|
||||
return None
|
||||
|
||||
def numberxkcd(segment):
|
||||
query = ''
|
||||
original = segment
|
||||
while segment and segment[0].isdigit():
|
||||
query += segment[0]
|
||||
segment = segment[1:]
|
||||
if query:
|
||||
return 'https://xkcd.com/' + query, '', segment
|
||||
return '', '', original
|
||||
|
||||
# Righty, so all our searching mechanisms are above us. Let's table 'em up in a dict.
|
||||
|
||||
methods = {
|
||||
'xkcd': (relevantxkcd, googlexkcd, explainxkcd),
|
||||
# 'smbc': (),
|
||||
# 'satw': (),
|
||||
# 'ssss': (),
|
||||
'tvtropes': (googletvtropes,),
|
||||
}
|
||||
|
||||
# They return answer, query, segment
|
||||
special = {
|
||||
'xkcd': numberxkcd,
|
||||
}
|
||||
|
||||
# Now for matching quotes.
|
||||
|
||||
matching = [
|
||||
('"', '"'),
|
||||
("'", "'"),
|
||||
('“', '”'),
|
||||
('„', '”', '“'),
|
||||
('<', '>'),
|
||||
('«', '»'),
|
||||
('»', '«'),
|
||||
('‹', '›'),
|
||||
('《', '》'),
|
||||
('〈', '〉'),
|
||||
('「', '」'),
|
||||
('﹁', '﹂'),
|
||||
('『', '』'),
|
||||
('﹃', '﹄'),
|
||||
('(', ')'),
|
||||
('[', ']'),
|
||||
('{', '}'),
|
||||
('【', '】'),
|
||||
('〔', '〕'),
|
||||
('⦗', '⦘'),
|
||||
('〖', '〗'),
|
||||
('〘', '〙'),
|
||||
('‚', '’', '‘'),
|
||||
('lu', "li'u")
|
||||
]
|
||||
|
||||
|
||||
# And for an attempt to extract a comic.
|
||||
|
||||
def attempt(line):
|
||||
output = []
|
||||
segment = line
|
||||
|
||||
while segment:
|
||||
i = len(segment)
|
||||
c = ''
|
||||
for comic in methods.keys():
|
||||
try:
|
||||
n = segment.index(comic + '!')
|
||||
if n < i:
|
||||
i = n
|
||||
c = comic
|
||||
except:
|
||||
pass
|
||||
|
||||
if not c:
|
||||
# We have not found any comic-related things in this line. Bye!
|
||||
return None
|
||||
print('Searching for ' + c + ':')
|
||||
|
||||
i += len(c) + 1 # len(comic + '!')
|
||||
segment = segment[i:] # Right, skippity skip.
|
||||
query = ''
|
||||
|
||||
# Special cases.
|
||||
if c in special.keys():
|
||||
print("| There's a special case:")
|
||||
result, query, segment = special[c](segment)
|
||||
if result:
|
||||
print("| | Result:", result)
|
||||
output.append(result)
|
||||
continue
|
||||
if not query:
|
||||
print("| | Special case did not match.")
|
||||
|
||||
if not query:
|
||||
# See if there's a quoted thing.
|
||||
for pair in matching:
|
||||
start, *ends = pair
|
||||
l = len(start)
|
||||
if segment[:l] != start:
|
||||
continue
|
||||
print('| Found matching initial quote:', start)
|
||||
segment = segment[l:]
|
||||
for end in ends:
|
||||
try:
|
||||
i = segment.index(end)
|
||||
query = segment[:i]
|
||||
segment = segment[i + len(end):]
|
||||
print('| Found matching end:', end)
|
||||
break
|
||||
except:
|
||||
pass
|
||||
if query:
|
||||
break
|
||||
|
||||
if not query:
|
||||
while segment:
|
||||
if not segment[0].isspace():
|
||||
query += segment[0]
|
||||
segment = segment[1:]
|
||||
else:
|
||||
break
|
||||
if '_' in query:
|
||||
print('| Replacing "_" with " ".')
|
||||
query = query.replace('_', ' ')
|
||||
elif '-' in query:
|
||||
print('| Replacing "-" with " ".')
|
||||
query = query.replace('-', ' ')
|
||||
|
||||
if query:
|
||||
query = query.strip()
|
||||
print('| Searching for:', query)
|
||||
for method in methods[c]:
|
||||
print('| Search using:', method.__name__)
|
||||
result = method(query)
|
||||
if result is not None:
|
||||
output.append(result)
|
||||
print('| Result:', result)
|
||||
break
|
||||
|
||||
return ' '.join(output)
|
||||
|
||||
# Connect it to happybot.
|
||||
|
||||
from sys import argv
|
||||
|
||||
if len(argv) != 3:
|
||||
print('Usage: ./xkcd.py out in')
|
||||
exit(1)
|
||||
|
||||
for line in cmd(['tail', '-f', argv[1]]):
|
||||
line = line.split(' ', 3)[3]
|
||||
# ACTIONs shmacktions, I don't give a char 'bout that.
|
||||
if line[:8] == '\x01ACTION ' and line[-1] == '\x01':
|
||||
line = line[8:-1]
|
||||
# Oh, oh noes! We can't look at these lines! HUMANS ARE EVIL!
|
||||
if line.startswith('\u200b') or line.startswith('nolog:') or line.startswith('[nolog]'):
|
||||
continue
|
||||
# I'm trying... trying...
|
||||
result = attempt(line)
|
||||
if result:
|
||||
with open(argv[2], 'w') as fh:
|
||||
fh.write('\u200b' + result + '\n')
|
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
echo -e "$(cat /home/zgrep/zwsp)\x02\x0311,01Happy $@! ♥" >> "/home/zgrep/offtopiabday/irc.freenode.net/#offtopia/in";
|
|
@ -1,24 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import requests as rq
|
||||
from lxml import html
|
||||
|
||||
from sys import argv
|
||||
if len(argv) != 2:
|
||||
print('Not enough arguments. Bug zgrep.')
|
||||
exit(1)
|
||||
|
||||
q = argv[1]
|
||||
|
||||
r = rq.get('http://ichi.moe/cl/qr/', params={'q': q})
|
||||
|
||||
if r.status_code != 200:
|
||||
print('Non-200 status code. Bug zgrep.')
|
||||
exit()
|
||||
|
||||
# tree
|
||||
t = html.fromstring(r.content)
|
||||
|
||||
ichi = ''.join(t.xpath('//span[@class="ds-text"]//text()'))
|
||||
|
||||
print(ichi)
|
|
@ -1,9 +0,0 @@
|
|||
#!/usr/bin/env ash
|
||||
|
||||
. /home/zgrep/offtopiabday/happybot/common.sh
|
||||
|
||||
irc | while read -r n m; do
|
||||
if reg '^(happy|hate)bot[:,] ichi (.*)' "$m"; then
|
||||
python3 happybot/ichi.py "$(m 2)" | say;
|
||||
fi;
|
||||
done;
|
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
echo -e "$(cat /home/zgrep/zwsp)\x02\x0311,01Happy$@! ♥" >> "/home/zgrep/offtopiabday/irc.freenode.net/#offtopia/in";
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
rm /home/zgrep/offtopiabday/hateweekfile;
|
||||
echo -e "$(cat /home/zgrep/zwsp)\x02\x0304,01I hate how hateweek is over!" >> "/home/zgrep/offtopiabday/irc.freenode.net/#offtopia/in";
|
||||
echo "/n happybot" >> "/home/zgrep/offtopiabday/irc.freenode.net/in";
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
touch /home/zgrep/offtopiabday/hateweekfile;
|
||||
echo "/n hatebot" >> "/home/zgrep/offtopiabday/irc.freenode.net/in";
|
||||
echo -e "$(cat /home/zgrep/zwsp)\x02\x0304,01Hateweek is here! Hate how it's only once a year!" >> "/home/zgrep/offtopiabday/irc.freenode.net/#offtopia/in";
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
happy=':-*D|=D|(:|։|܃|܄|᛬|︰|᠃|᠉|⁚|׃|˸|꞉|∶|ː|ꓽ|⠨|⡁|⠅)(ᴅ|Ⅾ|ⅅ|𝐃|𝐷|𝑫|𝒟|𝓓|𝔇|𝔻|𝕯|𝖣|𝗗|𝘋|𝘿|𝙳|Ꭰ|ᗞ|ᗪ|ꓓ|ᴰ|Ɖ|Ð|⫐|𐌃|Ɒ)'
|
||||
tail -n 200 "/home/zgrep/offtopiabday/irc.freenode.net/##:d/out" | awk '{if($3=="-!-")gsub(/\([^)]+\)/,"");if(/^\S+ \S+ \S+ :D$/){}else if(/'"$happy"'/){sub(/>.*/, "> [REDACTED: NON-CONFORMANT]")}else{sub(/>.*/, "> [REDACTED: NON-HAPPY]")};print}'
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from sys import argv
|
||||
import re
|
||||
import requests as rq
|
||||
from lxml import html
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
if len(argv) != 2:
|
||||
print('Usage:', argv[0], '#channel')
|
||||
exit(1)
|
||||
chan = argv[1]
|
||||
|
||||
def cmd(args):
|
||||
proc = Popen(args, stdout=PIPE)
|
||||
while True:
|
||||
line = proc.stdout.readline()
|
||||
if line:
|
||||
try:
|
||||
yield str(line[:-1], 'utf-8', 'ignore')
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
|
||||
fdir = '/home/zgrep/offtopiabday/irc.freenode.net/' + chan
|
||||
fin = fdir + '/in'
|
||||
fout = fdir + '/out'
|
||||
|
||||
def irc():
|
||||
for line in cmd(['tail', '-n', '0', '-f', fout]):
|
||||
date, time, nick, line = line.split(' ', 3)
|
||||
print(line)
|
||||
m = re.match(r'(?i)((happy|hate)bot[:,]\s+ichi|ハピロボット[:,])\s(.+)', line)
|
||||
if m:
|
||||
q = m.group(3)
|
||||
print('Matched!', q)
|
||||
r = get(q)
|
||||
print('Result!', r)
|
||||
with open(fin, 'w') as fh:
|
||||
fh.write(r + '\n')
|
||||
|
||||
omitnum = 3
|
||||
|
||||
def ichi(q, extra=False):
|
||||
r = rq.get('http://ichi.moe/cl/qr/', params={'q': q})
|
||||
if r.status_code != 200:
|
||||
return 'Non-200 status code. Bug zgrep.'
|
||||
t = html.fromstring(r.content)
|
||||
ichi = ''.join(t.xpath('//span[@class="ds-text"]//text()'))
|
||||
more = ''
|
||||
if extra:
|
||||
e = t.xpath('//span[@class="gloss-desc"]//text()')
|
||||
more = ' - '.join(e[:omitnum])
|
||||
if len(e) > omitnum:
|
||||
more += ' - \x1dmore omitted\x0f'
|
||||
if more:
|
||||
more = ' (' + more + ')'
|
||||
return '"' + ichi + '"' + more
|
||||
|
||||
def kanji(q):
|
||||
r = rq.get('http://ichi.moe/cl/kanji/', params={'q': q})
|
||||
if r.status_code != 200:
|
||||
return None
|
||||
if 'No kanji found' in r.text:
|
||||
return None
|
||||
t = html.fromstring(r.content)
|
||||
return 'Not yet implemented.'
|
||||
|
||||
def get(q):
|
||||
if len(q) == 1:
|
||||
# k = kanji(q)
|
||||
# if k: return k
|
||||
return ichi(q, True)
|
||||
return ichi(q)
|
||||
|
||||
irc()
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
nick="$1"; shift;
|
||||
|
||||
echo "/privmsg $nick :$@" >> "/home/zgrep/offtopiabday/irc.freenode.net/in";
|
|
@ -0,0 +1,313 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
from random import choice, random
|
||||
from time import sleep
|
||||
from os import chdir
|
||||
|
||||
map_url = 'https://zgrep.org/taxreturns/rfk.txt'
|
||||
|
||||
# Log.
|
||||
|
||||
def logging(msg):
|
||||
with open('log.txt', 'a') as fh:
|
||||
fh.write(msg.strip() + '\n')
|
||||
|
||||
# Items.
|
||||
|
||||
def get_items():
|
||||
with open('rfk.txt') as fh:
|
||||
return [l.strip() for l in fh]
|
||||
|
||||
def add_item(item):
|
||||
items = set(get_items() + [item])
|
||||
with open('rfk.txt', 'w') as fh:
|
||||
fh.write('\n'.join(items) + '\n')
|
||||
logging('add item: ' + item)
|
||||
return 'Added item: ' + item
|
||||
|
||||
def del_item(item):
|
||||
items = set(get_items())
|
||||
if item in items:
|
||||
items.remove(item)
|
||||
with open('rfk.txt', 'w') as fh:
|
||||
fh.write('\n'.join(items) + '\n')
|
||||
logging('del item: ' + item)
|
||||
return 'Removed item: ' + item
|
||||
else:
|
||||
removal = None
|
||||
for maybe in items:
|
||||
if maybe.lower().startswith(item.lower()):
|
||||
if removal:
|
||||
break
|
||||
else:
|
||||
removal = maybe
|
||||
else:
|
||||
if removal:
|
||||
items.remove(removal)
|
||||
with open('rfk.txt', 'w') as fh:
|
||||
fh.write('\n'.join(items) + '\n')
|
||||
logging('del item: ' + removal)
|
||||
return 'Removed item: ' + removal
|
||||
else:
|
||||
return 'No items matched: ' + item
|
||||
return 'More than one item matched: ' + item
|
||||
|
||||
# Robot finds kitten bits below.
|
||||
|
||||
grid = {}
|
||||
width, height = 30, 15
|
||||
rx, ry = width // 2, height // 2
|
||||
percent = 0.1
|
||||
blind = False
|
||||
found = False
|
||||
|
||||
def string(): # prints the grid as a string
|
||||
global grid, rx, ry, width, height, found
|
||||
result = ''
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
if (x, y) in grid:
|
||||
item = grid[(x, y)]
|
||||
if found and item[2]:
|
||||
result += 'K'
|
||||
else:
|
||||
result += item[0]
|
||||
elif x == rx and y == ry:
|
||||
result += '#'
|
||||
else:
|
||||
result += ' '
|
||||
result += '\n'
|
||||
return result
|
||||
|
||||
def move(x, y): # teleports to location
|
||||
global rx, ry, width, height, grid, found
|
||||
if x < 0 or y < 0 or x >= width or y >= height:
|
||||
return 'There is a wall in the way.'
|
||||
elif (x, y) in grid:
|
||||
result = grid[(x, y)]
|
||||
if result[2]:
|
||||
found = True
|
||||
return result[1]
|
||||
else:
|
||||
rx, ry = x, y
|
||||
return None
|
||||
|
||||
up = lambda: move(rx, ry - 1)
|
||||
down = lambda: move(rx, ry + 1)
|
||||
left = lambda: move(rx - 1, ry)
|
||||
right = lambda: move(rx + 1, ry)
|
||||
|
||||
symbols = '~!@$%^&*()`[]{}=+\\/?|-_;:\'"<>,.abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
|
||||
def reset(): # Set up a new game.
|
||||
global width, height, rx, ry, grid, percent, found
|
||||
grid = {}
|
||||
found = False
|
||||
items = get_items()
|
||||
rx, ry = width // 2, height // 2
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
if random() <= percent and x != rx and y != ry:
|
||||
grid[(x, y)] = (choice(symbols), choice(items), False)
|
||||
if not grid:
|
||||
kitten = (rx - 2, ry - 2)
|
||||
else:
|
||||
kitten = choice(list(grid))
|
||||
with open('found.txt') as fh:
|
||||
messages = [f.strip('\n') for f in fh.read().strip('\n').split('\n%\n')]
|
||||
grid[kitten] = (choice(symbols), choice(messages), True)
|
||||
if len(grid) == 1:
|
||||
objects = 'there is 1 object'
|
||||
else:
|
||||
objects = 'there are {} objects'.format(len(grid))
|
||||
if not blind:
|
||||
append = 'Map: ' + map_url
|
||||
else:
|
||||
append = 'No map is being made, blind is set to true.'
|
||||
return 'New game! The grid is {} by {}, and {}. You are in the center. {}'\
|
||||
.format(width, height, objects, append)
|
||||
|
||||
# Parsing input.
|
||||
|
||||
def tofile():
|
||||
global blind
|
||||
if not blind:
|
||||
with open('/home/zgrep/tax/rfk.txt', 'w') as fh:
|
||||
fh.write(string())
|
||||
|
||||
def dedup(gen):
|
||||
prev = None
|
||||
for item in gen:
|
||||
if item == prev:
|
||||
continue
|
||||
else:
|
||||
prev = item
|
||||
yield item
|
||||
|
||||
def parse(cmd, normalcase):
|
||||
global width, height, percent, blind
|
||||
if all(c in 'udlrnsew^v<>←↑→↓' for c in cmd):
|
||||
for c in cmd:
|
||||
if c in 'u^n↑':
|
||||
yield up()
|
||||
elif c in 'dvs→':
|
||||
yield down()
|
||||
elif c in 'l<w←':
|
||||
yield left()
|
||||
elif c in 'r>e↓':
|
||||
yield right()
|
||||
tofile()
|
||||
elif cmd in ('up', 'north'):
|
||||
yield up()
|
||||
tofile()
|
||||
elif cmd in ('down', 'south'):
|
||||
yield down()
|
||||
tofile()
|
||||
elif cmd in ('left', 'west'):
|
||||
yield left()
|
||||
tofile()
|
||||
elif cmd in ('right', 'east'):
|
||||
yield right()
|
||||
tofile()
|
||||
elif cmd.startswith('size '):
|
||||
cmd = cmd.replace('size ', '', 1)
|
||||
try:
|
||||
w, h = map(int, cmd.split('x'))
|
||||
w = min(max(w, 5), 1000)
|
||||
h = min(max(h, 5), 1000)
|
||||
width, height = w, h
|
||||
yield reset()
|
||||
tofile()
|
||||
yield topic()
|
||||
except:
|
||||
yield 'The correct format for size is 10x10.'
|
||||
elif cmd.startswith('blind '):
|
||||
cmd = cmd.replace('blind ', '', 1)
|
||||
if ' ' not in cmd:
|
||||
if cmd in ('true', 'yes', 'on', '1'):
|
||||
blind = True
|
||||
with open('/home/zgrep/tax/rfk.txt', 'w') as fh:
|
||||
fh.write('Blind is turned on, no map is being generated.\n')
|
||||
yield topic()
|
||||
yield 'Blind has been set to true, no new maps with be generated.'
|
||||
elif cmd in ('false', 'no', 'off', '0'):
|
||||
blind = False
|
||||
tofile()
|
||||
yield topic()
|
||||
yield 'Blind has been turned off, a map has been generated: ' + map_url
|
||||
else:
|
||||
yield 'Expected either true or false.'
|
||||
elif cmd.startswith('prob '):
|
||||
cmd = cmd.replace('prob ', '', 1)
|
||||
try:
|
||||
m = 1
|
||||
if cmd[-1] == '%':
|
||||
cmd = cmd[:-1]
|
||||
m = 0.01
|
||||
p = min(max(m*float(cmd), 0), 1)
|
||||
percent = p
|
||||
yield reset()
|
||||
tofile()
|
||||
yield topic()
|
||||
except:
|
||||
yield 'The correct format for prob is 0.1 or 10%.'
|
||||
elif cmd.startswith('add item '):
|
||||
yield add_item(normalcase[9:])
|
||||
elif cmd.startswith('del item '):
|
||||
yield del_item(normalcase[9:])
|
||||
elif cmd in ('reset', 'new game', 'restart'):
|
||||
yield reset()
|
||||
tofile()
|
||||
yield topic()
|
||||
elif cmd == 'help':
|
||||
yield 'Commands: size, prob, add item, del item, up (north), down (south), left (west), right (east), new game, blind, map, help.'
|
||||
yield '^<>vudlrnsew becomes up left right down up down left right north south east west. Only the one-character short commands can be chained together in one IRC message.'
|
||||
if not blind:
|
||||
yield 'A map of the grid can be found at: {}'.format(map_url)
|
||||
else:
|
||||
yield 'Currently blind is set to true, and therefore no map of the grid is generated. But normally, it would be found here: {}'.format(map_url)
|
||||
elif cmd in ('map', 'grid'):
|
||||
yield map_url
|
||||
elif cmd == 'size':
|
||||
yield '{} by {}'.format(width, height)
|
||||
elif cmd == 'prob':
|
||||
s = 's'
|
||||
if len(grid) == 1: s = ''
|
||||
yield '{}%, with {} object{} on the current grid.'\
|
||||
.format(percent*100, len(grid), s)
|
||||
elif cmd == 'blind':
|
||||
yield ('blind is set to false, a map is being generated.',
|
||||
'blind is set to true, no map is being generated.')[blind]
|
||||
|
||||
# IRC-specific bits below.
|
||||
|
||||
def topic():
|
||||
global found, width, height, grid
|
||||
s = 's'
|
||||
if len(grid) == 1: s = ''
|
||||
append = 'No map.'
|
||||
if not blind:
|
||||
append = 'Map: ' + map_url
|
||||
finding = ''
|
||||
if found is True:
|
||||
finding = ' Kitten has been found!'
|
||||
elif found:
|
||||
finding = ' Kitten has been found by {}!'.format(found)
|
||||
return '/t Robot finds kitten. To play, type "help". | The grid is {} by {}, and has {} object{}.{} {}'\
|
||||
.format(width, height, len(grid), s, finding, append)
|
||||
|
||||
def cmd(args):
|
||||
proc = Popen(args, stdout=PIPE)
|
||||
while True:
|
||||
line = proc.stdout.readline()
|
||||
if line:
|
||||
try:
|
||||
yield str(line[:-1], 'utf-8', 'ignore')
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
|
||||
def begin(fin, fout):
|
||||
global found
|
||||
|
||||
fin = '/home/zgrep/offtopiabday/' + fin
|
||||
fout = '/home/zgrep/offtopiabday/' + fout
|
||||
|
||||
def send(msg):
|
||||
if msg:
|
||||
with open(fin, 'w') as fh:
|
||||
fh.write(msg.strip() + '\n')
|
||||
|
||||
send(reset())
|
||||
tofile()
|
||||
send(topic())
|
||||
|
||||
for line in cmd(['tail', '-n', '0', '-f', fout]):
|
||||
_, _, nick, line = line.split(' ', 3)
|
||||
nick = nick[1:-1]
|
||||
if nick in ('happybot', 'hatebot'):
|
||||
continue
|
||||
output = list(dedup(parse(line.lower(), line)))
|
||||
if found is True:
|
||||
found = nick
|
||||
with open('finders.txt', 'a') as fh:
|
||||
fh.write(found + '\n')
|
||||
send(topic())
|
||||
time = 0
|
||||
if len(output) > 3:
|
||||
time = 0.5
|
||||
for line in output:
|
||||
send(line)
|
||||
sleep(time)
|
||||
|
||||
from sys import argv
|
||||
|
||||
if len(argv) != 3:
|
||||
print('Usage: in out')
|
||||
exit(1)
|
||||
|
||||
chdir('/home/zgrep/offtopiabday/rfk')
|
||||
|
||||
begin(*argv[1:])
|
|
@ -0,0 +1,140 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
def sizeof_fmt(num, suffix='B'):
|
||||
for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
|
||||
if abs(num) < 1024.0:
|
||||
return "%3.1f%s%s" % (num, unit, suffix)
|
||||
num /= 1024.0
|
||||
return "%.1f%s%s" % (num, 'Yi', suffix)
|
||||
|
||||
from re import compile as regex
|
||||
|
||||
urls = regex(r'(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?')
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
def cmd(*args):
|
||||
proc = Popen(args, stdout=PIPE)
|
||||
while True:
|
||||
line = proc.stdout.readline()
|
||||
if line:
|
||||
try:
|
||||
yield str(line[:-1], 'utf-8', 'ignore')
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
|
||||
from sys import argv
|
||||
|
||||
if len(argv) != 2:
|
||||
print('Usage:', argv[0], '#channel')
|
||||
exit(1)
|
||||
|
||||
chan = '/home/zgrep/offtopiabday/irc.freenode.net/' + argv[1]
|
||||
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
def quote(url):
|
||||
res = ''
|
||||
for c in url:
|
||||
if ord(c) > 127:
|
||||
res += ''.join('%' + hex(b)[2:] for b in c.encode('utf-8'))
|
||||
else:
|
||||
res += c
|
||||
return res
|
||||
|
||||
irccloud_none = 'irccloud.com/pastebin/'
|
||||
irccloud_with = irccloud_none + 'raw/'
|
||||
|
||||
for line in cmd('tail', '-n', '0', '-f', chan + '/out'):
|
||||
date, time, nick, line = line.split(' ', 3)
|
||||
nick = nick[1:-1]
|
||||
if nick in ('happybot', 'hatebot'):
|
||||
continue
|
||||
result = []
|
||||
print('Doing line:', line)
|
||||
for url in urls.findall(line):
|
||||
url = quote(url)
|
||||
if irccloud_none in url and irccloud_with not in url:
|
||||
result.append(url.replace(irccloud_none, irccloud_with, 1))
|
||||
continue
|
||||
if url[-5:] == '.gifv': # hack for imgur gifv's
|
||||
url = url[:-5]
|
||||
print('| Got gifv:', url)
|
||||
try:
|
||||
r = urlopen(Request(url + '.mp4', method='HEAD'))
|
||||
contenttype = r.getheader('content-type')
|
||||
length1 = r.getheader('content-length')
|
||||
r.close()
|
||||
except:
|
||||
print('| Could not get mp4.')
|
||||
if 'video' not in contenttype.lower():
|
||||
print('| Video is not a video?')
|
||||
result.append('???')
|
||||
continue
|
||||
try:
|
||||
r = urlopen(Request(url + '.gif', method='HEAD'))
|
||||
contenttype = r.getheader('content-type')
|
||||
length2 = r.getheader('content-length')
|
||||
r.close()
|
||||
except:
|
||||
print('| Could not get gif.')
|
||||
if 'image' not in contenttype.lower():
|
||||
print('| Image is not an image?')
|
||||
result.append('???')
|
||||
continue
|
||||
try:
|
||||
length1 = int(length1)
|
||||
length2 = int(length2)
|
||||
except:
|
||||
print('| Lengths are not ints.')
|
||||
continue
|
||||
if length1 <= length2:
|
||||
url += '.mp4'
|
||||
length = length1
|
||||
else:
|
||||
url += '.gif'
|
||||
length = length2
|
||||
result.append(url + ' ' + sizeof_fmt(length))
|
||||
continue
|
||||
print('| Got URL:', url)
|
||||
rq = Request(url, method='HEAD')
|
||||
try:
|
||||
r = urlopen(rq)
|
||||
contenttype = r.getheader('content-type').lower()
|
||||
length = r.getheader('content-length')
|
||||
r.close()
|
||||
print('| | HEAD request completed.')
|
||||
download = 0 # 0 ignore, 1 get from HEAD, 2+ get from HEAD otherwise GET
|
||||
if 'image' in contenttype:
|
||||
download = 2 # download images, fine...
|
||||
elif 'video' in contenttype:
|
||||
download = 1 # Eh... I'll draw the line at videos.
|
||||
if download > 0:
|
||||
if length:
|
||||
try:
|
||||
b = int(length)
|
||||
except:
|
||||
b = -1
|
||||
elif download > 1:
|
||||
try:
|
||||
rq = Request(url, method='HEAD')
|
||||
r = urlopen(rq)
|
||||
b = len(r.read())
|
||||
r.close()
|
||||
print('| | Normal request required and complete.')
|
||||
except:
|
||||
b = -1
|
||||
print('| | Normal request required and failed.')
|
||||
if b < 0:
|
||||
print('| | Failure.')
|
||||
result.append('???')
|
||||
else:
|
||||
print('| | Success.')
|
||||
result.append(sizeof_fmt(b))
|
||||
except:
|
||||
print('| | Failure.')
|
||||
if result:
|
||||
with open(chan + '/in', 'w') as fh:
|
||||
fh.write('[' + '] ['.join(result) + ']\n')
|
Loading…
Reference in New Issue