The Dod
10 years ago
4 changed files with 250 additions and 2 deletions
@ -0,0 +1,60 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
import sys |
||||||
|
import os |
||||||
|
import json |
||||||
|
import darkened |
||||||
|
import pastee3 |
||||||
|
|
||||||
|
__version__ = (0, 1, 0) |
||||||
|
|
||||||
|
pasteclient = pastee3.PasteClient() |
||||||
|
|
||||||
|
def todarkive(s,folder,filename): |
||||||
|
"""Store a string as a file in the "darkive", and notify the user""" |
||||||
|
folder = os.path.join('darkive',folder) |
||||||
|
os.makedirs(folder,0o700,True) |
||||||
|
filename = os.path.join(folder,filename) |
||||||
|
if os.path.exists(filename): |
||||||
|
sys.stderr.write('# Skipping existing file! {}\n'.format(filename)) |
||||||
|
else: |
||||||
|
open(filename,'w').write(s) |
||||||
|
sys.stderr.write('# Wrote file: {}\n'.format(filename)) |
||||||
|
|
||||||
|
def daget(pasteid): |
||||||
|
pasteid = pasteid.split('/')[-1] # in case it's a full url |
||||||
|
if '#' in pasteid: |
||||||
|
p,needhash = pasteid.split('#') |
||||||
|
else: |
||||||
|
p,needhash = pasteid,None |
||||||
|
sys.stderr.write('# getting paste {}\n'.format(p)) |
||||||
|
payload = pasteclient.sloppy_get(p) |
||||||
|
if not payload: |
||||||
|
sys.stderr.write('# bad or missing pastee!\n') |
||||||
|
return False |
||||||
|
if needhash: |
||||||
|
gothash = darkened.hash64(bytes(payload.strip(),'ascii','replace')) |
||||||
|
if gothash == needhash: |
||||||
|
sys.stderr.write('# Hash Matches\n') |
||||||
|
d = json.loads(payload) |
||||||
|
todarkive(payload,d['msgid'],'{}.json'.format(p)) |
||||||
|
return True |
||||||
|
else: |
||||||
|
sys.stderr.write('# Hash mismatch! need {}, got {}. Corrupt paste?\n'.format(repr(needhash),repr(gothash))) |
||||||
|
todarkive(payload,'corrupt','{}.corrupt.json'.format(p)) |
||||||
|
return False |
||||||
|
else: |
||||||
|
sys.stderr.write('# Not checking hash(!)\n') |
||||||
|
d = json.loads(payload) |
||||||
|
todarkive(payload,d['msgid'],'{}.unverified.json'.format(p)) |
||||||
|
return True |
||||||
|
|
||||||
|
if __name__=='__main__': |
||||||
|
if len(sys.argv)<2: |
||||||
|
sys.stderr.write("""Usage: {} pasteeurl[#hash] ... |
||||||
|
E.g. {} https://pastee.org/69f38#V4F8BjwgSfzkaentZlcBsacuLNM= hzrk2 |
||||||
|
(second argument is in the shortest form: only id, no hash) |
||||||
|
""") |
||||||
|
sys.exit(1) |
||||||
|
for pasteid in sys.argv[1:]: |
||||||
|
sys.stderr.write('### getting {}\n'.format(pasteid)) |
||||||
|
daget(pasteid) |
@ -0,0 +1,51 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
import sys |
||||||
|
import optparse |
||||||
|
import json |
||||||
|
import darkened |
||||||
|
import pastee3 |
||||||
|
|
||||||
|
__version__ = (0, 1, 0) |
||||||
|
|
||||||
|
pasteclient = pastee3.PasteClient() |
||||||
|
|
||||||
|
def paste(value, indent=None): |
||||||
|
b = bytes(json.dumps(value, indent=indent).strip(), 'ascii') |
||||||
|
h = darkened.hash64(b) |
||||||
|
return '#'.join((pasteclient.paste(b, ttl=365), h)) |
||||||
|
|
||||||
|
def main(): |
||||||
|
parser = optparse.OptionParser( |
||||||
|
usage='%prog [options] From To [To ...]', |
||||||
|
epilog='This will create some pastee.org pastes, ' |
||||||
|
'and write stuff you need to copy/paste and tweet/DM') |
||||||
|
parser.add_option("-s", "--subject", default="(untitled)", |
||||||
|
help=("Subject")) |
||||||
|
parser.add_option("-d", "--debug", action="store_true", |
||||||
|
help=("Debug: don't crate pastes, dump as json to stdout instead")) |
||||||
|
(options, args) = parser.parse_args() |
||||||
|
if len(args)<2: |
||||||
|
parser.print_help() |
||||||
|
exit(1) |
||||||
|
redaction = darkened.redact(sys.stdin.read(), sender=args.pop(0), recipients=args, subject=options.subject) |
||||||
|
if options.debug: |
||||||
|
json.dump(redaction, sys.stdout, indent=4) |
||||||
|
else: |
||||||
|
players = darkened.getplayers() |
||||||
|
payload = redaction.pop('__public__') |
||||||
|
pasteurl = paste(payload, indent=4) |
||||||
|
print('== Publicly twist:\n#Darkages #{} public: {}'.format(payload.get('msgid', 'bug!!!'), pasteurl)) |
||||||
|
payload = redaction.pop('__to__') |
||||||
|
pasteurl = paste(payload, indent=4) |
||||||
|
for r in payload['recipients']: |
||||||
|
if r in players: |
||||||
|
print('== DM @{}:\n#Darkages #{} for {}: {}'.format(players[r]['twister'], payload.get('msgid', 'bug!!!'), pasteurl)) |
||||||
|
else: |
||||||
|
print('[No need to DM NPC] {}:\n#Darkages #{} full: {}'.format(r, payload.get('msgid', 'bug!!!'), pasteurl)) |
||||||
|
for t in redaction: # Only trustees left after popping those two |
||||||
|
payload = redaction[t] |
||||||
|
pasteurl = paste(payload, indent=4) |
||||||
|
print('== DM @{}:\n#Darkages #{} trustee {}: {}'.format(players[t]['twister'], payload.get('msgid', 'bug!!!'), t, pasteurl)) |
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
main() |
@ -0,0 +1,51 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
import sys |
||||||
|
import os |
||||||
|
import json |
||||||
|
import darkened |
||||||
|
import pastee3 |
||||||
|
|
||||||
|
__version__ = (0, 1, 0) |
||||||
|
|
||||||
|
pasteclient = pastee3.PasteClient() |
||||||
|
|
||||||
|
def fromdarkive(msgid): |
||||||
|
"""Retrieve all files in a "darkive" folder, and returns cipher and consolidated pads""" |
||||||
|
folder = os.path.join('darkive',msgid) |
||||||
|
if not os.path.isdir(folder): |
||||||
|
sys.stderr.write('# Folder does not exist! {}\n'.format(folder)) |
||||||
|
return None, None |
||||||
|
sys.stderr.write('# Scanning folder {}\n'.format(folder)) |
||||||
|
cipher = None |
||||||
|
pads = None |
||||||
|
for f in os.listdir(folder): |
||||||
|
# sys.stderr.write('Reading {}\n'.format(f)) |
||||||
|
try: |
||||||
|
d=json.load(open(os.path.join(folder,f))) |
||||||
|
except Exception as e: |
||||||
|
sys.stderr.write('Error reading {}! {}\n'.format(os.path.join(folder,f),e)) |
||||||
|
continue |
||||||
|
if 'cipher' in d: |
||||||
|
cipher = d |
||||||
|
else: |
||||||
|
if pads: |
||||||
|
pads['pads'].update(d['pads']) # Todo: check conflicts? |
||||||
|
else: |
||||||
|
pads = d |
||||||
|
return cipher, pads |
||||||
|
|
||||||
|
if __name__=='__main__': |
||||||
|
if len(sys.argv)<2: |
||||||
|
sys.stderr.write("Usage: {} msgid [trustee ...]\n") |
||||||
|
sys.exit(1) |
||||||
|
# Trick to allow e.g. 'darkive/DA14342254974005/' (like autocomplete does) |
||||||
|
msgid = list(filter(None,sys.argv[1].split('/')))[-1] |
||||||
|
cipher,pads = fromdarkive(msgid) |
||||||
|
if cipher or pads: |
||||||
|
d = cipher or pads |
||||||
|
for k in ['msgid', 'sender', 'recipients', 'trustees', 'subject']: |
||||||
|
if k in d: |
||||||
|
print('{}: {}'.format(k,d[k])) |
||||||
|
if cipher and pads: |
||||||
|
print() |
||||||
|
print(darkened.unredact(cipher,pads,trustees=sys.argv[2:])) |
Loading…
Reference in new issue