Example #1
0
    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()
Example #2
0
    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()
Example #3
0
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))
Example #4
0
    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()
Example #5
0
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)
Example #6
0
    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()
Example #7
0
    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()
Example #8
0
    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()
Example #9
0
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)
Example #10
0
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>'
        )
Example #11
0
    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()
Example #12
0
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)
Example #13
0
    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()
Example #14
0
    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()
Example #15
0
    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()
Example #16
0
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))
Example #17
0
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))
Example #18
0
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))
Example #19
0
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)