cli fun
parent
18ba159a97
commit
db46ee8a65
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
@ -0,0 +1,285 @@
|
|||||||
|
ART_TELEPHONE = '''
|
||||||
|
..--""""----..
|
||||||
|
.-" ..--""""--.j-.
|
||||||
|
.-" .-" .--.""--..
|
||||||
|
.-" .-" ..--"-. \/ ;
|
||||||
|
.-" .-"_.--..--"" ..--' "-. :
|
||||||
|
.' .' / `. \..--"" __ _ \ ;
|
||||||
|
:.__.-" \ / .' ( )"-. Y
|
||||||
|
; ;: ( ) ( ). \
|
||||||
|
.': /:: : \ \
|
||||||
|
.'.-"\._ _.-" ; ; ( ) .-. ( ) \
|
||||||
|
" `.""" .j" : : \ ; ; \
|
||||||
|
bug /"""""/ ; ( ) "" :.( ) \
|
||||||
|
/\ / : \ \`.: _ \
|
||||||
|
: `. / ; `( ) (\/ :" \ \
|
||||||
|
\ `. : "-.(_)_.' t-' ;
|
||||||
|
\ `. ; ..--":
|
||||||
|
`. `. : ..--"" :
|
||||||
|
`. "-. ; ..--"" ;
|
||||||
|
`. "-.:_..--"" ..--"
|
||||||
|
`. : ..--""
|
||||||
|
"-. : ..--""
|
||||||
|
"-.;_..--""
|
||||||
|
|
||||||
|
'''
|
||||||
|
ART_PHONE_SM1 = """
|
||||||
|
.----------------.
|
||||||
|
/ _H______H_ \@,
|
||||||
|
\____/ \____/ @,
|
||||||
|
/ \ `@
|
||||||
|
| LI LI LI | ,@
|
||||||
|
| LI LI LI | ,@'
|
||||||
|
| LI LI LI | ,@'
|
||||||
|
| LI LI LI |@@'
|
||||||
|
jgs \ /'
|
||||||
|
`----------'
|
||||||
|
"""
|
||||||
|
|
||||||
|
ART_ROTARY2="""
|
||||||
|
_______________
|
||||||
|
/ \
|
||||||
|
| .---------. |@
|
||||||
|
'---' .-----. '---'@
|
||||||
|
.' /6 5_4 3\ '. @
|
||||||
|
| |7 /...\ 2| | @
|
||||||
|
| |8 \___/ 1| | @
|
||||||
|
| \_9_0_)\/ | @@
|
||||||
|
/==|_____________|@@@@
|
||||||
|
H-------------------@@
|
||||||
|
H ) || || ( @@
|
||||||
|
H / || || \ @
|
||||||
|
H |----''---''----|
|
||||||
|
=/ |_______________|
|
||||||
|
"""
|
||||||
|
|
||||||
|
ART_KEY = """
|
||||||
|
|
||||||
|
8 8 8 8 ,ooo.
|
||||||
|
8a8 8a8 oP ?b
|
||||||
|
d888a888zzzzzzzzzzzzzzzzzzzz8 8b
|
||||||
|
`""^""' ?o___oP'
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
ART_OLDPHONE = """
|
||||||
|
__
|
||||||
|
/` _`\
|
||||||
|
| (_()| .-.
|
||||||
|
\_ _/_/ \
|
||||||
|
||=[_] |
|
||||||
|
|| | | |
|
||||||
|
||/ \ |
|
||||||
|
||`---' /
|
||||||
|
.--'||-.___.'
|
||||||
|
/` .-||-.
|
||||||
|
'-/`.____.`\
|
||||||
|
jgs '.______.'
|
||||||
|
"""
|
||||||
|
|
||||||
|
ART_OLDPHONE2="""
|
||||||
|
|
||||||
|
_|~|/|
|
||||||
|
( | | |
|
||||||
|
/_|_|\|
|
||||||
|
| |
|
||||||
|
| |~|
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
| |-|
|
||||||
|
| | \
|
||||||
|
| |__|
|
||||||
|
|_|_
|
||||||
|
/ ~-_
|
||||||
|
/ ~-_
|
||||||
|
|___________|
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
ART_ROTARY = """
|
||||||
|
_...----..._
|
||||||
|
,-' ,-. `-.
|
||||||
|
,' ,-. ( 4 ) ,-. `.
|
||||||
|
,' ( 5 ) `-' ( 3 ) `.
|
||||||
|
/ ,-. `-',-'' ``-.`-' ,-. \
|
||||||
|
/ ( 6 ) ,' `. ( 2 ) \
|
||||||
|
: `-' / FEUER \ `-' :
|
||||||
|
| ,-. : ________ : ,-. |
|
||||||
|
|( 7 ) | |________| | ( 1 )|
|
||||||
|
| `-' : ; `-' |
|
||||||
|
: ,-. \ NOTRUF / ;
|
||||||
|
\ ( 8 ) `. ,'(`. /
|
||||||
|
\ `-' ,-.`-..__..-' \ `-./
|
||||||
|
`. ( 9 ) ,-. \ ,'
|
||||||
|
`. `-' ( 0 ) ,'`
|
||||||
|
`-._ `-' _.-'
|
||||||
|
```----''' SSt
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
ART_PHONE_DIAGRAM = """
|
||||||
|
________
|
||||||
|
.' / / )
|
||||||
|
/ /##/ /|
|
||||||
|
/ `--' / |
|
||||||
|
/__ __ __ / |
|
||||||
|
//_//_//_// / __
|
||||||
|
//_//_//_// / \`.___ Listening end
|
||||||
|
//_//_//_// /
|
||||||
|
//_//_//_// /__
|
||||||
|
/ / / \`.___ Buttons
|
||||||
|
/ .-. / /
|
||||||
|
/ /#/ / /
|
||||||
|
/ `-' / /__
|
||||||
|
/ .====. / / \`.___ Speaking end
|
||||||
|
|`--------' /
|
||||||
|
\ , .'__
|
||||||
|
`-//----' \`.___ Disconnect button
|
||||||
|
//
|
||||||
|
"""
|
||||||
|
|
||||||
|
ART_OLDPHONE3 = """
|
||||||
|
|
||||||
|
__ _
|
||||||
|
.: .' '.
|
||||||
|
/: / \_
|
||||||
|
;: ; ,-'/`:\
|
||||||
|
|: | | |():|
|
||||||
|
;: ; '-.\_:/
|
||||||
|
\: \ /`
|
||||||
|
':_'._.'
|
||||||
|
||
|
||||||
|
/__\
|
||||||
|
.---. {====}
|
||||||
|
.' _,"-,__|:: |
|
||||||
|
/ ((O)=;--.:: |
|
||||||
|
; `|: | |:: |
|
||||||
|
| |: | |:: |
|
||||||
|
| |: | |:: |
|
||||||
|
| |: | |:: |
|
||||||
|
| |: | |:: |
|
||||||
|
| |: | |:: |
|
||||||
|
| /:'__\ |:: |
|
||||||
|
| [______]|:: |
|
||||||
|
| `----` |:: |__
|
||||||
|
| _.--|:: | ''--._
|
||||||
|
; .' __{====}__ '.
|
||||||
|
\ .'_.-'._ `""` _.'-._ '.
|
||||||
|
'--'/` `''''` `\ '.__
|
||||||
|
jgs '._ _.'
|
||||||
|
`""--......--""`
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
ART_OLDPHONE4 = """
|
||||||
|
|
||||||
|
__
|
||||||
|
/` _`\
|
||||||
|
| (_()| .-.
|
||||||
|
\_ _/_/ \
|
||||||
|
||=[_] |
|
||||||
|
|| | | |
|
||||||
|
||/ \ |
|
||||||
|
||`---' /
|
||||||
|
.--'||-.___.'
|
||||||
|
/` .-||-.
|
||||||
|
'-/`.____.`\
|
||||||
|
jgs '.______.'
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
ART_PAYPHONE = """
|
||||||
|
_________________
|
||||||
|
/ __ \
|
||||||
|
| (__) |
|
||||||
|
| |
|
||||||
|
| .-----. .--. |
|
||||||
|
| | | / \ |
|
||||||
|
| '-----' \ / |
|
||||||
|
| | | |
|
||||||
|
| LI LI LI | | |
|
||||||
|
| LI LI LI | | |Oo
|
||||||
|
| LI LI LI | | |`Oo
|
||||||
|
| LI LI LI | | | Oo
|
||||||
|
| | | | Oo
|
||||||
|
| .------. / \ | oO
|
||||||
|
| | | \ / | Oo
|
||||||
|
| '------' '-oO | oO
|
||||||
|
| .---Oo | Oo
|
||||||
|
| || ||`Oo oO
|
||||||
|
| |'--'| | OoO
|
||||||
|
| '----' |
|
||||||
|
jgs \_________________/
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
####
|
||||||
|
# code
|
||||||
|
###
|
||||||
|
from PIL import Image
|
||||||
|
ASCII_CHARS = [ '#', '?', '%', '.', 'S', '+', '.', '*', ':', ',', '@']
|
||||||
|
|
||||||
|
def scale_image(image, new_width=100):
|
||||||
|
"""Resizes an image preserving the aspect ratio.
|
||||||
|
"""
|
||||||
|
(original_width, original_height) = image.size
|
||||||
|
aspect_ratio = original_height/float(original_width)
|
||||||
|
new_height = int(aspect_ratio * new_width)
|
||||||
|
|
||||||
|
new_image = image.resize((new_width, new_height))
|
||||||
|
return new_image
|
||||||
|
|
||||||
|
def convert_to_grayscale(image):
|
||||||
|
return image.convert('L')
|
||||||
|
|
||||||
|
def map_pixels_to_ascii_chars(image, range_width=25):
|
||||||
|
"""Maps each pixel to an ascii char based on the range
|
||||||
|
in which it lies.
|
||||||
|
|
||||||
|
0-255 is divided into 11 ranges of 25 pixels each.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pixels_in_image = list(image.getdata())
|
||||||
|
pixels_to_chars = [ASCII_CHARS[pixel_value//range_width] for pixel_value in
|
||||||
|
pixels_in_image]
|
||||||
|
|
||||||
|
return "".join(pixels_to_chars)
|
||||||
|
|
||||||
|
def convert_image_to_ascii(image, new_width=100):
|
||||||
|
image = scale_image(image)
|
||||||
|
image = convert_to_grayscale(image)
|
||||||
|
|
||||||
|
pixels_to_chars = map_pixels_to_ascii_chars(image)
|
||||||
|
len_pixels_to_chars = len(pixels_to_chars)
|
||||||
|
|
||||||
|
image_ascii = [pixels_to_chars[index: index + new_width] for index in
|
||||||
|
range(0, len_pixels_to_chars, new_width)]
|
||||||
|
|
||||||
|
return "\n".join(image_ascii)
|
||||||
|
|
||||||
|
def handle_image_conversion(image_filepath):
|
||||||
|
image = None
|
||||||
|
try:
|
||||||
|
image = Image.open(image_filepath)
|
||||||
|
except Exception as e:
|
||||||
|
# print "Unable to open image file {image_filepath}.".format(image_filepath=image_filepath)
|
||||||
|
# print e
|
||||||
|
return
|
||||||
|
|
||||||
|
image_ascii = convert_image_to_ascii(image)
|
||||||
|
print(image_ascii)
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
import sys
|
||||||
|
|
||||||
|
image_file_path = sys.argv[1]
|
||||||
|
handle_image_conversion(image_file_path)
|
@ -0,0 +1,155 @@
|
|||||||
|
import os,sys; sys.path.append(os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__),'..')),'..')))
|
||||||
|
from komrade import *
|
||||||
|
from komrade.backend import *
|
||||||
|
import art
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CLI(Logger):
|
||||||
|
ROUTES = {
|
||||||
|
'help':'see help messages',
|
||||||
|
'register':'register new user',
|
||||||
|
'login':'log back in'
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.name=''
|
||||||
|
self.cmd=''
|
||||||
|
|
||||||
|
async def run(self,inp,name=''):
|
||||||
|
if name: self.name=name
|
||||||
|
clear_screen()
|
||||||
|
self.boot()
|
||||||
|
self.help()
|
||||||
|
|
||||||
|
if inp: self.route(inp)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
inp=input()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
exit()
|
||||||
|
self.route(inp)
|
||||||
|
await asyncio.sleep(0.5)
|
||||||
|
|
||||||
|
def route(self,inp):
|
||||||
|
inp=inp.strip()
|
||||||
|
if not inp.startswith('/'): return
|
||||||
|
cmd=inp.split()[0]
|
||||||
|
dat=inp[len(cmd):].strip()
|
||||||
|
cmd=cmd[1:]
|
||||||
|
if cmd in self.ROUTES and hasattr(self,cmd):
|
||||||
|
f=getattr(self,cmd)
|
||||||
|
return f(dat)
|
||||||
|
|
||||||
|
def boot(self):
|
||||||
|
print(art.text2art(CLI_TITLE,font=CLI_FONT))
|
||||||
|
|
||||||
|
def help(self):
|
||||||
|
print()
|
||||||
|
for cmd,info in self.ROUTES.items():
|
||||||
|
print(f' /{cmd}: {info}')
|
||||||
|
print('\n')
|
||||||
|
|
||||||
|
def intro(self):
|
||||||
|
self.status(None,)
|
||||||
|
|
||||||
|
## routes
|
||||||
|
def register(self,name=None):
|
||||||
|
# defaults
|
||||||
|
if name and not self.name: self.name=name
|
||||||
|
if not name and self.name: name=self.name
|
||||||
|
if not name and not self.name: name=''
|
||||||
|
|
||||||
|
# self.status(None,ART_PAYPHONE,3,pause=False) #,ticks = None)
|
||||||
|
|
||||||
|
# hello, op?
|
||||||
|
nm=name if name else '?'
|
||||||
|
self.status(
|
||||||
|
f'\n\n@{nm}: Uh yes hello, Operator? I would like to join Komrade, the socialist network. Could you patch me through?',clear=False)
|
||||||
|
|
||||||
|
while not name:
|
||||||
|
name=self.status(('name','@TheTelephone: Of course, Komrade...?\n@')).get('vals').get('name').strip()
|
||||||
|
print()
|
||||||
|
self.name = name
|
||||||
|
self.persona = Persona(name)
|
||||||
|
|
||||||
|
self.status(
|
||||||
|
f'@TheTelephone: Of course, Komrade @{name}. A fine name.',
|
||||||
|
|
||||||
|
'''@TheTelephone: However, I'm just the local operator who lives on your device; my only job is to communicate with the remote operator securely.''',
|
||||||
|
|
||||||
|
'''Komrade @TheOperator lives on the deep web. She's the one you want to speak with.''',
|
||||||
|
|
||||||
|
f'''@{name}: Hm, ok. Well, could you patch me through to the remote operator then?''',
|
||||||
|
|
||||||
|
f'''@{TELEPHONE_NAME}: I could, but it's not safe yet. Your information could be exposed. You need to forge your encryption keys first.''',
|
||||||
|
|
||||||
|
f'@{name}: Fine, but how do I do that?',
|
||||||
|
|
||||||
|
f'@{TELEPHONE_NAME}: Visit the Keymaker.',
|
||||||
|
|
||||||
|
clear=False,pause=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### KEYMAKER
|
||||||
|
self.status(None,ART_KEY,3,pause=False,clear=False)
|
||||||
|
# convo
|
||||||
|
self.status('',
|
||||||
|
f'@{name}: Hello, Komrade @Keymaker? I would like help forging a new set of keys.',
|
||||||
|
|
||||||
|
f'@Keymaker: Of course, Komrade @{name}.',
|
||||||
|
|
||||||
|
'''We will make three keys. First, a matching, "asymmetric" pair.''',
|
||||||
|
|
||||||
|
'\t1) A "public key" you can share with anyone.',
|
||||||
|
|
||||||
|
'\t2) A "private key" other no one can ever, ever see.',
|
||||||
|
|
||||||
|
'With both together, you can communicate privately and securely with anyone who also has their own key pair.',
|
||||||
|
|
||||||
|
'We will use the use the iron-clad Elliptic Curve algorthm to generate the keypair, accessed via a high-level cryptography library, Themis (https://github.com/cossacklabs/themis).',
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
# make and save keys locally
|
||||||
|
self.log(f'{KEYMAKER_DEFAULT_KEYS_TO_SAVE_ON_CLIENT + KEYMAKER_DEFAULT_KEYS_TO_SAVE_ON_SERVER}!!!!!')
|
||||||
|
uri_id,keys_returned = self.persona.forge_new_keys(
|
||||||
|
name=name,
|
||||||
|
passphrase=None,
|
||||||
|
keys_to_save = [],
|
||||||
|
keys_to_return = KEYMAKER_DEFAULT_KEYS_TO_SAVE_ON_CLIENT + KEYMAKER_DEFAULT_KEYS_TO_SAVE_ON_SERVER
|
||||||
|
)
|
||||||
|
self.status('got back',dict_format(keys_returned))
|
||||||
|
#self.log(f'my new uri is {uri_id} and I got new keys!: {dict_format(keys_returned)}')
|
||||||
|
|
||||||
|
self.status(
|
||||||
|
'Generating public key now: ',5,'\n\t',repr(KomradeAsymmetricPublicKey(keychain['pubkey'])),'\n\n',
|
||||||
|
'Generating private key now: ',5,'\n\t',repr(KomradeAsymmetricPrivateKey(keychain['privkey'])),
|
||||||
|
clear=False,pause=False,end=' ',speed=2
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# save the ones we should on server
|
||||||
|
data = {
|
||||||
|
**{'name':name, 'passphrase':self.crypt_keys.hash(passphrase.encode()), ROUTE_KEYNAME:'register_new_user'},
|
||||||
|
**keys_returned
|
||||||
|
}
|
||||||
|
self.log('sending to server:',dict_format(data,tab=2))
|
||||||
|
# msg_to_op = self.compose_msg_to(data, self.op)
|
||||||
|
|
||||||
|
|
||||||
|
# ring operator
|
||||||
|
# call from phone since I don't have pubkey on record on Op yet
|
||||||
|
resp_msg_obj = self.phone.ring_ring(data)
|
||||||
|
self.log('register got back from op:',dict_format(resp_msg_obj,tab=2))
|
||||||
|
|
||||||
|
def run_cli():
|
||||||
|
cli = CLI()
|
||||||
|
asyncio.run(cli.run('/register',name='elon'))
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
run_cli()
|
||||||
|
# asyncio.run(test_async())
|
Loading…
Reference in New Issue