2010-05-28 02:38:06 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2010-07-13 01:09:42 +00:00
|
|
|
# Copyright (c) 2010 Correl J. Roush
|
2010-05-28 02:38:06 +00:00
|
|
|
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import base64
|
|
|
|
import xbmc
|
|
|
|
import xbmcgui
|
|
|
|
from basictypes.bytes import Bytes
|
|
|
|
from repeater import Repeater
|
|
|
|
|
|
|
|
_ = sys.modules[ "__main__" ].__language__
|
2010-06-10 17:10:31 +00:00
|
|
|
__settings__ = sys.modules[ "__main__" ].__settings__
|
2010-05-28 02:38:06 +00:00
|
|
|
|
|
|
|
KEY_BUTTON_BACK = 275
|
|
|
|
KEY_KEYBOARD_ESC = 61467
|
|
|
|
|
2010-06-10 17:10:31 +00:00
|
|
|
EXIT_SCRIPT = ( 6, 10, 247, 275, 61467, 216, 257, 61448, )
|
|
|
|
CANCEL_DIALOG = EXIT_SCRIPT + ( 216, 257, 61448, )
|
|
|
|
|
2011-03-29 03:22:40 +00:00
|
|
|
|
2010-05-28 02:38:06 +00:00
|
|
|
class TransmissionGUI(xbmcgui.WindowXMLDialog):
|
|
|
|
def __init__(self, strXMLname, strFallbackPath, strDefaultName, bforeFallback=0):
|
2010-07-15 19:58:42 +00:00
|
|
|
self.list = {}
|
|
|
|
self.torrents = {}
|
2011-03-29 03:22:40 +00:00
|
|
|
self.repeater = None
|
2010-07-15 19:58:42 +00:00
|
|
|
def onInit(self):
|
|
|
|
p = xbmcgui.DialogProgress()
|
|
|
|
p.create(_(0), _(1)) # 'Transmission', 'Connecting to Transmission'
|
2010-05-28 02:38:06 +00:00
|
|
|
params = {
|
|
|
|
'address': __settings__.getSetting('rpc_host'),
|
|
|
|
'port': __settings__.getSetting('rpc_port'),
|
|
|
|
'user': __settings__.getSetting('rpc_user'),
|
|
|
|
'password': __settings__.getSetting('rpc_password')
|
|
|
|
}
|
2011-03-27 06:19:08 +00:00
|
|
|
import transmissionrpc
|
2010-07-15 19:58:42 +00:00
|
|
|
try:
|
2011-03-28 17:54:08 +00:00
|
|
|
self.transmission = transmissionrpc.Client(**params)
|
2011-03-29 03:22:40 +00:00
|
|
|
except:
|
|
|
|
p.close()
|
2011-03-29 17:07:23 +00:00
|
|
|
self.close()
|
2011-03-29 03:22:40 +00:00
|
|
|
d = xbmcgui.Dialog()
|
|
|
|
(type, e, traceback) = sys.exc_info()
|
2011-03-29 16:53:53 +00:00
|
|
|
|
|
|
|
message = _(9000) # Unexpected error
|
|
|
|
if type is transmissionrpc.TransmissionError:
|
|
|
|
if e.original:
|
|
|
|
if e.original.code is 401:
|
|
|
|
message = _(9002) # Invalid auth
|
|
|
|
else:
|
|
|
|
message = _(9001) # Unable to connect
|
2011-03-29 17:07:23 +00:00
|
|
|
if d.yesno(_(2), message, _(3)):
|
|
|
|
__settings__.openSettings()
|
2011-03-29 16:53:53 +00:00
|
|
|
elif type is ValueError:
|
|
|
|
# In python 2.4, urllib2.HTTPDigestAuthHandler will barf up a lung
|
|
|
|
# if auth fails and the server wants non-digest authentication
|
|
|
|
message = _(9002) # Invalid auth
|
2011-03-29 17:07:23 +00:00
|
|
|
if d.yesno(_(2), message, _(3)):
|
|
|
|
__settings__.openSettings()
|
|
|
|
else:
|
|
|
|
message = _(9000) # Unexpected error
|
|
|
|
d.ok(_(2), message)
|
2011-03-29 16:53:53 +00:00
|
|
|
|
2010-07-15 19:58:42 +00:00
|
|
|
return False
|
|
|
|
p.close()
|
2010-05-28 02:38:06 +00:00
|
|
|
self.updateTorrents()
|
|
|
|
self.repeater = Repeater(1.0, self.updateTorrents)
|
|
|
|
self.repeater.start()
|
|
|
|
def updateTorrents(self):
|
|
|
|
list = self.getControl(20)
|
|
|
|
torrents = self.transmission.info()
|
|
|
|
for i, torrent in torrents.iteritems():
|
|
|
|
statusline = "[%(status)s] %(down)s down (%(pct).2f%%), %(up)s up (Ratio: %(ratio).2f)" % \
|
|
|
|
{'down': Bytes.format(torrent.downloadedEver), 'pct': torrent.progress, \
|
|
|
|
'up': Bytes.format(torrent.uploadedEver), 'ratio': torrent.ratio, \
|
|
|
|
'status': torrent.status}
|
|
|
|
if torrent.status is 'downloading':
|
|
|
|
statusline += " ETA: %(eta)s" % \
|
|
|
|
{'eta': torrent.eta}
|
|
|
|
if i not in self.list:
|
|
|
|
# Create a new list item
|
|
|
|
l = xbmcgui.ListItem(label=torrent.name, label2=statusline)
|
|
|
|
list.addItem(l)
|
|
|
|
self.list[i] = l
|
|
|
|
else:
|
|
|
|
# Update existing list item
|
|
|
|
l = self.list[i]
|
|
|
|
self.torrents = torrents
|
|
|
|
l.setLabel(torrent.name)
|
|
|
|
l.setLabel2(statusline)
|
|
|
|
l.setProperty('TorrentID', str(i))
|
|
|
|
l.setProperty('TorrentProgress', "%.2ff" % torrent.progress)
|
|
|
|
l.setInfo('torrent', torrent.fields)
|
|
|
|
l.setInfo('video', {'episode': int(torrent.progress)})
|
|
|
|
|
|
|
|
removed = [id for id in self.list.keys() if id not in torrents.keys()]
|
|
|
|
if len(removed) > 0:
|
|
|
|
# Clear torrents from the list that have been removed
|
|
|
|
for id in removed:
|
|
|
|
del self.list[id]
|
|
|
|
list.reset()
|
|
|
|
for id, item in self.list.iteritems():
|
|
|
|
list.addItem(item)
|
2010-06-10 17:10:31 +00:00
|
|
|
|
2010-05-28 02:38:06 +00:00
|
|
|
def onClick(self, controlID):
|
|
|
|
list = self.getControl(20)
|
|
|
|
if (controlID == 11):
|
|
|
|
# Add torrent
|
|
|
|
d = xbmcgui.Dialog()
|
|
|
|
f = d.browse(1, _(0), 'files', '.torrent')
|
|
|
|
self.transmission.add_url(f)
|
|
|
|
if (controlID == 12):
|
|
|
|
# Remove selected torrent
|
|
|
|
item = list.getSelectedItem()
|
|
|
|
if item and xbmcgui.Dialog().yesno(_(0), 'Remove \'%s\'?' % self.torrents[int(item.getProperty('TorrentID'))].name):
|
|
|
|
remove_data = xbmcgui.Dialog().yesno(_(0), 'Remove data as well?')
|
|
|
|
self.transmission.remove(int(item.getProperty('TorrentID')), remove_data)
|
|
|
|
if (controlID == 13):
|
|
|
|
# Stop selected torrent
|
|
|
|
item = list.getSelectedItem()
|
|
|
|
if item:
|
|
|
|
self.transmission.stop(int(item.getProperty('TorrentID')))
|
|
|
|
if (controlID == 14):
|
|
|
|
# Start selected torrent
|
|
|
|
item = list.getSelectedItem()
|
|
|
|
if item:
|
|
|
|
t = int(item.getProperty('TorrentID'))
|
|
|
|
self.transmission.start(int(item.getProperty('TorrentID')))
|
|
|
|
if (controlID == 15):
|
|
|
|
# Stop all torrents
|
|
|
|
self.transmission.stop(self.torrents.keys())
|
|
|
|
if (controlID == 16):
|
|
|
|
# Start all torrents
|
|
|
|
self.transmission.start(self.torrents.keys())
|
|
|
|
if (controlID == 17):
|
|
|
|
# Exit button
|
2011-03-29 03:22:40 +00:00
|
|
|
self.close()
|
2010-05-28 02:38:06 +00:00
|
|
|
if (controlID == 20):
|
|
|
|
# A torrent was chosen, show details
|
|
|
|
item = list.getSelectedItem()
|
2010-07-16 19:36:06 +00:00
|
|
|
w = TorrentInfoGUI("script-Transmission-details.xml",os.getcwd() ,"Default")
|
|
|
|
w.setTorrent(self.transmission, int(item.getProperty('TorrentID')))
|
2010-05-28 02:38:06 +00:00
|
|
|
w.doModal()
|
|
|
|
del w
|
|
|
|
def onFocus(self, controlID):
|
|
|
|
pass
|
|
|
|
|
2010-06-10 17:10:31 +00:00
|
|
|
def onAction( self, action ):
|
|
|
|
if ( action.getButtonCode() in CANCEL_DIALOG ):
|
2011-03-29 03:22:40 +00:00
|
|
|
self.close()
|
|
|
|
def close(self):
|
|
|
|
if self.repeater:
|
|
|
|
self.repeater.stop()
|
|
|
|
super(TransmissionGUI, self).close()
|
|
|
|
|
2010-06-10 17:10:31 +00:00
|
|
|
|
2010-05-28 02:38:06 +00:00
|
|
|
class TorrentInfoGUI(xbmcgui.WindowXMLDialog):
|
|
|
|
def __init__(self, strXMLname, strFallbackPath, strDefaultName, bforeFallback=0):
|
2010-07-16 19:36:06 +00:00
|
|
|
self.transmission = None
|
2010-05-28 02:38:06 +00:00
|
|
|
self.torrent_id = None
|
2010-07-16 19:36:06 +00:00
|
|
|
self.list = {}
|
|
|
|
self.repeater = Repeater(1.0, self.updateTorrent)
|
|
|
|
def setTorrent(self, transmission, t_id):
|
|
|
|
self.transmission = transmission
|
2010-05-28 02:38:06 +00:00
|
|
|
self.torrent_id = t_id
|
2010-07-16 19:36:06 +00:00
|
|
|
self.repeater.start()
|
|
|
|
def updateTorrent(self):
|
|
|
|
pbar = self.getControl(219)
|
|
|
|
list = self.getControl(220)
|
|
|
|
labelName = self.getControl(1)
|
|
|
|
labelStatus = self.getControl(2)
|
|
|
|
torrent = self.transmission.info()[self.torrent_id]
|
|
|
|
files = self.transmission.get_files(self.torrent_id)[self.torrent_id]
|
|
|
|
|
|
|
|
statusline = "[%(status)s] %(down)s down (%(pct).2f%%), %(up)s up (Ratio: %(ratio).2f)" % \
|
|
|
|
{'down': Bytes.format(torrent.downloadedEver), 'pct': torrent.progress, \
|
|
|
|
'up': Bytes.format(torrent.uploadedEver), 'ratio': torrent.ratio, \
|
|
|
|
'status': torrent.status}
|
|
|
|
if torrent.status is 'downloading':
|
|
|
|
statusline += " ETA: %(eta)s" % \
|
|
|
|
{'eta': torrent.eta}
|
|
|
|
|
|
|
|
labelName.setLabel(torrent.name)
|
|
|
|
labelStatus.setLabel(statusline)
|
|
|
|
pbar.setPercent(torrent.progress)
|
|
|
|
|
|
|
|
for i, file in files.iteritems():
|
|
|
|
if i not in self.list:
|
|
|
|
# Create a new list item
|
|
|
|
l = xbmcgui.ListItem(label=file['name'])
|
|
|
|
list.addItem(l)
|
|
|
|
self.list[i] = l
|
|
|
|
else:
|
|
|
|
# Update existing list item
|
|
|
|
l = self.list[i]
|
|
|
|
l.setProperty('Progress', '[%3d%%]' % (file['completed'] * 100 / file['size']))
|
2010-05-28 02:38:06 +00:00
|
|
|
def onInit(self):
|
2010-07-16 19:36:06 +00:00
|
|
|
self.updateTorrent()
|
|
|
|
def close(self):
|
|
|
|
self.repeater.stop()
|
|
|
|
super(TorrentInfoGUI, self).close()
|
2010-05-28 02:38:06 +00:00
|
|
|
def onAction(self, action):
|
2010-07-16 19:36:06 +00:00
|
|
|
if (action.getButtonCode() in CANCEL_DIALOG):
|
2010-05-28 02:38:06 +00:00
|
|
|
self.close()
|
2010-07-16 19:36:06 +00:00
|
|
|
pass
|
2010-05-28 02:38:06 +00:00
|
|
|
def onClick(self, controlID):
|
|
|
|
pass
|
|
|
|
def onFocus(self, controlID):
|
2010-06-10 17:10:31 +00:00
|
|
|
pass
|