Browse Source

Use trio guest mode

unifiedWindowUI
Luke Murphy 4 years ago
parent
commit
9975ff8163
No known key found for this signature in database GPG Key ID: 5E2EF5A63E3718CC
  1. 103
      dropship.py
  2. 1
      requirements.txt

103
dropship.py

@ -3,10 +3,10 @@
import logging import logging
import os import os
from signal import SIGINT, SIGTERM from signal import SIGINT, SIGTERM
from subprocess import PIPE, Popen, TimeoutExpired from subprocess import PIPE
from threading import Thread
import gi import gi
import trio
gi.require_version("Gtk", "3.0") gi.require_version("Gtk", "3.0")
gi.require_version("Gdk", "3.0") gi.require_version("Gdk", "3.0")
@ -25,13 +25,14 @@ AUTO_CLIP_COPY_SIZE = -1
class DropShip: class DropShip:
"""Drag it, drop it, ship it.""" """Drag it, drop it, ship it."""
def __init__(self): def __init__(self, nursery):
"""Object initialisation.""" """Object initialisation."""
self.GLADE_FILE = "dropship.glade" self.GLADE_FILE = "dropship.glade"
self.CSS_FILE = "dropship.css" self.CSS_FILE = "dropship.css"
self.DOWNLOAD_DIR = os.path.expanduser("~") self.DOWNLOAD_DIR = os.path.expanduser("~")
self.clipboard = gtk.Clipboard.get(gdk.SELECTION_CLIPBOARD) self.clipboard = gtk.Clipboard.get(gdk.SELECTION_CLIPBOARD)
self.nursery = nursery
self.init_glade() self.init_glade()
self.init_css() self.init_css()
@ -98,78 +99,78 @@ class DropShip:
self.files_to_send = files self.files_to_send = files
if len(files) == 1: if len(files) == 1:
fpath = files[0].replace("file://", "") fpath = files[0].replace("file://", "")
Thread(target=self.wormhole_send, args=(self, fpath,)).start() self.nursery.start_soon(self.wormhole_send, fpath)
self.update_send_ui()
else: else:
log.info("Multiple file sending coming soon ™") log.info("Multiple file sending coming soon ™")
def update_send_ui(self): def on_recv(self, entry):
"""Manage UI response after adding files.""" """Handler for receiving transfers."""
self.drop_label.set_visible(False) self.nursery.start_soon(self.wormhole_recv, entry.get_text())
self.drop_label.set_vexpand(False)
self.drop_spinner.set_vexpand(True)
self.drop_spinner.set_visible(True)
self.drop_spinner.start()
def add_files(self, widget, event): def add_files(self, widget, event):
"""Handler for adding files with system interface""" """Handler for adding files with system interface"""
response = self.file_chooser.run() response = self.file_chooser.run()
if response == gtk.ResponseType.OK: if response == gtk.ResponseType.OK:
fpath = self.file_chooser.get_filenames()[0] fpath = self.file_chooser.get_filenames()[0]
Thread(target=self.wormhole_send, args=(self, fpath,)).start() self.nursery.start_soon(self.wormhole_send, fpath)
self.update_send_ui()
self.file_chooser.hide() self.file_chooser.hide()
def read_wormhole_send_code(self, process): async def wormhole_send(self, fpath):
"""Read wormhole send code from command-line output.""" """Run `wormhole send` on a local file path."""
command = ["wormhole", "send", fpath]
process = await trio.open_process(command, stderr=PIPE)
while True: self.drop_label.set_visible(False)
output = ( self.drop_label.set_vexpand(False)
process.stderr.readline()
) # (rra) Why is it printing to stderr tho?
if output == "" and process.poll() is not None:
print(output)
return # (rra) We need some exception handling here
if output:
log.info(output)
if output.startswith(b"Wormhole code is: "):
code_line = output.decode("utf-8")
return code_line.split()[-1]
def on_recv(self, entry): self.drop_spinner.set_vexpand(True)
"""Handler for receiving transfers.""" self.drop_spinner.set_visible(True)
code = entry.get_text() self.drop_spinner.start()
Thread(target=self.wormhole_recv, args=(self, code,)).start()
def wormhole_send(self, widget, fpath): output = await process.stderr.receive_some()
"""Run `wormhole send` on a local file path.""" code = output.decode().split()[-1]
command = ["wormhole", "send", fpath]
process = Popen(command, stderr=PIPE, stdout=PIPE)
code = self.read_wormhole_send_code(process)
# UI response self.drop_label.set_text(code)
self.drop_label.set_visible(True) self.drop_label.set_visible(True)
self.drop_label.set_selectable(True) self.drop_label.set_selectable(True)
self.drop_label.set_text(code)
self.drop_label.set_vexpand(True)
self.drop_spinner.stop() self.drop_spinner.stop()
self.drop_spinner.set_vexpand(False) self.drop_spinner.set_vexpand(False)
self.drop_spinner.set_visible(False) self.drop_spinner.set_visible(False)
self.clipboard.set_text(code, AUTO_CLIP_COPY_SIZE) await process.wait()
def wormhole_recv(self, widget, code): async def wormhole_recv(self, code):
"""Run `wormhole receive` with a pending transfer code.""" """Run `wormhole receive` with a pending transfer code."""
command = ["wormhole", "receive", "--accept-file", code] command = ["wormhole", "receive", "--accept-file", code]
process = Popen(command, stderr=PIPE) await trio.run_process(command, stderr=PIPE)
process.communicate()
if __name__ == "__main__": def trio_run_with_gtk():
DropShip() """Run Trio and Gtk together."""
async def trio_main():
"""Trio main loop."""
async with trio.open_nursery() as nursery:
DropShip(nursery=nursery)
while True:
await trio.sleep(1) # Note(decentral1se): replace this hack
def done_callback(outcome):
glib.idle_add(gtk.main_quit)
def glib_schedule(function):
glib.idle_add(function)
trio.lowlevel.start_guest_run(
trio_main,
run_sync_soon_threadsafe=glib_schedule,
done_callback=done_callback,
host_uses_signal_set_wakeup_fd=True,
)
gtk.main() gtk.main()
if __name__ == "__main__":
trio_run_with_gtk()

1
requirements.txt

@ -1,3 +1,4 @@
PyGObject==3.36.1 PyGObject==3.36.1
PyInstaller==3.6 PyInstaller==3.6
magic-wormhole==0.12.0 magic-wormhole==0.12.0
trio==0.16.0

Loading…
Cancel
Save