class TransmissionClient(BitTorrentClient): def __init__(self): BitTorrentClient.__init__(self, TRANSMISSION_CLIENT) self.dict_client = {} def connect(self, address, port, user, password): try: self.client = TClient(address, port, user, password) except TransmissionError as err: raise BTCexception(" {} TransmissionError {}".format(address, err)) except socket.timeout as err: raise BTCexception(" {} Socket error {}".format(address, err)) else: self.dict_client['name'] = address def get_torrents(self): tr_torrents = self.client.get_torrents() self.dict_client['torrents'] = [] for _torrent in tr_torrents: _torrent_dict = { u'name': _torrent.name, u'hash': _torrent.hashString, u'progress': _torrent.progress, u'status': _torrent.status, u'date_active': _torrent.date_active, u'date_added': _torrent.date_added, u'date_started': _torrent.date_started, u'date_done': _torrent.date_done, u'eta': -1, u'error': _torrent.error, u'errorString': _torrent.errorString[:350], } #TODO: Warning eta can return exception ValuerError try: _torrent_dict[u'eta'] = timedelta.total_seconds(_torrent.eta) except ValueError: pass self.dict_client['torrents'].append(_torrent_dict) if _torrent_dict[u'error'] == 3: _torrent_dict[u'status'] = u'error_torrentclient' if _torrent_dict[u'error'] in [1, 2]: _torrent_dict[u'status'] = u'error_torrenttracker' return self.dict_client def add_torrent(self, torrent_path): pass def remove(self, torrent_hash): self.client.remove_torrent(torrent_hash) def verify(self, torrent_hash): self.client.verify_torrent(torrent_hash) def free_space_bytes(self): free_space = None try: session = self.client.get_session() except TransmissionError as err: raise BTCexception(" {} TransmissionError {}".format( self.dict_client['name'], err)) except socket.timeout as err: raise BTCexception(" {} Socket error {}".format( self.dict_client['name'], err)) except Exception as err: raise BTCexception("{}: {}".format(self.dict_client['name'], err.message)) else: free_space = session.download_dir_free_space return free_space
class EmissionOverview(Screen, HelpableScreen): skin = """<screen name="EmissionOverview" title="Torrent Overview" position="75,135" size="565,330"> <ePixmap position="0,0" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" /> <ePixmap position="140,0" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" /> <ePixmap position="280,0" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" /> <ePixmap position="420,0" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" /> <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget size="320,25" alphatest="on" position="5,45" zPosition="1" name="all_sel" pixmap="skin_default/epg_now.png" /> <widget valign="center" transparent="1" size="108,22" backgroundColor="#25062748" position="5,47" zPosition="2" source="all_text" render="Label" halign="center" font="Regular;18" /> <widget size="320,25" alphatest="on" position="5,45" zPosition="1" name="downloading_sel" pixmap="skin_default/epg_next.png" /> <widget valign="center" transparent="1" size="108,22" backgroundColor="#25062748" position="111,47" zPosition="2" source="downloading_text" render="Label" halign="center" font="Regular;18" /> <widget size="320,25" alphatest="on" position="5,45" zPosition="1" name="seeding_sel" pixmap="skin_default/epg_more.png" /> <widget valign="center" transparent="1" size="108,22" backgroundColor="#25062748" position="212,47" zPosition="2" source="seeding_text" render="Label" halign="center" font="Regular;18" /> <widget source="torrents" render="Label" size="240,22" position="320,47" halign="right" font="Regular;18" /> <!--ePixmap size="550,230" alphatest="on" position="5,65" pixmap="skin_default/border_epg.png" /--> <widget source="list" render="Listbox" position="5,70" size="550,225" scrollbarMode="showAlways"> <convert type="TemplatedMultiContent"> {"template": [ MultiContentEntryText(pos=(2,2), size=(555,22), text = 1, font = 0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER), MultiContentEntryText(pos=(2,26), size=(555,18), text = 2, font = 1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER), (eListboxPythonMultiContent.TYPE_PROGRESS, 0, 44, 537, 6, -3), ], "fonts": [gFont("Regular", 20),gFont("Regular", 16)], "itemHeight": 51 } </convert> </widget> <widget source="upspeed" render="Label" size="150,20" position="5,300" halign="left" font="Regular;18" /> <widget source="downspeed" render="Label" size="150,20" position="410,300" halign="right" font="Regular;18" /> </screen>""" def __init__(self, session): Screen.__init__(self, session) HelpableScreen.__init__(self) try: self.transmission = Client( address=config.plugins.emission.hostname.value, port=config.plugins.emission.port.value, user=config.plugins.emission.username.value, password=config.plugins.emission.password.value) except TransmissionError as te: self.transmission = None self["SetupActions"] = HelpableActionMap( self, "SetupActions", { "ok": (self.ok, _("show details")), "cancel": (self.close, _("close")), }) self["ColorActions"] = HelpableActionMap( self, "ColorActions", { "green": (self.bandwidth, _("open bandwidth settings")), "yellow": (self.prevlist, _("show previous list")), "blue": (self.nextlist, _("show next list")), }) self["MenuActions"] = HelpableActionMap(self, "MenuActions", { "menu": (self.menu, _("open context menu")), }) self["key_red"] = StaticText(_("Close")) self["key_green"] = StaticText(_("Bandwidth")) self["key_yellow"] = StaticText("") self["key_blue"] = StaticText("") self["all_text"] = StaticText(_("All")) self["downloading_text"] = StaticText(_("DL")) self["seeding_text"] = StaticText(_("UL")) self["upspeed"] = StaticText("") self["downspeed"] = StaticText("") self["torrents"] = StaticText("") self["all_sel"] = Pixmap() self["downloading_sel"] = Pixmap() self["seeding_sel"] = Pixmap() self['list'] = List([]) self.list_type = config.plugins.emission.last_tab.value self.sort_type = config.plugins.emission.last_sort.value self.showHideSetTextMagic() self.timer = eTimer() self.timer_conn = self.timer.timeout.connect(self.updateList) self.timer.start(0, 1) def bandwidthCallback(self, ret=None): if self.transmission is not None and ret: try: self.transmission.set_session(**ret) except TransmissionError as te: self.session.open( MessageBox, _("Error communicating with transmission-daemon: %s.") % (te), type=MessageBox.TYPE_ERROR, timeout=5) self.updateList() def menuCallback(self, ret=None): ret and ret[1]() def newDlCallback(self, ret=None): if self.transmission is not None and ret: try: res = self.transmission.add_url(ret) except TransmissionError as te: self.session.open( MessageBox, _("Error communicating with transmission-daemon: %s.") % (te), type=MessageBox.TYPE_ERROR, timeout=5) else: if not res: self.session.open( MessageBox, _("Torrent could not be scheduled not download!"), type=MessageBox.TYPE_ERROR, timeout=5) self.updateList() def newDl(self): self.timer.stop() self.session.openWithCallback(self.newDlCallback, TorrentLocationBox) def sortCallback(self, ret=None): if ret is not None: self.sort_type = config.plugins.emission.last_sort.value = ret[1] config.plugins.emission.last_sort.save() self.updateList() def sort(self): self.timer.stop() self.session.openWithCallback(self.sortCallback, ChoiceBox, _("Which sorting method do you prefer?"), [(_("by eta"), SORT_TYPE_TIME), (_("by progress"), SORT_TYPE_PROGRESS), (_("by age"), SORT_TYPE_ADDED), (_("by speed"), SORT_TYPE_SPEED)]) def pauseShown(self): if self.transmission is not None: self.transmission.stop([x[0].id for x in self.list]) def unpauseShown(self): if self.transmission is not None: self.transmission.start([x[0].id for x in self.list]) def pauseAll(self): if self.transmission is None: return try: self.transmission.stop( [x.id for x in self.transmission.list().values()]) except TransmissionError as te: self.session.open( MessageBox, _("Error communicating with transmission-daemon: %s.") % (te), type=MessageBox.TYPE_ERROR, timeout=5) def unpauseAll(self): if self.transmission is None: return try: self.transmission.start( [x.id for x in self.transmission.list().values()]) except TransmissionError as te: self.session.open( MessageBox, _("Error communicating with transmission-daemon: %s.") % (te), type=MessageBox.TYPE_ERROR, timeout=5) def configure(self): #reload(EmissionSetup) self.timer.stop() self.session.openWithCallback(self.configureCallback, EmissionSetup.EmissionSetup) def menu(self): self.session.openWithCallback( self.menuCallback, ChoiceBox, _("What do you want to do?"), [(_("Configure connection"), self.configure), (_("Change sorting"), self.sort), (_("Add new download"), self.newDl), (_("Pause shown"), self.pauseShown), (_("Unpause shown"), self.unpauseShown), (_("Pause all"), self.pauseAll), (_("Unpause all"), self.unpauseAll)], ) def showHideSetTextMagic(self): list_type = self.list_type if list_type == LIST_TYPE_ALL: self["all_sel"].show() self["downloading_sel"].hide() self["seeding_sel"].hide() self["key_yellow"].setText(_("Seeding")) self["key_blue"].setText(_("Download")) elif list_type == LIST_TYPE_DOWNLOADING: self["all_sel"].hide() self["downloading_sel"].show() self["seeding_sel"].hide() self["key_yellow"].setText(_("All")) self["key_blue"].setText(_("Seeding")) else: #if list_type == LIST_TYPE_SEEDING: self["all_sel"].hide() self["downloading_sel"].hide() self["seeding_sel"].show() self["key_yellow"].setText(_("Download")) self["key_blue"].setText(_("All")) def prevlist(self): self.timer.stop() list_type = self.list_type if list_type == LIST_TYPE_ALL: self.list_type = LIST_TYPE_SEEDING elif list_type == LIST_TYPE_DOWNLOADING: self.list_type = LIST_TYPE_ALL else: #if list_type == LIST_TYPE_SEEDING: self.list_type = LIST_TYPE_DOWNLOADING self.showHideSetTextMagic() self.updateList() def nextlist(self): self.timer.stop() list_type = self.list_type if list_type == LIST_TYPE_ALL: self.list_type = LIST_TYPE_DOWNLOADING elif list_type == LIST_TYPE_DOWNLOADING: self.list_type = LIST_TYPE_SEEDING else: #if list_type == LIST_TYPE_SEEDING: self.list_type = LIST_TYPE_ALL self.showHideSetTextMagic() self.updateList() def prevItem(self): self['list'].selectPrevious() cur = self['list'].getCurrent() return cur and cur[0] def nextItem(self): self['list'].selectNext() cur = self['list'].getCurrent() return cur and cur[0] def bandwidth(self): if self.transmission is None: return #reload(EmissionBandwidth) self.timer.stop() try: sess = self.transmission.get_session() rpc_version = self.transmission.rpc_version except TransmissionError as te: self.session.open( MessageBox, _("Error communicating with transmission-daemon: %s.") % (te), type=MessageBox.TYPE_ERROR, timeout=5) # XXX: this seems silly but cleans the gui and restarts the timer :-) self.updateList() else: self.session.openWithCallback(self.bandwidthCallback, EmissionBandwidth.EmissionBandwidth, sess, False, rpc_version) def configureCallback(self): try: self.transmission = Client( address=config.plugins.emission.hostname.value, port=config.plugins.emission.port.value, user=config.plugins.emission.username.value, password=config.plugins.emission.password.value) except TransmissionError as te: self.transmission = None self.session.open( MessageBox, _("Error communicating with transmission-daemon: %s.") % (te), type=MessageBox.TYPE_ERROR, timeout=5) else: self.updateList() def updateList(self, *args, **kwargs): # XXX: if we are not connected do NOT restart timer, it's useless anyway if self.transmission is None: return try: lst = list(self.transmission.list().values()) session = self.transmission.session_stats() except TransmissionError: # XXX: some hint in gui would be nice self['list'].setList([]) self["torrents"].setText("") self["upspeed"].setText("") self["downspeed"].setText("") else: sort_type = self.sort_type if sort_type == SORT_TYPE_TIME: def cmp_func(x, y): x_eta = x.fields['eta'] y_eta = y.fields['eta'] if x_eta > -1 and y_eta < 0: return 1 if x_eta < 0 and y_eta > -1: return -1 # note: cmp call inversed because lower eta is "better" return cmp(y_eta, x_eta) or cmp(x.progress, y.progress) lst.sort(cmp=cmp_func, reverse=True) elif sort_type == SORT_TYPE_PROGRESS: lst.sort(key=lambda x: x.progress, reverse=True) elif sort_type == SORT_TYPE_SPEED: lst.sort(key=lambda x: (x.rateDownload, x.rateUpload), reverse=True) # SORT_TYPE_ADDED is what we already have list_type = self.list_type if list_type == LIST_TYPE_ALL: lst = [(x, x.name.encode('utf-8', 'ignore'), str(x.eta or '?:??:??').encode('utf-8'), int(x.progress)) for x in lst] elif list_type == LIST_TYPE_DOWNLOADING: lst = [(x, x.name.encode('utf-8', 'ignore'), str(x.eta or '?:??:??').encode('utf-8'), int(x.progress)) for x in lst if x.status == "downloading"] else: #if list_type == LIST_TYPE_SEEDING: lst = [(x, x.name.encode('utf-8', 'ignore'), str(x.eta or '?:??:??').encode('utf-8'), int(x.progress)) for x in lst if x.status == "seeding"] self["torrents"].setText( _("Active Torrents: %d/%d") % (session.activeTorrentCount, session.torrentCount)) self["upspeed"].setText( _("UL: %d kb/s") % (session.uploadSpeed / 1024)) self["downspeed"].setText( _("DL: %d kb/s") % (session.downloadSpeed / 1024)) # XXX: this is a little ugly but this way we have the least # visible distortion :-) index = min(self['list'].index, len(lst) - 1) self['list'].setList(lst) self['list'].index = index self.list = lst self.timer.startLongTimer(10) def ok(self): cur = self['list'].getCurrent() if self.transmission is not None and cur: #reload(EmissionDetailview) self.timer.stop() self.session.openWithCallback( self.updateList, EmissionDetailview.EmissionDetailview, self.transmission, cur[0], self.prevItem, self.nextItem, ) def close(self): self.timer.stop() config.plugins.emission.last_tab.value = self.list_type config.plugins.emission.last_tab.save() Screen.close(self)
class EmissionOverview(Screen, HelpableScreen): skin = """<screen name="EmissionOverview" title="Torrent Overview" position="75,135" size="565,330"> <ePixmap position="0,0" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" /> <ePixmap position="140,0" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" /> <ePixmap position="280,0" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" /> <ePixmap position="420,0" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" /> <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget size="320,25" alphatest="on" position="5,45" zPosition="1" name="all_sel" pixmap="skin_default/epg_now.png" /> <widget valign="center" transparent="1" size="108,22" backgroundColor="#25062748" position="5,47" zPosition="2" source="all_text" render="Label" halign="center" font="Regular;18" /> <widget size="320,25" alphatest="on" position="5,45" zPosition="1" name="downloading_sel" pixmap="skin_default/epg_next.png" /> <widget valign="center" transparent="1" size="108,22" backgroundColor="#25062748" position="111,47" zPosition="2" source="downloading_text" render="Label" halign="center" font="Regular;18" /> <widget size="320,25" alphatest="on" position="5,45" zPosition="1" name="seeding_sel" pixmap="skin_default/epg_more.png" /> <widget valign="center" transparent="1" size="108,22" backgroundColor="#25062748" position="212,47" zPosition="2" source="seeding_text" render="Label" halign="center" font="Regular;18" /> <widget source="torrents" render="Label" size="240,22" position="320,47" halign="right" font="Regular;18" /> <!--ePixmap size="550,230" alphatest="on" position="5,65" pixmap="skin_default/border_epg.png" /--> <widget source="list" render="Listbox" position="5,70" size="550,225" scrollbarMode="showAlways"> <convert type="TemplatedMultiContent"> {"template": [ MultiContentEntryText(pos=(2,2), size=(555,22), text = 1, font = 0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER), MultiContentEntryText(pos=(2,26), size=(555,18), text = 2, font = 1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER), (eListboxPythonMultiContent.TYPE_PROGRESS, 0, 44, 537, 6, -3), ], "fonts": [gFont("Regular", 20),gFont("Regular", 16)], "itemHeight": 51 } </convert> </widget> <widget source="upspeed" render="Label" size="150,20" position="5,300" halign="left" font="Regular;18" /> <widget source="downspeed" render="Label" size="150,20" position="410,300" halign="right" font="Regular;18" /> </screen>""" def __init__(self, session): Screen.__init__(self, session) HelpableScreen.__init__(self) try: self.transmission = Client( address=config.plugins.emission.hostname.value, port=config.plugins.emission.port.value, user=config.plugins.emission.username.value, password=config.plugins.emission.password.value, ) except TransmissionError as te: self.transmission = None self["SetupActions"] = HelpableActionMap( self, "SetupActions", {"ok": (self.ok, _("show details")), "cancel": (self.close, _("close"))} ) self["ColorActions"] = HelpableActionMap( self, "ColorActions", { "green": (self.bandwidth, _("open bandwidth settings")), "yellow": (self.prevlist, _("show previous list")), "blue": (self.nextlist, _("show next list")), }, ) self["MenuActions"] = HelpableActionMap(self, "MenuActions", {"menu": (self.menu, _("open context menu"))}) self["key_red"] = StaticText(_("Close")) self["key_green"] = StaticText(_("Bandwidth")) self["key_yellow"] = StaticText("") self["key_blue"] = StaticText("") self["all_text"] = StaticText(_("All")) self["downloading_text"] = StaticText(_("DL")) self["seeding_text"] = StaticText(_("UL")) self["upspeed"] = StaticText("") self["downspeed"] = StaticText("") self["torrents"] = StaticText("") self["all_sel"] = Pixmap() self["downloading_sel"] = Pixmap() self["seeding_sel"] = Pixmap() self["list"] = List([]) self.list_type = config.plugins.emission.last_tab.value self.sort_type = config.plugins.emission.last_sort.value self.showHideSetTextMagic() self.timer = eTimer() self.timer.callback.append(self.updateList) self.timer.start(0, 1) def bandwidthCallback(self, ret=None): if self.transmission is not None and ret: try: self.transmission.set_session(**ret) except TransmissionError as te: self.session.open( MessageBox, _("Error communicating with transmission-daemon: %s.") % (te), type=MessageBox.TYPE_ERROR, timeout=5, ) self.updateList() def menuCallback(self, ret=None): ret and ret[1]() def newDlCallback(self, ret=None): if self.transmission is not None and ret: try: res = self.transmission.add_url(ret) except TransmissionError as te: self.session.open( MessageBox, _("Error communicating with transmission-daemon: %s.") % (te), type=MessageBox.TYPE_ERROR, timeout=5, ) else: if not res: self.session.open( MessageBox, _("Torrent could not be scheduled not download!"), type=MessageBox.TYPE_ERROR, timeout=5, ) self.updateList() def newDl(self): self.timer.stop() self.session.openWithCallback(self.newDlCallback, TorrentLocationBox) def sortCallback(self, ret=None): if ret is not None: self.sort_type = config.plugins.emission.last_sort.value = ret[1] config.plugins.emission.last_sort.save() self.updateList() def sort(self): self.timer.stop() self.session.openWithCallback( self.sortCallback, ChoiceBox, _("Which sorting method do you prefer?"), [ (_("by eta"), SORT_TYPE_TIME), (_("by progress"), SORT_TYPE_PROGRESS), (_("by age"), SORT_TYPE_ADDED), (_("by speed"), SORT_TYPE_SPEED), ], ) def pauseShown(self): if self.transmission is not None: self.transmission.stop([x[0].id for x in self.list]) def unpauseShown(self): if self.transmission is not None: self.transmission.start([x[0].id for x in self.list]) def pauseAll(self): if self.transmission is None: return try: self.transmission.stop([x.id for x in self.transmission.list().values()]) except TransmissionError as te: self.session.open( MessageBox, _("Error communicating with transmission-daemon: %s.") % (te), type=MessageBox.TYPE_ERROR, timeout=5, ) def unpauseAll(self): if self.transmission is None: return try: self.transmission.start([x.id for x in self.transmission.list().values()]) except TransmissionError as te: self.session.open( MessageBox, _("Error communicating with transmission-daemon: %s.") % (te), type=MessageBox.TYPE_ERROR, timeout=5, ) def configure(self): # reload(EmissionSetup) self.timer.stop() self.session.openWithCallback(self.configureCallback, EmissionSetup.EmissionSetup) def menu(self): self.session.openWithCallback( self.menuCallback, ChoiceBox, _("What do you want to do?"), [ (_("Configure connection"), self.configure), (_("Change sorting"), self.sort), (_("Add new download"), self.newDl), (_("Pause shown"), self.pauseShown), (_("Unpause shown"), self.unpauseShown), (_("Pause all"), self.pauseAll), (_("Unpause all"), self.unpauseAll), ], ) def showHideSetTextMagic(self): list_type = self.list_type if list_type == LIST_TYPE_ALL: self["all_sel"].show() self["downloading_sel"].hide() self["seeding_sel"].hide() self["key_yellow"].setText(_("Seeding")) self["key_blue"].setText(_("Download")) elif list_type == LIST_TYPE_DOWNLOADING: self["all_sel"].hide() self["downloading_sel"].show() self["seeding_sel"].hide() self["key_yellow"].setText(_("All")) self["key_blue"].setText(_("Seeding")) else: # if list_type == LIST_TYPE_SEEDING: self["all_sel"].hide() self["downloading_sel"].hide() self["seeding_sel"].show() self["key_yellow"].setText(_("Download")) self["key_blue"].setText(_("All")) def prevlist(self): self.timer.stop() list_type = self.list_type if list_type == LIST_TYPE_ALL: self.list_type = LIST_TYPE_SEEDING elif list_type == LIST_TYPE_DOWNLOADING: self.list_type = LIST_TYPE_ALL else: # if list_type == LIST_TYPE_SEEDING: self.list_type = LIST_TYPE_DOWNLOADING self.showHideSetTextMagic() self.updateList() def nextlist(self): self.timer.stop() list_type = self.list_type if list_type == LIST_TYPE_ALL: self.list_type = LIST_TYPE_DOWNLOADING elif list_type == LIST_TYPE_DOWNLOADING: self.list_type = LIST_TYPE_SEEDING else: # if list_type == LIST_TYPE_SEEDING: self.list_type = LIST_TYPE_ALL self.showHideSetTextMagic() self.updateList() def prevItem(self): self["list"].selectPrevious() cur = self["list"].getCurrent() return cur and cur[0] def nextItem(self): self["list"].selectNext() cur = self["list"].getCurrent() return cur and cur[0] def bandwidth(self): if self.transmission is None: return # reload(EmissionBandwidth) self.timer.stop() try: sess = self.transmission.get_session() rpc_version = self.transmission.rpc_version except TransmissionError as te: self.session.open( MessageBox, _("Error communicating with transmission-daemon: %s.") % (te), type=MessageBox.TYPE_ERROR, timeout=5, ) # XXX: this seems silly but cleans the gui and restarts the timer :-) self.updateList() else: self.session.openWithCallback( self.bandwidthCallback, EmissionBandwidth.EmissionBandwidth, sess, False, rpc_version ) def configureCallback(self): try: self.transmission = Client( address=config.plugins.emission.hostname.value, port=config.plugins.emission.port.value, user=config.plugins.emission.username.value, password=config.plugins.emission.password.value, ) except TransmissionError as te: self.transmission = None self.session.open( MessageBox, _("Error communicating with transmission-daemon: %s.") % (te), type=MessageBox.TYPE_ERROR, timeout=5, ) else: self.updateList() def updateList(self, *args, **kwargs): # XXX: if we are not connected do NOT restart timer, it's useless anyway if self.transmission is None: return try: lst = list(self.transmission.list().values()) session = self.transmission.session_stats() except TransmissionError: # XXX: some hint in gui would be nice self["list"].setList([]) self["torrents"].setText("") self["upspeed"].setText("") self["downspeed"].setText("") else: sort_type = self.sort_type if sort_type == SORT_TYPE_TIME: def cmp_func(x, y): x_eta = x.fields["eta"] y_eta = y.fields["eta"] if x_eta > -1 and y_eta < 0: return 1 if x_eta < 0 and y_eta > -1: return -1 # note: cmp call inversed because lower eta is "better" return cmp(y_eta, x_eta) or cmp(x.progress, y.progress) lst.sort(cmp=cmp_func, reverse=True) elif sort_type == SORT_TYPE_PROGRESS: lst.sort(key=lambda x: x.progress, reverse=True) elif sort_type == SORT_TYPE_SPEED: lst.sort(key=lambda x: (x.rateDownload, x.rateUpload), reverse=True) # SORT_TYPE_ADDED is what we already have list_type = self.list_type if list_type == LIST_TYPE_ALL: lst = [ (x, x.name.encode("utf-8", "ignore"), str(x.eta or "?:??:??").encode("utf-8"), int(x.progress)) for x in lst ] elif list_type == LIST_TYPE_DOWNLOADING: lst = [ (x, x.name.encode("utf-8", "ignore"), str(x.eta or "?:??:??").encode("utf-8"), int(x.progress)) for x in lst if x.status == "downloading" ] else: # if list_type == LIST_TYPE_SEEDING: lst = [ (x, x.name.encode("utf-8", "ignore"), str(x.eta or "?:??:??").encode("utf-8"), int(x.progress)) for x in lst if x.status == "seeding" ] self["torrents"].setText(_("Active Torrents: %d/%d") % (session.activeTorrentCount, session.torrentCount)) self["upspeed"].setText(_("UL: %d kb/s") % (session.uploadSpeed / 1024)) self["downspeed"].setText(_("DL: %d kb/s") % (session.downloadSpeed / 1024)) # XXX: this is a little ugly but this way we have the least # visible distortion :-) index = min(self["list"].index, len(lst) - 1) self["list"].setList(lst) self["list"].index = index self.list = lst self.timer.startLongTimer(10) def ok(self): cur = self["list"].getCurrent() if self.transmission is not None and cur: # reload(EmissionDetailview) self.timer.stop() self.session.openWithCallback( self.updateList, EmissionDetailview.EmissionDetailview, self.transmission, cur[0], self.prevItem, self.nextItem, ) def close(self): self.timer.stop() config.plugins.emission.last_tab.value = self.list_type config.plugins.emission.last_tab.save() Screen.close(self)