Use trio guest mode
This commit is contained in:
parent
0e8f211807
commit
9975ff8163
105
dropship.py
105
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."""
|
|
||||||
|
|
||||||
while True:
|
|
||||||
output = (
|
|
||||||
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):
|
|
||||||
"""Handler for receiving transfers."""
|
|
||||||
code = entry.get_text()
|
|
||||||
Thread(target=self.wormhole_recv, args=(self, code,)).start()
|
|
||||||
|
|
||||||
def wormhole_send(self, widget, fpath):
|
|
||||||
"""Run `wormhole send` on a local file path."""
|
"""Run `wormhole send` on a local file path."""
|
||||||
command = ["wormhole", "send", fpath]
|
command = ["wormhole", "send", fpath]
|
||||||
process = Popen(command, stderr=PIPE, stdout=PIPE)
|
process = await trio.open_process(command, stderr=PIPE)
|
||||||
code = self.read_wormhole_send_code(process)
|
|
||||||
|
|
||||||
# UI response
|
self.drop_label.set_visible(False)
|
||||||
|
self.drop_label.set_vexpand(False)
|
||||||
|
|
||||||
|
self.drop_spinner.set_vexpand(True)
|
||||||
|
self.drop_spinner.set_visible(True)
|
||||||
|
self.drop_spinner.start()
|
||||||
|
|
||||||
|
output = await process.stderr.receive_some()
|
||||||
|
code = output.decode().split()[-1]
|
||||||
|
|
||||||
|
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()
|
|
||||||
|
|
||||||
|
def trio_run_with_gtk():
|
||||||
|
"""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()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
DropShip()
|
trio_run_with_gtk()
|
||||||
gtk.main()
|
|
||||||
|
@ -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…
Reference in New Issue
Block a user