def __init__(self, blueman): blueman.List.connect("adapter-changed", self.on_adapter_changed) if blueman.List.Adapter: self.hci = adapter_path_to_name(blueman.List.Adapter.get_object_path()) else: self.hci = None self.time = None self.up_speed = SpeedCalc() self.down_speed = SpeedCalc() self.im_upload = Gtk.Image(icon_name="blueman-up-inactive", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Data activity indication")) self.im_download = Gtk.Image(icon_name="blueman-down-inactive", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Data activity indication")) self.down_rate = Gtk.Label(halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data received and rate of transmission")) self.down_rate.show() self.up_rate = Gtk.Label(halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data sent and rate of transmission")) self.up_rate.show() self.uparrow = Gtk.Image(icon_name="go-up", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data sent and rate of transmission")) self.downarrow = Gtk.Image(icon_name="go-down", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data received and rate of transmission")) self.hbox = hbox = blueman.Builder.get_object("status_activity") hbox.pack_start(self.uparrow, False, False, 0) hbox.pack_start(self.up_rate, False, False, 0) hbox.pack_start(self.downarrow, False, False, 0) hbox.pack_start(self.down_rate, False, False, 0) hbox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.VERTICAL), False, False, 0) hbox.pack_start(self.im_upload, False, False, 0) hbox.pack_start(self.im_download, False, False, 0) hbox.show_all() self.on_adapter_changed(blueman.List, blueman.List.GetAdapterPath()) self.up_blinker = Animation(self.im_upload, ["blueman-up-inactive","blueman-up-active"]) self.down_blinker = Animation(self.im_download, ["blueman-down-inactive", "blueman-down-active"]) self.start_update()
def __init__(self, blueman): blueman.List.connect("adapter-changed", self.on_adapter_changed) self.hci = adapter_path_to_name(blueman.List.Adapter.get_object_path()) self.time = None self.up_speed = SpeedCalc() self.down_speed = SpeedCalc() self.im_upload = Gtk.Image(icon_name="blueman-up-inactive", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Data activity indication")) self.im_download = Gtk.Image(icon_name="blueman-down-inactive", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Data activity indication")) self.down_rate = Gtk.Label(halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data received and rate of transmission")) self.down_rate.show() self.up_rate = Gtk.Label(halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data sent and rate of transmission")) self.up_rate.show() self.uparrow = Gtk.Image(icon_name="go-up", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data sent and rate of transmission")) self.downarrow = Gtk.Image(icon_name="go-down", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data received and rate of transmission")) self.hbox = hbox = blueman.Builder.get_object("status_activity") hbox.pack_start(self.uparrow, False, False, 0) hbox.pack_start(self.up_rate, False, False, 0) hbox.pack_start(self.downarrow, False, False, 0) hbox.pack_start(self.down_rate, False, False, 0) hbox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.VERTICAL), False, False, 0) hbox.pack_start(self.im_upload, False, False, 0) hbox.pack_start(self.im_download, False, False, 0) hbox.show_all() self.on_adapter_changed(blueman.List, blueman.List.get_adapter_path()) self.up_blinker = Animation(self.im_upload, ["blueman-up-inactive", "blueman-up-active"]) self.down_blinker = Animation(self.im_download, ["blueman-down-inactive", "blueman-down-active"]) self.start_update()
class ManagerStats: def __init__(self, blueman): blueman.List.connect("adapter-changed", self.on_adapter_changed) if blueman.List.Adapter: self.hci = adapter_path_to_name(blueman.List.Adapter.get_object_path()) else: self.hci = None self.time = None self.up_speed = SpeedCalc() self.down_speed = SpeedCalc() self.im_upload = Gtk.Image(icon_name="blueman-up-inactive", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Data activity indication")) self.im_download = Gtk.Image(icon_name="blueman-down-inactive", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Data activity indication")) self.down_rate = Gtk.Label(halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data received and rate of transmission")) self.down_rate.show() self.up_rate = Gtk.Label(halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data sent and rate of transmission")) self.up_rate.show() self.uparrow = Gtk.Image(icon_name="go-up", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data sent and rate of transmission")) self.downarrow = Gtk.Image(icon_name="go-down", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data received and rate of transmission")) self.hbox = hbox = blueman.Builder.get_object("status_activity") hbox.pack_start(self.uparrow, False, False, 0) hbox.pack_start(self.up_rate, False, False, 0) hbox.pack_start(self.downarrow, False, False, 0) hbox.pack_start(self.down_rate, False, False, 0) hbox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.VERTICAL), False, False, 0) hbox.pack_start(self.im_upload, False, False, 0) hbox.pack_start(self.im_download, False, False, 0) hbox.show_all() self.on_adapter_changed(blueman.List, blueman.List.GetAdapterPath()) self.up_blinker = Animation(self.im_upload, ["blueman-up-inactive","blueman-up-active"]) self.down_blinker = Animation(self.im_download, ["blueman-down-inactive", "blueman-down-active"]) self.start_update() def on_adapter_changed(self, List, adapter_path): if adapter_path is not None: self.hci = adapter_path_to_name(adapter_path) self.hbox.props.sensitive = True else: self.hci = None self.hbox.props.sensitive = False self.up_speed.reset() self.down_speed.reset() def set_blinker_by_speed(self, blinker, speed): if speed > 0 and not blinker.status(): blinker.start() if speed > 40 * 1024 and blinker.status(): blinker.set_rate(10) elif speed > (30 * 1024) and blinker.status(): blinker.set_rate(8) elif speed > (20 * 1024) and blinker.status(): blinker.set_rate(6) elif speed > (10 * 1024) and blinker.status(): blinker.set_rate(4) elif speed > 1024 and blinker.status(): blinker.set_rate(2) elif speed == 0 and blinker.status(): blinker.stop() else: blinker.set_rate(1) def _update(self): if self.hci is not None: devinfo = device_info(self.hci) _tx = devinfo["stat"]["byte_tx"] _rx = devinfo["stat"]["byte_rx"] tx, s_tx = format_bytes(_tx) rx, s_rx = format_bytes(_rx) _u_speed = self.up_speed.calc(_tx) _d_speed = self.down_speed.calc(_rx) self.set_blinker_by_speed(self.up_blinker, _u_speed) self.set_blinker_by_speed(self.down_blinker, _d_speed) u_speed, s_u_speed = format_bytes(_u_speed) d_speed, s_d_speed = format_bytes(_d_speed) self.set_data(tx, s_tx, rx, s_rx, u_speed, s_u_speed, d_speed, s_d_speed) return 1 def start_update(self): self._update() self.timer = GLib.timeout_add(1000, self._update) def stop_update(self): if self.timer: GLib.source_remove(self.timer) def set_data(self, uploaded, u_name, downloaded, d_name, u_speed, us_name, d_speed, ds_name): self.down_rate.set_markup( '<span size="small">%.2f %s <i>%5.2f %s/s</i></span>' % (downloaded, d_name, d_speed, ds_name)) self.up_rate.set_markup( '<span size="small">%.2f %s <i>%5.2f %s/s</i></span>' % (uploaded, u_name, u_speed, us_name))
def __init__(self, device, adapter_path, files): super().__init__( title=_("Bluetooth File Transfer"), name="BluemanSendTo", icon_name="blueman", border_width=5, default_width=400, window_position=Gtk.WindowPosition.CENTER, type_hint=Gdk.WindowTypeHint.DIALOG ) self.b_cancel = self.add_button("_Stop", Gtk.ResponseType.CLOSE) self.b_cancel.props.receives_default = True self.b_cancel.props.use_underline = True self.b_cancel.connect("clicked", self.on_cancel) self.Builder = Gtk.Builder(translation_domain="blueman") bind_textdomain_codeset("blueman", "UTF-8") self.Builder.add_from_file(UI_PATH + "/send-dialog.ui") grid = self.Builder.get_object("sendto") content_area = self.get_content_area() content_area.add(grid) self.l_dest = self.Builder.get_object("l_dest") self.l_file = self.Builder.get_object("l_file") self.pb = self.Builder.get_object("pb") self.pb.props.text = _("Connecting") self.device = device self.adapter = Adapter(adapter_path) self.manager = Manager() self.files: List[Gio.File] = [] self.num_files = 0 self.object_push = None self.transfer = None self.total_bytes = 0 self.total_transferred = 0 self._last_bytes = 0 self._last_update = 0.0 self.error_dialog = None self.cancelling = False # bytes transferred on a current transfer self.transferred = 0 self.speed = SpeedCalc(6) for file_name in files: parsed_file = Gio.File.parse_name(file_name) if not parsed_file.query_exists(): logging.info("Skipping non existing file %s" % parsed_file.get_path()) continue file_info = parsed_file.query_info("standard::*", Gio.FileQueryInfoFlags.NONE) if file_info.get_file_type() == Gio.FileType.DIRECTORY: logging.info("Skipping directory %s" % parsed_file.get_path()) continue self.files.append(parsed_file) self.num_files += 1 self.total_bytes += file_info.get_size() if len(self.files) == 0: self.emit("result", False) try: self.client = Client() self.manager.connect_signal('session-added', self.on_session_added) self.manager.connect_signal('session-removed', self.on_session_removed) except GLib.Error as e: if 'StartServiceByName' in e.message: logging.debug(e.message) d = ErrorDialog(_("obexd not available"), _("Failed to autostart obex service. Make sure the obex " "daemon is running"), parent=self.get_toplevel()) d.run() d.destroy() self.emit("result", False) else: # Fail on anything else raise self.l_file.props.label = self.files[-1].get_basename() self.client.connect('session-failed', self.on_session_failed) logging.info("Sending to %s" % device['Address']) self.l_dest.props.label = device['Alias'] # Stop discovery if discovering and let adapter settle for a second if self.adapter["Discovering"]: self.adapter.stop_discovery() time.sleep(1) self.create_session() self.show()
class Sender(Gtk.Dialog): __gsignals__: GSignals = { 'result': (GObject.SignalFlags.RUN_FIRST, None, (GObject.TYPE_BOOLEAN,)), } def __init__(self, device, adapter_path, files): super().__init__( title=_("Bluetooth File Transfer"), name="BluemanSendTo", icon_name="blueman", border_width=5, default_width=400, window_position=Gtk.WindowPosition.CENTER, type_hint=Gdk.WindowTypeHint.DIALOG ) self.b_cancel = self.add_button("_Stop", Gtk.ResponseType.CLOSE) self.b_cancel.props.receives_default = True self.b_cancel.props.use_underline = True self.b_cancel.connect("clicked", self.on_cancel) self.Builder = Gtk.Builder(translation_domain="blueman") bind_textdomain_codeset("blueman", "UTF-8") self.Builder.add_from_file(UI_PATH + "/send-dialog.ui") grid = self.Builder.get_object("sendto") content_area = self.get_content_area() content_area.add(grid) self.l_dest = self.Builder.get_object("l_dest") self.l_file = self.Builder.get_object("l_file") self.pb = self.Builder.get_object("pb") self.pb.props.text = _("Connecting") self.device = device self.adapter = Adapter(adapter_path) self.manager = Manager() self.files: List[Gio.File] = [] self.num_files = 0 self.object_push = None self.transfer = None self.total_bytes = 0 self.total_transferred = 0 self._last_bytes = 0 self._last_update = 0.0 self.error_dialog = None self.cancelling = False # bytes transferred on a current transfer self.transferred = 0 self.speed = SpeedCalc(6) for file_name in files: parsed_file = Gio.File.parse_name(file_name) if not parsed_file.query_exists(): logging.info("Skipping non existing file %s" % parsed_file.get_path()) continue file_info = parsed_file.query_info("standard::*", Gio.FileQueryInfoFlags.NONE) if file_info.get_file_type() == Gio.FileType.DIRECTORY: logging.info("Skipping directory %s" % parsed_file.get_path()) continue self.files.append(parsed_file) self.num_files += 1 self.total_bytes += file_info.get_size() if len(self.files) == 0: self.emit("result", False) try: self.client = Client() self.manager.connect_signal('session-added', self.on_session_added) self.manager.connect_signal('session-removed', self.on_session_removed) except GLib.Error as e: if 'StartServiceByName' in e.message: logging.debug(e.message) d = ErrorDialog(_("obexd not available"), _("Failed to autostart obex service. Make sure the obex " "daemon is running"), parent=self.get_toplevel()) d.run() d.destroy() self.emit("result", False) else: # Fail on anything else raise self.l_file.props.label = self.files[-1].get_basename() self.client.connect('session-failed', self.on_session_failed) logging.info("Sending to %s" % device['Address']) self.l_dest.props.label = device['Alias'] # Stop discovery if discovering and let adapter settle for a second if self.adapter["Discovering"]: self.adapter.stop_discovery() time.sleep(1) self.create_session() self.show() def create_session(self): self.client.create_session(self.device['Address'], self.adapter["Address"]) def on_cancel(self, button): self.pb.props.text = _("Cancelling") if button: button.props.sensitive = False if self.object_push: self.client.remove_session(self.object_push.get_session_path()) self.emit("result", False) def on_transfer_started(self, _object_push, transfer_path, filename): if self.total_transferred == 0: self.pb.props.text = _("Sending File") + (" %(0)s/%(1)s (%(2).2f %(3)s/s) " + _("ETA:") + " %(4)s") % { "1": self.num_files, "0": (self.num_files - len(self.files) + 1), "2": 0.0, "3": "B/s", "4": "∞"} self.l_file.props.label = filename self._last_bytes = 0 self.transferred = 0 self.transfer = Transfer(transfer_path) self.transfer.connect("error", self.on_transfer_error) self.transfer.connect("progress", self.on_transfer_progress) self.transfer.connect("completed", self.on_transfer_completed) def on_transfer_failed(self, _object_push, error): self.on_transfer_error(None, str(error)) def on_transfer_progress(self, _transfer, progress): self.transferred = progress if self._last_bytes == 0: self.total_transferred += progress else: self.total_transferred += (progress - self._last_bytes) self._last_bytes = progress tm = time.time() if tm - self._last_update > 0.5: spd = self.speed.calc(self.total_transferred) (size, units) = format_bytes(spd) try: x = ((self.total_bytes - self.total_transferred) / spd) + 1 if x > 60: x /= 60 eta = ngettext("%.0f Minute", "%.0f Minutes", round(x)) % x else: eta = ngettext("%.0f Second", "%.0f Seconds", round(x)) % x except ZeroDivisionError: eta = "∞" self.pb.props.text = _("Sending File") + (" %(0)s/%(1)s (%(2).2f %(3)s/s) " + _("ETA:") + " %(4)s") % { "1": self.num_files, "0": (self.num_files - len(self.files) + 1), "2": size, "3": units, "4": eta} self._last_update = tm self.pb.props.fraction = float(self.total_transferred) / self.total_bytes def on_transfer_completed(self, _transfer): del self.files[-1] self.transfer = None self.process_queue() def process_queue(self): if len(self.files) > 0: self.send_file(self.files[-1].get_path()) else: self.emit("result", True) def send_file(self, file_path): logging.info(file_path) if self.object_push: self.object_push.send_file(file_path) def on_transfer_error(self, _transfer, msg=""): if not self.error_dialog: self.speed.reset() d = ErrorDialog(msg, _("Error occurred while sending file %s") % self.files[-1].get_basename(), modal=True, icon_name="blueman", parent=self.get_toplevel(), buttons=[]) if len(self.files) > 1: d.add_button(_("Skip"), Gtk.ResponseType.NO) d.add_button(_("Retry"), Gtk.ResponseType.YES) d.add_button("_Cancel", Gtk.ResponseType.CANCEL) if self.object_push: self.client.remove_session(self.object_push.get_object_path()) def on_response(dialog, resp): dialog.destroy() self.error_dialog = None if resp == Gtk.ResponseType.CANCEL: self.on_cancel(None) elif resp == Gtk.ResponseType.NO: finfo = self.files[-1].query_info('standard::*', Gio.FileQueryInfoFlags.NONE) self.total_bytes -= finfo.get_size() self.total_transferred -= self.transferred self.transferred = 0 del self.files[-1] if not self.object_push: self.create_session() self.process_queue() elif resp == Gtk.ResponseType.YES: self.total_transferred -= self.transferred self.transferred = 0 if not self.object_push: self.create_session() self.process_queue() else: self.on_cancel(None) d.connect("response", on_response) d.show() self.error_dialog = d def on_session_added(self, _manager, session_path): self.object_push = ObjectPush(session_path) self.object_push.connect("transfer-started", self.on_transfer_started) self.object_push.connect("transfer-failed", self.on_transfer_failed) self.process_queue() def on_session_removed(self, _manager, session_path): logging.debug('Session removed: %s' % session_path) if self.object_push: self.object_push.disconnect_by_func(self.on_transfer_started) self.object_push.disconnect_by_func(self.on_transfer_failed) self.object_push = None def on_session_failed(self, _client, msg): d = ErrorDialog(_("Error occurred"), msg.reason.split(None, 1)[1], icon_name="blueman", parent=self.get_toplevel()) d.run() d.destroy() self.emit("result", False)
def __init__(self, blueman): blueman.List.connect("adapter-changed", self.on_adapter_changed) if blueman.List.Adapter: self.hci = adapter_path_to_name( blueman.List.Adapter.GetObjectPath()) else: self.hci = None self.time = None self.up_speed = SpeedCalc() self.down_speed = SpeedCalc() up = get_icon("blueman-up-inactive", 15) down = get_icon("blueman-down-inactive", 15) self.im_upload = gtk.Image() self.im_upload.set_tooltip_text(_("Data activity indication")) self.im_upload.set_from_pixbuf(up) self.im_download = gtk.Image() self.im_download.set_tooltip_text(_("Data activity indication")) self.im_download.set_from_pixbuf(down) self.im_upload.set_alignment(1, 0.5) self.im_download.set_alignment(1, 0.5) self.down_rate = gtk.Label() self.down_rate.show() self.down_rate.set_alignment(1, 0.5) self.down_rate.set_tooltip_text( _("Total data received and rate of transmission")) self.up_rate = gtk.Label() self.up_rate.show() self.up_rate.set_alignment(1, 0.5) self.up_rate.set_tooltip_text( _("Total data sent and rate of transmission")) self.uparrow = gtk.Image() self.uparrow.set_tooltip_text( _("Total data sent and rate of transmission")) self.uparrow.set_from_stock(gtk.STOCK_GO_UP, 1) self.uparrow.set_alignment(1, 0.5) self.downarrow = gtk.Image() self.downarrow.set_tooltip_text( _("Total data received and rate of transmission")) self.downarrow.set_from_stock(gtk.STOCK_GO_DOWN, 1) self.hbox = hbox = blueman.Builder.get_object("statusbar2") hbox.pack_start(self.uparrow, True, False) hbox.pack_start(self.up_rate, False, False) hbox.pack_start(self.downarrow, False, False) hbox.pack_start(self.down_rate, False, False) hbox.pack_start(gtk.VSeparator(), False, False) hbox.pack_start(self.im_upload, False, False) hbox.pack_start(self.im_download, False, False) hbox.show_all() self.on_adapter_changed(blueman.List, blueman.List.GetAdapterPath()) self.up_blinker = Animation(self.im_upload, [ get_icon("blueman-up-inactive", 15), get_icon("blueman-up-active", 15) ]) #self.down_blinker = Animation(self.im_download, ["/down_inactive.png", "/down_active.png"]) self.down_blinker = Animation(self.im_download, [ get_icon("blueman-down-inactive", 16), get_icon("blueman-down-active", 16) ]) self.start_update()
def __init__(self, device, adapter_path, files): super(Sender, self).__init__(title=_("Bluetooth File Transfer")) self.set_name("BluemanSendTo") self.set_position(Gtk.WindowPosition.CENTER) self.set_type_hint(Gdk.WindowTypeHint.DIALOG) self.props.border_width = 5 self.props.icon_name = "blueman" self.props.width_request = 400 self.b_cancel = self.add_button("_Stop", Gtk.ResponseType.CLOSE) self.b_cancel.props.receives_default = True self.b_cancel.props.use_underline = True self.b_cancel.connect("clicked", self.on_cancel) self.Builder = Gtk.Builder() self.Builder.set_translation_domain("blueman") bind_textdomain_codeset("blueman", "UTF-8") self.Builder.add_from_file(UI_PATH + "/send-dialog.ui") grid = self.Builder.get_object("sendto") content_area = self.get_content_area() content_area.add(grid) self.l_dest = self.Builder.get_object("l_dest") self.l_file = self.Builder.get_object("l_file") self.pb = self.Builder.get_object("pb") self.pb.props.text = _("Connecting") self.device = device self.adapter = Adapter(adapter_path) self.files = files self.object_push = None self.transfer = None self.total_bytes = 0 self.total_transferred = 0 self._last_bytes = 0 self._last_update = 0 self.error_dialog = None self.cancelling = False #bytes transferred on a current transfer self.transferred = 0 self.speed = SpeedCalc(6) for i in range(len(self.files) - 1, -1, -1): f = self.files[i] match = re.match("file://(.*)", f) if match: f = self.files[i] = urllib.parse.unquote(match.groups(1)[0]) if os.path.exists(f) and not os.path.isdir(f): f = os.path.abspath(f) self.total_bytes += os.path.getsize(f) else: self.files.remove(f) self.num_files = len(self.files) try: self.client = obex.Client() except obex.ObexdNotFoundError: d = ErrorDialog(_("obexd not available"), _("obexd is probably not installed")) d.run() d.destroy() exit(1) if self.num_files == 0: exit(1) self.l_file.props.label = os.path.basename(self.files[-1]) self.client.connect('session-created', self.on_session_created) self.client.connect('session-failed', self.on_session_failed) self.client.connect('session-removed', self.on_session_removed) logging.info("Sending to %s" % device['Address']) self.l_dest.props.label = device['Alias'] # Stop discovery if discovering and let adapter settle for a second if self.adapter["Discovering"]: self.adapter.stop_discovery() time.sleep(1) self.create_session() self.show()
def __init__(self, blueman): blueman.List.connect("adapter-changed", self.on_adapter_changed) if blueman.List.Adapter: self.hci = adapter_path_to_name(blueman.List.Adapter.get_object_path()) else: self.hci = None self.time = None self.up_speed = SpeedCalc() self.down_speed = SpeedCalc() up = get_icon("blueman-up-inactive", 15) down = get_icon("blueman-down-inactive", 15) self.im_upload = Gtk.Image() self.im_upload.set_tooltip_text(_("Data activity indication")) self.im_upload.set_from_pixbuf(up) self.im_download = Gtk.Image() self.im_download.set_tooltip_text(_("Data activity indication")) self.im_download.set_from_pixbuf(down) self.im_upload.set_alignment(1, 0.5) self.im_download.set_alignment(1, 0.5) self.down_rate = Gtk.Label() self.down_rate.show() self.down_rate.set_alignment(1, 0.5) self.down_rate.set_tooltip_text(_("Total data received and rate of transmission")) self.up_rate = Gtk.Label() self.up_rate.show() self.up_rate.set_alignment(1, 0.5) self.up_rate.set_tooltip_text(_("Total data sent and rate of transmission")) self.uparrow = Gtk.Image() self.uparrow.set_tooltip_text(_("Total data sent and rate of transmission")) self.uparrow.set_from_icon_name("go-up", 1) self.uparrow.set_alignment(1, 0.5) self.downarrow = Gtk.Image() self.downarrow.set_tooltip_text(_("Total data received and rate of transmission")) self.downarrow.set_from_icon_name("go-down", 1) self.hbox = hbox = blueman.Builder.get_object("statusbar2") hbox.pack_start(self.uparrow, True, False, 0) hbox.pack_start(self.up_rate, False, False, 0) hbox.pack_start(self.downarrow, False, False, 0) hbox.pack_start(self.down_rate, False, False, 0) hbox.pack_start(Gtk.VSeparator(), False, False, 0) hbox.pack_start(self.im_upload, False, False, 0) hbox.pack_start(self.im_download, False, False, 0) hbox.show_all() self.on_adapter_changed(blueman.List, blueman.List.GetAdapterPath()) self.up_blinker = Animation(self.im_upload, [get_icon("blueman-up-inactive", 15), get_icon("blueman-up-active", 15)]) #self.down_blinker = Animation(self.im_download, ["/down_inactive.png", "/down_active.png"]) self.down_blinker = Animation(self.im_download, [get_icon("blueman-down-inactive", 16), get_icon("blueman-down-active", 16)]) self.start_update()
class Sender(Gtk.Dialog): __gsignals__ = { 'result': (GObject.SignalFlags.RUN_FIRST, None, (GObject.TYPE_BOOLEAN,)), } def __init__(self, device, adapter_path, files): super().__init__( title=_("Bluetooth File Transfer"), name="BluemanSendTo", icon_name="blueman", border_width=5, default_width=400, window_position=Gtk.WindowPosition.CENTER, type_hint=Gdk.WindowTypeHint.DIALOG ) self.b_cancel = self.add_button("_Stop", Gtk.ResponseType.CLOSE) self.b_cancel.props.receives_default = True self.b_cancel.props.use_underline = True self.b_cancel.connect("clicked", self.on_cancel) self.Builder = Gtk.Builder(translation_domain="blueman") bind_textdomain_codeset("blueman", "UTF-8") self.Builder.add_from_file(UI_PATH + "/send-dialog.ui") grid = self.Builder.get_object("sendto") content_area = self.get_content_area() content_area.add(grid) self.l_dest = self.Builder.get_object("l_dest") self.l_file = self.Builder.get_object("l_file") self.pb = self.Builder.get_object("pb") self.pb.props.text = _("Connecting") self.device = device self.adapter = Adapter(adapter_path) self.files = [] self.num_files = 0 self.object_push = None self.transfer = None self.total_bytes = 0 self.total_transferred = 0 self._last_bytes = 0 self._last_update = 0 self.error_dialog = None self.cancelling = False # bytes transferred on a current transfer self.transferred = 0 self.speed = SpeedCalc(6) for file_name in files: parsed_file = Gio.File.parse_name(file_name) if not parsed_file.query_exists(): logging.info("Skipping non existing file %s" % parsed_file.get_path()) continue file_info = parsed_file.query_info("standard::*", Gio.FileQueryInfoFlags.NONE) if file_info.get_file_type() == Gio.FileType.DIRECTORY: logging.info("Skipping directory %s" % parsed_file.get_path()) continue self.files.append(parsed_file) self.num_files += 1 self.total_bytes += file_info.get_size() if len(self.files) == 0: exit(1) try: self.client = obex.Client() except GLib.Error as e: if 'StartServiceByName' in e.message: logging.debug(e.message) d = ErrorDialog(_("obexd not available"), _("Failed to autostart obex service. Make sure the obex " "daemon is running"), parent=self.get_toplevel()) d.run() d.destroy() exit(1) else: # Fail on anything else raise self.l_file.props.label = self.files[-1].get_basename() self.client.connect('session-created', self.on_session_created) self.client.connect('session-failed', self.on_session_failed) self.client.connect('session-removed', self.on_session_removed) logging.info("Sending to %s" % device['Address']) self.l_dest.props.label = device['Alias'] # Stop discovery if discovering and let adapter settle for a second if self.adapter["Discovering"]: self.adapter.stop_discovery() time.sleep(1) self.create_session() self.show() def create_session(self): self.client.create_session(self.device['Address'], self.adapter["Address"]) def on_cancel(self, button): self.pb.props.text = _("Cancelling") if button: button.props.sensitive = False if self.object_push: self.client.remove_session(self.object_push.get_session_path()) else: self.emit("result", False) def on_transfer_started(self, _object_push, transfer_path, filename): if self.total_transferred == 0: self.pb.props.text = _("Sending File") + (" %(0)s/%(1)s (%(2).2f %(3)s/s) " + _("ETA:") + " %(4)s") % { "1": self.num_files, "0": (self.num_files - len(self.files) + 1), "2": 0.0, "3": "B/s", "4": "∞"} self.l_file.props.label = filename self._last_bytes = 0 self.transferred = 0 self.transfer = obex.Transfer(transfer_path) self.transfer.connect("error", self.on_transfer_error) self.transfer.connect("progress", self.on_transfer_progress) self.transfer.connect("completed", self.on_transfer_completed) def on_transfer_failed(self, _object_push, error): self.on_transfer_error(None, str(error)) def on_transfer_progress(self, _transfer, progress): self.transferred = progress if self._last_bytes == 0: self.total_transferred += progress else: self.total_transferred += (progress - self._last_bytes) self._last_bytes = progress tm = time.time() if tm - self._last_update > 0.5: spd = self.speed.calc(self.total_transferred) (size, units) = format_bytes(spd) try: x = ((self.total_bytes - self.total_transferred) / spd) + 1 if x > 60: x /= 60 eta = ngettext("%.0f Minute", "%.0f Minutes", round(x)) % x else: eta = ngettext("%.0f Second", "%.0f Seconds", round(x)) % x except ZeroDivisionError: eta = "∞" self.pb.props.text = _("Sending File") + (" %(0)s/%(1)s (%(2).2f %(3)s/s) " + _("ETA:") + " %(4)s") % { "1": self.num_files, "0": (self.num_files - len(self.files) + 1), "2": size, "3": units, "4": eta} self._last_update = tm self.pb.props.fraction = float(self.total_transferred) / self.total_bytes def on_transfer_completed(self, _transfer): del self.files[-1] self.transfer = None self.process_queue() def process_queue(self): if len(self.files) > 0: self.send_file(self.files[-1].get_path()) else: self.emit("result", True) def send_file(self, file_path): logging.info(file_path) if self.object_push: self.object_push.send_file(file_path) def on_transfer_error(self, _transfer, msg=""): if not self.error_dialog: self.speed.reset() d = ErrorDialog(msg, _("Error occurred while sending file %s") % os.path.basename(self.files[-1]), modal=True, icon_name="blueman", parent=self.get_toplevel()) if len(self.files) > 1: d.add_button(_("Skip"), Gtk.ResponseType.NO) d.add_button(_("Retry"), Gtk.ResponseType.YES) d.add_button("_Cancel", Gtk.ResponseType.CANCEL) def on_response(dialog, resp): dialog.destroy() self.error_dialog = None if resp == "_Cancel": self.on_cancel(None) elif resp == Gtk.ResponseType.NO: self.total_bytes -= os.path.getsize(self.files[-1]) self.total_transferred -= self.transferred self.transferred = 0 del self.files[-1] if not self.object_push: self.create_session() self.process_queue() elif resp == Gtk.ResponseType.YES: self.total_transferred -= self.transferred self.transferred = 0 if not self.object_push: self.create_session() self.process_queue() else: self.on_cancel(None) d.connect("response", on_response) d.show() self.error_dialog = d def on_session_created(self, _client, session_path): self.object_push = ObjectPush(session_path) self.object_push.connect("transfer-started", self.on_transfer_started) self.object_push.connect("transfer-failed", self.on_transfer_failed) self.process_queue() def on_session_failed(self, _client, msg): d = ErrorDialog(_("Error occurred"), msg.reason.split(None, 1)[1], icon_name="blueman", parent=self.get_toplevel()) d.run() d.destroy() exit(1) def on_session_removed(self, _client): self.emit("result", False)
class ManagerStats: hbox: Gtk.Box def __init__(self, blueman: "Blueman") -> None: blueman.List.connect("adapter-changed", self.on_adapter_changed) assert blueman.List.Adapter is not None self.hci = adapter_path_to_name(blueman.List.Adapter.get_object_path()) self.time = None self.up_speed = SpeedCalc() self.down_speed = SpeedCalc() self.im_upload = Gtk.Image(icon_name="blueman-up-inactive", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Data activity indication")) self.im_download = Gtk.Image( icon_name="blueman-down-inactive", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Data activity indication")) self.down_rate = Gtk.Label( halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data received and rate of transmission")) self.down_rate.show() self.up_rate = Gtk.Label( halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data sent and rate of transmission")) self.up_rate.show() self.uparrow = Gtk.Image( icon_name="go-up-symbolic", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data sent and rate of transmission")) self.downarrow = Gtk.Image( icon_name="go-down-symbolic", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data received and rate of transmission")) self.hbox = hbox = blueman.builder.get_widget("status_activity", Gtk.Box) hbox.pack_start(self.uparrow, False, False, 0) hbox.pack_start(self.up_rate, False, False, 0) hbox.pack_start(self.downarrow, False, False, 0) hbox.pack_start(self.down_rate, False, False, 0) hbox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.VERTICAL), False, False, 0) hbox.pack_start(self.im_upload, False, False, 0) hbox.pack_start(self.im_download, False, False, 0) hbox.show_all() self.on_adapter_changed(blueman.List, blueman.List.get_adapter_path()) self.up_blinker = Animation( self.im_upload, ["blueman-up-inactive", "blueman-up-active"]) self.down_blinker = Animation( self.im_download, ["blueman-down-inactive", "blueman-down-active"]) self.start_update() def on_adapter_changed(self, _lst: ManagerDeviceList, adapter_path: Optional[str]) -> None: self.hci = adapter_path_to_name(adapter_path) if self.hci is None: self.hbox.props.sensitive = False else: self.hbox.props.sensitive = True self.up_speed.reset() self.down_speed.reset() def set_blinker_by_speed(self, blinker: Animation, speed: float) -> None: if speed > 0 and not blinker.status(): blinker.start() if speed > 40 * 1024 and blinker.status(): blinker.set_rate(10) elif speed > (30 * 1024) and blinker.status(): blinker.set_rate(8) elif speed > (20 * 1024) and blinker.status(): blinker.set_rate(6) elif speed > (10 * 1024) and blinker.status(): blinker.set_rate(4) elif speed > 1024 and blinker.status(): blinker.set_rate(2) elif speed == 0 and blinker.status(): blinker.stop() else: blinker.set_rate(1) def _update(self) -> bool: if self.hci is not None: devinfo = device_info(self.hci) _tx = devinfo["stat"]["byte_tx"] _rx = devinfo["stat"]["byte_rx"] tx, s_tx = format_bytes(_tx) rx, s_rx = format_bytes(_rx) _u_speed = self.up_speed.calc(_tx) _d_speed = self.down_speed.calc(_rx) self.set_blinker_by_speed(self.up_blinker, _u_speed) self.set_blinker_by_speed(self.down_blinker, _d_speed) u_speed, s_u_speed = format_bytes(_u_speed) d_speed, s_d_speed = format_bytes(_d_speed) self.set_data(tx, s_tx, rx, s_rx, u_speed, s_u_speed, d_speed, s_d_speed) return True def start_update(self) -> None: self._update() self.timer = GLib.timeout_add(1000, self._update) def stop_update(self) -> None: if self.timer: GLib.source_remove(self.timer) def set_data(self, uploaded: float, u_name: str, downloaded: float, d_name: str, u_speed: float, us_name: str, d_speed: float, ds_name: str) -> None: self.down_rate.set_markup( f'<span size="small">{downloaded:.2f} {d_name} <i>{d_speed:5.2f} {ds_name}/s</i></span>' ) self.up_rate.set_markup( f'<span size="small">{uploaded:.2f} {u_name} <i>{u_speed:5.2f} {us_name}/s</i></span>' )
def __init__(self, device, adapter_path, files): super(Sender, self).__init__(title=_("Bluetooth File Transfer")) self.set_name("BluemanSendTo") self.set_position(Gtk.WindowPosition.CENTER) self.set_type_hint(Gdk.WindowTypeHint.DIALOG) self.props.border_width = 5 self.props.icon_name = "blueman" self.props.width_request = 400 self.b_cancel = self.add_button("_Stop", Gtk.ResponseType.CLOSE) self.b_cancel.props.receives_default = True self.b_cancel.props.use_underline = True self.b_cancel.connect("clicked", self.on_cancel) self.Builder = Gtk.Builder() self.Builder.set_translation_domain("blueman") bind_textdomain_codeset("blueman", "UTF-8") self.Builder.add_from_file(UI_PATH + "/send-dialog.ui") grid = self.Builder.get_object("sendto") content_area = self.get_content_area() content_area.add(grid) self.l_dest = self.Builder.get_object("l_dest") self.l_file = self.Builder.get_object("l_file") self.pb = self.Builder.get_object("pb") self.pb.props.text = _("Connecting") self.device = device self.adapter = Adapter(adapter_path) self.files = files self.object_push = None self.transfer = None self.total_bytes = 0 self.total_transferred = 0 self._last_bytes = 0 self._last_update = 0 self.error_dialog = None self.cancelling = False # bytes transferred on a current transfer self.transferred = 0 self.speed = SpeedCalc(6) for i in range(len(self.files) - 1, -1, -1): f = self.files[i] match = re.match("file://(.*)", f) if match: f = self.files[i] = urllib.parse.unquote(match.groups(1)[0]) if os.path.exists(f) and not os.path.isdir(f): f = os.path.abspath(f) self.total_bytes += os.path.getsize(f) else: self.files.remove(f) self.num_files = len(self.files) try: self.client = obex.Client() except GLib.Error as e: if 'StartServiceByName' in e.message: logging.debug(e.message) d = ErrorDialog( _("obexd not available"), _("Failed to autostart obex service. Make sure the obex " "daemon is running")) d.run() d.destroy() exit(1) else: # Fail on anything else raise if self.num_files == 0: exit(1) self.l_file.props.label = os.path.basename(self.files[-1]) self.client.connect('session-created', self.on_session_created) self.client.connect('session-failed', self.on_session_failed) self.client.connect('session-removed', self.on_session_removed) logging.info("Sending to %s" % device['Address']) self.l_dest.props.label = device['Alias'] # Stop discovery if discovering and let adapter settle for a second if self.adapter["Discovering"]: self.adapter.stop_discovery() time.sleep(1) self.create_session() self.show()
class Sender(Gtk.Dialog): __gsignals__ = { 'result': (GObject.SignalFlags.RUN_FIRST, None, (GObject.TYPE_BOOLEAN, )), } def __init__(self, device, adapter_path, files): super(Sender, self).__init__(title=_("Bluetooth File Transfer")) self.set_name("BluemanSendTo") self.set_position(Gtk.WindowPosition.CENTER) self.set_type_hint(Gdk.WindowTypeHint.DIALOG) self.props.border_width = 5 self.props.icon_name = "blueman" self.props.width_request = 400 self.b_cancel = self.add_button("_Stop", Gtk.ResponseType.CLOSE) self.b_cancel.props.receives_default = True self.b_cancel.props.use_underline = True self.b_cancel.connect("clicked", self.on_cancel) self.Builder = Gtk.Builder() self.Builder.set_translation_domain("blueman") bind_textdomain_codeset("blueman", "UTF-8") self.Builder.add_from_file(UI_PATH + "/send-dialog.ui") grid = self.Builder.get_object("sendto") content_area = self.get_content_area() content_area.add(grid) self.l_dest = self.Builder.get_object("l_dest") self.l_file = self.Builder.get_object("l_file") self.pb = self.Builder.get_object("pb") self.pb.props.text = _("Connecting") self.device = device self.adapter = Adapter(adapter_path) self.files = files self.object_push = None self.transfer = None self.total_bytes = 0 self.total_transferred = 0 self._last_bytes = 0 self._last_update = 0 self.error_dialog = None self.cancelling = False # bytes transferred on a current transfer self.transferred = 0 self.speed = SpeedCalc(6) for i in range(len(self.files) - 1, -1, -1): f = self.files[i] match = re.match("file://(.*)", f) if match: f = self.files[i] = urllib.parse.unquote(match.groups(1)[0]) if os.path.exists(f) and not os.path.isdir(f): f = os.path.abspath(f) self.total_bytes += os.path.getsize(f) else: self.files.remove(f) self.num_files = len(self.files) try: self.client = obex.Client() except GLib.Error as e: if 'StartServiceByName' in e.message: logging.debug(e.message) d = ErrorDialog( _("obexd not available"), _("Failed to autostart obex service. Make sure the obex " "daemon is running")) d.run() d.destroy() exit(1) else: # Fail on anything else raise if self.num_files == 0: exit(1) self.l_file.props.label = os.path.basename(self.files[-1]) self.client.connect('session-created', self.on_session_created) self.client.connect('session-failed', self.on_session_failed) self.client.connect('session-removed', self.on_session_removed) logging.info("Sending to %s" % device['Address']) self.l_dest.props.label = device['Alias'] # Stop discovery if discovering and let adapter settle for a second if self.adapter["Discovering"]: self.adapter.stop_discovery() time.sleep(1) self.create_session() self.show() def create_session(self): self.client.create_session(self.device['Address'], self.adapter["Address"]) def on_cancel(self, button): self.pb.props.text = _("Cancelling") if button: button.props.sensitive = False if self.object_push: self.client.remove_session(self.object_push.get_session_path()) else: self.emit("result", False) def on_transfer_started(self, _object_push, transfer_path, filename): if self.total_transferred == 0: self.pb.props.text = _("Sending File") + ( " %(0)s/%(1)s (%(2).2f %(3)s/s) " + _("ETA:") + " %(4)s") % { "1": self.num_files, "0": (self.num_files - len(self.files) + 1), "2": 0.0, "3": "B/s", "4": "∞" } self.l_file.props.label = filename self._last_bytes = 0 self.transferred = 0 self.transfer = obex.Transfer(transfer_path) self.transfer.connect("error", self.on_transfer_error) self.transfer.connect("progress", self.on_transfer_progress) self.transfer.connect("completed", self.on_transfer_completed) def on_transfer_failed(self, _object_push, error): self.on_transfer_error(None, str(error)) def on_transfer_progress(self, _transfer, progress): self.transferred = progress if self._last_bytes == 0: self.total_transferred += progress else: self.total_transferred += (progress - self._last_bytes) self._last_bytes = progress tm = time.time() if tm - self._last_update > 0.5: spd = self.speed.calc(self.total_transferred) (size, units) = format_bytes(spd) try: x = ((self.total_bytes - self.total_transferred) / spd) + 1 if x > 60: x /= 60 eta = ngettext("%.0f Minute", "%.0f Minutes", round(x)) % x else: eta = ngettext("%.0f Second", "%.0f Seconds", round(x)) % x except ZeroDivisionError: eta = "∞" self.pb.props.text = _("Sending File") + ( " %(0)s/%(1)s (%(2).2f %(3)s/s) " + _("ETA:") + " %(4)s") % { "1": self.num_files, "0": (self.num_files - len(self.files) + 1), "2": size, "3": units, "4": eta } self._last_update = tm self.pb.props.fraction = float( self.total_transferred) / self.total_bytes def on_transfer_completed(self, _transfer): del self.files[-1] self.transfer = None self.process_queue() def process_queue(self): if len(self.files) > 0: self.send_file(self.files[-1]) else: self.emit("result", True) def send_file(self, file_path): logging.info(file_path) if self.object_push: self.object_push.send_file(file_path) def on_transfer_error(self, _transfer, msg=""): if not self.error_dialog: self.speed.reset() d = ErrorDialog(msg, _("Error occurred while sending file %s") % os.path.basename(self.files[-1]), modal=True, icon_name="blueman") if len(self.files) > 1: d.add_button(_("Skip"), Gtk.ResponseType.NO) d.add_button(_("Retry"), Gtk.ResponseType.YES) d.add_button("_Cancel", Gtk.ResponseType.CANCEL) def on_response(dialog, resp): dialog.destroy() self.error_dialog = None if resp == "_Cancel": self.on_cancel(None) elif resp == Gtk.ResponseType.NO: self.total_bytes -= os.path.getsize(self.files[-1]) self.total_transferred -= self.transferred self.transferred = 0 del self.files[-1] if not self.object_push: self.create_session() self.process_queue() elif resp == Gtk.ResponseType.YES: self.total_transferred -= self.transferred self.transferred = 0 if not self.object_push: self.create_session() self.process_queue() else: self.on_cancel(None) d.connect("response", on_response) d.show() self.error_dialog = d def on_session_created(self, _client, session_path): self.object_push = ObjectPush(session_path) self.object_push.connect("transfer-started", self.on_transfer_started) self.object_push.connect("transfer-failed", self.on_transfer_failed) self.process_queue() def on_session_failed(self, _client, msg): d = ErrorDialog(_("Error occurred"), msg.reason.split(None, 1)[1], icon_name="blueman") d.run() d.destroy() exit(1) def on_session_removed(self, _client): self.emit("result", False)
def __init__(self, blueman): blueman.List.connect("adapter-changed", self.on_adapter_changed) if blueman.List.Adapter: self.hci = adapter_path_to_name(blueman.List.Adapter.get_object_path()) else: self.hci = None self.time = None self.up_speed = SpeedCalc() self.down_speed = SpeedCalc() up = get_icon("blueman-up-inactive", 15) down = get_icon("blueman-down-inactive", 15) self.im_upload = Gtk.Image() self.im_upload.set_tooltip_text(_("Data activity indication")) self.im_upload.set_from_pixbuf(up) self.im_download = Gtk.Image() self.im_download.set_tooltip_text(_("Data activity indication")) self.im_download.set_from_pixbuf(down) self.im_upload.props.halign = Gtk.Align.END self.im_upload.props.valign = Gtk.Align.CENTER self.im_download.props.halign = Gtk.Align.END self.im_download.props.valign = Gtk.Align.CENTER self.down_rate = Gtk.Label() self.down_rate.show() self.down_rate.props.halign = Gtk.Align.END self.down_rate.props.valign = Gtk.Align.CENTER self.down_rate.set_tooltip_text(_("Total data received and rate of transmission")) self.up_rate = Gtk.Label() self.up_rate.show() self.up_rate.props.halign = Gtk.Align.END self.up_rate.props.valign = Gtk.Align.CENTER self.up_rate.set_tooltip_text(_("Total data sent and rate of transmission")) self.uparrow = Gtk.Image() self.uparrow.set_tooltip_text(_("Total data sent and rate of transmission")) self.uparrow.set_from_icon_name("go-up", 1) self.uparrow.props.halign = Gtk.Align.END self.uparrow.props.valign = Gtk.Align.CENTER self.downarrow = Gtk.Image() self.downarrow.set_tooltip_text(_("Total data received and rate of transmission")) self.downarrow.set_from_icon_name("go-down", 1) self.hbox = hbox = blueman.Builder.get_object("status_activity") hbox.pack_start(self.uparrow, True, False, 0) hbox.pack_start(self.up_rate, False, False, 0) hbox.pack_start(self.downarrow, False, False, 0) hbox.pack_start(self.down_rate, False, False, 0) hbox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.VERTICAL), False, False, 0) hbox.pack_start(self.im_upload, False, False, 0) hbox.pack_start(self.im_download, False, False, 0) hbox.show_all() self.on_adapter_changed(blueman.List, blueman.List.GetAdapterPath()) self.up_blinker = Animation(self.im_upload, [get_icon("blueman-up-inactive", 15), get_icon("blueman-up-active", 15)]) #self.down_blinker = Animation(self.im_download, ["/down_inactive.png", "/down_active.png"]) self.down_blinker = Animation(self.im_download, [get_icon("blueman-down-inactive", 16), get_icon("blueman-down-active", 16)]) self.start_update()
def __init__(self, device, adapter, files): super(Sender, self).__init__(title=_("Bluetooth File Transfer")) self.set_name("BluemanSendTo") self.set_position(Gtk.WindowPosition.CENTER) self.set_type_hint(Gdk.WindowTypeHint.DIALOG) self.props.border_width = 5 self.props.icon_name = "blueman" self.props.width_request = 400 self.b_cancel = self.add_button("_Stop", Gtk.ResponseType.CLOSE) self.b_cancel.props.receives_default = True self.b_cancel.props.use_underline = True self.b_cancel.connect("clicked", self.on_cancel) self.Builder = Gtk.Builder() self.Builder.set_translation_domain("blueman") bind_textdomain_codeset("blueman", "UTF-8") self.Builder.add_from_file(UI_PATH + "/send-dialog.ui") grid = self.Builder.get_object("sendto") content_area = self.get_content_area() content_area.add(grid) self.l_dest = self.Builder.get_object("l_dest") self.l_file = self.Builder.get_object("l_file") self.pb = self.Builder.get_object("pb") self.pb.props.text = _("Connecting") self.device = device self.adapter = Adapter(adapter) self.files = files self.object_push = None self.transfer = None self.total_bytes = 0 self.total_transferred = 0 self._last_bytes = 0 self._last_update = 0 self.error_dialog = None self.cancelling = False #bytes transferred on a current transfer self.transferred = 0 self.speed = SpeedCalc(6) for i in range(len(self.files) - 1, -1, -1): f = self.files[i] match = re.match("file://(.*)", f) if match: f = self.files[i] = urllib.unquote(match.groups(1)[0]) if os.path.exists(f) and not os.path.isdir(f): f = os.path.abspath(f) self.total_bytes += os.path.getsize(f) else: self.files.remove(f) self.num_files = len(self.files) try: self.client = obex.Client() except obex.ObexdNotFoundError: d = Gtk.MessageDialog(self, type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) d.props.text = _("obexd not available") d.props.secondary_text = _("obexd is probably not installed") d.run() d.destroy() exit(1) if self.num_files == 0: exit(1) self.l_file.props.label = os.path.basename(self.files[-1]) self.client.connect('session-created', self.on_session_created) self.client.connect('session-failed', self.on_session_failed) self.client.connect('session-removed', self.on_session_removed) logging.info("Sending to %s" % device['Address']) self.l_dest.props.label = device['Alias'] self.create_session() self.show()
def __init__(self, device, adapter_path, files): super().__init__( title=_("Bluetooth File Transfer"), name="BluemanSendTo", icon_name="blueman", border_width=5, default_width=400, window_position=Gtk.WindowPosition.CENTER, type_hint=Gdk.WindowTypeHint.DIALOG ) self.b_cancel = self.add_button("_Stop", Gtk.ResponseType.CLOSE) self.b_cancel.props.receives_default = True self.b_cancel.props.use_underline = True self.b_cancel.connect("clicked", self.on_cancel) self.Builder = Gtk.Builder(translation_domain="blueman") bind_textdomain_codeset("blueman", "UTF-8") self.Builder.add_from_file(UI_PATH + "/send-dialog.ui") grid = self.Builder.get_object("sendto") content_area = self.get_content_area() content_area.add(grid) self.l_dest = self.Builder.get_object("l_dest") self.l_file = self.Builder.get_object("l_file") self.pb = self.Builder.get_object("pb") self.pb.props.text = _("Connecting") self.device = device self.adapter = Adapter(adapter_path) self.files = [] self.num_files = 0 self.object_push = None self.transfer = None self.total_bytes = 0 self.total_transferred = 0 self._last_bytes = 0 self._last_update = 0 self.error_dialog = None self.cancelling = False # bytes transferred on a current transfer self.transferred = 0 self.speed = SpeedCalc(6) for file_name in files: parsed_file = Gio.File.parse_name(file_name) if not parsed_file.query_exists(): logging.info("Skipping non existing file %s" % parsed_file.get_path()) continue file_info = parsed_file.query_info("standard::*", Gio.FileQueryInfoFlags.NONE) if file_info.get_file_type() == Gio.FileType.DIRECTORY: logging.info("Skipping directory %s" % parsed_file.get_path()) continue self.files.append(parsed_file) self.num_files += 1 self.total_bytes += file_info.get_size() if len(self.files) == 0: exit(1) try: self.client = obex.Client() except GLib.Error as e: if 'StartServiceByName' in e.message: logging.debug(e.message) d = ErrorDialog(_("obexd not available"), _("Failed to autostart obex service. Make sure the obex " "daemon is running"), parent=self.get_toplevel()) d.run() d.destroy() exit(1) else: # Fail on anything else raise self.l_file.props.label = self.files[-1].get_basename() self.client.connect('session-created', self.on_session_created) self.client.connect('session-failed', self.on_session_failed) self.client.connect('session-removed', self.on_session_removed) logging.info("Sending to %s" % device['Address']) self.l_dest.props.label = device['Alias'] # Stop discovery if discovering and let adapter settle for a second if self.adapter["Discovering"]: self.adapter.stop_discovery() time.sleep(1) self.create_session() self.show()
class ManagerStats: def __init__(self, blueman): blueman.List.connect("adapter-changed", self.on_adapter_changed) if blueman.List.Adapter: self.hci = adapter_path_to_name(blueman.List.Adapter.get_object_path()) else: self.hci = None self.time = None self.up_speed = SpeedCalc() self.down_speed = SpeedCalc() up = get_icon("blueman-up-inactive", 15) down = get_icon("blueman-down-inactive", 15) self.im_upload = Gtk.Image() self.im_upload.set_tooltip_text(_("Data activity indication")) self.im_upload.set_from_pixbuf(up) self.im_download = Gtk.Image() self.im_download.set_tooltip_text(_("Data activity indication")) self.im_download.set_from_pixbuf(down) self.im_upload.set_alignment(1, 0.5) self.im_download.set_alignment(1, 0.5) self.down_rate = Gtk.Label() self.down_rate.show() self.down_rate.set_alignment(1, 0.5) self.down_rate.set_tooltip_text(_("Total data received and rate of transmission")) self.up_rate = Gtk.Label() self.up_rate.show() self.up_rate.set_alignment(1, 0.5) self.up_rate.set_tooltip_text(_("Total data sent and rate of transmission")) self.uparrow = Gtk.Image() self.uparrow.set_tooltip_text(_("Total data sent and rate of transmission")) self.uparrow.set_from_icon_name("go-up", 1) self.uparrow.set_alignment(1, 0.5) self.downarrow = Gtk.Image() self.downarrow.set_tooltip_text(_("Total data received and rate of transmission")) self.downarrow.set_from_icon_name("go-down", 1) self.hbox = hbox = blueman.Builder.get_object("statusbar2") hbox.pack_start(self.uparrow, True, False, 0) hbox.pack_start(self.up_rate, False, False, 0) hbox.pack_start(self.downarrow, False, False, 0) hbox.pack_start(self.down_rate, False, False, 0) hbox.pack_start(Gtk.VSeparator(), False, False, 0) hbox.pack_start(self.im_upload, False, False, 0) hbox.pack_start(self.im_download, False, False, 0) hbox.show_all() self.on_adapter_changed(blueman.List, blueman.List.GetAdapterPath()) self.up_blinker = Animation(self.im_upload, [get_icon("blueman-up-inactive", 15), get_icon("blueman-up-active", 15)]) #self.down_blinker = Animation(self.im_download, ["/down_inactive.png", "/down_active.png"]) self.down_blinker = Animation(self.im_download, [get_icon("blueman-down-inactive", 16), get_icon("blueman-down-active", 16)]) self.start_update() def on_adapter_changed(self, List, adapter_path): if adapter_path != None: self.hci = adapter_path_to_name(adapter_path) self.hbox.props.sensitive = True else: self.hci = None self.hbox.props.sensitive = False self.up_speed.reset() self.down_speed.reset() def set_blinker_by_speed(self, blinker, speed): if speed > 0 and not blinker.status(): blinker.start() if speed > (30 * 1024) and blinker.status(): blinker.set_rate(20) elif speed > (20 * 1024) and blinker.status(): blinker.set_rate(15) elif speed > (10 * 1024) and blinker.status(): blinker.set_rate(10) elif speed > 1024 and blinker.status(): blinker.set_rate(5) elif speed == 0 and blinker.status(): blinker.stop() else: blinker.set_rate(1) def _update(self): #if self.hbox.parent.parent.parent.props.visible: if self.hci != None: devinfo = device_info(self.hci) _tx = devinfo["stat"]["byte_tx"] _rx = devinfo["stat"]["byte_rx"] tx, s_tx = format_bytes(_tx) rx, s_rx = format_bytes(_rx) _u_speed = self.up_speed.calc(_tx) _d_speed = self.down_speed.calc(_rx) self.set_blinker_by_speed(self.up_blinker, _u_speed) self.set_blinker_by_speed(self.down_blinker, _d_speed) u_speed, s_u_speed = format_bytes(_u_speed) d_speed, s_d_speed = format_bytes(_d_speed) self.set_data(tx, s_tx, rx, s_rx, u_speed, s_u_speed, d_speed, s_d_speed) return 1 def start_update(self): self._update() self.timer = GObject.timeout_add(1000, self._update) def stop_update(self): if self.timer: GObject.source_remove(self.timer) def set_data(self, uploaded, u_name, downloaded, d_name, u_speed, us_name, d_speed, ds_name): self.down_rate.set_markup( '<span size="small">%.2f %s <i>%5.2f %s/s</i></span>' % (downloaded, d_name, d_speed, ds_name)) self.up_rate.set_markup( '<span size="small">%.2f %s <i>%5.2f %s/s</i></span>' % (uploaded, u_name, u_speed, us_name))
class ManagerStats: def __init__(self, blueman): blueman.List.connect("adapter-changed", self.on_adapter_changed) if blueman.List.Adapter: self.hci = adapter_path_to_name( blueman.List.Adapter.GetObjectPath()) else: self.hci = None self.time = None self.up_speed = SpeedCalc() self.down_speed = SpeedCalc() up = get_icon("blueman-up-inactive", 15) down = get_icon("blueman-down-inactive", 15) self.im_upload = gtk.Image() self.im_upload.set_tooltip_text(_("Data activity indication")) self.im_upload.set_from_pixbuf(up) self.im_download = gtk.Image() self.im_download.set_tooltip_text(_("Data activity indication")) self.im_download.set_from_pixbuf(down) self.im_upload.set_alignment(1, 0.5) self.im_download.set_alignment(1, 0.5) self.down_rate = gtk.Label() self.down_rate.show() self.down_rate.set_alignment(1, 0.5) self.down_rate.set_tooltip_text( _("Total data received and rate of transmission")) self.up_rate = gtk.Label() self.up_rate.show() self.up_rate.set_alignment(1, 0.5) self.up_rate.set_tooltip_text( _("Total data sent and rate of transmission")) self.uparrow = gtk.Image() self.uparrow.set_tooltip_text( _("Total data sent and rate of transmission")) self.uparrow.set_from_stock(gtk.STOCK_GO_UP, 1) self.uparrow.set_alignment(1, 0.5) self.downarrow = gtk.Image() self.downarrow.set_tooltip_text( _("Total data received and rate of transmission")) self.downarrow.set_from_stock(gtk.STOCK_GO_DOWN, 1) self.hbox = hbox = blueman.Builder.get_object("statusbar2") hbox.pack_start(self.uparrow, True, False) hbox.pack_start(self.up_rate, False, False) hbox.pack_start(self.downarrow, False, False) hbox.pack_start(self.down_rate, False, False) hbox.pack_start(gtk.VSeparator(), False, False) hbox.pack_start(self.im_upload, False, False) hbox.pack_start(self.im_download, False, False) hbox.show_all() self.on_adapter_changed(blueman.List, blueman.List.GetAdapterPath()) self.up_blinker = Animation(self.im_upload, [ get_icon("blueman-up-inactive", 15), get_icon("blueman-up-active", 15) ]) #self.down_blinker = Animation(self.im_download, ["/down_inactive.png", "/down_active.png"]) self.down_blinker = Animation(self.im_download, [ get_icon("blueman-down-inactive", 16), get_icon("blueman-down-active", 16) ]) self.start_update() def on_adapter_changed(self, List, adapter_path): if adapter_path != None: self.hci = adapter_path_to_name(adapter_path) self.hbox.props.sensitive = True else: self.hci = None self.hbox.props.sensitive = False self.up_speed.reset() self.down_speed.reset() def set_blinker_by_speed(self, blinker, speed): if speed > 0 and not blinker.status(): blinker.start() if speed > (30 * 1024) and blinker.status(): blinker.set_rate(20) elif speed > (20 * 1024) and blinker.status(): blinker.set_rate(15) elif speed > (10 * 1024) and blinker.status(): blinker.set_rate(10) elif speed > 1024 and blinker.status(): blinker.set_rate(5) elif speed == 0 and blinker.status(): blinker.stop() else: blinker.set_rate(1) def _update(self): #if self.hbox.parent.parent.parent.props.visible: if self.hci != None: devinfo = Lib.device_info(self.hci) _tx = devinfo["stat"]["byte_tx"] _rx = devinfo["stat"]["byte_rx"] tx, s_tx = format_bytes(_tx) rx, s_rx = format_bytes(_rx) _u_speed = self.up_speed.calc(_tx) _d_speed = self.down_speed.calc(_rx) self.set_blinker_by_speed(self.up_blinker, _u_speed) self.set_blinker_by_speed(self.down_blinker, _d_speed) u_speed, s_u_speed = format_bytes(_u_speed) d_speed, s_d_speed = format_bytes(_d_speed) self.set_data(tx, s_tx, rx, s_rx, u_speed, s_u_speed, d_speed, s_d_speed) return 1 def start_update(self): self._update() self.timer = gobject.timeout_add(1000, self._update) def stop_update(self): if self.timer: gobject.source_remove(self.timer) def set_data(self, uploaded, u_name, downloaded, d_name, u_speed, us_name, d_speed, ds_name): self.down_rate.set_markup( '<span size="small">%.2f %s <i>%5.2f %s/s</i></span>' % (downloaded, d_name, d_speed, ds_name)) self.up_rate.set_markup( '<span size="small">%.2f %s <i>%5.2f %s/s</i></span>' % (uploaded, u_name, u_speed, us_name))
class ManagerStats: def __init__(self, blueman): blueman.List.connect("adapter-changed", self.on_adapter_changed) if blueman.List.Adapter: self.hci = adapter_path_to_name( blueman.List.Adapter.get_object_path()) else: self.hci = None self.time = None self.up_speed = SpeedCalc() self.down_speed = SpeedCalc() self.im_upload = Gtk.Image(icon_name="blueman-up-inactive", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Data activity indication")) self.im_download = Gtk.Image( icon_name="blueman-down-inactive", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Data activity indication")) self.down_rate = Gtk.Label( halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data received and rate of transmission")) self.down_rate.show() self.up_rate = Gtk.Label( halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data sent and rate of transmission")) self.up_rate.show() self.uparrow = Gtk.Image( icon_name="go-up", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data sent and rate of transmission")) self.downarrow = Gtk.Image( icon_name="go-down", pixel_size=16, halign=Gtk.Align.END, valign=Gtk.Align.CENTER, tooltip_text=_("Total data received and rate of transmission")) self.hbox = hbox = blueman.Builder.get_object("status_activity") hbox.pack_start(self.uparrow, False, False, 0) hbox.pack_start(self.up_rate, False, False, 0) hbox.pack_start(self.downarrow, False, False, 0) hbox.pack_start(self.down_rate, False, False, 0) hbox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.VERTICAL), False, False, 0) hbox.pack_start(self.im_upload, False, False, 0) hbox.pack_start(self.im_download, False, False, 0) hbox.show_all() self.on_adapter_changed(blueman.List, blueman.List.get_adapter_path()) self.up_blinker = Animation( self.im_upload, ["blueman-up-inactive", "blueman-up-active"]) self.down_blinker = Animation( self.im_download, ["blueman-down-inactive", "blueman-down-active"]) self.start_update() def on_adapter_changed(self, lst, adapter_path): if adapter_path is not None: self.hci = adapter_path_to_name(adapter_path) self.hbox.props.sensitive = True else: self.hci = None self.hbox.props.sensitive = False self.up_speed.reset() self.down_speed.reset() def set_blinker_by_speed(self, blinker, speed): if speed > 0 and not blinker.status(): blinker.start() if speed > 40 * 1024 and blinker.status(): blinker.set_rate(10) elif speed > (30 * 1024) and blinker.status(): blinker.set_rate(8) elif speed > (20 * 1024) and blinker.status(): blinker.set_rate(6) elif speed > (10 * 1024) and blinker.status(): blinker.set_rate(4) elif speed > 1024 and blinker.status(): blinker.set_rate(2) elif speed == 0 and blinker.status(): blinker.stop() else: blinker.set_rate(1) def _update(self): if self.hci is not None: devinfo = device_info(self.hci) _tx = devinfo["stat"]["byte_tx"] _rx = devinfo["stat"]["byte_rx"] tx, s_tx = format_bytes(_tx) rx, s_rx = format_bytes(_rx) _u_speed = self.up_speed.calc(_tx) _d_speed = self.down_speed.calc(_rx) self.set_blinker_by_speed(self.up_blinker, _u_speed) self.set_blinker_by_speed(self.down_blinker, _d_speed) u_speed, s_u_speed = format_bytes(_u_speed) d_speed, s_d_speed = format_bytes(_d_speed) self.set_data(tx, s_tx, rx, s_rx, u_speed, s_u_speed, d_speed, s_d_speed) return 1 def start_update(self): self._update() self.timer = GLib.timeout_add(1000, self._update) def stop_update(self): if self.timer: GLib.source_remove(self.timer) def set_data(self, uploaded, u_name, downloaded, d_name, u_speed, us_name, d_speed, ds_name): self.down_rate.set_markup( '<span size="small">%.2f %s <i>%5.2f %s/s</i></span>' % (downloaded, d_name, d_speed, ds_name)) self.up_rate.set_markup( '<span size="small">%.2f %s <i>%5.2f %s/s</i></span>' % (uploaded, u_name, u_speed, us_name))
class Sender(Gtk.Dialog): __gsignals__ = { 'result': (GObject.SignalFlags.RUN_FIRST, None, (GObject.TYPE_BOOLEAN,)), } def __init__(self, device, adapter_path, files): super(Sender, self).__init__(title=_("Bluetooth File Transfer")) self.set_name("BluemanSendTo") self.set_position(Gtk.WindowPosition.CENTER) self.set_type_hint(Gdk.WindowTypeHint.DIALOG) self.props.border_width = 5 self.props.icon_name = "blueman" self.props.width_request = 400 self.b_cancel = self.add_button("_Stop", Gtk.ResponseType.CLOSE) self.b_cancel.props.receives_default = True self.b_cancel.props.use_underline = True self.b_cancel.connect("clicked", self.on_cancel) self.Builder = Gtk.Builder() self.Builder.set_translation_domain("blueman") bind_textdomain_codeset("blueman", "UTF-8") self.Builder.add_from_file(UI_PATH + "/send-dialog.ui") grid = self.Builder.get_object("sendto") content_area = self.get_content_area() content_area.add(grid) self.l_dest = self.Builder.get_object("l_dest") self.l_file = self.Builder.get_object("l_file") self.pb = self.Builder.get_object("pb") self.pb.props.text = _("Connecting") self.device = device self.adapter = Adapter(adapter_path) self.files = files self.object_push = None self.transfer = None self.total_bytes = 0 self.total_transferred = 0 self._last_bytes = 0 self._last_update = 0 self.error_dialog = None self.cancelling = False #bytes transferred on a current transfer self.transferred = 0 self.speed = SpeedCalc(6) for i in range(len(self.files) - 1, -1, -1): f = self.files[i] match = re.match("file://(.*)", f) if match: f = self.files[i] = urllib.parse.unquote(match.groups(1)[0]) if os.path.exists(f) and not os.path.isdir(f): f = os.path.abspath(f) self.total_bytes += os.path.getsize(f) else: self.files.remove(f) self.num_files = len(self.files) try: self.client = obex.Client() except obex.ObexdNotFoundError: d = ErrorDialog(_("obexd not available"), _("obexd is probably not installed")) d.run() d.destroy() exit(1) if self.num_files == 0: exit(1) self.l_file.props.label = os.path.basename(self.files[-1]) self.client.connect('session-created', self.on_session_created) self.client.connect('session-failed', self.on_session_failed) self.client.connect('session-removed', self.on_session_removed) logging.info("Sending to %s" % device['Address']) self.l_dest.props.label = device['Alias'] # Stop discovery if discovering and let adapter settle for a second if self.adapter["Discovering"]: self.adapter.stop_discovery() time.sleep(1) self.create_session() self.show() def create_session(self): self.client.create_session(self.device['Address'], self.adapter["Address"]) def on_cancel(self, button): self.pb.props.text = _("Cancelling") if button: button.props.sensitive = False if self.object_push: self.client.remove_session(self.object_push.get_session_path()) else: self.emit("result", False) def on_transfer_started(self, _object_push, transfer_path, filename): if self.total_transferred == 0: self.pb.props.text = _("Sending File") + (" %(0)s/%(1)s (%(2).2f %(3)s/s) " + _("ETA:") + " %(4)s") % { "1": self.num_files, "0": (self.num_files - len(self.files) + 1), "2": 0.0, "3": "B/s", "4": "∞"} self.l_file.props.label = filename self._last_bytes = 0 self.transferred = 0 self.transfer = obex.Transfer(transfer_path) self.transfer.connect("error", self.on_transfer_error) self.transfer.connect("progress", self.on_transfer_progress) self.transfer.connect("completed", self.on_transfer_completed) def on_transfer_failed(self, _object_push, error): self.on_transfer_error(None, str(error)) def on_transfer_progress(self, _transfer, progress): self.transferred = progress if self._last_bytes == 0: self.total_transferred += progress else: self.total_transferred += (progress - self._last_bytes) self._last_bytes = progress tm = time.time() if tm - self._last_update > 0.5: spd = self.speed.calc(self.total_transferred) (size, units) = format_bytes(spd) try: x = ((self.total_bytes - self.total_transferred) / spd) + 1 if x > 60: x /= 60 eta = ngettext("%.0f Minute", "%.0f Minutes", round(x)) % x else: eta = ngettext("%.0f Second", "%.0f Seconds", round(x)) % x except ZeroDivisionError: eta = "∞" self.pb.props.text = _("Sending File") + (" %(0)s/%(1)s (%(2).2f %(3)s/s) " + _("ETA:") + " %(4)s") % { "1": self.num_files, "0": (self.num_files - len(self.files) + 1), "2": size, "3": units, "4": eta} self._last_update = tm self.pb.props.fraction = float(self.total_transferred) / self.total_bytes def on_transfer_completed(self, _transfer): del self.files[-1] self.transfer = None self.process_queue() def process_queue(self): if len(self.files) > 0: self.send_file(self.files[-1]) else: self.emit("result", True) def send_file(self, file_path): logging.info(file_path) if self.object_push: self.object_push.send_file(file_path) def on_transfer_error(self, _transfer, msg=""): if not self.error_dialog: self.speed.reset() d = ErrorDialog(msg, _("Error occurred while sending file %s") % os.path.basename(self.files[-1]), modal=True, icon_name="blueman", buttons=None) if len(self.files) > 1: d.add_button(_("Skip"), Gtk.ResponseType.NO) d.add_button(_("Retry"), Gtk.ResponseType.YES) d.add_button("_Cancel", Gtk.ResponseType.CANCEL) def on_response(dialog, resp): dialog.destroy() self.error_dialog = None if resp == "_Cancel": self.on_cancel(None) elif resp == Gtk.ResponseType.NO: self.total_bytes -= os.path.getsize(self.files[-1]) self.total_transferred -= self.transferred self.transferred = 0 del self.files[-1] if not self.object_push: self.create_session() self.process_queue() elif resp == Gtk.ResponseType.YES: self.total_transferred -= self.transferred self.transferred = 0 if not self.object_push: self.create_session() self.process_queue() else: self.on_cancel(None) d.connect("response", on_response) d.show() self.error_dialog = d def on_session_created(self, _client, session_path): self.object_push = ObjectPush(session_path) self.object_push.connect("transfer-started", self.on_transfer_started) self.object_push.connect("transfer-failed", self.on_transfer_failed) self.process_queue() def on_session_failed(self, _client, msg): d = ErrorDialog(_("Error occurred"), msg.reason.split(None, 1)[1], icon_name="blueman") d.run() d.destroy() exit(1) def on_session_removed(self, _client): self.emit("result", False)