test update
parent
652c756201
commit
ffad6b76e4
|
@ -1,3 +1,2 @@
|
|||
.idea/
|
||||
*.py[cod]
|
||||
bin/
|
|
@ -0,0 +1,25 @@
|
|||
#-*- coding: utf-8 -*-
|
||||
'''
|
||||
Torrenter v2 plugin for XBMC/Kodi
|
||||
Copyright (C) 2015 srg70, RussakHH, DiMartino
|
||||
'''
|
||||
|
||||
from functions import *
|
||||
import xbmc, xbmcaddon
|
||||
import sys
|
||||
import os
|
||||
|
||||
__settings__ = xbmcaddon.Addon(id='script.module.libtorrent')
|
||||
__version__ = __settings__.getAddonInfo('version')
|
||||
__plugin__ = __settings__.getAddonInfo('name') + " v." + __version__
|
||||
|
||||
lm=LibraryManager(dest_path, platform)
|
||||
if not lm.check_exist():
|
||||
ok=lm.download()
|
||||
xbmc.sleep(2000)
|
||||
|
||||
|
||||
if __settings__.getSetting('plugin_name')!=__plugin__:
|
||||
__settings__.setSetting('plugin_name', __plugin__)
|
||||
lm.update()
|
||||
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,66 @@
|
|||
#import sys
|
||||
import os
|
||||
import xbmc, xbmcgui, xbmcvfs, xbmcaddon
|
||||
from net import HTTP
|
||||
|
||||
__libbaseurl__ = "https://github.com/DiMartinoXBMC/script.module.torrent2http/tree/master/bin"
|
||||
__settings__ = xbmcaddon.Addon(id='script.module.torrent2http')
|
||||
__version__ = __settings__.getAddonInfo('version')
|
||||
__plugin__ = __settings__.getAddonInfo('name') + " v." + __version__
|
||||
|
||||
def get_libname(platform):
|
||||
return ["torrent2http" + (".exe" if 'windows' in platform else "")]
|
||||
|
||||
def log(msg):
|
||||
try:
|
||||
xbmc.log("### [%s]: %s" % (__plugin__,msg,), level=xbmc.LOGNOTICE )
|
||||
except UnicodeEncodeError:
|
||||
xbmc.log("### [%s]: %s" % (__plugin__,msg.encode("utf-8", "ignore"),), level=xbmc.LOGNOTICE )
|
||||
except:
|
||||
xbmc.log("### [%s]: %s" % (__plugin__,'ERROR LOG',), level=xbmc.LOGNOTICE )
|
||||
|
||||
def getSettingAsBool(setting):
|
||||
return __settings__.getSetting(setting).lower() == "true"
|
||||
|
||||
class LibraryManager():
|
||||
def __init__(self, dest_path, platform):
|
||||
self.dest_path = dest_path
|
||||
self.platform = platform
|
||||
self.root=os.path.dirname(__file__)
|
||||
|
||||
def check_update(self):
|
||||
need_update=False
|
||||
if __settings__.getSetting('plugin_name')!=__plugin__:
|
||||
__settings__.setSetting('plugin_name', __plugin__)
|
||||
for libname in get_libname(self.platform):
|
||||
self.libpath = os.path.join(self.dest_path, libname)
|
||||
self.sizepath=os.path.join(self.root, self.platform, libname+'.size.txt')
|
||||
size=str(os.path.getsize(self.libpath))
|
||||
size_old=open( self.sizepath, "r" ).read()
|
||||
if size_old!=size:
|
||||
need_update=True
|
||||
return need_update
|
||||
|
||||
def update(self):
|
||||
if self.check_update():
|
||||
for libname in get_libname(self.platform):
|
||||
self.libpath = os.path.join(self.dest_path, libname)
|
||||
xbmcvfs.delete(self.libpath)
|
||||
self.download()
|
||||
|
||||
def download(self):
|
||||
xbmcvfs.mkdirs(self.dest_path)
|
||||
for libname in get_libname(self.platform):
|
||||
dest = os.path.join(self.dest_path, libname)
|
||||
log("try to fetch %s" % libname)
|
||||
url = "%s/%s/%s.zip" % (__libbaseurl__, self.platform, libname)
|
||||
try:
|
||||
self.http = HTTP()
|
||||
self.http.fetch(url, download=dest + ".zip", progress=True)
|
||||
log("%s -> %s" % (url, dest))
|
||||
xbmc.executebuiltin('XBMC.Extract("%s.zip","%s")' % (dest, self.dest_path), True)
|
||||
xbmcvfs.delete(dest + ".zip")
|
||||
except:
|
||||
text = 'Failed download %s!' % libname
|
||||
xbmc.executebuiltin("XBMC.Notification(%s,%s,%s)" % (__plugin__,text,750))
|
||||
return True
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,297 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import urllib
|
||||
import urllib2
|
||||
import cookielib
|
||||
import base64
|
||||
import mimetools
|
||||
import itertools
|
||||
|
||||
import xbmc
|
||||
import xbmcgui
|
||||
import xbmcvfs
|
||||
|
||||
RE = {
|
||||
'content-disposition': re.compile('attachment;\sfilename="*([^"\s]+)"|\s')
|
||||
}
|
||||
|
||||
# ################################
|
||||
#
|
||||
# HTTP
|
||||
#
|
||||
# ################################
|
||||
|
||||
class HTTP:
|
||||
def __init__(self):
|
||||
self._dirname = xbmc.translatePath('special://temp')
|
||||
for subdir in ('xbmcup', 'script.module.libtorrent'):
|
||||
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)
|
||||
|
||||
xbmc.log('XBMCup: HTTP: request: ' + str(self.request), xbmc.LOGDEBUG)
|
||||
|
||||
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:
|
||||
self.response.body = self.con.read()
|
||||
|
||||
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)
|
|
@ -0,0 +1,63 @@
|
|||
#-*- coding: utf-8 -*-
|
||||
'''
|
||||
Torrenter v2 plugin for XBMC/Kodi
|
||||
Copyright (C) 2015 srg70, RussakHH, DiMartino
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
def get_libname(platform):
|
||||
return ["torrent2http" + (".exe" if 'windows' in platform else "")]
|
||||
|
||||
class Public:
|
||||
def __init__( self ):
|
||||
self.platforms=[]
|
||||
self.root=os.path.dirname(__file__)
|
||||
for dir in os.listdir(self.root):
|
||||
if os.path.isdir(os.path.join(self.root,dir)):
|
||||
self.platforms.append(dir)
|
||||
self._generate_size_file()
|
||||
|
||||
def _generate_size_file( self ):
|
||||
for platform in self.platforms:
|
||||
for libname in get_libname(platform):
|
||||
self.libname=libname
|
||||
self.platform=platform
|
||||
self.libdir = os.path.join(self.root, self.platform)
|
||||
self.libpath = os.path.join(self.libdir, self.libname)
|
||||
self.sizepath=self.libpath+'.size.txt'
|
||||
self.zipname=self.libname+'.zip'
|
||||
zippath=os.path.join(self.libdir, self.zipname)
|
||||
system=platform+'/'
|
||||
if os.path.exists(self.libpath):
|
||||
if not os.path.exists(self.sizepath):
|
||||
print system+self.libname+' NO SIZE'
|
||||
self._makezip()
|
||||
elif not os.path.exists(zippath):
|
||||
print system+self.libname+' NO ZIP'
|
||||
self._makezip()
|
||||
else:
|
||||
size=str(os.path.getsize(self.libpath))
|
||||
size_old=open( self.sizepath, "r" ).read()
|
||||
if size_old!=size:
|
||||
print system+self.libname+' NOT EQUAL'
|
||||
self._makezip()
|
||||
else:
|
||||
print system+self.libname+' NO ACTION'
|
||||
else:
|
||||
print system+self.libname+' NO LIB'
|
||||
|
||||
def _makezip(self):
|
||||
open( self.sizepath, "w" ).write( str(os.path.getsize(self.libpath)) )
|
||||
os.chdir(self.libdir)
|
||||
os.system('del %s' % (self.zipname))
|
||||
os.system('"C:\\Program Files\\7-Zip\\7z.exe" a %s.zip %s' %
|
||||
(self.libname, self.libname))
|
||||
os.chdir(self.root)
|
||||
#os.system('"C:\\Program Files\\7-Zip\\7z.exe" a %s.zip %s' %
|
||||
# (self.platform['system']+os.sep+self.libname, self.platform['system']+os.sep+self.libname))
|
||||
|
||||
if ( __name__ == "__main__" ):
|
||||
# start
|
||||
#TODO: publicate
|
||||
Public()
|
Binary file not shown.
|
@ -9,6 +9,7 @@ import time
|
|||
import urllib2
|
||||
import httplib
|
||||
from os.path import dirname
|
||||
from bin.functions import *
|
||||
|
||||
import logpipe
|
||||
import mimetypes
|
||||
|
@ -56,9 +57,14 @@ class Engine:
|
|||
binary = "torrent2http" + (".exe" if self.platform.system == 'windows' else "")
|
||||
binary_dir = os.path.join(binaries_path, "%s_%s" % (self.platform.system, self.platform.arch))
|
||||
binary_path = os.path.join(binary_dir, binary)
|
||||
lm=LibraryManager(binary_dir, "%s_%s" % (self.platform.system, self.platform.arch))
|
||||
if not os.path.isfile(binary_path):
|
||||
raise Error("Can't find torrent2http binary for %s" % self.platform,
|
||||
success=lm.download()
|
||||
if not success:
|
||||
raise Error("Can't find torrent2http or download binary for %s" % self.platform,
|
||||
Error.UNKNOWN_PLATFORM, platform=str(self.platform))
|
||||
else:
|
||||
lm.update()
|
||||
|
||||
if not self._ensure_binary_executable(binary_path):
|
||||
if self.platform.system == "android":
|
||||
|
|
Loading…
Reference in New Issue