2015-01-09 14:11:21 +03:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
'''
|
2015-06-30 18:08:57 +03:00
|
|
|
Torrenter v2 plugin for XBMC/Kodi
|
|
|
|
Copyright (C) 2012-2015 Vadim Skorba v1 - DiMartino v2
|
2016-02-13 20:33:16 +03:00
|
|
|
https://forums.tvaddons.ag/addon-releases/29224-torrenter-v2.html
|
2015-06-30 18:08:57 +03:00
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
'''
|
|
|
|
|
|
|
|
import re
|
|
|
|
import tempfile
|
|
|
|
import hashlib
|
|
|
|
import os
|
|
|
|
from StringIO import StringIO
|
2016-03-29 18:57:54 +03:00
|
|
|
import zlib
|
2015-01-09 14:11:21 +03:00
|
|
|
import socket
|
|
|
|
import sys
|
|
|
|
|
2017-12-08 16:58:04 +03:00
|
|
|
proxy = int(sys.modules["__main__"].__settings__.getSetting("proxy"))
|
|
|
|
if proxy == 2:
|
2017-12-11 22:21:28 +03:00
|
|
|
socks_ip = sys.modules["__main__"].__settings__.getSetting("socks_ip")
|
2017-12-08 16:58:04 +03:00
|
|
|
from resources import socks
|
2017-12-11 22:28:04 +03:00
|
|
|
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, socks_ip, 9050)
|
2017-12-08 16:58:04 +03:00
|
|
|
socket.socket = socks.socksocket
|
|
|
|
import urllib
|
|
|
|
import urllib2
|
|
|
|
import cookielib
|
2015-01-09 14:11:21 +03:00
|
|
|
import xbmcgui
|
|
|
|
import xbmc
|
|
|
|
import Localization
|
2016-03-12 20:47:49 +03:00
|
|
|
from functions import log, debug, showMessage
|
2015-01-09 14:11:21 +03:00
|
|
|
|
2016-12-27 18:47:09 +03:00
|
|
|
import ssl
|
2015-01-09 14:11:21 +03:00
|
|
|
|
2017-02-22 15:02:46 +03:00
|
|
|
#ssl._create_default_https_context = ssl._create_unverified_context
|
2015-01-09 14:11:21 +03:00
|
|
|
class SearcherABC:
|
|
|
|
searchIcon = '/icons/video.png'
|
|
|
|
sourceWeight = 1
|
|
|
|
cookieJar = None
|
|
|
|
timeout_multi=int(sys.modules["__main__"].__settings__.getSetting("timeout"))
|
2015-07-16 20:32:50 +03:00
|
|
|
__plugin__='Empty v 0 0 0'
|
2015-07-19 11:56:56 +03:00
|
|
|
baseurl = 'site.com'
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
socket.setdefaulttimeout(10+(10*int(timeout_multi)))
|
|
|
|
|
|
|
|
def search(self, keyword):
|
|
|
|
'''
|
|
|
|
Retrieve keyword from the input and return a list of tuples:
|
|
|
|
filesList.append((
|
|
|
|
int(weight),
|
|
|
|
int(seeds),
|
|
|
|
str(title),
|
|
|
|
str(link),
|
|
|
|
str(image),
|
|
|
|
))
|
|
|
|
'''
|
|
|
|
return
|
|
|
|
|
|
|
|
def isMagnetLinkSource(self):
|
|
|
|
return 'Should never see this'
|
|
|
|
|
|
|
|
def getTorrentFile(self, url):
|
|
|
|
return url
|
|
|
|
|
|
|
|
def sizeConvert(self, sizeBytes):
|
|
|
|
if long(sizeBytes) >= 1024 * 1024 * 1024:
|
|
|
|
size = str(long(sizeBytes) / (1024 * 1024 * 1024)) + 'GB'
|
|
|
|
elif long(sizeBytes) >= 1024 * 1024:
|
|
|
|
size = str(long(sizeBytes) / (1024 * 1024)) + 'MB'
|
|
|
|
elif sizeBytes >= 1024:
|
|
|
|
size = str(long(sizeBytes) / 1024) + 'KB'
|
|
|
|
else:
|
|
|
|
size = str(long(sizeBytes)) + 'B'
|
|
|
|
|
|
|
|
return size
|
|
|
|
|
|
|
|
def check_login(self, response=None):
|
|
|
|
return True
|
|
|
|
|
|
|
|
def login(self):
|
|
|
|
return True
|
|
|
|
|
|
|
|
def load_cookie(self):
|
2015-12-20 02:35:06 +03:00
|
|
|
cookie=os.path.join(self.tempdir(), self.__class__.__name__+'.txt')
|
2015-01-09 14:11:21 +03:00
|
|
|
self.cookieJar = cookielib.MozillaCookieJar(cookie)
|
2015-08-26 21:01:36 +03:00
|
|
|
try:
|
|
|
|
if os.path.exists(cookie): self.cookieJar.load(ignore_discard=True)
|
|
|
|
except:
|
2016-01-05 19:27:10 +03:00
|
|
|
self.log('[load_cookie]: os.remove(cookie)')
|
2015-08-26 21:01:36 +03:00
|
|
|
os.remove(cookie)
|
|
|
|
self.cookieJar = cookielib.MozillaCookieJar(cookie)
|
2015-01-09 14:11:21 +03:00
|
|
|
|
2015-07-12 16:14:12 +03:00
|
|
|
def clear_cookie(self, domain):
|
2015-12-20 02:35:06 +03:00
|
|
|
cookie=os.path.join(self.tempdir(),self.__class__.__name__+'.txt')
|
2015-07-12 16:14:12 +03:00
|
|
|
self.cookieJar = cookielib.MozillaCookieJar(cookie)
|
|
|
|
if os.path.exists(cookie):
|
2015-12-20 11:51:06 +03:00
|
|
|
os.remove(cookie)
|
2016-01-05 19:27:10 +03:00
|
|
|
self.log('[clear_cookie]: cookie cleared')
|
2015-07-12 16:14:12 +03:00
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
def makeRequest(self, url, data={}, headers={}):
|
|
|
|
self.load_cookie()
|
2016-12-27 18:47:09 +03:00
|
|
|
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookieJar))
|
2017-12-08 16:58:04 +03:00
|
|
|
if proxy == 1:
|
2016-03-12 20:47:49 +03:00
|
|
|
try:
|
|
|
|
from resources.proxy import antizapret
|
2016-12-27 18:47:09 +03:00
|
|
|
opener.add_handler(antizapret.AntizapretProxyHandler())
|
2016-03-12 20:47:49 +03:00
|
|
|
config = antizapret.config()
|
|
|
|
self.debug('[antizapret]: '+str(config["domains"]))
|
|
|
|
self.debug('[antizapret]: '+str(config["server"]))
|
|
|
|
except:
|
|
|
|
showMessage('AntiZapret', Localization.localize('Error'))
|
|
|
|
self.debug('[antizapret]: OFF!')
|
2016-12-27 18:47:09 +03:00
|
|
|
# python ssl Context support - PEP 0466
|
2017-02-22 15:02:46 +03:00
|
|
|
if 'https:' in url:
|
|
|
|
ssl_context = ssl.create_default_context()
|
|
|
|
ssl_context.check_hostname = False
|
|
|
|
ssl_context.verify_mode = ssl.CERT_NONE
|
|
|
|
log('urllib2.HTTPSHandler(context=ssl_context)')
|
2016-12-27 18:47:09 +03:00
|
|
|
opener.add_handler(urllib2.HTTPSHandler(context=ssl_context))
|
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
opener.addheaders = headers
|
|
|
|
if 0 < len(data):
|
|
|
|
encodedData = urllib.urlencode(data)
|
|
|
|
else:
|
|
|
|
encodedData = None
|
2015-07-01 23:15:29 +03:00
|
|
|
try:
|
|
|
|
response = opener.open(url, encodedData)
|
|
|
|
except urllib2.HTTPError as e:
|
|
|
|
if e.code == 404:
|
2016-01-05 19:27:10 +03:00
|
|
|
self.log('[makeRequest]: Not Found! HTTP Error, e.code=' + str(e.code))
|
2015-07-01 23:15:29 +03:00
|
|
|
return
|
|
|
|
elif e.code in [503]:
|
2016-01-05 19:27:10 +03:00
|
|
|
self.log('[makeRequest]: Denied, HTTP Error, e.code=' + str(e.code))
|
2015-07-01 23:15:29 +03:00
|
|
|
return
|
|
|
|
else:
|
2016-01-05 19:27:10 +03:00
|
|
|
self.log('[makeRequest]: HTTP Error, e.code=' + str(e.code))
|
2015-07-01 23:15:29 +03:00
|
|
|
return
|
2015-01-09 14:11:21 +03:00
|
|
|
#self.cookieJar.extract_cookies(response, urllib2)
|
2016-11-29 21:47:37 +03:00
|
|
|
#self.log(response.info().get('Set-Cookie'))
|
2015-01-09 14:11:21 +03:00
|
|
|
if response.info().get('Content-Encoding') == 'gzip':
|
|
|
|
buf = StringIO(response.read())
|
2016-03-29 18:57:54 +03:00
|
|
|
decomp = zlib.decompressobj(16 + zlib.MAX_WBITS)
|
2016-11-29 21:47:37 +03:00
|
|
|
text = decomp.decompress(buf.getvalue())
|
2015-01-09 14:11:21 +03:00
|
|
|
else:
|
2016-11-29 21:47:37 +03:00
|
|
|
text = response.read()
|
|
|
|
return text
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
def askCaptcha(self, url):
|
2015-08-29 17:18:25 +03:00
|
|
|
temp_dir = self.tempdir()
|
2015-01-09 14:11:21 +03:00
|
|
|
if isinstance(temp_dir, list): temp_dir = temp_dir[0]
|
|
|
|
urllib.URLopener().retrieve(url, temp_dir + '/captcha.png')
|
|
|
|
window = xbmcgui.Window(xbmcgui.getCurrentWindowId())
|
|
|
|
if isinstance(temp_dir, list): temp_dir = temp_dir[0]
|
|
|
|
image = xbmcgui.ControlImage(460, 20, 360, 160, temp_dir + '/captcha.png')
|
|
|
|
window.addControl(image)
|
2015-07-27 21:59:05 +03:00
|
|
|
keyboardCaptcha = xbmc.Keyboard('', '[%s] %s' % (self.__plugin__, Localization.localize('Input symbols from CAPTCHA image:')))
|
2015-01-09 14:11:21 +03:00
|
|
|
keyboardCaptcha.doModal()
|
|
|
|
captchaText = keyboardCaptcha.getText()
|
|
|
|
window.removeControl(image)
|
|
|
|
if not captchaText:
|
|
|
|
return False
|
|
|
|
else:
|
|
|
|
return captchaText
|
|
|
|
|
|
|
|
htmlCodes = (
|
|
|
|
('&', '&'),
|
|
|
|
('<', '<'),
|
|
|
|
('>', '>'),
|
|
|
|
('"', '"'),
|
2016-01-13 00:09:52 +03:00
|
|
|
('"', '"'),
|
2015-01-09 14:11:21 +03:00
|
|
|
("'", '''),
|
2015-07-27 21:02:50 +03:00
|
|
|
("&", '&'),
|
|
|
|
("'", '''),
|
|
|
|
("&", '&'),)
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
stripPairs = (
|
|
|
|
('<p>', '\n'),
|
|
|
|
('<li>', '\n'),
|
|
|
|
('<br>', '\n'),
|
|
|
|
('<.+?>', ' '),
|
|
|
|
('</.+?>', ' '),
|
|
|
|
(' ', ' '),
|
|
|
|
('«', '"'),
|
|
|
|
('»', '"'),
|
|
|
|
)
|
|
|
|
|
|
|
|
def unescape(self, string):
|
|
|
|
for (symbol, code) in self.htmlCodes:
|
|
|
|
string = re.sub(code, symbol, string)
|
|
|
|
return string
|
|
|
|
|
|
|
|
def stripHtml(self, string):
|
|
|
|
for (html, replacement) in self.stripPairs:
|
|
|
|
string = re.sub(html, replacement, string)
|
|
|
|
return string
|
|
|
|
|
|
|
|
def md5(self, string):
|
|
|
|
hasher = hashlib.md5()
|
|
|
|
hasher.update(string)
|
|
|
|
return hasher.hexdigest()
|
|
|
|
|
|
|
|
def tempdir(self):
|
|
|
|
dirname = xbmc.translatePath('special://temp')
|
|
|
|
for subdir in ('xbmcup', 'plugin.video.torrenter'):
|
|
|
|
dirname = os.path.join(dirname, subdir)
|
|
|
|
if not os.path.exists(dirname):
|
|
|
|
os.mkdir(dirname)
|
|
|
|
return dirname
|
|
|
|
|
|
|
|
def timeout(self, add_seconds=0):
|
|
|
|
seconds=10+(10*int(self.timeout_multi))+int(add_seconds)
|
|
|
|
socket.setdefaulttimeout(int(seconds))
|
|
|
|
|
|
|
|
def clean(self, string):
|
|
|
|
specials = ['/', '\\', '-', '[', ']', '(', ')', ',']
|
|
|
|
for symbol in specials:
|
|
|
|
string = string.replace(symbol, ' ')
|
|
|
|
if len(string) > 120:
|
|
|
|
string = string[:120]
|
|
|
|
last_piece = string.split(' ')[-1]
|
|
|
|
string = string[:120 - len(last_piece)].strip()
|
|
|
|
return string
|
|
|
|
|
|
|
|
def saveTorrentFile(self, url, content):
|
|
|
|
try:
|
|
|
|
temp_dir = tempfile.gettempdir()
|
|
|
|
except:
|
|
|
|
temp_dir = self.tempdir()
|
2015-12-20 11:51:06 +03:00
|
|
|
localFileName = temp_dir + os.path.sep + self.md5(url) + ".torrent"
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
localFile = open(localFileName, 'wb+')
|
|
|
|
localFile.write(content)
|
|
|
|
localFile.close()
|
|
|
|
|
2015-07-12 13:28:33 +03:00
|
|
|
return localFileName
|
|
|
|
|
|
|
|
def logout(self):
|
2015-07-16 20:39:02 +03:00
|
|
|
pass
|
|
|
|
|
|
|
|
def log(self, msg):
|
2016-01-05 19:27:10 +03:00
|
|
|
log('[%s] ' % self.__plugin__ +msg)
|
2015-07-16 20:39:02 +03:00
|
|
|
|
|
|
|
def debug(self, msg):
|
2016-01-05 19:27:10 +03:00
|
|
|
debug('[%s] ' % self.__plugin__ +msg)
|
2015-07-19 00:44:38 +03:00
|
|
|
|
|
|
|
def open2(self, url=''):
|
|
|
|
import httplib
|
|
|
|
conn = httplib.HTTPConnection(self.baseurl)
|
|
|
|
conn.request("GET", str(url))
|
|
|
|
r1 = conn.getresponse()
|
|
|
|
status = str(r1.status) + " " + r1.reason
|
|
|
|
content = r1.read()
|
|
|
|
self.debug('[open2] status:'+str(status))
|
2016-03-17 23:08:37 +03:00
|
|
|
return content
|
|
|
|
|
|
|
|
def showMessage(self, heading, message, times=10000):
|
|
|
|
xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s, "%s")' % (
|
|
|
|
heading.replace('"', "'"), message.replace('"', "'"), times, self.searchIcon))
|
|
|
|
self.log(str((heading.replace('"', "'"), message.replace('"', "'"), times, self.searchIcon)))
|