plugin.video.torrenter/resources/utorrent/net.py

1339 lines
44 KiB
Python
Raw Normal View History

2015-01-09 14:11:21 +03:00
# -*- coding: utf-8 -*-
import os
import sys
import time
import re
import urllib
import urllib2
import cookielib
import base64
import mimetools
import json
import itertools
2015-01-14 23:24:01 +03:00
from StringIO import StringIO
import gzip
2015-01-09 14:11:21 +03:00
import xbmc
import xbmcgui
import xbmcvfs
os.sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__))))
import dopal.main
__plugin__ = sys.modules["__main__"].__plugin__
__settings__ = sys.modules["__main__"].__settings__
ROOT = sys.modules["__main__"].__root__ # .decode('utf-8').encode(sys.getfilesystemencoding())
userStorageDirectory = __settings__.getSetting("storage")
USERAGENT = "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0"
URL = 'http://torrenter.host.org'
torrentFilesDirectory = 'torrents'
__addonpath__ = __settings__.getAddonInfo('path')
icon = __addonpath__ + '/icon.png'
RE = {
'content-disposition': re.compile('attachment;\sfilename="*([^"\s]+)"|\s')
}
# ################################
#
# HTTP
#
# ################################
class HTTP:
def __init__(self):
self._dirname = xbmc.translatePath('special://temp') # .decode('utf-8').encode('cp1251')
for subdir in ('xbmcup', sys.argv[0].replace('plugin://', '').replace('/', '')):
self._dirname = os.path.join(self._dirname, subdir)
if not xbmcvfs.exists(self._dirname):
xbmcvfs.mkdir(self._dirname)
def fetch(self, request, **kwargs):
self.con, self.fd, self.progress, self.cookies, self.request = None, None, None, None, request
if not isinstance(self.request, HTTPRequest):
self.request = HTTPRequest(url=self.request, **kwargs)
self.response = HTTPResponse(self.request)
# Debug('XBMCup: HTTP: request: ' + str(self.request))
try:
self._opener()
self._fetch()
except Exception, e:
xbmc.log('XBMCup: HTTP: ' + str(e), xbmc.LOGERROR)
if isinstance(e, urllib2.HTTPError):
self.response.code = e.code
self.response.error = e
else:
self.response.code = 200
if self.fd:
self.fd.close()
self.fd = None
if self.con:
self.con.close()
self.con = None
if self.progress:
self.progress.close()
self.progress = None
self.response.time = time.time() - self.response.time
xbmc.log('XBMCup: HTTP: response: ' + str(self.response), xbmc.LOGDEBUG)
return self.response
def _opener(self):
build = [urllib2.HTTPHandler()]
if self.request.redirect:
build.append(urllib2.HTTPRedirectHandler())
if self.request.proxy_host and self.request.proxy_port:
build.append(urllib2.ProxyHandler(
{self.request.proxy_protocol: self.request.proxy_host + ':' + str(self.request.proxy_port)}))
if self.request.proxy_username:
proxy_auth_handler = urllib2.ProxyBasicAuthHandler()
proxy_auth_handler.add_password('realm', 'uri', self.request.proxy_username,
self.request.proxy_password)
build.append(proxy_auth_handler)
if self.request.cookies:
self.request.cookies = os.path.join(self._dirname, self.request.cookies)
self.cookies = cookielib.MozillaCookieJar()
if os.path.isfile(self.request.cookies):
self.cookies.load(self.request.cookies)
build.append(urllib2.HTTPCookieProcessor(self.cookies))
urllib2.install_opener(urllib2.build_opener(*build))
def _fetch(self):
params = {} if self.request.params is None else self.request.params
if self.request.upload:
boundary, upload = self._upload(self.request.upload, params)
req = urllib2.Request(self.request.url)
req.add_data(upload)
else:
if self.request.method == 'POST':
if isinstance(params, dict) or isinstance(params, list):
params = urllib.urlencode(params)
req = urllib2.Request(self.request.url, params)
else:
req = urllib2.Request(self.request.url)
for key, value in self.request.headers.iteritems():
req.add_header(key, value)
if self.request.upload:
req.add_header('Content-type', 'multipart/form-data; boundary=%s' % boundary)
req.add_header('Content-length', len(upload))
if self.request.auth_username and self.request.auth_password:
req.add_header('Authorization', 'Basic %s' % base64.encodestring(
':'.join([self.request.auth_username, self.request.auth_password])).strip())
# self.con = urllib2.urlopen(req, timeout=self.request.timeout)
self.con = urllib2.urlopen(req)
self.response.headers = self._headers(self.con.info())
if self.request.download:
self._download()
else:
2015-01-14 23:24:01 +03:00
if not self.response.headers.get('content-encoding')=='gzip':
self.response.body = self.con.read()
else:
buf = StringIO(self.con.read())
f = gzip.GzipFile(fileobj=buf)
self.response.body = f.read()
2015-01-09 14:11:21 +03:00
if self.request.cookies:
self.cookies.save(self.request.cookies)
def _download(self):
fd = open(self.request.download, 'wb')
if self.request.progress:
self.progress = xbmcgui.DialogProgress()
self.progress.create(u'Download')
bs = 1024 * 8
size = -1
read = 0
name = None
if self.request.progress:
if 'content-length' in self.response.headers:
size = int(self.response.headers['content-length'])
if 'content-disposition' in self.response.headers:
r = RE['content-disposition'].search(self.response.headers['content-disposition'])
if r:
name = urllib.unquote(r.group(1))
while 1:
buf = self.con.read(bs)
if buf == '':
break
read += len(buf)
fd.write(buf)
if self.request.progress:
self.progress.update(*self._progress(read, size, name))
self.response.filename = self.request.download
def _upload(self, upload, params):
res = []
boundary = mimetools.choose_boundary()
part_boundary = '--' + boundary
if params:
for name, value in params.iteritems():
res.append([part_boundary, 'Content-Disposition: form-data; name="%s"' % name, '', value])
if isinstance(upload, dict):
upload = [upload]
for obj in upload:
name = obj.get('name')
filename = obj.get('filename', 'default')
content_type = obj.get('content-type')
try:
body = obj['body'].read()
except AttributeError:
body = obj['body']
if content_type:
res.append([part_boundary,
'Content-Disposition: file; name="%s"; filename="%s"' % (name, urllib.quote(filename)),
'Content-Type: %s' % content_type, '', body])
else:
res.append([part_boundary,
'Content-Disposition: file; name="%s"; filename="%s"' % (name, urllib.quote(filename)), '',
body])
result = list(itertools.chain(*res))
result.append('--' + boundary + '--')
result.append('')
return boundary, '\r\n'.join(result)
def _headers(self, raw):
headers = {}
for line in raw.headers:
pair = line.split(':', 1)
if len(pair) == 2:
tag = pair[0].lower().strip()
value = pair[1].strip()
if tag and value:
headers[tag] = value
return headers
def _progress(self, read, size, name):
res = []
if size < 0:
res.append(1)
else:
res.append(int(float(read) / (float(size) / 100.0)))
if name:
res.append(u'File: ' + name)
if size != -1:
res.append(u'Size: ' + self._human(size))
res.append(u'Load: ' + self._human(read))
return res
def _human(self, size):
human = None
for h, f in (('KB', 1024), ('MB', 1024 * 1024), ('GB', 1024 * 1024 * 1024), ('TB', 1024 * 1024 * 1024 * 1024)):
if size / f > 0:
human = h
factor = f
else:
break
if human is None:
return (u'%10.1f %s' % (size, u'byte')).replace(u'.0', u'')
else:
return u'%10.2f %s' % (float(size) / float(factor), human)
class HTTPRequest:
def __init__(self, url, method='GET', headers=None, cookies=None, params=None, upload=None, download=None,
progress=False, auth_username=None, auth_password=None, proxy_protocol='http', proxy_host=None,
proxy_port=None, proxy_username=None, proxy_password='', timeout=20.0, redirect=True, gzip=False):
if headers is None:
headers = {}
self.url = url
self.method = method
self.headers = headers
self.cookies = cookies
self.params = params
self.upload = upload
self.download = download
self.progress = progress
self.auth_username = auth_username
self.auth_password = auth_password
self.proxy_protocol = proxy_protocol
self.proxy_host = proxy_host
self.proxy_port = proxy_port
self.proxy_username = proxy_username
self.proxy_password = proxy_password
self.timeout = timeout
self.redirect = redirect
self.gzip = gzip
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, ','.join('%s=%r' % i for i in self.__dict__.iteritems()))
class HTTPResponse:
def __init__(self, request):
self.request = request
self.code = None
self.headers = {}
self.error = None
self.body = None
self.filename = None
self.time = time.time()
def __repr__(self):
args = ','.join('%s=%r' % i for i in self.__dict__.iteritems() if i[0] != 'body')
if self.body:
args += ',body=<data>'
else:
args += ',body=None'
return '%s(%s)' % (self.__class__.__name__, args)
class UTorrent:
def config(self, login, password, host, port, url=None):
self.login = login
self.password = password
self.url = 'http://' + host
if port:
self.url += ':' + str(port)
self.url += '/gui/'
self.http = HTTP()
self.re = {
'cookie': re.compile('GUID=([^;]+);'),
'token': re.compile("<div[^>]+id='token'[^>]*>([^<]+)</div>")
}
def listdirs(self):
obj = self.action('action=list-dirs')
if not obj:
return False
items = []
clean = []
for r in obj.get('download-dirs', []):
available = int(r['available'])
if available > 1024:
memory = '[%s GB]' % str(available / 1024)
else:
memory = '[%s MB]' % str(available)
items.append(r['path'] + ' ' + memory)
path = r['path']
if path[len(path) - 1:] != '\\': path += '\\'
clean.append(path)
return items, clean
def list(self):
obj = self.action('list=1')
if not obj:
return False
res = []
for r in obj.get('torrents', []):
res.append({
'id': r[0],
'status': self.get_status(r[1], r[4] / 10),
'name': r[2],
'size': r[3],
'progress': r[4] / 10,
'download': r[5],
'upload': r[6],
'ratio': float(r[7]) / 1000,
'upspeed': r[8],
'downspeed': r[9],
'eta': r[10],
'peer': r[12] + r[14],
'leach': r[12],
'seed': r[14],
'add': r[23],
'finish': r[24],
'dir': r[26]
})
return res
def listfiles(self, id):
obj = self.action('action=getfiles&hash=' + id)
if not obj:
return None
res = []
i = -1
for x in obj['files'][1]:
i += 1
if x[1] >= 1024 * 1024 * 1024:
size = str(x[1] / (1024 * 1024 * 1024)) + 'GB'
elif x[1] >= 1024 * 1024:
size = str(x[1] / (1024 * 1024)) + 'MB'
elif x[1] >= 1024:
size = str(x[1] / 1024) + 'KB'
else:
size = str(x[1]) + 'B'
res.append((x[0], (int(x[2] * 100 / x[1])), i, size))
return res
def dirid(self, dirname):
if __settings__.getSetting("torrent_save") == '0':
dirid = self.listdirs()[1].index(dirname)
else:
dirname = __settings__.getSetting("torrent_dir")
clean = self.listdirs()[1]
try:
dirid = clean.index(dirname)
except:
dirid = 0
return dirid
def add(self, torrent, dirname):
dirid = self.dirid(dirname)
res = self.action('action=add-file&download_dir=' + str(dirid),
{'name': 'torrent_file', 'download_dir': str(dirid),
'content-type': 'application/x-bittorrent', 'body': torrent})
return True if res else None
def add_url(self, torrent, dirname):
dirid = self.dirid(dirname)
res = self.action('action=add-url&download_dir=' + str(dirid) + '&s=' + urllib.quote(torrent))
return True if res else None
def setprio(self, id, ind):
obj = self.action('action=getfiles&hash=' + id)
if not obj or ind == None:
return None
i = -1
for x in obj['files'][1]:
i += 1
if x[3] == 2: self.setprio_simple(id, '0', i)
res = self.setprio_simple(id, '3', ind)
return True if res else None
def setprio_simple(self, id, prio, ind):
obj = self.action('action=setprio&hash=%s&p=%s&f=%s' % (id, prio, ind))
if not obj or ind == None:
return None
return True if obj else None
2015-01-15 22:53:23 +03:00
def setprio_simple_multi(self, menu):
for hash, action, ind in menu:
self.setprio_simple(hash, action, ind)
2015-01-09 14:11:21 +03:00
def delete(self, id):
pass
def action(self, uri, upload=None):
cookie, token = self.get_token()
if not cookie:
return None
req = HTTPRequest(self.url + '?' + uri + '&token=' + token, headers={'Cookie': cookie},
auth_username=self.login, auth_password=self.password)
if upload:
req.upload = upload
response = self.http.fetch(req)
if response.error:
return None
else:
try:
obj = json.loads(response.body)
except:
return None
else:
return obj
def action_simple(self, action, id):
obj = self.action('action=%s&hash=%s' % (action, id))
return True if obj else None
def get_token(self):
response = self.http.fetch(self.url + 'token.html', auth_username=self.login, auth_password=self.password)
if response.error:
return None, None
r = self.re['cookie'].search(response.headers.get('set-cookie', ''))
if r:
cookie = r.group(1).strip()
r = self.re['token'].search(response.body)
if r:
token = r.group(1).strip()
if cookie and token:
return 'GUID=' + cookie, token
return None, None
def get_status(self, status, progress):
mapping = {
'error': 'stopped',
'paused': 'stopped',
'forcepaused': 'stopped',
'stopped': 'stopped',
'notloaded': 'check_pending',
'checked': 'checking',
'queued': 'download_pending',
'downloading': 'downloading',
'forcedownloading': 'downloading',
'finished': 'seed_pending',
'queuedseed': 'seed_pending',
'seeding': 'seeding',
'forceseeding': 'seeding'
}
return mapping[self.get_status_raw(status, progress)]
def get_status_raw(self, status, progress):
"""
Return status: notloaded, error, checked,
paused, forcepaused,
queued,
downloading,
finished, forcedownloading
queuedseed, seeding, forceseeding
"""
started = bool(status & 1)
checking = bool(status & 2)
start_after_check = bool(status & 4)
checked = bool(status & 8)
error = bool(status & 16)
paused = bool(status & 32)
queued = bool(status & 64)
loaded = bool(status & 128)
if not loaded:
return 'notloaded'
if error:
return 'error'
if checking:
return 'checked'
if paused:
if queued:
return 'paused'
else:
return 'forcepaused'
if progress == 100:
if queued:
if started:
return 'seeding'
else:
return 'queuedseed'
else:
if started:
return 'forceseeding'
else:
return 'finished'
else:
if queued:
if started:
return 'downloading'
else:
return 'queued'
else:
if started:
return 'forcedownloading'
return 'stopped'
class Transmission:
def config(self, login, password, host, port, url):
self.login = login
self.password = password
self.url = 'http://' + host
if port:
self.url += ':' + str(port)
if url[0] != '/':
url = '/' + url
if url[-1] != '/':
url += '/'
self.url += url
self.http = HTTP()
self.token = '0'
def list(self):
obj = self.action({'method': 'torrent-get', 'arguments': {
'fields': ['id', 'status', 'name', 'totalSize', 'sizeWhenDone', 'leftUntilDone', 'downloadedEver',
'uploadedEver', 'uploadRatio', 'rateUpload', 'rateDownload', 'eta', 'peersConnected',
'peersFrom',
'addedDate', 'doneDate', 'downloadDir', 'fileStats', 'peersConnected', 'peersGettingFromUs',
'peersSendingToUs']}})
if obj is None:
return False
res = []
for r in obj['arguments'].get('torrents', []):
if len(r['fileStats']) > 1:
res.append({
'id': str(r['id']),
'status': self.get_status(r['status']),
'name': r['name'],
'size': r['totalSize'],
'progress': 0 if not r['sizeWhenDone'] else int(
100.0 * float(r['sizeWhenDone'] - r['leftUntilDone']) / float(r['sizeWhenDone'])),
'download': r['downloadedEver'],
'upload': r['uploadedEver'],
'upspeed': r['rateUpload'],
'downspeed': r['rateDownload'],
'ratio': float(r['uploadRatio']),
'eta': r['eta'],
'peer': r['peersConnected'],
'seed': r['peersSendingToUs'],
'leech': r['peersGettingFromUs'],
'add': r['addedDate'],
'finish': r['doneDate'],
'dir': os.path.join(r['downloadDir'], r['name'])
})
else:
res.append({
'id': str(r['id']),
'status': self.get_status(r['status']),
'name': r['name'],
'size': r['totalSize'],
'progress': 0 if not r['sizeWhenDone'] else int(
100.0 * float(r['sizeWhenDone'] - r['leftUntilDone']) / float(r['sizeWhenDone'])),
'download': r['downloadedEver'],
'upload': r['uploadedEver'],
'upspeed': r['rateUpload'],
'downspeed': r['rateDownload'],
'ratio': float(r['uploadRatio']),
'eta': r['eta'],
'peer': r['peersConnected'],
'seed': r['peersSendingToUs'],
'leech': r['peersGettingFromUs'],
'add': r['addedDate'],
'finish': r['doneDate'],
'dir': r['downloadDir']
})
return res
def listdirs(self):
obj = self.action({'method': 'session-get'})
if obj is None:
return False
res = [obj['arguments'].get('download-dir')]
# Debug('[Transmission][listdirs]: %s' % (str(res)))
return res, res
def listfiles(self, id):
obj = self.action({"method": "torrent-get", "arguments": {
"fields": ["id", "activityDate", "corruptEver", "desiredAvailable", "downloadedEver", "fileStats",
"haveUnchecked", "haveValid", "peers", "startDate", "trackerStats", "comment", "creator",
"dateCreated", "files", "hashString", "isPrivate", "pieceCount", "pieceSize"],
"ids": [int(id)]}})['arguments']['torrents'][0]
if obj is None:
return None
res = []
i = -1
lenf = len(obj['files'])
for x in obj['files']:
i += 1
if x['length'] >= 1024 * 1024 * 1024:
size = str(x['length'] / (1024 * 1024 * 1024)) + 'GB'
elif x['length'] >= 1024 * 1024:
size = str(x['length'] / (1024 * 1024)) + 'MB'
elif x['length'] >= 1024:
size = str(x['length'] / 1024) + 'KB'
else:
size = str(x['length']) + 'B'
if lenf > 1:
x['name'] = x['name'].strip('/\\').replace('\\', '/')
x['name'] = x['name'].replace(x['name'].split('/')[0] + '/', '')
res.append([x['name'], (int(x['bytesCompleted'] * 100 / x['length'])), i, size])
return res
def add(self, torrent, dirname):
if self.action({'method': 'torrent-add',
'arguments': {'download-dir': dirname, 'metainfo': base64.b64encode(torrent)}}) is None:
return None
return True
def add_url(self, torrent, dirname):
if self.action({'method': 'torrent-add', 'arguments': {'download-dir': dirname, 'filename': torrent}}) is None:
return None
return True
def delete(self, id):
pass
def setprio(self, id, ind):
obj = self.action({"method": "torrent-get", "arguments": {"fields": ["id", "fileStats", "files"],
"ids": [int(id)]}})['arguments']['torrents'][0]
if not obj or ind == None:
return None
inds = []
i = -1
for x in obj['fileStats']:
i += 1
if x['wanted'] == True and x['priority'] == 0:
inds.append(i)
if len(inds) > 1: self.action(
{"method": "torrent-set", "arguments": {"ids": [int(id)], "priority-high": inds, "files-unwanted": inds}})
res = self.setprio_simple(id, '3', ind)
# self.action_simple('start',id)
return True if res else None
def setprio_simple(self, id, prio, ind):
if ind == None:
return None
res = None
inds = [int(ind)]
if prio == '3':
res = self.action(
{"method": "torrent-set", "arguments": {"ids": [int(id)], "priority-high": inds, "files-wanted": inds}})
elif prio == '0':
res = self.action({"method": "torrent-set",
"arguments": {"ids": [int(id)], "priority-high": inds, "files-unwanted": inds}})
return True if res else None
2015-01-15 22:53:23 +03:00
def setprio_simple_multi(self, menu):
id=menu[0][0]
prio=menu[0][1]
inds=[]
for hash, action, ind in menu:
inds.append(int(ind))
if prio == '3':
res = self.action(
{"method": "torrent-set", "arguments": {"ids": [int(id)], "priority-high": inds, "files-wanted": inds}})
elif prio == '0':
res = self.action({"method": "torrent-set",
"arguments": {"ids": [int(id)], "priority-high": inds, "files-unwanted": inds}})
return True if res else None
2015-01-09 14:11:21 +03:00
def action(self, request):
try:
jsobj = json.dumps(request)
except:
return None
else:
while True:
# пробуем сделать запрос
if self.login:
response = self.http.fetch(self.url + 'rpc/', method='POST', params=jsobj,
headers={'X-Transmission-Session-Id': self.token,
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'charset=UTF-8'}, auth_username=self.login,
auth_password=self.password)
else:
response = self.http.fetch(self.url + 'rpc/', method='POST', params=jsobj,
headers={'X-Transmission-Session-Id': self.token,
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'charset=UTF-8'})
if response.error:
# требуется авторизация?
if response.code == 401:
if not self.get_auth():
return None
# требуется новый токен?
elif response.code == 409:
if not self.get_token(response.error):
return None
else:
return None
else:
try:
obj = json.loads(response.body)
except:
return None
else:
return obj
def action_simple(self, action, id):
actions = {'start': {"method": "torrent-start", "arguments": {"ids": [int(id)]}},
'stop': {"method": "torrent-stop", "arguments": {"ids": [int(id)]}},
'remove': {"method": "torrent-remove", "arguments": {"ids": [int(id)], "delete-local-data": False}},
'removedata': {"method": "torrent-remove",
"arguments": {"ids": [int(id)], "delete-local-data": True}}}
obj = self.action(actions[action])
return True if obj else None
def get_auth(self):
response = self.http.fetch(self.url, auth_username=self.login, auth_password=self.password)
if response.error:
if response.code == 409:
return self.get_token(response.error)
return False
def get_token(self, error):
token = error.headers.get('x-transmission-session-id')
if not token:
return False
self.token = token
return True
def get_status(self, code):
mapping = {
0: 'stopped',
1: 'check_pending',
2: 'checking',
3: 'download_pending',
4: 'downloading',
5: 'seed_pending',
6: 'seeding'
}
return mapping[code]
2015-01-14 23:24:01 +03:00
class Deluge:
def config(self, login, password, host, port, url):
self.login = login
self.password = password
self.url = ['http://','https://'][int(url)] + host
if port:
self.url += ':' + str(port)
self.http = HTTP()
2015-01-15 22:53:23 +03:00
def get_info(self):
obj = self.action({"method":"web.update_ui",
"params":[[],{}],"id":1})
return obj
2015-01-14 23:24:01 +03:00
def list(self):
2015-01-15 22:53:23 +03:00
obj=self.get_info()
2015-01-14 23:24:01 +03:00
if obj is None:
return False
res = []
if len(obj['result'].get('torrents'))>0:
for k in obj['result'].get('torrents').keys():
r=obj['result']['torrents'][k]
2015-01-15 22:53:23 +03:00
add={
2015-01-14 23:24:01 +03:00
'id': str(k),
'status': self.get_status(r['state']),
'name': r['name'],
'size': r['total_wanted'],
'progress': round(r['progress'], 2),
'download': r['total_done'],
'upload': r['total_uploaded'],
'upspeed': r['upload_payload_rate'],
'downspeed': r['download_payload_rate'],
'ratio': round(r['ratio'], 2),
'eta': r['eta'],
'peer': r['total_peers'],
'seed': r['num_seeds'],
'leech': r['num_peers'],
'add': r['time_added'],
'dir': r['save_path']
2015-01-15 22:53:23 +03:00
}
if len(r['files'])>1: add['dir']=os.path.join(r['save_path'],r['name'])
res.append(add)
2015-01-14 23:24:01 +03:00
return res
def listdirs(self):
2015-01-15 22:53:23 +03:00
obj = self.action({"method":"core.get_config","params":[],"id":5})
2015-01-14 23:24:01 +03:00
if obj is None:
return False
2015-01-24 23:24:15 +03:00
try:
res = [obj['result'].get('download_location')]
except:
res=[None]
2015-01-14 23:24:01 +03:00
return res, res
def listfiles(self, id):
2015-01-15 22:53:23 +03:00
obj = self.get_info()
2015-01-14 23:24:01 +03:00
if obj is None:
return None
res = []
2015-01-15 22:53:23 +03:00
obj=obj['result']['torrents'][id]
#print str(obj)
if len(obj['files'])==1:
strip_path=None
else:
strip_path=obj['name']
2015-01-14 23:24:01 +03:00
2015-01-15 22:53:23 +03:00
for x in obj['files']:
2015-01-14 23:24:01 +03:00
if x['size'] >= 1024 * 1024 * 1024:
size = str(x['size'] / (1024 * 1024 * 1024)) + 'GB'
elif x['size'] >= 1024 * 1024:
size = str(x['size'] / (1024 * 1024)) + 'MB'
elif x['size'] >= 1024:
size = str(x['size'] / 1024) + 'KB'
else:
size = str(x['size']) + 'B'
2015-01-15 22:53:23 +03:00
if strip_path:
path=x['path'].lstrip(strip_path).lstrip('/')
else:
path=x['path']
if x.get('progress'):
percent=int(x['progress']*100)
else:percent=0
2015-01-14 23:24:01 +03:00
2015-01-15 22:53:23 +03:00
res.append([path, percent, x['index'], size])
return res
def get_prio(self, id):
obj = self.get_info()
if obj is None:
return None
res=obj['result']['torrents'][id]['file_priorities']
return res
2015-01-14 23:24:01 +03:00
def add(self, torrent, dirname):
2015-01-15 22:53:23 +03:00
torrentFile=os.path.join(self.http._dirname,'deluge.torrent')
if self.action({'method': 'core.add_torrent_file',
'params': [torrentFile,
base64.b64encode(torrent), {"download_path": dirname}],"id":3}) is None:
2015-01-14 23:24:01 +03:00
return None
return True
def add_url(self, torrent, dirname):
2015-01-15 22:53:23 +03:00
if re.match("^magnet\:.+$", torrent):
if self.action({'method': 'core.add_torrent_magnet', 'params':[torrent,
{'download_path': dirname}],"id":3}) is None:
return None
else:
if self.action({"method": "core.add_torrent_url", "params":[torrent, {'download_path': dirname}],"id":3}) is None:
return None
2015-01-14 23:24:01 +03:00
return True
def delete(self, id):
pass
def setprio(self, id, ind):
i = -1
2015-01-15 22:53:23 +03:00
prios=self.get_prio(id)
2015-01-14 23:24:01 +03:00
2015-01-15 22:53:23 +03:00
for p in prios:
i=i+1
if p==1:
prios.pop(i)
prios.insert(i,0)
2015-01-14 23:24:01 +03:00
2015-01-15 22:53:23 +03:00
prios.pop(int(ind))
prios.insert(int(ind),7)
2015-01-14 23:24:01 +03:00
2015-01-15 22:53:23 +03:00
if self.action({"method": "core.set_torrent_file_priorities", "params":[id, prios],"id":6}) is None:
return None
2015-01-14 23:24:01 +03:00
2015-01-15 22:53:23 +03:00
return True
2015-01-14 23:24:01 +03:00
def setprio_simple(self, id, prio, ind):
2015-01-15 22:53:23 +03:00
prios=self.get_prio(id)
if ind!=None:
prios.pop(int(ind))
if prio == '3':
prios.insert(int(ind),7)
elif prio == '0':
prios.insert(int(ind),0)
if self.action({"method": "core.set_torrent_file_priorities", "params":[id, prios],"id":6}) is None:
2015-01-14 23:24:01 +03:00
return None
2015-01-15 22:53:23 +03:00
return True
2015-01-14 23:24:01 +03:00
2015-01-15 22:53:23 +03:00
def setprio_simple_multi(self, menu):
id=menu[0][0]
prios=self.get_prio(id)
2015-01-14 23:24:01 +03:00
2015-01-15 22:53:23 +03:00
for hash, action, ind in menu:
prios.pop(int(ind))
if action == '3':
prios.insert(int(ind),7)
elif action == '0':
prios.insert(int(ind),0)
2015-01-14 23:24:01 +03:00
2015-01-15 22:53:23 +03:00
if self.action({"method": "core.set_torrent_file_priorities", "params":[id, prios],"id":6}) is None:
return None
2015-01-14 23:24:01 +03:00
def action(self, request):
cookie = self.get_auth()
if not cookie:
return None
try:
jsobj = json.dumps(request)
except:
return None
else:
2015-01-15 22:53:23 +03:00
response = self.http.fetch(self.url + '/json', method='POST', params=jsobj,
headers={'X-Requested-With': 'XMLHttpRequest', 'Cookie': cookie,
'Content-Type': 'application/json; charset=UTF-8'})
2015-01-14 23:24:01 +03:00
2015-01-15 22:53:23 +03:00
if response.error:
return None
2015-01-14 23:24:01 +03:00
2015-01-15 22:53:23 +03:00
else:
try:
obj = json.loads(response.body)
except:
2015-01-14 23:24:01 +03:00
return None
else:
2015-01-15 22:53:23 +03:00
return obj
2015-01-14 23:24:01 +03:00
def action_simple(self, action, id):
2015-01-15 22:53:23 +03:00
actions = {'start': {"method":"core.resume_torrent","params":[[id]],"id":4},
'stop': {"method":"core.pause_torrent","params":[[id]],"id":4},
'remove': {"method":"core.remove_torrent","params":[id, False],"id":4},
'removedata': {"method":"core.remove_torrent", "params":[id, True],"id":4}}
2015-01-14 23:24:01 +03:00
obj = self.action(actions[action])
return True if obj else None
def get_auth(self):
params=json.dumps({"method":"auth.login","params":[self.password],"id":0})
response = self.http.fetch(self.url + '/json', method='POST', params=params, gzip=True,
headers={'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json; charset=UTF-8'})
if response.error:
return None
auth=json.loads(response.body)
if auth["result"]==False:
return False
else:
r = re.compile('_session_id=([^;]+);').search(response.headers.get('set-cookie', ''))
if r:
cookie = r.group(1).strip()
return '_session_id=' + cookie
def get_status(self, code):
mapping = {
'Queued': 'stopped',
2015-01-15 22:53:23 +03:00
'Error': 'stopped',
2015-01-14 23:24:01 +03:00
'Checking': 'checking',
2015-01-15 22:53:23 +03:00
'Paused': 'seed_pending',
2015-01-14 23:24:01 +03:00
'Downloading': 'downloading',
'Active': 'seed_pending',
'Seeding': 'seeding'
}
return mapping[code]
2015-01-09 14:11:21 +03:00
class Vuze:
def config(self, login, password, host, port, url):
self.login = login
self.password = password
self.connection = dopal.main.make_connection(host=host, port=port, user=login, password=password)
try:
self.interface = self.connection.getPluginInterface()
self.downloads = self.interface.getDownloadManager().getDownloads()
except:
self.downloads = False
def list(self):
if self.downloads == False:
return self.downloads
i = -1
res = []
for r in self.downloads:
i += 1
res.append({
'id': str(i),
'status': self.get_status(int(getattr(r, 'state'))),
'name': getattr(getattr(r, 'torrent'), 'name'),
'size': getattr(getattr(r, 'torrent'), 'size'),
'progress': round(
float(long(r.stats.downloaded) + 1 / (long(r.stats.downloaded) + long(r.stats.remaining) + 1)),
4) * 100,
'download': float(getattr(getattr(r, 'stats'), 'downloaded')),
'upload': getattr(getattr(r, 'stats'), 'uploaded'),
# 'upspeed': r['rateUpload'],
#'downspeed': r['rateDownload'],
'ratio': float(r.stats.share_ratio) / 1000,
'eta': getattr(getattr(r, 'stats'), 'eta'),
'peer': getattr(getattr(r, 'scrape_result'), 'non_seed_count') + getattr(getattr(r, 'scrape_result'),
'seed_count'),
'seed': getattr(getattr(r, 'scrape_result'), 'seed_count'),
'leech': getattr(getattr(r, 'scrape_result'), 'non_seed_count'),
'add': getattr(r, 'creation_time'),
'finish': getattr(r, 'creation_time') + getattr(getattr(r, 'stats'), 'seconds_downloading'),
'dir': getattr(r, 'save_path')
})
return res
def listdirs(self):
res = []
return res, res
def listfiles(self, id):
obj = self.downloads[int(id)].getDiskManagerFileInfo()
if obj is None:
return None
res = []
i = -1
for x in obj:
i += 1
if long(x.length) >= 1024 * 1024 * 1024:
size = str(long(x.length) / (1024 * 1024 * 1024)) + 'GB'
elif long(x.length) >= 1024 * 1024:
size = str(long(x.length) / (1024 * 1024)) + 'MB'
elif x.length >= 1024:
size = str(long(x.length) / 1024) + 'KB'
else:
size = str(long(x.length)) + 'B'
if '\\' in x.file:
title = x.file.split('\\')[-1]
elif '/' in x.file:
title = x.file.split('/')[-1]
else:
title = x.file
res.append([title, (long(x.downloaded * 100 / long(x.length))), i, size])
return res
def add(self, torrent, dirname):
torrent = self.interface.getTorrentManager().createFromBEncodedData(torrent)
obj = self.interface.getDownloadManager().addDownload(torrent)
return True if obj else None
def add_url(self, torrent, dirname):
obj = self.interface.getDownloadManager().addDownload(torrent)
return True if obj else None
def delete(self, id):
pass
def setprio(self, id, ind):
self.setprioobj = self.downloads[int(id)].getDiskManagerFileInfo()
# -1 low, 0 normal, 1 high
if not self.setprioobj or ind == None:
return None
i = -1
for x in self.setprioobj:
i += 1
if not x.isPriority(): self.setprio_simple_vuze(id, i, skip=True, prio=-1)
res = self.setprio_simple_vuze(id, ind, skip=False, prio=1)
return True if res else None
def setprio_simple(self, id, prio, ind):
if ind == None:
return None
res = None
if prio == '0':
res = self.setprio_simple_vuze(id, ind, skip=True, prio=-1)
elif prio == '3':
res = self.setprio_simple_vuze(id, ind, skip=False, prio=1)
def setprio_simple_vuze(self, id, ind, skip=None, prio=None):
obj = None
self.setprioobj = self.downloads[int(id)].getDiskManagerFileInfo()
if prio != None:
obj = self.setprioobj[int(ind)].setNumericPriority(prio)
if skip != None:
obj = self.setprioobj[int(ind)].setSkipped(skip)
if not obj or ind == None:
return None
time.sleep(0.1)
return True if obj else None
2015-01-15 22:53:23 +03:00
def setprio_simple_multi(self, menu):
for hash, action, ind in menu:
self.setprio_simple(hash, action, ind)
2015-01-09 14:11:21 +03:00
def action_simple(self, action, id):
torrent = self.downloads[int(id)]
obj = None
if action == 'start':
obj = torrent.restart()
if action == 'stop':
obj = torrent.stopDownload()
if action == 'remove':
obj = torrent.remove()
if action == 'removedata':
obj = torrent.remove(True, True)
return True if obj else None
def get_status(self, status):
mapping = ['stopped', 'download_pending', 'download_pending', 'download_pending', 'downloading', 'seeding',
'seed_pending', 'stopped', 'stopped', 'download_pending']
return mapping[status]
class Download():
def __init__(self):
self.handle()
def handle(self):
config = self.get_torrent_client()
if self.client == 'utorrent':
self.client = UTorrent()
elif self.client == 'transmission':
self.client = Transmission()
elif self.client == 'vuze':
self.client = Vuze()
2015-01-14 23:24:01 +03:00
elif self.client == 'deluge':
self.client = Deluge()
2015-01-09 14:11:21 +03:00
self.client.config(host=config['host'], port=config['port'], login=config['login'], password=config['password'],
url=config['url'])
# print(self.client.list())
return True
def get_torrent_client(self):
self.setting = __settings__
client = self.setting.getSetting("torrent")
config = {}
if client == '0':
self.client = 'utorrent'
config = {
'host': self.setting.getSetting("torrent_utorrent_host"),
'port': self.setting.getSetting("torrent_utorrent_port"),
'url': '',
'login': self.setting.getSetting("torrent_utorrent_login"),
'password': self.setting.getSetting("torrent_utorrent_password")
}
elif client == '1':
self.client = 'transmission'
config = {
'host': self.setting.getSetting("torrent_transmission_host"),
'port': self.setting.getSetting("torrent_transmission_port"),
'url': self.setting.getSetting("torrent_transmission_url"),
'login': self.setting.getSetting("torrent_transmission_login"),
'password': self.setting.getSetting("torrent_transmission_password")
}
elif client == '2':
self.client = 'vuze'
config = {
'host': self.setting.getSetting("torrent_vuze_host"),
'port': self.setting.getSetting("torrent_vuze_port"),
'url': '',
'login': self.setting.getSetting("torrent_vuze_login"),
'password': self.setting.getSetting("torrent_vuze_password")
}
2015-01-14 23:24:01 +03:00
elif client == '3':
self.client = 'deluge'
config = {
'host': self.setting.getSetting("torrent_deluge_host"),
'port': self.setting.getSetting("torrent_deluge_port"),
'url': self.setting.getSetting("torrent_deluge_url"),
'login': '',
'password': self.setting.getSetting("torrent_deluge_password")
}
2015-01-09 14:11:21 +03:00
return config
def add(self, torrent, dirname):
return self.client.add(torrent, dirname)
def add_url(self, torrent, dirname):
return self.client.add_url(torrent, dirname)
def list(self):
return self.client.list()
def listdirs(self):
return self.client.listdirs()
def listfiles(self, id):
return self.client.listfiles(id)
def delete(self, id):
return self.client.delete(id)
def setprio(self, id, ind):
return self.client.setprio(id, ind)
def setprio_simple(self, id, prio, ind):
# Debug('[setprio_simple] '+str((id, prio, ind)))
return self.client.setprio_simple(id, prio, ind)
2015-01-15 22:53:23 +03:00
def setprio_simple_multi(self, prio_list):
return self.client.setprio_simple_multi(prio_list)
2015-01-09 14:11:21 +03:00
def action_simple(self, action, id):
return self.client.action_simple(action, id)