Telnet, terminal and display interfaces working fine
This commit is contained in:
parent
d123096b49
commit
814aa8c182
1 changed files with 53 additions and 18 deletions
71
clippy.py
71
clippy.py
|
|
@ -9,6 +9,8 @@ import numpy
|
|||
import bz2
|
||||
import os
|
||||
import functools
|
||||
import contextlib
|
||||
import math
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
|
@ -34,9 +36,11 @@ class Display:
|
|||
self.size = 56*8, 8*20
|
||||
|
||||
def sendframe(self, frame):
|
||||
self.sock.sendto(struct.pack('!HHHHH', CMD_LED_DRAW, 0,
|
||||
(56*8*(12*20-8))%65536, 0x627a, 0) + # do. not. fucking. ask.
|
||||
bz2.compress(frame), (HOST, PORT))
|
||||
pl = struct.pack('!HHHHH', CMD_LED_DRAW, 0, 0, 0x627a, 0) + bz2.compress(frame)
|
||||
self.sock.sendto(pl, (HOST, PORT))
|
||||
# for i in range(100):
|
||||
# time.sleep(0.0001)
|
||||
self.sock.sendto(pl, (HOST, PORT))
|
||||
|
||||
@staticmethod
|
||||
def do_gamma(im, gamma):
|
||||
|
|
@ -66,35 +70,41 @@ class Agent:
|
|||
for ani in self.config['animations'].values():
|
||||
for f in ani['frames']:
|
||||
branching, exitBranch = f.get('branching'), f.get('exitBranch')
|
||||
if 'branching' in f:
|
||||
if 'exitBranch' in f:
|
||||
f['next'] = lambda f, idx: f['exitBranch']
|
||||
elif 'branching' in f:
|
||||
f['next'] = lambda f, idx: weightedChoice(
|
||||
[ (b['weight']/100, b['frameIndex']) for b in f['branching']['branches'] ]
|
||||
, default=idx+1)
|
||||
elif 'exitBranch' in f:
|
||||
f['next'] = lambda f, idx: f['exitBranch']
|
||||
else:
|
||||
f['next'] = lambda f, idx: idx+1
|
||||
self.picmap = Image.open(path / 'map.png')
|
||||
self.path = path
|
||||
|
||||
def __call__(self, action):
|
||||
print('Playing:', action)
|
||||
for frame in self._animate(action):
|
||||
print('frame:', frame)
|
||||
# print('frame:', frame)
|
||||
if 'images_encoded' in frame: # some frames contain branch info and sound, but no images
|
||||
yield frame['images_encoded']
|
||||
time.sleep(frame['duration']/1000)
|
||||
|
||||
def precalculate_images(self, dsp, termsize):
|
||||
print('\033[93mPrecalculating images\033[0m')
|
||||
total = sum(1 for ani in self.config['animations'].values() for f in ani['frames'] if 'images' in f)
|
||||
i = 0
|
||||
for ani in self.config['animations'].values():
|
||||
for f in ani['frames']:
|
||||
if 'images' in f:
|
||||
print(('(\033[38;5;245m{: '+str(1+int(math.log10(total)))+'}/{}\033[0m) ').format(i, total), end='')
|
||||
i += 1
|
||||
f['images_encoded'] = self._precalculate_one_image(tuple(f['images'][0]), dsp, termsize)
|
||||
print()
|
||||
print('\033[93mdone.\033[0m')
|
||||
self._precalculate_one_image.cache_clear()
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def _precalculate_one_image(self, coords, dsp, termsize):
|
||||
img = self.get_image(*coords)
|
||||
img = self._get_image(*coords)
|
||||
return ( dsp.encode_image(img, dsp.size) if dsp else None,
|
||||
pixelterm.termify_pixels(resize_image(img, termsize)) if termsize else None )
|
||||
|
||||
|
|
@ -104,8 +114,9 @@ class Agent:
|
|||
yield anim[idx]
|
||||
idx = anim[idx]['next'](anim[idx], idx)
|
||||
|
||||
def get_image(self, x, y):
|
||||
print('cropbox:', x, y, *self.config['framesize'], 'map:', self.picmap.size)
|
||||
def _get_image(self, x, y):
|
||||
print('\033[38;5;96mcropbox:\033[0m {:04} {:04} {:04} {:04} \033[38;5;96mmap:\033[0m {:04} {:04}'.format(
|
||||
x, y, *self.config['framesize'], *self.picmap.size), end='')
|
||||
tw, th = self.config['framesize']
|
||||
return self.picmap.crop((x, y, x+tw, y+th))
|
||||
|
||||
|
|
@ -122,6 +133,9 @@ if __name__ == '__main__':
|
|||
parser.add_argument('-e', '--endless', action='store_true')
|
||||
parser.add_argument('-d', '--display', action='store_true')
|
||||
parser.add_argument('-t', '--terminal', action='store_true')
|
||||
parser.add_argument('-x', '--termsize', type=str)
|
||||
parser.add_argument('-s', '--socket', action='store_true')
|
||||
parser.add_argument('-b', '--bind', type=str, default='0.0.0.0:2342')
|
||||
parser.add_argument('action', default='Greeting', nargs='?')
|
||||
args = parser.parse_args()
|
||||
|
||||
|
|
@ -136,18 +150,39 @@ if __name__ == '__main__':
|
|||
|
||||
dsp = Display() if args.display else None
|
||||
agent = Agent(agent_path)
|
||||
tx, ty = os.get_terminal_size()
|
||||
termsize = (tx, ty*2) if args.terminal else None
|
||||
if args.socket:
|
||||
tx, ty = (args.termsize or '60x30').split('x')
|
||||
tx, ty = int(tx), int(ty)
|
||||
elif args.terminal:
|
||||
tx, ty = args.termsize.split('x') or os.get_terminal_size()
|
||||
tx, ty = int(tx), int(ty)
|
||||
termsize = (tx, ty*2) if args.terminal or args.socket else None
|
||||
agent.precalculate_images(dsp, termsize)
|
||||
|
||||
if args.endless:
|
||||
if args.socket:
|
||||
import socketserver
|
||||
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||
pass
|
||||
class ClippyRequestHandler(socketserver.BaseRequestHandler):
|
||||
def handle(self):
|
||||
with contextlib.suppress(BrokenPipeError):
|
||||
while True:
|
||||
action = random.choice(agent.animations)
|
||||
print('[\033[38;5;245m{}\033[0m] Playing: {}'.format(self.client_address[0], action))
|
||||
for _img_dsp, img_term in agent(action):
|
||||
self.request.sendall(b'\033[H'+img_term.encode())
|
||||
host, port = args.bind.split(':')
|
||||
port = int(port)
|
||||
server = ThreadedTCPServer((host, port), ClippyRequestHandler)
|
||||
server.serve_forever()
|
||||
elif args.endless:
|
||||
while True:
|
||||
if random.random() > 0.2:
|
||||
for img_dsp, img_term in agent(random.choice(agent.animations)):
|
||||
action = random.choice(agent.animations)
|
||||
print('Playing:', action)
|
||||
for img_dsp, img_term in agent(action):
|
||||
if args.terminal:
|
||||
print('\033[H', end='')
|
||||
print(pixelterm.termify_pixels(
|
||||
resize_image(img, termsize)))
|
||||
print('\033[H'+img_term)
|
||||
if args.display:
|
||||
dsp.sendframe(img_dsp)
|
||||
time.sleep(1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue