Merge pull request from dadav/feature/multi_display_preview

Feature/multi display preview
This commit is contained in:
evilsocket 2019-10-06 00:22:50 +02:00 committed by GitHub
commit 10a3500d27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 116 additions and 117 deletions
docs
scripts

@ -26,7 +26,7 @@ usage: ./scripts/create_sibling.sh [OPTIONS]
`GLib-ERROR **: 20:50:46.361: getauxval () failed: No such file or directory`
- Affected DEB & Versions: QEMU <= 2.11
- Affected DEB & Versions: QEMU <= 2.11
- Fix: Upgrade QEMU to >= 3.1
- Bug Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=923289
@ -55,7 +55,6 @@ If you changed the `voice.py`- File, the translations need an update. Do it like
Now you can use the `preview.py`-script to preview the changes:
```shell
./scripts/preview.py --lang it --display ws2 --port 8080 &
./scripts/preview.py --lang it --display inky --port 8081 &
# Now open http://localhost:8080 and http://localhost:8081
./scripts/preview.py --lang it --display ws1 ws2 inky --output preview.png
# Now open preview.png
```

@ -14,64 +14,26 @@ sys.path.insert(0,
'../sdcard/rootfs/root/pwnagotchi/scripts/'))
from pwnagotchi.ui.display import Display, VideoHandler
from PIL import Image
class CustomDisplay(Display):
def __init__(self, config, state):
self.last_image = None
super(CustomDisplay, self).__init__(config, state)
def _http_serve(self):
if self._video_address is not None:
self._httpd = HTTPServer((self._video_address, self._video_port),
CustomVideoHandler)
logging.info("ui available at http://%s:%d/" % (self._video_address,
self._video_port))
self._httpd.serve_forever()
else:
logging.info("could not get ip of usb0, video server not starting")
# do nothing
pass
def _on_view_rendered(self, img):
CustomVideoHandler.render(img)
self.last_image = img
if self._enabled:
self.canvas = (img if self._rotation == 0 else img.rotate(self._rotation))
if self._render_cb is not None:
self._render_cb()
class CustomVideoHandler(VideoHandler):
@staticmethod
def render(img):
with CustomVideoHandler._lock:
try:
img.save("/tmp/pwnagotchi-{rand}.png".format(rand=id(CustomVideoHandler)), format='PNG')
except BaseException:
logging.exception("could not write preview")
def do_GET(self):
if self.path == '/':
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
try:
self.wfile.write(
bytes(
self._index %
('localhost', 1000), "utf8"))
except BaseException:
pass
elif self.path.startswith('/ui'):
with self._lock:
self.send_response(200)
self.send_header('Content-type', 'image/png')
self.end_headers()
try:
with open("/tmp/pwnagotchi-{rand}.png".format(rand=id(CustomVideoHandler)), 'rb') as fp:
shutil.copyfileobj(fp, self.wfile)
except BaseException:
logging.exception("could not open preview")
else:
self.send_response(404)
def get_image(self):
"""
Return the saved image
"""
return self.last_image
class DummyPeer:
@ -79,21 +41,43 @@ class DummyPeer:
def name():
return "beta"
def append_images(images, horizontal=True, xmargin=0, ymargin=0):
w, h = zip(*(i.size for i in images))
if horizontal:
t_w = sum(w)
t_h = max(h)
else:
t_w = max(w)
t_h = sum(h)
result = Image.new('RGB', (t_w, t_h))
x_offset = 0
y_offset = 0
for im in images:
result.paste(im, (x_offset,y_offset))
if horizontal:
x_offset += im.size[0] + xmargin
else:
y_offset += im.size[1] + ymargin
return result
def main():
parser = argparse.ArgumentParser(description="This program emulates\
the pwnagotchi display")
parser.add_argument('--display', help="Which display to use.",
parser.add_argument('--displays', help="Which displays to use.", nargs="+",
default="waveshare_2")
parser.add_argument('--port', help="Which port to use",
default=8080)
parser.add_argument('--sleep', type=int, help="Time between emotions",
default=2)
parser.add_argument('--lang', help="Language to use",
default="en")
parser.add_argument('--output', help="Path to output image (PNG)", default="preview.png")
parser.add_argument('--xmargin', type=int, default=5)
parser.add_argument('--ymargin', type=int, default=5)
args = parser.parse_args()
CONFIG = yaml.load('''
config_template = '''
main:
lang: {lang}
ui:
@ -107,65 +91,81 @@ def main():
video:
enabled: true
address: "0.0.0.0"
port: {port}
'''.format(display=args.display,
port=args.port,
lang=args.lang))
port: 8080
'''
DISPLAY = CustomDisplay(config=CONFIG, state={'name': '%s>' % 'preview'})
list_of_displays = list()
for display_type in args.displays:
config = yaml.safe_load(config_template.format(display=display_type,
lang=args.lang))
display = CustomDisplay(config=config, state={'name': f"{display_type}>"})
list_of_displays.append(display)
while True:
DISPLAY.on_starting()
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_ai_ready()
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_normal()
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_new_peer(DummyPeer())
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_lost_peer(DummyPeer())
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_free_channel('6')
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.wait(args.sleep)
DISPLAY.update()
DISPLAY.on_bored()
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_sad()
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_motivated(1)
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_demotivated(-1)
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_excited()
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_deauth({'mac': 'DE:AD:BE:EF:CA:FE'})
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_miss('test')
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_lonely()
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_handshakes(1)
DISPLAY.update()
time.sleep(args.sleep)
DISPLAY.on_rebooting()
DISPLAY.update()
time.sleep(args.sleep)
columns = list()
for display in list_of_displays:
emotions = list()
# Starting
display.on_starting()
display.update()
emotions.append(display.get_image())
display.on_ai_ready()
display.update()
emotions.append(display.get_image())
display.on_normal()
display.update()
emotions.append(display.get_image())
display.on_new_peer(DummyPeer())
display.update()
emotions.append(display.get_image())
display.on_lost_peer(DummyPeer())
display.update()
emotions.append(display.get_image())
display.on_free_channel('6')
display.update()
emotions.append(display.get_image())
display.wait(2)
display.update()
emotions.append(display.get_image())
display.on_bored()
display.update()
emotions.append(display.get_image())
display.on_sad()
display.update()
emotions.append(display.get_image())
display.on_motivated(1)
display.update()
emotions.append(display.get_image())
display.on_demotivated(-1)
display.update()
emotions.append(display.get_image())
display.on_excited()
display.update()
emotions.append(display.get_image())
display.on_deauth({'mac': 'DE:AD:BE:EF:CA:FE'})
display.update()
emotions.append(display.get_image())
display.on_miss('test')
display.update()
emotions.append(display.get_image())
display.on_lonely()
display.update()
emotions.append(display.get_image())
display.on_handshakes(1)
display.update()
emotions.append(display.get_image())
display.on_rebooting()
display.update()
emotions.append(display.get_image())
# append them all together (vertical)
columns.append(append_images(emotions, horizontal=False, xmargin=args.xmargin, ymargin=args.ymargin))
# append columns side by side
final_image = append_images(columns, horizontal=True, xmargin=args.xmargin, ymargin=args.ymargin)
final_image.save(args.output, 'PNG')
if __name__ == '__main__':
SystemExit(main())