-
-
Save cdunklau/8447316 to your computer and use it in GitHub Desktop.
Chatserver Nightmare! Now with flake8 compliance!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*.py[co] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
main = lambda port: (lambda dt: (lambda mm: (lambda n: (map(lambda r: (lambda | |
rr: setattr(n, *rr) if (type(rr) is tuple and len(rr) == 2) else None)(r()), | |
[lambda: map(setattr, *zip(*[(n, m, __import__(m)) for m in mm.m.decode('ba' | |
'se64').split()])), lambda: map(n.s['signal.signal'], (n.s['signal.SIGINT'], | |
n.s['signal.SIGTERM']), [lambda s, f: (n.s['sys.exit']() if n.f else [n.sa( | |
mm.l[0], n.o)] and n.u('f', True) or n.fc(n.l))] * 2), lambda: setattr(mm, | |
'l', mm.l.decode('base64').split('~~~')), lambda: ('sw', n.s['types.Functio' | |
'nType'] (compile("try:\n\tv = n.select.select(n.so, n.w(), [])\nexcept n.s" | |
"elect.error, e:\n\tif e[0] != n.errno.EINTR: raise\nelse:\n\tn.u('sr', v)", | |
'', 'exec'), dict(n=n, OSError=OSError))),lambda: ('l', n.s['socket.socket'] | |
(n.s['socket.AF_INET'], n.s['socket.SOCK_STREAM'])), lambda: n.s['l.bind'](( | |
'', port)), lambda: n.s['l.listen'](5), lambda: ('ro', lambda: filter(lambda | |
s: s in n.nn, n.so)), lambda: n.update(si=(lambda o: o.__setitem__), di=( | |
lambda o: o.__delitem__), cr=n.s['re.compile'](mm.l[11]), nn={}, dp=lambda | |
s, d, c, l: n.dd.get(c, d)(s, l, c), dd=dict(me=lambda s, l, c: n.sa(mm.l[14 | |
] % (n.nn[s], l)), quit=lambda s, l, c: n.c(s), who=lambda s, l, c: n.ws(s, | |
mm.l[1] + ', '.join(n.s['nn.values']())), help=lambda s, l, c: n.ws(s, mm.l[ | |
2]), nick=lambda s, l, c: ((([n.sa(mm.l[3] % (n.nn[s], l))] and n.si(n.nn)( | |
s, l)) if n.nr.match(l) else n.ws(s, mm.l[4])) if l not in n.nn.values() | |
else n.ws(s, mm.l[7]))), so=(n.u('f', False) or [n.l]), ib=n.s['collections' | |
'.defaultdict'](list), ob=n.s['collections.defaultdict'](list), o=(lambda: | |
filter(lambda s: s is not n.l, n.so)), w=(lambda: filter(n.ob.__getitem__, | |
n.o())), ws=(lambda s, l: n.ob[s].append(l + '\r\n')), nr=n.s['re.compile']( | |
mm.l[12]), sa=(lambda d, f=n.ro: map(lambda s: n.ws(s, d), f())), fs=set(), | |
c=(lambda s: [n.sa(mm.l[13] % n.nn[s]) if s in n.nn and s not in n.fs else | |
None] and n.s['fs.add'](s)), fc=(lambda s: [s.close()] and (n.so.remove(s) | |
if s in n.so else None) or (n.fs.remove(s) if s in n.fs else None) or (n.di( | |
n.ib)(s) if s in n.ib else None) or (n.di(n.ob)(s) if s in n.ob else None) | |
or (n.di(n.nn)(s) if s in n.nn else None))), lambda: map(lambda f: map( | |
apply, [lambda: n.u('sr', ([], [], [])), lambda: n.sw(), lambda: map(apply, | |
[lambda *ss: map(lambda s: map(apply, [lambda: n.sa(mm.l[8]), lambda: n.so. | |
append(s.accept()[0]), lambda: n.ws(n.so[-1], mm.l[6])]) if s is n.l else | |
map(apply, [lambda: n.ib[s].append(s.recv(4096)) or (n.c(s) if n.ib[s][-1] | |
== '' else None)]), ss), lambda *ss: map(lambda s: (lambda d: (n.si(n.ob)(s, | |
[d[s.send(d):]]) or (n.si(n.ob)(s, []) if n.ob[s] == [''] else None)))(''. | |
join(n.ob[s])), ss), lambda *ss: None], n.sr), lambda: [n.di(v)(slice(None, | |
None)) for k, v in n.ob.items() if v and not filter(None, v)], lambda: n.u( | |
'sl', {}), lambda: map((lambda (k, v): n.si(n.sl)(k, ''.join(v).split('\r\n' | |
)) or n.si(n.ib)(k, [n.sl[k].pop()])), n.ib.items()), lambda: n.sl and map( | |
lambda (s, l): ((n.sa(mm.l[15] % (n.nn[s], l[1:] if l.startswith('//') else | |
l)) if not l.startswith('/') or l.startswith('//') else (n.dp(s, lambda s, | |
l, c: n.ws(s, mm.l[9] % c), *n.s['cr.match'](l).groups()))) if s in n.nn | |
else (((n.si(n.nn)(s, l) or [n.ws(s, mm.l[5])] and n.sa(mm.l[10] % l)) if n. | |
nr.match(l) else n.ws(s, mm.l[4])) if l not in n.nn.values() else n.ws(s, | |
mm.l[7]))), [(s, l.rstrip()) for s, ll in n.sl.items() for l in ll]), | |
lambda: n.f and map(lambda (s, b): n.fc(s) if not filter(None, b) else None, | |
n.ob.items()), lambda: map(lambda s: n.fc(s) if not filter(None, n.ob[s]) | |
else None, list(n.fs))]), iter(lambda: bool(n.so), False)), lambda: n.s['l.' | |
'close']()])))(dt()))(dt(m='c3lzIHNpZ25hbCBzb2NrZXQgc2VsZWN0IGNvbGxlY3Rpb25' | |
'zIGVycm5vIHR5cGVzIGl0ZXJ0b29scyByZQ==', l='KioqIFNlcnZlciBnb2luZyBkb3duIX5' | |
'+fioqKiBDdXJyZW50bHkgY29ubmVjdGVkOiB+fn4qKiogQXZhaWxhYmxlIGNvbW1hbmRzOg0KK' | |
'ioqICAvaGVscCAtLSBnZXQgaGVscA0KKioqICAvcXVpdCAtLSBkaXNjb25uZWN0DQoqKiogIC9' | |
'tZSAtLSBwZXJmb3JtIGFuIGFjdGlvbg0KKioqICAvd2hvIC0tIGxpc3QgY29ubmVjdGVkIHVzZ' | |
'XJzDQoqKiogIC9uaWNrIC0tIGNoYW5nZSB5b3VyIG5pY2tuYW1lIHRvIHNvbWV0aGluZyBiZXR' | |
'0ZXJ+fn4qKiogJXMgaXMgbm93IGtub3duIGFzICVzLn5+fioqKiBUaGF0IG5pY2tuYW1lIGlzI' | |
'GludmFsaWQufn5+KioqIFR5cGUgIi9oZWxwIiBmb3IgaGVscC5+fn4qKiogSGVsbG8hIFdoYXQ' | |
'gaXMgeW91ciBuaWNrbmFtZT9+fn4qKiogVGhhdCBuaWNrbmFtZSBpcyBhbHJlYWR5IGluIHVzZ' | |
'S5+fn4qKiogSW5jb21pbmcgY29ubmVjdGlvbiF+fn4qKiogTm8gc3VjaCBjb21tYW5kOiAvJXN' | |
'+fn4qKiogJXMgaGFzIGpvaW5lZC5+fn5eLyhbQS16XSopXHMqKC4qKSR+fn5eW0EtejAtOV9dK' | |
'yR+fn4qKiogJXMgaGFzIGxlZnQufn5+KiAlcyAlc35+fjwlcz4gJXM=')))(type('', (dict, | |
), dict(__getattr__=lambda s, k: s[k], u=lambda s, *a: s.__setitem__(*a), | |
__setattr__=lambda s, k, v: s.__setitem__(k, v), s=property(lambda s: type( | |
'', (object,), dict(__getitem__=lambda ss, k: reduce(getattr, k.split('.'), | |
s)))())))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
main = lambda port: ( | |
lambda dt: ( | |
lambda mm: ( | |
lambda n: ( | |
map( | |
lambda r: ( | |
lambda rr: ( | |
setattr(n, *rr) | |
if (type(rr) is tuple and len(rr) == 2) | |
else None | |
) | |
)(r()), | |
[ | |
lambda: map( | |
setattr, | |
*zip( | |
*[ | |
(n, m, __import__(m)) | |
for m | |
in mm.m.decode('ba' 'se64').split() | |
] | |
) | |
), | |
lambda: map( | |
n.s['signal.signal'], | |
(n.s['signal.SIGINT'], n.s['signal.SIGTERM']), | |
[ | |
lambda s, f: ( | |
n.s['sys.exit']() | |
if n.f | |
else ( | |
[n.sa(mm.l[0], n.o)] and | |
n.u('f', True) or | |
n.fc(n.l) | |
) | |
) | |
] * 2 | |
), | |
lambda: setattr( | |
mm, 'l', mm.l.decode('base64').split('~~~') | |
), | |
lambda: ( | |
'sw', | |
n.s['types.Functio' 'nType']( | |
compile( | |
"try:\n" | |
"\tv = n.select.select(n.so, n.w(), [])\n" | |
"except n.select.error, e:\n" | |
"\tif e[0] != n.errno.EINTR: raise\n" | |
"else:\n" | |
"\tn.u('sr', v)", | |
'', | |
'exec' | |
), | |
dict(n=n, OSError=OSError) | |
) | |
), | |
lambda: ( | |
'l', | |
n.s['socket.socket']( | |
n.s['socket.AF_INET'], | |
n.s['socket.SOCK_STREAM'] | |
) | |
), | |
lambda: n.s['l.bind'](('', port)), | |
lambda: n.s['l.listen'](5), | |
lambda: ( | |
'ro', lambda: filter(lambda s: s in n.nn, n.so) | |
), | |
lambda: n.update( | |
si=(lambda o: o.__setitem__), | |
di=(lambda o: o.__delitem__), | |
cr=n.s['re.compile'](mm.l[11]), | |
nn={}, | |
dp=lambda s, d, c, l: n.dd.get(c, d)(s, l, c), | |
dd=dict( | |
me=lambda s, l, c: ( | |
n.sa(mm.l[14] % (n.nn[s], l)) | |
), | |
quit=lambda s, l, c: n.c(s), | |
who=lambda s, l, c: n.ws( | |
s, mm.l[1] + ', '.join(n.s['nn.values']()) | |
), | |
help=lambda s, l, c: n.ws(s, mm.l[2]), | |
nick=lambda s, l, c: ( | |
( | |
( | |
[n.sa(mm.l[3] % (n.nn[s], l))] and | |
n.si(n.nn)(s, l) | |
) | |
if n.nr.match(l) | |
else n.ws(s, mm.l[4]) | |
) | |
if l not in n.nn.values() | |
else n.ws(s, mm.l[7]) | |
) | |
), | |
so=(n.u('f', False) or [n.l]), | |
ib=n.s['collections' '.defaultdict'](list), | |
ob=n.s['collections.defaultdict'](list), | |
o=(lambda: filter(lambda s: s is not n.l, n.so)), | |
w=(lambda: filter(n.ob.__getitem__, n.o())), | |
ws=(lambda s, l: n.ob[s].append(l + '\r\n')), | |
nr=n.s['re.compile'](mm.l[12]), | |
sa=( | |
lambda d, f=n.ro: map( | |
lambda s: n.ws(s, d), | |
f() | |
) | |
), | |
fs=set(), | |
c=( | |
lambda s: [ | |
n.sa(mm.l[13] % n.nn[s]) | |
if s in n.nn and s not in n.fs | |
else None | |
] and n.s['fs.add'](s) | |
), | |
fc=( | |
lambda s: ( | |
[s.close()] and | |
(n.so.remove(s) if s in n.so else None) or | |
(n.fs.remove(s) if s in n.fs else None) or | |
(n.di(n.ib)(s) if s in n.ib else None) or | |
(n.di(n.ob)(s) if s in n.ob else None) or | |
(n.di(n.nn)(s) if s in n.nn else None) | |
) | |
) | |
), | |
lambda: map( | |
lambda f: map( | |
apply, | |
[ | |
lambda: n.u('sr', ([], [], [])), | |
lambda: n.sw(), | |
lambda: map( | |
apply, | |
[ | |
lambda *ss: map( | |
lambda s: map( | |
apply, | |
[ | |
lambda: ( | |
n.sa(mm.l[8]) | |
), | |
lambda: ( | |
n.so.append( | |
s.accept()[0] | |
) | |
), | |
lambda: n.ws( | |
n.so[-1], | |
mm.l[6] | |
) | |
] | |
) if s is n.l else map( | |
apply, | |
[ | |
lambda: ( | |
n.ib[s].append( | |
s.recv(4096) | |
) or | |
( | |
n.c(s) | |
if ( | |
n.ib[s][-1] | |
== '' | |
) | |
else None | |
) | |
) | |
] | |
), | |
ss | |
), | |
lambda *ss: map( | |
lambda s: ( | |
lambda d: ( | |
n.si(n.ob)( | |
s, | |
[d[s.send(d):]] | |
) or | |
( | |
n.si(n.ob)(s, []) | |
if n.ob[s] == [''] | |
else None | |
) | |
) | |
)(''. join(n.ob[s])), ss), | |
lambda *ss: None | |
], | |
n.sr | |
), | |
lambda: [ | |
n.di(v)(slice(None, None)) | |
for k, v | |
in n.ob.items() | |
if v and not filter(None, v) | |
], | |
lambda: n.u('sl', {}), | |
lambda: map( | |
( | |
lambda (k, v): ( | |
n.si(n.sl)( | |
k, | |
''.join(v).split('\r\n') | |
) or n.si(n.ib)( | |
k, | |
[n.sl[k].pop()] | |
) | |
) | |
), | |
n.ib.items() | |
), | |
lambda: n.sl and map( | |
lambda (s, l): ( | |
( | |
n.sa( | |
mm.l[15] % ( | |
n.nn[s], | |
l[1:] | |
if l.startswith('//') | |
else l | |
) | |
) | |
if ( | |
not l.startswith('/') or | |
l.startswith('//') | |
) | |
else ( | |
n.dp( | |
s, | |
lambda s, l, c: ( | |
n.ws( | |
s, | |
mm.l[9] % c | |
) | |
), | |
*n.s['cr.match']( | |
l | |
).groups() | |
) | |
) | |
) | |
if s in n.nn | |
else ( | |
( | |
( | |
n.si(n.nn)(s, l) or | |
[n.ws(s, mm.l[5])] and | |
n.sa(mm.l[10] % l) | |
) | |
if n.nr.match(l) | |
else n.ws(s, mm.l[4]) | |
) | |
if l not in n.nn.values() | |
else n.ws(s, mm.l[7]) | |
) | |
), | |
[ | |
(s, l.rstrip()) | |
for s, ll | |
in n.sl.items() | |
for l | |
in ll | |
] | |
), | |
lambda: ( | |
n.f and | |
map( | |
lambda (s, b): ( | |
n.fc(s) | |
if not filter(None, b) | |
else None | |
), | |
n.ob.items() | |
) | |
), | |
lambda: map( | |
lambda s: ( | |
n.fc(s) | |
if not filter(None, n.ob[s]) | |
else None | |
), | |
list(n.fs) | |
) | |
] | |
), | |
iter(lambda: bool(n.so), False) | |
), | |
lambda: n.s['l.' 'close']() | |
] | |
) | |
) | |
)(dt()) | |
)( | |
dt( | |
m='c3lzIHNpZ25hbCBzb2NrZXQgc2VsZWN0IGNvbGxlY3Rpb25zIGVycm5vIHR5cGV' | |
'zIGl0ZXJ0b29scyByZQ==', | |
l='KioqIFNlcnZlciBnb2luZyBkb3duIX5+fioqKiBDdXJyZW50bHkgY29ubmVjdGV' | |
'kOiB+fn4qKiogQXZhaWxhYmxlIGNvbW1hbmRzOg0KKioqICAvaGVscCAtLSBnZXQg' | |
'aGVscA0KKioqICAvcXVpdCAtLSBkaXNjb25uZWN0DQoqKiogIC9tZSAtLSBwZXJmb' | |
'3JtIGFuIGFjdGlvbg0KKioqICAvd2hvIC0tIGxpc3QgY29ubmVjdGVkIHVzZXJzDQ' | |
'oqKiogIC9uaWNrIC0tIGNoYW5nZSB5b3VyIG5pY2tuYW1lIHRvIHNvbWV0aGluZyB' | |
'iZXR0ZXJ+fn4qKiogJXMgaXMgbm93IGtub3duIGFzICVzLn5+fioqKiBUaGF0IG5p' | |
'Y2tuYW1lIGlzIGludmFsaWQufn5+KioqIFR5cGUgIi9oZWxwIiBmb3IgaGVscC5+f' | |
'n4qKiogSGVsbG8hIFdoYXQgaXMgeW91ciBuaWNrbmFtZT9+fn4qKiogVGhhdCBuaW' | |
'NrbmFtZSBpcyBhbHJlYWR5IGluIHVzZS5+fn4qKiogSW5jb21pbmcgY29ubmVjdGl' | |
'vbiF+fn4qKiogTm8gc3VjaCBjb21tYW5kOiAvJXN+fn4qKiogJXMgaGFzIGpvaW5l' | |
'ZC5+fn5eLyhbQS16XSopXHMqKC4qKSR+fn5eW0EtejAtOV9dKyR+fn4qKiogJXMga' | |
'GFzIGxlZnQufn5+KiAlcyAlc35+fjwlcz4gJXM=' | |
) | |
) | |
)( | |
type( | |
'', | |
(dict,), | |
dict( | |
__getattr__=lambda s, k: s[k], | |
u=lambda s, *a: s.__setitem__(*a), | |
__setattr__=lambda s, k, v: s.__setitem__(k, v), | |
s=property( | |
lambda s: type( | |
'', | |
(object,), | |
dict( | |
__getitem__=lambda ss, k: reduce( | |
getattr, | |
k.split('.'), | |
s | |
) | |
) | |
)() | |
) | |
) | |
) | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### The first thing that jumped out at me was the big blocks of strings | |
### starting at line 49 of the original code. There are two arguments to the | |
### ``dt`` function, named ``m`` and ``l``, and they both sure look like | |
### base-64 encoding. Here are the originals, the only change is the | |
### indentation and naming. | |
ORIGINAL_M_BASE64 = ( | |
'c3lzIHNpZ25hbCBzb2NrZXQgc2VsZWN0IGNvbGxlY3Rpb25' | |
'zIGVycm5vIHR5cGVzIGl0ZXJ0b29scyByZQ==' | |
) | |
ORIGINAL_L_BASE64 = ( | |
'KioqIFNlcnZlciBnb2luZyBkb3duIX5' | |
'+fioqKiBDdXJyZW50bHkgY29ubmVjdGVkOiB+fn4qKiogQXZhaWxhYmxlIGNvbW1hbmRzOg0KK' | |
'ioqICAvaGVscCAtLSBnZXQgaGVscA0KKioqICAvcXVpdCAtLSBkaXNjb25uZWN0DQoqKiogIC9' | |
'tZSAtLSBwZXJmb3JtIGFuIGFjdGlvbg0KKioqICAvd2hvIC0tIGxpc3QgY29ubmVjdGVkIHVzZ' | |
'XJzDQoqKiogIC9uaWNrIC0tIGNoYW5nZSB5b3VyIG5pY2tuYW1lIHRvIHNvbWV0aGluZyBiZXR' | |
'0ZXJ+fn4qKiogJXMgaXMgbm93IGtub3duIGFzICVzLn5+fioqKiBUaGF0IG5pY2tuYW1lIGlzI' | |
'GludmFsaWQufn5+KioqIFR5cGUgIi9oZWxwIiBmb3IgaGVscC5+fn4qKiogSGVsbG8hIFdoYXQ' | |
'gaXMgeW91ciBuaWNrbmFtZT9+fn4qKiogVGhhdCBuaWNrbmFtZSBpcyBhbHJlYWR5IGluIHVzZ' | |
'S5+fn4qKiogSW5jb21pbmcgY29ubmVjdGlvbiF+fn4qKiogTm8gc3VjaCBjb21tYW5kOiAvJXN' | |
'+fn4qKiogJXMgaGFzIGpvaW5lZC5+fn5eLyhbQS16XSopXHMqKC4qKSR+fn5eW0EtejAtOV9dK' | |
'yR+fn4qKiogJXMgaGFzIGxlZnQufn5+KiAlcyAlc35+fjwlcz4gJXM=' | |
) | |
### And here are the same strings, as presented in the redented version. | |
REDENT_M_BASE64 = ( | |
'c3lzIHNpZ25hbCBzb2NrZXQgc2VsZWN0IGNvbGxlY3Rpb25zIGVycm5vIHR5cGV' | |
'zIGl0ZXJ0b29scyByZQ==' | |
) | |
REDENT_L_BASE64 = ( | |
'KioqIFNlcnZlciBnb2luZyBkb3duIX5+fioqKiBDdXJyZW50bHkgY29ubmVjdGV' | |
'kOiB+fn4qKiogQXZhaWxhYmxlIGNvbW1hbmRzOg0KKioqICAvaGVscCAtLSBnZXQg' | |
'aGVscA0KKioqICAvcXVpdCAtLSBkaXNjb25uZWN0DQoqKiogIC9tZSAtLSBwZXJmb' | |
'3JtIGFuIGFjdGlvbg0KKioqICAvd2hvIC0tIGxpc3QgY29ubmVjdGVkIHVzZXJzDQ' | |
'oqKiogIC9uaWNrIC0tIGNoYW5nZSB5b3VyIG5pY2tuYW1lIHRvIHNvbWV0aGluZyB' | |
'iZXR0ZXJ+fn4qKiogJXMgaXMgbm93IGtub3duIGFzICVzLn5+fioqKiBUaGF0IG5p' | |
'Y2tuYW1lIGlzIGludmFsaWQufn5+KioqIFR5cGUgIi9oZWxwIiBmb3IgaGVscC5+f' | |
'n4qKiogSGVsbG8hIFdoYXQgaXMgeW91ciBuaWNrbmFtZT9+fn4qKiogVGhhdCBuaW' | |
'NrbmFtZSBpcyBhbHJlYWR5IGluIHVzZS5+fn4qKiogSW5jb21pbmcgY29ubmVjdGl' | |
'vbiF+fn4qKiogTm8gc3VjaCBjb21tYW5kOiAvJXN+fn4qKiogJXMgaGFzIGpvaW5l' | |
'ZC5+fn5eLyhbQS16XSopXHMqKC4qKSR+fn5eW0EtejAtOV9dKyR+fn4qKiogJXMga' | |
'GFzIGxlZnQufn5+KiAlcyAlc35+fjwlcz4gJXM=' | |
) | |
### A simple test to make sure I didn't screw up with my reformatting: | |
assert ORIGINAL_M_BASE64 == REDENT_M_BASE64 | |
assert ORIGINAL_L_BASE64 == REDENT_L_BASE64 | |
### Those didn't blow up. Let's make it a bit nicer-looking with triple-quoted | |
### strings and strip the newlines. The asserts make sure they're equal. | |
M_BASE64 = """ | |
c3lzIHNpZ25hbCBzb2NrZXQgc2VsZWN0IGNvbGxlY3Rpb25zIGVycm5vIHR5cGVzIGl0ZXJ0b29scy | |
ByZQ== | |
""".replace('\n', '') | |
L_BASE64 = """ | |
KioqIFNlcnZlciBnb2luZyBkb3duIX5+fioqKiBDdXJyZW50bHkgY29ubmVjdGVkOiB+fn4qKiogQX | |
ZhaWxhYmxlIGNvbW1hbmRzOg0KKioqICAvaGVscCAtLSBnZXQgaGVscA0KKioqICAvcXVpdCAtLSBk | |
aXNjb25uZWN0DQoqKiogIC9tZSAtLSBwZXJmb3JtIGFuIGFjdGlvbg0KKioqICAvd2hvIC0tIGxpc3 | |
QgY29ubmVjdGVkIHVzZXJzDQoqKiogIC9uaWNrIC0tIGNoYW5nZSB5b3VyIG5pY2tuYW1lIHRvIHNv | |
bWV0aGluZyBiZXR0ZXJ+fn4qKiogJXMgaXMgbm93IGtub3duIGFzICVzLn5+fioqKiBUaGF0IG5pY2 | |
tuYW1lIGlzIGludmFsaWQufn5+KioqIFR5cGUgIi9oZWxwIiBmb3IgaGVscC5+fn4qKiogSGVsbG8h | |
IFdoYXQgaXMgeW91ciBuaWNrbmFtZT9+fn4qKiogVGhhdCBuaWNrbmFtZSBpcyBhbHJlYWR5IGluIH | |
VzZS5+fn4qKiogSW5jb21pbmcgY29ubmVjdGlvbiF+fn4qKiogTm8gc3VjaCBjb21tYW5kOiAvJXN+ | |
fn4qKiogJXMgaGFzIGpvaW5lZC5+fn5eLyhbQS16XSopXHMqKC4qKSR+fn5eW0EtejAtOV9dKyR+fn | |
4qKiogJXMgaGFzIGxlZnQufn5+KiAlcyAlc35+fjwlcz4gJXM= | |
""".replace('\n', '') | |
assert M_BASE64 == ORIGINAL_M_BASE64 | |
assert L_BASE64 == ORIGINAL_L_BASE64 | |
### Now let's see what we actually have. | |
import base64 | |
M_BASE64_DECODED = base64.b64decode(M_BASE64) | |
L_BASE64_DECODED = base64.b64decode(L_BASE64) | |
print repr(M_BASE64_DECODED) | |
### Result: | |
# 'sys signal socket select collections errno types itertools re' | |
### It's pretty obvious these are (at least some of) the modules used, so | |
### let's just make a list out of it. So far, so good. | |
modules_list = M_BASE64.split() | |
### How about the other one? | |
print repr(L_BASE64_DECODED) | |
### Result: | |
# '*** Server going down!~~~*** Currently connected: ~~~*** Available commands:\r\n*** /help -- get help\r\n*** /quit -- disconnect\r\n*** /me -- perform an action\r\n*** /who -- list connected users\r\n*** /nick -- change your nickname to something better~~~*** %s is now known as %s.~~~*** That nickname is invalid.~~~*** Type "/help" for help.~~~*** Hello! What is your nickname?~~~*** That nickname is already in use.~~~*** Incoming connection!~~~*** No such command: /%s~~~*** %s has joined.~~~^/([A-z]*)\\s*(.*)$~~~^[A-z0-9_]+$~~~*** %s has left.~~~* %s %s~~~<%s> %s' | |
### Those look really familar! We saw most of that stuff when we ran the thing | |
### earlier. I didn't see any tildes in my interaction, and I vaguely remember | |
### a split involving tildes... so let's try that, and grab the indicies for | |
### good measure. | |
for i, msg in enumerate(L_BASE64_DECODED.split('~~~')): | |
print '{0}: {1}'.format(i, repr(msg)) | |
# 0: '*** Server going down!' | |
# 1: '*** Currently connected: ' | |
# 2: '*** Available commands:\r\n*** /help -- get help\r\n*** /quit -- disconnect\r\n*** /me -- perform an action\r\n*** /who -- list connected users\r\n*** /nick -- change your nickname to something better' | |
# 3: '*** %s is now known as %s.' | |
# 4: '*** That nickname is invalid.' | |
# 5: '*** Type "/help" for help.' | |
# 6: '*** Hello! What is your nickname?' | |
# 7: '*** That nickname is already in use.' | |
# 8: '*** Incoming connection!' | |
# 9: '*** No such command: /%s' | |
# 10: '*** %s has joined.' | |
# 11: '^/([A-z]*)\\s*(.*)$' | |
# 12: '^[A-z0-9_]+$' | |
# 13: '*** %s has left.' | |
# 14: '* %s %s' | |
# 15: '<%s> %s' | |
### Progress! Most of these things are obvious. The regex patterns and the | |
### very simple format strings stick out, but it's not immediately obvious | |
### what they're for. Let's structure this a bit better so we can get an idea | |
### about the semantics of these strings, the non-obvious ones are marked | |
### with the reasoning I used to name them. | |
outputs_list = L_BASE64_DECODED.split('~~~') | |
outputs_keys = [ | |
'server_exit', # 0: '*** Server going down!' | |
'who_response_prefix', # 1: '*** Currently connected: ' | |
'help_response', # 2: '*** Available commands:\r\n*** <trunc> | |
'nick_response_format', # 3: '*** %s is now known as %s.' | |
'nick_response_error', # 4: '*** That nickname is invalid.' | |
'help_message', # 5: '*** Type "/help" for help.' | |
'greeting_prompt', # 6: '*** Hello! What is your nickname?' | |
'nonunique_nick_error', # 7: '*** That nickname is already in use.' | |
'incoming_message', # 8: '*** Incoming connection!' | |
'command_error_format', # 9: '*** No such command: /%s' | |
'join_message_format', # 10: '*** %s has joined.' | |
### This has to be the command pattern, since the anchor is followed | |
### immediately by a forward slash | |
'command_pattern', # 11: '^/([A-z]*)\\s*(.*)$' | |
### Not too sure what this is for yet, but it definitely matches a single | |
### word. Perhaps it's used for nick validation? | |
'word_pattern', # 12: '^[A-z0-9_]+$' | |
'part_message_format', # 13: '*** %s has left.' | |
### The only thing in the initial testing session that started with a | |
### single asterix was the result of the action command /me | |
'action_message_format', # 14: '* %s %s' | |
### Angle brackets around the nick, then the message. | |
'chat_message_format', # 15: '<%s> %s' | |
] | |
### Let's combine the keys and strings into a dict. The ``pprint`` module | |
### gives us a nice display that we can dump back into our source file. | |
outputs_from_keys = dict(zip(outputs_keys, outputs_list)) | |
import pprint | |
pprint.pprint(outputs_from_keys) | |
### We can then take the output of that and define the message store as a dict | |
### literal. I've redone the order of the keys in the literal so they match | |
### the keys list. | |
outputs_from_literal = { | |
'server_exit': '*** Server going down!', | |
'who_response_prefix': '*** Currently connected: ', | |
'help_response': ( | |
'*** Available commands:\r\n' | |
'*** /help -- get help\r\n' | |
'*** /quit -- disconnect\r\n' | |
'*** /me -- perform an action\r\n' | |
'*** /who -- list connected users\r\n' | |
'*** /nick -- change your nickname to something better' | |
), | |
'nick_response_format': '*** %s is now known as %s.', | |
'nick_response_error': '*** That nickname is invalid.', | |
'help_message': '*** Type "/help" for help.', | |
'greeting_prompt': '*** Hello! What is your nickname?', | |
'nonunique_nick_error': '*** That nickname is already in use.', | |
'incoming_message': '*** Incoming connection!', | |
'command_error_format': '*** No such command: /%s', | |
'join_message_format': '*** %s has joined.', | |
'command_pattern': '^/([A-z]*)\\s*(.*)$', | |
'word_pattern': '^[A-z0-9_]+$', | |
'part_message_format': '*** %s has left.', | |
'action_message_format': '* %s %s', | |
'chat_message_format': '<%s> %s', | |
} | |
### And a simple test to ensure I didn't screw up my copy-paste | |
assert outputs_from_keys == outputs_from_literal | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Functional tests for chatserver refactor. | |
Set the environment variable CHATSERVER_TEST_MODULE to the suffix | |
of the chatserver_*.py script you want to test, and use the unittest | |
module's __main__ interface to run this test module:: | |
CHATSERVER_TEST_MODULE=original python -m unittest test_chatserver | |
""" | |
import os | |
import os.path | |
import sys | |
import unittest | |
import subprocess | |
from glob import glob | |
from importlib import import_module | |
thisdir = os.path.abspath(os.path.dirname(__file__)) | |
available = {} | |
for module_path in glob(os.path.join(thisdir, 'chatserver_*.py')): | |
module_name, ext = os.path.splitext(os.path.basename(module_path)) | |
_, sep, key = module_name.partition('_') | |
if not sep: | |
continue | |
available[key] = module_name | |
#print available | |
chosen_suffix = os.environ.get('CHATSERVER_TEST_MODULE') | |
if not chosen_suffix: | |
print ( | |
'CHATSERVER_TEST_MODULE not set, set to one of ' | |
', '.join(available) | |
) | |
sys.exit(1) | |
if chosen_suffix not in available: | |
print 'Invalid suffix, choices are: ' + ', '.join(available) | |
sys.exit(1) | |
chatserver = import_module(available[chosen_suffix]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment