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
|
|
|
|
|
http://forum.kodi.tv/showthread.php?tid=214366
|
|
|
|
|
|
|
|
|
|
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/>.
|
|
|
|
|
'''
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
|
|
import urllib2
|
|
|
|
|
import re
|
|
|
|
|
import socket
|
|
|
|
|
import datetime
|
|
|
|
|
import time
|
|
|
|
|
import sys
|
|
|
|
|
import os
|
|
|
|
|
import json
|
|
|
|
|
import urllib
|
|
|
|
|
import hashlib
|
2015-07-12 16:14:12 +03:00
|
|
|
|
import traceback
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
|
|
import xbmcplugin
|
|
|
|
|
import xbmcgui
|
|
|
|
|
import xbmc
|
|
|
|
|
import xbmcaddon
|
|
|
|
|
import xbmcvfs
|
|
|
|
|
import Localization
|
|
|
|
|
from resources.scrapers.scrapers import Scrapers
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
from hashlib import md5
|
|
|
|
|
except ImportError:
|
|
|
|
|
from md5 import md5
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
from sqlite3 import dbapi2 as sqlite
|
|
|
|
|
except:
|
|
|
|
|
from pysqlite2 import dbapi2 as sqlite
|
|
|
|
|
|
|
|
|
|
__settings__ = xbmcaddon.Addon(id='plugin.video.torrenter')
|
|
|
|
|
__language__ = __settings__.getLocalizedString
|
|
|
|
|
ROOT = __settings__.getAddonInfo('path') # .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"
|
|
|
|
|
torrentFilesDirectory = 'torrents'
|
|
|
|
|
__addonpath__ = __settings__.getAddonInfo('path')
|
|
|
|
|
icon = __addonpath__ + '/icon.png'
|
|
|
|
|
debug = __settings__.getSetting("debug")
|
2015-07-01 23:15:29 +03:00
|
|
|
|
__version__ = __settings__.getAddonInfo('version')
|
|
|
|
|
__plugin__ = __settings__.getAddonInfo('name') + " v." + __version__
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def clearStorage(userStorageDirectory):
|
|
|
|
|
try:
|
|
|
|
|
userStorageDirectory = userStorageDirectory.decode('utf-8')
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
if xbmcvfs.exists(userStorageDirectory + os.sep):
|
|
|
|
|
import shutil
|
|
|
|
|
|
|
|
|
|
temp = userStorageDirectory.rstrip('Torrenter').rstrip('/\\')
|
2015-06-23 23:00:27 +03:00
|
|
|
|
torrents_temp, i = None, 0
|
2015-02-16 19:19:58 +03:00
|
|
|
|
while not torrents_temp or xbmcvfs.exists(torrents_temp):
|
2015-06-23 23:00:27 +03:00
|
|
|
|
torrents_temp = os.path.join(temp, 'torrents' + str(i)) + os.sep
|
|
|
|
|
i += 1
|
2015-02-16 19:19:58 +03:00
|
|
|
|
shutil.move(os.path.join(userStorageDirectory, 'torrents'), torrents_temp)
|
2015-01-09 14:11:21 +03:00
|
|
|
|
shutil.rmtree(userStorageDirectory, ignore_errors=True)
|
|
|
|
|
xbmcvfs.mkdir(userStorageDirectory)
|
2015-02-16 19:19:58 +03:00
|
|
|
|
shutil.move(torrents_temp, os.path.join(userStorageDirectory, 'torrents'))
|
2015-01-12 23:10:20 +03:00
|
|
|
|
DownloadDB().clear()
|
2015-01-09 14:11:21 +03:00
|
|
|
|
showMessage(Localization.localize('Storage'), Localization.localize('Storage was cleared'), forced=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def sortcomma(dict, json):
|
|
|
|
|
for x in dict:
|
|
|
|
|
y = dict[x].split(',')
|
|
|
|
|
dict[x] = ''
|
|
|
|
|
for i in y:
|
|
|
|
|
if i not in json:
|
|
|
|
|
dict[x] = dict[x] + ',' + i
|
|
|
|
|
if len(dict[x]) > 0: dict[x] = dict[x][1:len(dict[x])]
|
|
|
|
|
return dict
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def md5(string):
|
|
|
|
|
hasher = hashlib.md5()
|
|
|
|
|
try:
|
|
|
|
|
hasher.update(string)
|
|
|
|
|
except:
|
|
|
|
|
hasher.update(string.encode('utf-8', 'ignore'))
|
|
|
|
|
return hasher.hexdigest()
|
|
|
|
|
|
|
|
|
|
|
2015-07-16 20:32:50 +03:00
|
|
|
|
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 )
|
2015-07-16 22:36:48 +03:00
|
|
|
|
except:
|
|
|
|
|
xbmc.log("### [%s]: %s" % (__plugin__,'ERROR LOG',), level=xbmc.LOGNOTICE )
|
2015-07-16 20:32:50 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def debug(msg):
|
|
|
|
|
try:
|
|
|
|
|
xbmc.log("### [%s]: %s" % (__plugin__,msg,), level=xbmc.LOGDEBUG )
|
|
|
|
|
except UnicodeEncodeError:
|
|
|
|
|
xbmc.log("### [%s]: %s" % (__plugin__,msg.encode("utf-8", "ignore"),), level=xbmc.LOGDEBUG )
|
2015-07-16 22:36:48 +03:00
|
|
|
|
except:
|
|
|
|
|
xbmc.log("### [%s]: %s" % (__plugin__,'ERROR DEBUG',), level=xbmc.LOGDEBUG )
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def showMessage(heading, message, times=10000, forced=False):
|
|
|
|
|
xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s, "%s")' % (
|
|
|
|
|
heading.replace('"', "'"), message.replace('"', "'"), times, icon))
|
2015-07-19 00:44:38 +03:00
|
|
|
|
debug(str((heading.replace('"', "'"), message.replace('"', "'"), times, icon)))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def magnet_alert():
|
|
|
|
|
showMessage('Ace Stream', Localization.localize('Does not support magnet links!'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def dates_diff(fdate, ldate):
|
|
|
|
|
try:
|
|
|
|
|
if ldate == 'today':
|
|
|
|
|
x = datetime.datetime.now()
|
|
|
|
|
else:
|
|
|
|
|
x = datetime.datetime.strptime(ldate, '%d.%m.%Y')
|
|
|
|
|
y = datetime.datetime.strptime(fdate, '%d.%m.%Y')
|
|
|
|
|
z = x - y
|
|
|
|
|
except TypeError:
|
|
|
|
|
if ldate == 'today':
|
|
|
|
|
x = datetime.datetime.now()
|
|
|
|
|
else:
|
|
|
|
|
x = datetime.datetime(*(time.strptime(ldate, '%d.%m.%Y')[0:6]))
|
|
|
|
|
y = datetime.datetime(*(time.strptime(fdate, '%d.%m.%Y')[0:6]))
|
|
|
|
|
z = x - y
|
|
|
|
|
return str(z.days)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def today_str():
|
|
|
|
|
try:
|
|
|
|
|
x = datetime.datetime.now().strftime('%d.%m.%Y')
|
|
|
|
|
except TypeError:
|
|
|
|
|
x = datetime.datetime(*(time.strptime(datetime.datetime.now().strftime('%d.%m.%Y'), '%d.%m.%Y')[0:6]))
|
|
|
|
|
x = datetime.datetime.strftime(x, '%d.%m.%Y')
|
|
|
|
|
return str(x)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_params():
|
|
|
|
|
param = []
|
|
|
|
|
paramstring = sys.argv[2]
|
|
|
|
|
if len(paramstring) >= 2:
|
|
|
|
|
params = sys.argv[2]
|
|
|
|
|
cleanedparams = params.replace('?', '')
|
|
|
|
|
if (params[len(params) - 1] == '/'):
|
|
|
|
|
params = params[0:len(params) - 2]
|
|
|
|
|
pairsofparams = cleanedparams.split('&')
|
|
|
|
|
param = {}
|
|
|
|
|
for i in range(len(pairsofparams)):
|
|
|
|
|
splitparams = {}
|
|
|
|
|
splitparams = pairsofparams[i].split('=')
|
|
|
|
|
if (len(splitparams)) == 2:
|
|
|
|
|
param[splitparams[0]] = splitparams[1]
|
|
|
|
|
return param
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_apps(paramstring=None):
|
|
|
|
|
if not paramstring: paramstring = sys.argv[2]
|
|
|
|
|
if len(paramstring) >= 2:
|
|
|
|
|
try:
|
|
|
|
|
apps = json.loads(urllib.unquote_plus(paramstring))
|
|
|
|
|
except:
|
|
|
|
|
cleanapps = str(paramstring).replace('?', '', 1)
|
|
|
|
|
apps = json.loads(urllib.unquote_plus(cleanapps))
|
|
|
|
|
return apps
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def int_xx(intxx):
|
|
|
|
|
if intxx and intxx != 'None':
|
|
|
|
|
return '%02d' % (int(intxx))
|
|
|
|
|
else:
|
|
|
|
|
return '00'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def StripName(name, list, replace=' '):
|
|
|
|
|
lname = name.lower().split(' ')
|
|
|
|
|
name = ''
|
|
|
|
|
for n in lname:
|
|
|
|
|
if n not in list: name += ' ' + n
|
|
|
|
|
return name.strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def tempdir():
|
|
|
|
|
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 makeapp(s):
|
|
|
|
|
return urllib.quote_plus(json.dumps(s))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_url(cookie, url):
|
|
|
|
|
headers = {'User-Agent': 'XBMC',
|
|
|
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
|
|
|
'Cookie': cookie}
|
|
|
|
|
try:
|
|
|
|
|
conn = urllib2.urlopen(urllib2.Request(url, urllib.urlencode({}), headers))
|
|
|
|
|
array = conn.read()
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('[get_url]: arr"'+str(array)+'"')
|
2015-01-09 14:11:21 +03:00
|
|
|
|
if array == '':
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('[get_url][2]: arr=""')
|
2015-01-09 14:11:21 +03:00
|
|
|
|
array = True
|
|
|
|
|
return array
|
|
|
|
|
except urllib2.HTTPError as e:
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('[get_url]: HTTPError, e.code='+str(e.code))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
if e.code == 401:
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[get_url]: Denied! Wrong login or api is broken!')
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return
|
|
|
|
|
elif e.code in [503]:
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[get_url]: Denied, HTTP Error, e.code=' + str(e.code))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return
|
|
|
|
|
else:
|
|
|
|
|
showMessage('HTTP Error', str(e.code))
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[get_url]: HTTP Error, e.code=' + str(e.code))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
xbmc.sleep(2000)
|
|
|
|
|
return
|
|
|
|
|
except:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def post_url_json(cookie, url, post):
|
|
|
|
|
headers = {'User-Agent': 'XBMC',
|
|
|
|
|
'Connection': 'keep-alive',
|
|
|
|
|
'Cookie': cookie}
|
|
|
|
|
conn = urllib2.urlopen(urllib2.Request(url, post, headers))
|
|
|
|
|
array = conn.read()
|
|
|
|
|
conn.close()
|
|
|
|
|
return array
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def creat_db(dbfilename):
|
|
|
|
|
db = sqlite.connect(dbfilename)
|
|
|
|
|
cur = db.cursor()
|
|
|
|
|
cur.execute('pragma auto_vacuum=1')
|
|
|
|
|
cur.execute(
|
|
|
|
|
'create table sources(addtime integer, filename varchar(32) PRIMARY KEY, showId integer, seasonId integer, episodeId integer, id integer, stype varchar(32))')
|
|
|
|
|
cur.execute('create table cache(addtime integer, url varchar(32))')
|
|
|
|
|
cur.execute('create table scan(addtime integer, filename varchar(32) PRIMARY KEY)')
|
|
|
|
|
cur.execute('create table watched(addtime integer, rating integer, id varchar(32) PRIMARY KEY)')
|
|
|
|
|
db.commit()
|
|
|
|
|
cur.close()
|
|
|
|
|
db.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def invert_bool(var):
|
|
|
|
|
if bool(var):
|
|
|
|
|
var = False
|
|
|
|
|
else:
|
|
|
|
|
var = True
|
|
|
|
|
return var
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getSettingAsBool(setting):
|
|
|
|
|
return __settings__.getSetting(setting).lower() == "true"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def calculate(full):
|
|
|
|
|
consts = [(100, 20), (300, 15), (500, 10), (2000, 7), (4000, 5)]
|
|
|
|
|
max_const = 150
|
|
|
|
|
|
|
|
|
|
repl_const = 0
|
|
|
|
|
|
|
|
|
|
for size, const in consts:
|
|
|
|
|
if (size * 1024 * 1024) > full:
|
|
|
|
|
repl_const = int(float(const) / 100 * (full / (1024 * 1024))) # MB of first
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
if repl_const == 0:
|
|
|
|
|
repl_const = max_const
|
|
|
|
|
|
|
|
|
|
return repl_const
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
|
def getDirList(path, newl=None):
|
|
|
|
|
l = []
|
|
|
|
|
try:
|
|
|
|
|
if not newl: dirs, newl = xbmcvfs.listdir(path)
|
|
|
|
|
except:
|
|
|
|
|
try:
|
|
|
|
|
if not newl: dirs, newl = xbmcvfs.listdir(path.decode('utf-8').encode('cp1251'))
|
|
|
|
|
except:
|
|
|
|
|
showMessage(__language__(30206), __language__(30280), forced=True)
|
|
|
|
|
return l
|
|
|
|
|
for fl in newl:
|
|
|
|
|
match = re.match('.avi|.mp4|.mkV|.flv|.mov|.vob|.wmv|.ogm|.asx|.mpg|mpeg|.avc|.vp3|.fli|.flc|.m4v',
|
|
|
|
|
fl[int(len(fl)) - 4:len(fl)], re.I)
|
|
|
|
|
if match:
|
|
|
|
|
l.append(fl)
|
|
|
|
|
return l
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def cutFileNames(l):
|
|
|
|
|
from difflib import Differ
|
|
|
|
|
|
|
|
|
|
d = Differ()
|
|
|
|
|
|
|
|
|
|
text = sortext(l)
|
|
|
|
|
newl = []
|
|
|
|
|
for li in l: newl.append(cutStr(li[0:len(li) - 1 - len(li.split('.')[-1])]))
|
|
|
|
|
l = newl
|
|
|
|
|
|
|
|
|
|
text1 = cutStr(text[0][0:len(text[0]) - 1 - len(text[0].split('.')[-1])])
|
|
|
|
|
text2 = cutStr(text[1][0:len(text[1]) - 1 - len(text[1].split('.')[-1])])
|
|
|
|
|
sep_file = " "
|
|
|
|
|
result = list(d.compare(text1.split(sep_file), text2.split(sep_file)))
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[cutFileNames] ' + unicode(result))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
|
|
start = ''
|
|
|
|
|
end = ''
|
|
|
|
|
|
|
|
|
|
for res in result:
|
|
|
|
|
if str(res).startswith('-') or str(res).startswith('+') or str(res).startswith('.?'):
|
|
|
|
|
break
|
|
|
|
|
start = start + str(res).strip() + sep_file
|
|
|
|
|
result.reverse()
|
|
|
|
|
for res in result:
|
|
|
|
|
if str(res).startswith('-') or str(res).startswith('+') or str(res).startswith('?'):
|
|
|
|
|
break
|
|
|
|
|
end = sep_file + str(res).strip() + end
|
|
|
|
|
|
|
|
|
|
newl = l
|
|
|
|
|
l = []
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[cutFileNames] [start] ' + start)
|
|
|
|
|
debug('[cutFileNames] [end] ' + end)
|
2015-01-09 14:11:21 +03:00
|
|
|
|
for fl in newl:
|
|
|
|
|
if cutStr(fl[0:len(start)]) == cutStr(start): fl = fl[len(start):]
|
|
|
|
|
if cutStr(fl[len(fl) - len(end):]) == cutStr(end): fl = fl[0:len(fl) - len(end)]
|
|
|
|
|
try:
|
|
|
|
|
isinstance(int(fl.split(sep_file)[0]), int)
|
|
|
|
|
fl = fl.split(sep_file)[0]
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
l.append(fl)
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[cutFileNames] [sorted l] ' + unicode(sorted(l, key=lambda x: x)))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return l
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def cutStr(s):
|
|
|
|
|
return s.replace('.', ' ').replace('_', ' ').replace('[', ' ').replace(']', ' ').lower().strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def sortext(filelist):
|
|
|
|
|
result = {}
|
|
|
|
|
for name in filelist:
|
|
|
|
|
ext = name.split('.')[-1]
|
|
|
|
|
try:
|
|
|
|
|
result[ext] = result[ext] + 1
|
|
|
|
|
except:
|
|
|
|
|
result[ext] = 1
|
|
|
|
|
lol = result.iteritems()
|
|
|
|
|
lol = sorted(lol, key=lambda x: x[1])
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[sortext]: lol:' + str(lol))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
popext = lol[-1][0]
|
|
|
|
|
result, i = [], 0
|
|
|
|
|
for name in filelist:
|
|
|
|
|
if name.split('.')[-1] == popext:
|
|
|
|
|
result.append(name)
|
|
|
|
|
i = i + 1
|
|
|
|
|
result = sweetpair(result)
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[sortext]: result:' + str(result))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
2015-01-11 20:17:11 +03:00
|
|
|
|
def cutFolder(contentList, tdir=None):
|
|
|
|
|
dirList, contentListNew = [], []
|
|
|
|
|
|
|
|
|
|
if len(contentList) > 1:
|
|
|
|
|
common_folder = contentList[0][0]
|
|
|
|
|
if '\\' in common_folder:
|
|
|
|
|
common_folder = common_folder.split('\\')[0]
|
|
|
|
|
elif '/' in common_folder:
|
|
|
|
|
common_folder = common_folder.split('/')[0]
|
|
|
|
|
|
|
|
|
|
common = True
|
|
|
|
|
for fileTitle, contentId in contentList:
|
|
|
|
|
if common_folder not in fileTitle:
|
|
|
|
|
print 'no common'
|
|
|
|
|
common = False
|
|
|
|
|
break
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
# print common_folder
|
2015-01-11 20:17:11 +03:00
|
|
|
|
for fileTitle, contentId in contentList:
|
|
|
|
|
dir = None
|
|
|
|
|
if common:
|
|
|
|
|
fileTitle = fileTitle[len(common_folder) + 1:]
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
# print fileTitle
|
2015-01-11 20:17:11 +03:00
|
|
|
|
|
|
|
|
|
if '\\' in fileTitle:
|
|
|
|
|
dir = fileTitle.split('\\')[0]
|
|
|
|
|
elif '/' in fileTitle:
|
|
|
|
|
dir = fileTitle.split('/')[0]
|
|
|
|
|
elif not tdir:
|
|
|
|
|
contentListNew.append((fileTitle, contentId))
|
|
|
|
|
|
|
|
|
|
if tdir and dir == tdir:
|
|
|
|
|
contentListNew.append((fileTitle[len(dir) + 1:], contentId))
|
|
|
|
|
|
|
|
|
|
if not tdir and dir and dir not in dirList:
|
|
|
|
|
dirList.append(dir)
|
|
|
|
|
|
|
|
|
|
return dirList, contentListNew
|
|
|
|
|
else:
|
|
|
|
|
return dirList, contentList
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
|
def sweetpair(l):
|
|
|
|
|
from difflib import SequenceMatcher
|
|
|
|
|
|
|
|
|
|
s = SequenceMatcher()
|
|
|
|
|
ratio = []
|
|
|
|
|
for i in range(0, len(l)): ratio.append(0)
|
|
|
|
|
for i in range(0, len(l)):
|
|
|
|
|
for p in range(0, len(l)):
|
|
|
|
|
s.set_seqs(l[i], l[p])
|
|
|
|
|
ratio[i] = ratio[i] + s.quick_ratio()
|
|
|
|
|
id1, id2 = 0, 0
|
|
|
|
|
for i in range(0, len(l)):
|
|
|
|
|
if ratio[id1] <= ratio[i] and i != id2 or id2 == id1 and ratio[id1] == ratio[i]:
|
|
|
|
|
id2 = id1
|
|
|
|
|
id1 = i
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('1 - %d %d' % (id1, id2))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
elif (ratio[id2] <= ratio[i] or id1 == id2) and i != id1:
|
|
|
|
|
id2 = i
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('2 - %d %d' % (id1, id2))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[sweetpair]: id1 ' + l[id1] + ':' + str(ratio[id1]))
|
|
|
|
|
debug('[sweetpair]: id2 ' + l[id2] + ':' + str(ratio[id2]))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
|
|
return [l[id1], l[id2]]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def FileNamesPrepare(filename):
|
|
|
|
|
my_season = None
|
|
|
|
|
my_episode = None
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
if int(filename):
|
|
|
|
|
my_episode = int(filename)
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[FileNamesPrepare] ' + str([my_season, my_episode, filename]))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return [my_season, my_episode, filename]
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
urls = ['s(\d+)e(\d+)', '(\d+)[x|-](\d+)', 'E(\d+)', 'Ep(\d+)', '\((\d+)\)']
|
|
|
|
|
for file in urls:
|
|
|
|
|
match = re.compile(file, re.DOTALL | re.I | re.IGNORECASE).findall(filename)
|
|
|
|
|
if match:
|
|
|
|
|
try:
|
|
|
|
|
my_episode = int(match[1])
|
|
|
|
|
my_season = int(match[0])
|
|
|
|
|
except:
|
|
|
|
|
try:
|
|
|
|
|
my_episode = int(match[0])
|
|
|
|
|
except:
|
|
|
|
|
try:
|
|
|
|
|
my_episode = int(match[0][1])
|
|
|
|
|
my_season = int(match[0][0])
|
|
|
|
|
except:
|
|
|
|
|
try:
|
|
|
|
|
my_episode = int(match[0][0])
|
|
|
|
|
except:
|
|
|
|
|
break
|
|
|
|
|
if my_season and my_season > 100: my_season = None
|
|
|
|
|
if my_episode and my_episode > 365: my_episode = None
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[FileNamesPrepare] ' + str([my_season, my_episode, filename]))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return [my_season, my_episode, filename]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def filename2match(filename, no_date=False):
|
|
|
|
|
results = {'label': filename}
|
|
|
|
|
urls = ['(.+|.?)s(\d+)e(\d+)', '(.+|.?)s(\d+)\.e(\d+)', '(.+|.?) [\[|\(](\d+)[x|-](\d+)[\]|\)]',
|
|
|
|
|
'(.+|.?) (\d+)[x|-](\d+)'] # same in service
|
|
|
|
|
for file in urls:
|
|
|
|
|
match = re.compile(file, re.I | re.IGNORECASE).findall(filename)
|
|
|
|
|
# print str(results)
|
|
|
|
|
if match:
|
|
|
|
|
results['showtitle'], results['season'], results['episode'] = match[0]
|
|
|
|
|
results['showtitle'] = results['showtitle'].replace('.', ' ').replace('_', ' ').strip().replace(
|
|
|
|
|
'The Daily Show', 'The Daily Show With Jon Stewart')
|
|
|
|
|
results['season'], results['episode'] = int(results['season']), int(results['episode'])
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('[filename2match] '+str(results))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return results
|
|
|
|
|
if no_date: return
|
|
|
|
|
urls = ['(.+)(\d{4})\.(\d{2,4})\.(\d{2,4})', '(.+)(\d{4}) (\d{2}) (\d{2})'] # same in service
|
|
|
|
|
for file in urls:
|
|
|
|
|
match = re.compile(file, re.I | re.IGNORECASE).findall(filename)
|
|
|
|
|
if match:
|
|
|
|
|
results['showtitle'] = match[0][0].replace('.', ' ').strip().replace('The Daily Show',
|
|
|
|
|
'The Daily Show With Jon Stewart')
|
|
|
|
|
results['date'] = '%s.%s.%s' % (match[0][3], match[0][2], match[0][1])
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[filename2match] ' + str(results))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def TextBB(string, action=None, color=None):
|
|
|
|
|
if action == 'b':
|
|
|
|
|
string = '[B]' + string + '[/B]'
|
|
|
|
|
return string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def jstr(s):
|
|
|
|
|
if not s:
|
|
|
|
|
s = 'null'
|
|
|
|
|
elif not unicode(s).isnumeric():
|
|
|
|
|
s = '"%s"' % (s)
|
|
|
|
|
return str(s)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def view_style(func):
|
|
|
|
|
styles = {}
|
|
|
|
|
num_skin, style = 0, 'info'
|
|
|
|
|
view_style = int(__settings__.getSetting("skin_optimization"))
|
|
|
|
|
if view_style in [3, 2]:
|
|
|
|
|
styles['searchOption'] = styles['History'] = styles['List'] = 'info'
|
|
|
|
|
styles['drawContent'] = styles['drawtrackerList'] = styles['drawcontentList'] = 'info'
|
|
|
|
|
styles['sectionMenu'] = styles['Seasons'] = 'list'
|
|
|
|
|
styles['uTorrentBrowser'] = styles['torrentPlayer'] = styles['openTorrent'] = 'wide'
|
2015-01-13 21:19:14 +03:00
|
|
|
|
styles['showFilesList'] = styles['DownloadStatus'] = 'wide'
|
2015-01-09 14:11:21 +03:00
|
|
|
|
elif view_style in [1, 4]:
|
|
|
|
|
styles['searchOption'] = 'info'
|
|
|
|
|
styles['drawContent'] = styles['torrentPlayer'] = styles['openTorrent'] = styles['drawtrackerList'] = 'info'
|
2015-01-13 21:19:14 +03:00
|
|
|
|
styles['uTorrentBrowser'] = styles['History'] = styles['DownloadStatus'] = 'wide'
|
2015-01-09 14:11:21 +03:00
|
|
|
|
styles['showFilesList'] = styles['sectionMenu'] = 'wide'
|
|
|
|
|
styles['List'] = styles['drawcontentList'] = 'info3'
|
|
|
|
|
|
|
|
|
|
if view_style == 1:
|
2015-01-13 21:19:14 +03:00
|
|
|
|
styles['uTorrentBrowser'] = styles['torrentPlayer'] = 'wide'
|
|
|
|
|
styles['openTorrent'] = styles['History'] = styles['DownloadStatus'] = 'wide'
|
2015-01-09 14:11:21 +03:00
|
|
|
|
styles['sectionMenu'] = 'icons'
|
|
|
|
|
|
|
|
|
|
if view_style in [1, 3, 4]:
|
|
|
|
|
num_skin = 0
|
|
|
|
|
elif view_style == 2:
|
|
|
|
|
num_skin = 1
|
|
|
|
|
|
|
|
|
|
style = styles.get(func)
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('[view_style]: lock '+str(style))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
lockView(style, num_skin)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def lockView(viewId='info', num_skin=0):
|
|
|
|
|
xbmcplugin.setContent(int(sys.argv[1]), 'movies')
|
|
|
|
|
skinOptimizations = (
|
|
|
|
|
{'list': 50, 'info': 50, 'wide': 51, 'icons': 500, 'info3': 515, }, # Confluence
|
|
|
|
|
{'list': 50, 'info': 51, 'wide': 52, 'icons': 53, } # Transperency!
|
|
|
|
|
)
|
|
|
|
|
try:
|
|
|
|
|
xbmc.executebuiltin("Container.SetViewMode(%s)" % str(skinOptimizations[num_skin][viewId]))
|
|
|
|
|
except:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
<include>PosterWrapView2_Fanart</include> <!-- view id = 508 -->
|
|
|
|
|
<include>MediaListView3</include> <!-- view id = 503 -->
|
|
|
|
|
<include>MediaListView2</include> <!-- view id = 504 -->
|
|
|
|
|
<include>MediaListView4</include> <!-- view id = 515 -->
|
|
|
|
|
<include>WideIconView</include> <!-- view id = 505 -->
|
|
|
|
|
<include>MusicVideoInfoListView</include> <!-- view id = 511 -->
|
|
|
|
|
<include>AddonInfoListView1</include> <!-- view id = 550 -->
|
|
|
|
|
<include>AddonInfoThumbView1</include> <!-- view id = 551 -->
|
|
|
|
|
<include>LiveTVView1</include> <!-- view id = 560 -->
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def torrent_dir():
|
|
|
|
|
from resources.utorrent.net import Download
|
|
|
|
|
|
|
|
|
|
socket.setdefaulttimeout(3)
|
|
|
|
|
list = Download().list()
|
|
|
|
|
ret = 0
|
|
|
|
|
if list and len(list) > 0:
|
|
|
|
|
dirs = ["Keyboard"]
|
|
|
|
|
for dl in list:
|
|
|
|
|
if dl['dir'] not in dirs:
|
|
|
|
|
dirs.append(dl['dir'])
|
|
|
|
|
basename = os.path.dirname(dl['dir'])
|
|
|
|
|
if basename not in dirs:
|
|
|
|
|
dirs.append(basename)
|
|
|
|
|
else:
|
|
|
|
|
dirs.remove(basename)
|
|
|
|
|
dirs.insert(1, basename)
|
|
|
|
|
|
|
|
|
|
dialog = xbmcgui.Dialog()
|
|
|
|
|
ret = dialog.select(Localization.localize('Manual Torrent-client Path Edit'), dirs)
|
|
|
|
|
else:
|
|
|
|
|
ret = 0
|
|
|
|
|
|
|
|
|
|
if ret == 0:
|
|
|
|
|
KB = xbmc.Keyboard()
|
|
|
|
|
KB.setHeading(Localization.localize('Manual Torrent-client Path Edit'))
|
|
|
|
|
KB.setDefault(__settings__.getSetting("torrent_dir"))
|
|
|
|
|
KB.doModal()
|
|
|
|
|
if (KB.isConfirmed()):
|
|
|
|
|
__settings__.setSetting("torrent_dir", KB.getText())
|
|
|
|
|
elif ret > 0:
|
|
|
|
|
__settings__.setSetting("torrent_dir", dirs[ret])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def saveCheckPoint():
|
|
|
|
|
__settings__.setSetting("checkpoint", str(sys.argv[2]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def gotoCheckPoint():
|
|
|
|
|
xbmc.executebuiltin(
|
|
|
|
|
'XBMC.ActivateWindow(Videos,plugin://plugin.video.myshows/%s)' % (__settings__.getSetting("checkpoint")))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def smbtopath(path):
|
|
|
|
|
x = path.split('@')
|
|
|
|
|
if len(x) > 1:
|
|
|
|
|
path = x[1]
|
|
|
|
|
else:
|
|
|
|
|
path = path.replace('smb://', '')
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[smbtopath]:' + '\\\\' + path.replace('/', '\\'))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return '\\\\' + path.replace('/', '\\')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def PrepareFilename(filename):
|
|
|
|
|
badsymb = [':', '"', '\\', '/', '\'', '!', ['&', 'and'], '*', '?', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
|
|
|
|
' ',
|
|
|
|
|
' ', ' ']
|
|
|
|
|
for b in badsymb:
|
|
|
|
|
if not isinstance(b, list):
|
|
|
|
|
filename = filename.replace(b, ' ')
|
|
|
|
|
else:
|
|
|
|
|
filename = filename.replace(b[0], b[1])
|
|
|
|
|
return filename.rstrip('. ')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def PrepareSearch(filename):
|
|
|
|
|
titles = [filename]
|
|
|
|
|
rstr = '. -'
|
|
|
|
|
badsymb = [':', '"', r'\\', '/', r'\'', '!', '&', '*', '_', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
|
|
|
|
' ', ' ']
|
|
|
|
|
for b in badsymb:
|
|
|
|
|
filename = filename.replace(b, ' ')
|
|
|
|
|
|
|
|
|
|
filename = re.sub("\([^)]*\)([^(]*)", "\\1", filename)
|
|
|
|
|
filename = re.sub("\[[^\]]*\]([^\[]*)", "\\1", filename)
|
|
|
|
|
filename = filename.strip().rstrip(rstr)
|
|
|
|
|
|
|
|
|
|
if titles[0] != filename and filename != '': titles.insert(0, filename)
|
|
|
|
|
|
|
|
|
|
title_array = [(u'(.+?)(Cезон|cезон|Сезон|сезон|Season|season|СЕЗОН|SEASON)', titles[0], 0),
|
|
|
|
|
(u'(.+?)[sS](\d{1,2})', titles[0].replace('.', ' '), 0),
|
2015-06-23 23:00:27 +03:00
|
|
|
|
]
|
2015-01-09 14:11:21 +03:00
|
|
|
|
for regex, title, i in title_array:
|
|
|
|
|
recomp = re.compile(regex)
|
|
|
|
|
match = recomp.findall(title)
|
|
|
|
|
if match:
|
|
|
|
|
titles.insert(0, match[0][i].rstrip(rstr))
|
|
|
|
|
|
|
|
|
|
return titles
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def kinorate(title, year, titleAlt=None, kinopoiskId=None):
|
|
|
|
|
if kinopoiskId:
|
|
|
|
|
match = {'title': title.replace('"', ''), 'year': str(year), 'kinopoiskId': str(kinopoiskId)}
|
|
|
|
|
else:
|
|
|
|
|
match = {'title': title.replace('"', ''), 'year': str(year)}
|
|
|
|
|
if titleAlt:
|
|
|
|
|
match['titleAlt'] = titleAlt.replace('"', '')
|
|
|
|
|
try:
|
|
|
|
|
xbmc.executebuiltin(
|
|
|
|
|
'xbmc.RunScript(' + xbmcaddon.Addon("script.myshows").getAddonInfo("path") + os.sep +
|
|
|
|
|
'sync_exec.py,' + json.dumps(match).replace(',', '|:|') + ')')
|
|
|
|
|
except:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RateShow():
|
|
|
|
|
def __init__(self, showId, watched_jdata=None):
|
|
|
|
|
self.dialog = xbmcgui.Dialog()
|
|
|
|
|
self.showId = showId
|
|
|
|
|
self.list = {}
|
|
|
|
|
if watched_jdata:
|
|
|
|
|
self.watched_jdata = watched_jdata
|
|
|
|
|
else:
|
|
|
|
|
watched_data = Data(cookie_auth, __baseurl__ + '/profile/shows/' + str(showId) + '/',
|
|
|
|
|
__baseurl__ + '/profile/shows/' + str(showId) + '/')
|
|
|
|
|
try:
|
|
|
|
|
self.watched_jdata = json.loads(watched_data.get())
|
|
|
|
|
except:
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[RateShow] no watched_jdata1')
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return
|
|
|
|
|
if not self.watched_jdata:
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[RateShow] no watched_jdata2')
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
def seasonrates(self):
|
|
|
|
|
jload = Data(cookie_auth, __baseurl__ + '/profile/shows/').get()
|
|
|
|
|
jshowdata = json.loads(jload)
|
|
|
|
|
if str(self.showId) in jshowdata:
|
|
|
|
|
self.list, seasonNumber = self.listSE(jshowdata[str(self.showId)]['totalEpisodes'])
|
|
|
|
|
ratedict = {}
|
|
|
|
|
for i in self.list:
|
|
|
|
|
for j in self.list[i]:
|
|
|
|
|
if self.watched_jdata.has_key(j):
|
|
|
|
|
if self.watched_jdata[j]['rating']:
|
|
|
|
|
if ratedict.has_key(i):
|
|
|
|
|
ratedict[i].append(self.watched_jdata[j]['rating'])
|
|
|
|
|
else:
|
|
|
|
|
ratedict[i] = [self.watched_jdata[j]['rating']]
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('[ratedict]:'+str(ratedict))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
for i in ratedict:
|
|
|
|
|
ratedict[i] = (round(float(sum(ratedict[i])) / len(ratedict[i]), 2), len(ratedict[i]))
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[ratedict]:' + str(ratedict))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
else:
|
|
|
|
|
ratedict = {}
|
|
|
|
|
return ratedict
|
|
|
|
|
|
|
|
|
|
def count(self):
|
|
|
|
|
ratings, seasonratings = [], []
|
|
|
|
|
showId = str(self.showId)
|
|
|
|
|
jload = Data(cookie_auth, __baseurl__ + '/profile/shows/').get()
|
|
|
|
|
jshowdata = json.loads(jload)
|
|
|
|
|
self.list, seasonNumber = self.listSE(jshowdata[showId]['totalEpisodes'])
|
|
|
|
|
old_rating = jshowdata[showId]['rating']
|
|
|
|
|
for id in self.watched_jdata:
|
|
|
|
|
if self.watched_jdata[id]['rating']:
|
|
|
|
|
ratings.append(self.watched_jdata[id]['rating'])
|
|
|
|
|
if id in self.list[str(seasonNumber)]:
|
|
|
|
|
seasonratings.append(self.watched_jdata[id]['rating'])
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('ratings:'+str(ratings)+'; seasonratings:'+str(seasonratings))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
if len(ratings) > 0:
|
|
|
|
|
rating = round(float(sum(ratings)) / len(ratings), 2)
|
|
|
|
|
else:
|
|
|
|
|
rating = 0
|
|
|
|
|
if len(seasonratings) > 0:
|
|
|
|
|
seasonrating = round(float(sum(seasonratings)) / len(seasonratings), 2)
|
|
|
|
|
else:
|
|
|
|
|
seasonrating = 0
|
|
|
|
|
return rating, seasonNumber, seasonrating, old_rating
|
|
|
|
|
|
|
|
|
|
def listSE(self, maxep):
|
|
|
|
|
listSE, seasonNumber = {}, 0
|
|
|
|
|
data = Data(cookie_auth, __baseurl__ + '/shows/' + str(self.showId))
|
|
|
|
|
jdata = json.loads(data.get())
|
|
|
|
|
for id in jdata['episodes']:
|
|
|
|
|
if maxep >= jdata['episodes'][id]['sequenceNumber']:
|
|
|
|
|
if listSE.has_key(str(jdata['episodes'][id]['seasonNumber'])):
|
|
|
|
|
listSE[str(jdata['episodes'][id]['seasonNumber'])].append(id)
|
|
|
|
|
else:
|
|
|
|
|
listSE[str(jdata['episodes'][id]['seasonNumber'])] = [id]
|
|
|
|
|
if jdata['episodes'][id]['seasonNumber'] > seasonNumber:
|
|
|
|
|
seasonNumber = jdata['episodes'][id]['seasonNumber']
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('[listSE] '+str(listSE)+str(seasonNumber))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return listSE, seasonNumber
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def isRemoteTorr():
|
|
|
|
|
localhost = ['127.0.0.1', '0.0.0.0', 'localhost']
|
|
|
|
|
if __settings__.getSetting("torrent") == '0':
|
|
|
|
|
if __settings__.getSetting("torrent_utorrent_host") not in localhost:
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[isRemoteTorr]: uTorrent is Remote!')
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return True
|
|
|
|
|
elif __settings__.getSetting("torrent") == '1':
|
|
|
|
|
if __settings__.getSetting("torrent_transmission_host") not in localhost:
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[isRemoteTorr]: Transmission is Remote!')
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def changeDBTitle(showId):
|
|
|
|
|
from utilities import xbmcJsonRequest
|
|
|
|
|
|
|
|
|
|
shows = xbmcJsonRequest(
|
|
|
|
|
{'jsonrpc': '2.0', 'method': 'VideoLibrary.GetTVShows', 'params': {'properties': ['title']}, 'id': 0})
|
|
|
|
|
|
|
|
|
|
if not shows:
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[changeDBTitle]: XBMC JSON Result was empty.')
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if 'tvshows' in shows:
|
|
|
|
|
shows = shows['tvshows']
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug("[changeDBTitle]: XBMC JSON Result: '%s'" % str(shows))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
else:
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug("[changeDBTitle]: Key 'tvshows' not found")
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if len(shows) > 0:
|
|
|
|
|
newtitle = id2title(showId, None, True)[0].decode('utf-8', 'ignore')
|
|
|
|
|
dialog = xbmcgui.Dialog()
|
|
|
|
|
dialog_items, dialog_ids = [__language__(30205)], [-1]
|
|
|
|
|
shows = sorted(shows, key=lambda x: x['tvshowid'], reverse=True)
|
|
|
|
|
for show in shows:
|
|
|
|
|
dialog_ids.append(show['tvshowid'])
|
|
|
|
|
dialog_items.append(show['title'])
|
|
|
|
|
|
|
|
|
|
ret = dialog.select(newtitle, dialog_items)
|
|
|
|
|
if ret > 0:
|
|
|
|
|
ok = dialog.yesno(__language__(30322), __language__(30534),
|
|
|
|
|
__language__(30535) % (dialog_items[ret], newtitle))
|
|
|
|
|
if ok:
|
|
|
|
|
result = xbmcJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.SetTVShowDetails',
|
|
|
|
|
'params': {'tvshowid': int(dialog_ids[ret]), 'title': unicode(newtitle)},
|
|
|
|
|
'id': 1})
|
|
|
|
|
if result in [newtitle, 'OK']:
|
|
|
|
|
showMessage(__language__(30208), __language__(30536) % (newtitle), forced=True)
|
|
|
|
|
else:
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug("[changeDBTitle]: XBMC JSON Result: '%s'" % str(result))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TimeOut():
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.scan = CacheDB('web_timeout')
|
|
|
|
|
self.gone_online = CacheDB('go_online')
|
|
|
|
|
self.get = self.scan.get()
|
|
|
|
|
self.online = 30
|
|
|
|
|
self.offline = 1
|
|
|
|
|
|
|
|
|
|
def go_offline(self, manual=False):
|
|
|
|
|
gone_online = self.gone_online.get()
|
|
|
|
|
if gone_online:
|
|
|
|
|
gone_online = int(gone_online)
|
|
|
|
|
else:
|
|
|
|
|
gone_online = 0
|
|
|
|
|
if not manual:
|
|
|
|
|
if gone_online and gone_online + self.online >= int(round(time.time())):
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[TimeOut]: too soon to go back offline! %d s' % (
|
2015-01-09 14:11:21 +03:00
|
|
|
|
(gone_online + self.online * 4) - int(round(time.time()))))
|
|
|
|
|
return
|
|
|
|
|
if self.timeout() == self.online:
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[TimeOut]: Gone offline! %d s' % ((gone_online + self.online * 4) - int(round(time.time()))))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
showMessage(__language__(30520), __language__(30545) % (self.offline))
|
|
|
|
|
if self.get: self.scan.delete()
|
|
|
|
|
self.scan.add()
|
|
|
|
|
|
|
|
|
|
def go_online(self):
|
|
|
|
|
if self.get:
|
|
|
|
|
self.scan.delete()
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[TimeOut]: Gone online!')
|
2015-01-09 14:11:21 +03:00
|
|
|
|
showMessage(__language__(30521), __language__(30545) % (self.online))
|
|
|
|
|
if self.gone_online.get():
|
|
|
|
|
self.gone_online.delete()
|
|
|
|
|
self.gone_online.add()
|
|
|
|
|
|
|
|
|
|
def timeout(self):
|
|
|
|
|
if self.get and int(time.time()) - self.get < refresh_period * 3600:
|
|
|
|
|
to = self.offline
|
|
|
|
|
else:
|
|
|
|
|
to = self.online
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('[TimeOut]: '+str(to))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return to
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
|
class ListDB:
|
|
|
|
|
def __init__(self, version=1.0):
|
|
|
|
|
self.dbname = 'list' + '.db3'
|
|
|
|
|
dirname = xbmc.translatePath('special://temp')
|
|
|
|
|
self.dbfilename = os.path.join(dirname, 'xbmcup',
|
|
|
|
|
__settings__.getAddonInfo('id').replace('plugin://', '').replace('/', ''),
|
|
|
|
|
self.dbname)
|
|
|
|
|
self.version = version
|
|
|
|
|
if not xbmcvfs.exists(self.dbfilename):
|
|
|
|
|
self.creat_db()
|
|
|
|
|
|
|
|
|
|
def creat_db(self):
|
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute('pragma auto_vacuum=1')
|
|
|
|
|
self.cur.execute('create table db_ver(version real)')
|
|
|
|
|
# self.cur.execute('create table list(addtime integer PRIMARY KEY, title varchar(32), originaltitle varchar(32)'
|
|
|
|
|
# ', year integer, category varchar(32), subcategory varchar(32))')
|
|
|
|
|
self.cur.execute('create table list(addtime integer PRIMARY KEY, info varchar(32))')
|
2015-06-23 23:00:27 +03:00
|
|
|
|
self.cur.execute('insert into db_ver(version) values(?)', (self.version,))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
|
|
|
|
def get(self, addtime):
|
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute('select info from list where addtime="' + addtime + '"')
|
|
|
|
|
x = self.cur.fetchone()
|
|
|
|
|
self._close()
|
|
|
|
|
return x[0] if x else None
|
|
|
|
|
|
|
|
|
|
def get_all(self):
|
|
|
|
|
self._connect()
|
|
|
|
|
# self.cur.execute('select addtime,title,originaltitle,year,category,subcategory from list')
|
|
|
|
|
self.cur.execute('select addtime,info from list')
|
|
|
|
|
x = self.cur.fetchall()
|
|
|
|
|
self._close()
|
|
|
|
|
return x if x else None
|
|
|
|
|
|
|
|
|
|
def add(self, url):
|
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute('insert into list(addtime,info)'
|
|
|
|
|
' values(?,?)', (int(time.time()), url))
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
|
|
|
|
def delete(self, addtime):
|
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute('delete from list where addtime="' + addtime + '"')
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
|
|
|
|
def _connect(self):
|
|
|
|
|
self.db = sqlite.connect(self.dbfilename)
|
|
|
|
|
self.cur = self.db.cursor()
|
|
|
|
|
|
|
|
|
|
def _close(self):
|
|
|
|
|
self.cur.close()
|
|
|
|
|
self.db.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HistoryDB:
|
2015-01-12 23:10:20 +03:00
|
|
|
|
def __init__(self, version=1.1):
|
|
|
|
|
self.name = 'history.db3'
|
2015-01-09 14:11:21 +03:00
|
|
|
|
self.version = version
|
|
|
|
|
|
|
|
|
|
def get_all(self):
|
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute('select addtime,string,fav from history order by addtime DESC')
|
|
|
|
|
x = self.cur.fetchall()
|
|
|
|
|
self._close()
|
|
|
|
|
return x if x else None
|
|
|
|
|
|
|
|
|
|
def get(self, url):
|
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute('select string from history where string="' + url + '"')
|
|
|
|
|
x = self.cur.fetchone()
|
|
|
|
|
self._close()
|
|
|
|
|
return x[0] if x else None
|
|
|
|
|
|
|
|
|
|
def get_providers(self, addtime):
|
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute('select providers from history where addtime="' + addtime + '"')
|
|
|
|
|
x = self.cur.fetchone()
|
|
|
|
|
self._close()
|
2015-06-23 23:00:27 +03:00
|
|
|
|
# print 'get_providers: '+str(x[0].split(',') if x and x[0]!='' else None)
|
|
|
|
|
return x[0].split(',') if x and x[0] != '' else None
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
|
|
def set_providers(self, addtime, providers):
|
|
|
|
|
self._connect()
|
|
|
|
|
if isinstance(providers, dict):
|
2015-06-23 23:00:27 +03:00
|
|
|
|
temp = []
|
2015-01-09 14:11:21 +03:00
|
|
|
|
for i in providers.keys():
|
|
|
|
|
if providers.get(i):
|
|
|
|
|
temp.append(i)
|
2015-06-23 23:00:27 +03:00
|
|
|
|
providers = temp
|
|
|
|
|
str_p = ','.join(providers)
|
2015-01-09 14:11:21 +03:00
|
|
|
|
self.cur.execute('UPDATE history SET providers = "' + str_p + '" where addtime=' + addtime)
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
|
|
|
|
def change_providers(self, addtime, searcher):
|
|
|
|
|
self._connect()
|
2015-06-23 23:00:27 +03:00
|
|
|
|
providers = self.get_providers(addtime)
|
|
|
|
|
keys = Searchers().dic().keys()
|
|
|
|
|
if providers and len(providers) > 0:
|
2015-01-14 23:24:01 +03:00
|
|
|
|
if searcher in providers:
|
|
|
|
|
providers.remove(searcher)
|
|
|
|
|
else:
|
|
|
|
|
providers.append(searcher)
|
|
|
|
|
for i in providers:
|
|
|
|
|
if i not in keys:
|
|
|
|
|
providers.remove(i)
|
|
|
|
|
self.set_providers(addtime, providers)
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
|
|
def add(self, url):
|
2015-01-31 23:28:30 +03:00
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute('select fav from history where string="' + url + '"')
|
|
|
|
|
x = self.cur.fetchone()
|
2015-06-23 23:00:27 +03:00
|
|
|
|
if x: x = int(x[0])
|
|
|
|
|
fav = True if x else False
|
2015-01-31 23:28:30 +03:00
|
|
|
|
if not fav:
|
2015-06-23 23:00:27 +03:00
|
|
|
|
self.cur.execute('delete from history where string="' + decode(url) + '"')
|
2015-01-09 14:11:21 +03:00
|
|
|
|
self.cur.execute('insert into history(addtime,string,fav,providers)'
|
2015-06-23 23:00:27 +03:00
|
|
|
|
' values(?,?,?,?)', (int(time.time()), decode(url), 0, ""))
|
2015-01-31 23:28:30 +03:00
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
|
|
def update(self, addtime, fav):
|
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute('UPDATE history SET fav = ' + str(fav) + ' where addtime=' + addtime)
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
|
|
|
|
def fav(self, addtime):
|
|
|
|
|
self.update(addtime, fav=1)
|
|
|
|
|
|
|
|
|
|
def unfav(self, addtime):
|
|
|
|
|
self.update(addtime, fav=0)
|
|
|
|
|
|
|
|
|
|
def delete(self, addtime):
|
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute('delete from history where addtime="' + addtime + '"')
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
|
|
|
|
def clear(self):
|
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute('delete from history where fav=0')
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
|
|
|
|
def _connect(self):
|
|
|
|
|
dirname = xbmc.translatePath('special://temp')
|
|
|
|
|
for subdir in ('xbmcup', 'plugin.video.torrenter'):
|
|
|
|
|
dirname = os.path.join(dirname, subdir)
|
|
|
|
|
if not xbmcvfs.exists(dirname):
|
|
|
|
|
xbmcvfs.mkdir(dirname)
|
|
|
|
|
|
|
|
|
|
self.filename = os.path.join(dirname, self.name)
|
|
|
|
|
|
|
|
|
|
first = False
|
|
|
|
|
if not xbmcvfs.exists(self.filename):
|
|
|
|
|
first = True
|
|
|
|
|
|
|
|
|
|
self.db = sqlite.connect(self.filename, check_same_thread=False)
|
|
|
|
|
if not first:
|
|
|
|
|
self.cur = self.db.cursor()
|
|
|
|
|
try:
|
|
|
|
|
self.cur.execute('select version from db_ver')
|
|
|
|
|
row = self.cur.fetchone()
|
|
|
|
|
if not row or float(row[0]) != self.version:
|
|
|
|
|
self.cur.execute('drop table history')
|
|
|
|
|
self.cur.execute('drop table if exists db_ver')
|
|
|
|
|
first = True
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self.cur.close()
|
|
|
|
|
except:
|
|
|
|
|
self.cur.execute('drop table history')
|
|
|
|
|
first = True
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self.cur.close()
|
|
|
|
|
|
|
|
|
|
if first:
|
|
|
|
|
cur = self.db.cursor()
|
|
|
|
|
cur.execute('pragma auto_vacuum=1')
|
|
|
|
|
cur.execute('create table db_ver(version real)')
|
|
|
|
|
cur.execute(
|
|
|
|
|
'create table history(addtime integer PRIMARY KEY, string varchar(32), providers varchar(32), fav integer)')
|
2015-06-23 23:00:27 +03:00
|
|
|
|
cur.execute('insert into db_ver(version) values(?)', (self.version,))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
self.db.commit()
|
|
|
|
|
cur.close()
|
|
|
|
|
self.cur = self.db.cursor()
|
|
|
|
|
|
|
|
|
|
def _close(self):
|
|
|
|
|
self.cur.close()
|
|
|
|
|
self.db.close()
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
|
class Searchers():
|
|
|
|
|
def __init__(self):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def getBoolSetting(self, setting):
|
|
|
|
|
return __settings__.getSetting(setting).lower() == "true"
|
|
|
|
|
|
|
|
|
|
def setBoolSetting(self, setting, bool=True):
|
|
|
|
|
__settings__.setSetting(setting, "true" if bool else "false")
|
|
|
|
|
|
2015-07-01 23:15:29 +03:00
|
|
|
|
def list(self, only=None):
|
|
|
|
|
searchersDict = {}
|
|
|
|
|
if only!='external':
|
|
|
|
|
searchers_dir = os.path.join(ROOT, 'resources', 'searchers')
|
|
|
|
|
searchers_dirList=xbmcvfs.listdir(searchers_dir)[1]
|
|
|
|
|
for searcherFile in searchers_dirList:
|
|
|
|
|
if re.match('^(\w+)\.py$', searcherFile):
|
|
|
|
|
name=searcherFile.replace('.py', '')
|
|
|
|
|
searchersDict[name]={'name':name,
|
|
|
|
|
'path':searchers_dir,
|
|
|
|
|
'searcher':os.path.join(searchers_dir,name+'.py'),
|
|
|
|
|
'type':'local'}
|
|
|
|
|
if only!='local':
|
|
|
|
|
addons_dir = os.path.join(xbmc.translatePath('special://home'),'addons')
|
|
|
|
|
addons_dirsList = xbmcvfs.listdir(addons_dir)[0]
|
|
|
|
|
for searcherDir in addons_dirsList:
|
|
|
|
|
if re.match('^torrenter\.searcher\.(\w+)$', searcherDir):
|
|
|
|
|
name=searcherDir.replace('torrenter.searcher.', '')
|
|
|
|
|
path=os.path.join(addons_dir, searcherDir)
|
|
|
|
|
searchersDict[name]={'name':name,
|
|
|
|
|
'path':path,
|
|
|
|
|
'searcher':os.path.join(path,name+'.py'),
|
|
|
|
|
'type':'external'}
|
2015-07-15 19:14:22 +03:00
|
|
|
|
#if len(searchersDict)>1: break
|
2015-07-01 23:15:29 +03:00
|
|
|
|
return searchersDict
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
|
|
def dic(self, providers=[]):
|
|
|
|
|
dic = {}
|
|
|
|
|
for searcher in self.list():
|
|
|
|
|
if not providers:
|
|
|
|
|
dic[searcher] = self.old(searcher)
|
|
|
|
|
else:
|
|
|
|
|
dic[searcher] = searcher in providers
|
|
|
|
|
return dic
|
|
|
|
|
|
|
|
|
|
def old(self, searcher):
|
|
|
|
|
if not self.getBoolSetting('old_' + searcher):
|
|
|
|
|
self.setBoolSetting('old_' + searcher)
|
|
|
|
|
self.setBoolSetting(searcher)
|
|
|
|
|
return self.getBoolSetting(searcher)
|
|
|
|
|
|
|
|
|
|
def get_active(self):
|
|
|
|
|
get_active = []
|
2015-07-04 18:53:45 +03:00
|
|
|
|
for searcher in self.list().keys():
|
2015-01-09 14:11:21 +03:00
|
|
|
|
if self.old(searcher): get_active.append(searcher + '.py')
|
2015-07-17 23:16:00 +03:00
|
|
|
|
log('Active Searchers: ' + str(get_active))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return get_active
|
|
|
|
|
|
2015-07-01 23:15:29 +03:00
|
|
|
|
def searchWithSearcher(self, keyword, searcher):
|
|
|
|
|
filesList = []
|
|
|
|
|
slist = Searchers().list()
|
|
|
|
|
if slist[searcher]['path'] not in sys.path:
|
|
|
|
|
sys.path.insert(0, slist[searcher]['path'])
|
|
|
|
|
print 'Added %s in sys.path' % (slist[searcher]['path'])
|
|
|
|
|
try:
|
|
|
|
|
searcherObject = getattr(__import__(searcher), searcher)()
|
|
|
|
|
filesList = searcherObject.search(keyword)
|
|
|
|
|
except Exception, e:
|
|
|
|
|
print 'Unable to use searcher: ' + searcher + ' at ' + __plugin__ + ' searchWithSearcher(). Exception: ' + str(
|
|
|
|
|
e)
|
2015-07-12 16:14:12 +03:00
|
|
|
|
print(traceback.format_exc())
|
2015-07-01 23:15:29 +03:00
|
|
|
|
return filesList
|
|
|
|
|
|
|
|
|
|
def downloadWithSearcher(self, url, searcher):
|
|
|
|
|
slist = Searchers().list()
|
|
|
|
|
if slist[searcher]['path'] not in sys.path:
|
|
|
|
|
sys.path.insert(0, slist[searcher]['path'])
|
|
|
|
|
print 'Added %s in sys.path' % (slist[searcher]['path'])
|
|
|
|
|
try:
|
|
|
|
|
searcherObject = getattr(__import__(searcher), searcher)()
|
|
|
|
|
url = searcherObject.getTorrentFile(url)
|
|
|
|
|
except Exception, e:
|
|
|
|
|
print 'Unable to use searcher: ' + searcher + ' at ' + __plugin__ + ' downloadWithSearcher(). Exception: ' + str(
|
|
|
|
|
e)
|
|
|
|
|
return url
|
|
|
|
|
|
2015-07-15 19:14:22 +03:00
|
|
|
|
def checkExist(self, searcher):
|
|
|
|
|
if searcher not in self.list():
|
|
|
|
|
yes=xbmcgui.Dialog().yesno('< %s >' % Localization.localize('Torrenter Tracker Install'),
|
|
|
|
|
Localization.localize('Torrenter didn\'t find %s searcher' % searcher),
|
|
|
|
|
Localization.localize('Would you like to install %s from "MyShows.me Kodi Repo" in Programs section?') % searcher,)
|
|
|
|
|
if yes:
|
|
|
|
|
xbmc.executebuiltin('Dialog.Close(all,true)')
|
|
|
|
|
xbmc.executebuiltin('XBMC.ActivateWindow(Addonbrowser,addons://search/%s)' % ('Torrenter Searcher %s' % searcher))
|
|
|
|
|
|
2015-07-17 23:16:00 +03:00
|
|
|
|
def activeExternal(self):
|
|
|
|
|
slist = []
|
|
|
|
|
for searcher in self.list('external').keys():
|
|
|
|
|
if self.old(searcher): slist.append(searcher)
|
|
|
|
|
return slist
|
|
|
|
|
|
2015-07-15 19:14:22 +03:00
|
|
|
|
|
2015-07-01 23:15:29 +03:00
|
|
|
|
def search(url, searchersList, isApi=None):
|
|
|
|
|
from threading import Thread
|
2015-07-12 16:14:12 +03:00
|
|
|
|
try:
|
|
|
|
|
from Queue import Queue
|
|
|
|
|
except ImportError:
|
|
|
|
|
from queue import Queue
|
2015-07-01 23:15:29 +03:00
|
|
|
|
|
2015-07-17 23:16:00 +03:00
|
|
|
|
num_threads=__settings__.getSetting('num_threads')
|
2015-07-19 03:24:35 +03:00
|
|
|
|
if num_threads and int(num_threads)>0:
|
2015-07-17 23:16:00 +03:00
|
|
|
|
num_threads = int(num_threads)
|
|
|
|
|
else:
|
|
|
|
|
num_threads = 3
|
2015-07-01 23:15:29 +03:00
|
|
|
|
queue = Queue()
|
|
|
|
|
result = {}
|
|
|
|
|
iterator, filesList, left_searchers = 0, [], []
|
|
|
|
|
timeout_multi=int(sys.modules["__main__"].__settings__.getSetting("timeout"))
|
|
|
|
|
wait_time=10+(10*timeout_multi)
|
|
|
|
|
left_searchers.extend(searchersList)
|
|
|
|
|
if not isApi:
|
|
|
|
|
progressBar = xbmcgui.DialogProgress()
|
|
|
|
|
progressBar.create(Localization.localize('Please Wait'), Localization.localize('Materials are loading now.'))
|
|
|
|
|
|
|
|
|
|
def search_one(i, q):
|
|
|
|
|
while True:
|
|
|
|
|
if not isApi and progressBar.iscanceled():
|
|
|
|
|
progressBar.update(0)
|
|
|
|
|
progressBar.close()
|
|
|
|
|
return
|
|
|
|
|
iterator=100*int(len(searchersList)-len(left_searchers))/len(searchersList)
|
|
|
|
|
if not isApi:
|
|
|
|
|
progressBar.update(int(iterator), join_list(left_searchers, replace='.py'))
|
|
|
|
|
searcherFile = q.get()
|
|
|
|
|
searcher=searcherFile.replace('.py','')
|
|
|
|
|
print "Thread %s: Searching at %s" % (i, searcher)
|
|
|
|
|
result[searcherFile]=Searchers().searchWithSearcher(url, searcher)
|
|
|
|
|
left_searchers.remove(searcherFile)
|
|
|
|
|
q.task_done()
|
|
|
|
|
|
|
|
|
|
for i in range(num_threads):
|
|
|
|
|
worker = Thread(target=search_one, args=(i, queue))
|
|
|
|
|
worker.setDaemon(True)
|
|
|
|
|
worker.start()
|
|
|
|
|
|
|
|
|
|
for searcherFile in searchersList:
|
|
|
|
|
queue.put(searcherFile, timeout=wait_time)
|
|
|
|
|
|
|
|
|
|
print "Main Thread Waiting"
|
|
|
|
|
queue.join()
|
|
|
|
|
print "Done"
|
|
|
|
|
|
|
|
|
|
if not isApi:
|
|
|
|
|
progressBar.update(0)
|
|
|
|
|
progressBar.close()
|
|
|
|
|
|
|
|
|
|
for k in result.keys():
|
|
|
|
|
filesList.extend(result[k])
|
|
|
|
|
return filesList
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def join_list(l, char=', ', replace=''):
|
|
|
|
|
string=''
|
|
|
|
|
for i in l:
|
|
|
|
|
string+=i.replace(replace,'')+char
|
|
|
|
|
return string.rstrip(' ,')
|
|
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
|
|
|
|
|
|
class Contenters():
|
|
|
|
|
def __init__(self):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def first_time(self, scrapperDB_ver, language='ru'):
|
2015-01-15 22:53:23 +03:00
|
|
|
|
searcher = 'metadata'
|
2015-01-09 14:11:21 +03:00
|
|
|
|
redl = False
|
2015-06-23 23:00:27 +03:00
|
|
|
|
scrapperDB_ver = scrapperDB_ver[language]
|
|
|
|
|
if scrapperDB_ver != __settings__.getSetting('scrapperDB_ver' + language) and self.getBoolSetting(searcher):
|
|
|
|
|
__settings__.setSetting('scrapperDB_ver' + language, scrapperDB_ver)
|
2015-01-09 14:11:21 +03:00
|
|
|
|
ok = xbmcgui.Dialog().yesno('< %s >' % Localization.localize('Content Lists'),
|
|
|
|
|
Localization.localize('Your preloaded databases are outdated!'),
|
|
|
|
|
Localization.localize('Do you want to download new ones right now?'))
|
|
|
|
|
if ok:
|
|
|
|
|
dirname = xbmc.translatePath('special://temp')
|
|
|
|
|
dirname = os.path.join(dirname, 'xbmcup', 'plugin.video.torrenter')
|
|
|
|
|
scrapers = {'tvdb': 'TheTVDB.com', 'tmdb': 'TheMovieDB.org', 'kinopoisk': 'KinoPoisk.ru'}
|
|
|
|
|
for i in scrapers.keys():
|
2015-06-23 23:00:27 +03:00
|
|
|
|
xbmcvfs.delete(os.path.join(dirname, i + '.' + language + '.db'))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
showMessage(Localization.localize('Reset All Cache DBs'), Localization.localize('Deleted!'))
|
|
|
|
|
redl = True
|
|
|
|
|
else:
|
|
|
|
|
xbmcgui.Dialog().ok('< %s >' % Localization.localize('Content Lists'),
|
|
|
|
|
Localization.localize(
|
|
|
|
|
'You can always restart this by deleting DBs via Context Menu'), )
|
|
|
|
|
|
2015-01-15 22:53:23 +03:00
|
|
|
|
if not self.getBoolSetting('oldc_' + searcher + language):
|
2015-06-23 23:00:27 +03:00
|
|
|
|
self.setBoolSetting('oldc_' + searcher + language, True)
|
|
|
|
|
__settings__.setSetting('scrapperDB_ver' + language, scrapperDB_ver)
|
2015-01-09 14:11:21 +03:00
|
|
|
|
ok = xbmcgui.Dialog().yesno('< %s >' % Localization.localize('Content Lists'),
|
|
|
|
|
Localization.localize('Do you want to search and cache full metadata + arts?'),
|
|
|
|
|
Localization.localize(
|
|
|
|
|
'This vastly decreases load speed, but you will be asked to download premade bases!'))
|
|
|
|
|
if ok:
|
|
|
|
|
self.setBoolSetting(searcher, True)
|
|
|
|
|
redl = True
|
|
|
|
|
else:
|
|
|
|
|
self.setBoolSetting(searcher, False)
|
|
|
|
|
|
|
|
|
|
if redl:
|
|
|
|
|
self.Scraper = Scrapers()
|
|
|
|
|
scrapers = {'tvdb': 'TheTVDB.com', 'tmdb': 'TheMovieDB.org', 'kinopoisk': 'KinoPoisk.ru'}
|
|
|
|
|
for scraper in scrapers.keys():
|
2015-06-23 23:00:27 +03:00
|
|
|
|
if scraper != 'kinopoisk' or language == 'ru':
|
2015-01-09 14:11:21 +03:00
|
|
|
|
self.Scraper.scraper(scraper, {'label': 'Мстители', 'search': [u'Мстители', u'The Avengers'],
|
|
|
|
|
'year': 2012}, language)
|
|
|
|
|
|
|
|
|
|
def getBoolSetting(self, setting):
|
|
|
|
|
return __settings__.getSetting(setting).lower() == "true"
|
|
|
|
|
|
|
|
|
|
def setBoolSetting(self, setting, bool=True):
|
|
|
|
|
__settings__.setSetting(setting, "true" if bool else "false")
|
|
|
|
|
|
|
|
|
|
def list(self):
|
|
|
|
|
searchersList = []
|
|
|
|
|
dirList = os.listdir(ROOT + os.sep + 'resources' + os.sep + 'contenters')
|
|
|
|
|
for searcherFile in dirList:
|
|
|
|
|
if re.match('^(\w+)\.py$', searcherFile):
|
|
|
|
|
searchersList.append(searcherFile.replace('.py', ''))
|
|
|
|
|
return searchersList
|
|
|
|
|
|
|
|
|
|
def dic(self):
|
|
|
|
|
dic = {}
|
|
|
|
|
for searcher in self.list():
|
|
|
|
|
dic[searcher] = self.old(searcher)
|
|
|
|
|
return dic
|
|
|
|
|
|
|
|
|
|
def get_activedic(self):
|
|
|
|
|
dic = {}
|
|
|
|
|
# for searcher in self.list():
|
|
|
|
|
# if self.old(searcher): dic[searcher]=(searcher,)
|
|
|
|
|
for searcher in self.list():
|
|
|
|
|
dic[searcher] = (searcher,)
|
|
|
|
|
return dic
|
|
|
|
|
|
|
|
|
|
def old(self, searcher):
|
|
|
|
|
if not self.getBoolSetting('oldc_' + searcher):
|
|
|
|
|
self.setBoolSetting('oldc_' + searcher)
|
|
|
|
|
self.setBoolSetting(searcher)
|
|
|
|
|
return self.getBoolSetting(searcher)
|
|
|
|
|
|
|
|
|
|
def get_active(self):
|
|
|
|
|
get_active = []
|
|
|
|
|
for searcher in self.list():
|
|
|
|
|
if self.old(searcher): get_active.append(searcher)
|
|
|
|
|
return get_active
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WatchedDB:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
dirname = xbmc.translatePath('special://temp')
|
|
|
|
|
for subdir in ('xbmcup', __settings__.getAddonInfo('id').replace('plugin://', '').replace('/', '')):
|
|
|
|
|
dirname = os.path.join(dirname, subdir)
|
|
|
|
|
if not xbmcvfs.exists(dirname):
|
|
|
|
|
xbmcvfs.mkdir(dirname)
|
|
|
|
|
self.dbfilename = os.path.join(dirname, 'data.db3')
|
|
|
|
|
if not xbmcvfs.exists(self.dbfilename):
|
|
|
|
|
creat_db(self.dbfilename)
|
|
|
|
|
self.dialog = xbmcgui.Dialog()
|
|
|
|
|
|
|
|
|
|
def _get(self, id):
|
|
|
|
|
self._connect()
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[WatchedDB][_get]: Checking ' + id)
|
2015-01-09 14:11:21 +03:00
|
|
|
|
id = id.replace("'", "<&>").decode('utf-8', 'ignore')
|
|
|
|
|
self.where = " where id='%s'" % (id)
|
|
|
|
|
try:
|
|
|
|
|
self.cur.execute('select rating from watched' + self.where)
|
|
|
|
|
except:
|
|
|
|
|
self.cur.execute('create table watched(addtime integer, rating integer, id varchar(32) PRIMARY KEY)')
|
|
|
|
|
self.cur.execute('select rating from watched' + self.where)
|
|
|
|
|
res = self.cur.fetchone()
|
|
|
|
|
self._close()
|
|
|
|
|
return res[0] if res else None
|
|
|
|
|
|
|
|
|
|
def _get_all(self):
|
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute('select id, rating from watched order by addtime desc')
|
|
|
|
|
res = [[unicode(x[0]).replace("<&>", "'").encode('utf-8', 'ignore'), x[1]] for x in self.cur.fetchall()]
|
|
|
|
|
self._close()
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def check(self, id, rating=0):
|
|
|
|
|
ok1, ok3 = None, None
|
|
|
|
|
db_rating = self._get(id)
|
|
|
|
|
title = titlesync(id)
|
|
|
|
|
TimeOut().go_offline()
|
|
|
|
|
if getSettingAsBool("silentoffline"):
|
|
|
|
|
if db_rating == None and rating >= 0:
|
|
|
|
|
showMessage(__language__(30520), __language__(30522) % (str(rating)))
|
|
|
|
|
ok1 = True
|
|
|
|
|
elif db_rating >= 0 and rating != db_rating and rating > 0:
|
|
|
|
|
showMessage(__language__(30520), __language__(30523) % (str(rating)))
|
|
|
|
|
ok3 = True
|
|
|
|
|
elif db_rating != None and rating == db_rating:
|
|
|
|
|
showMessage(__language__(30520), __language__(30524) % (str(rating)))
|
|
|
|
|
else:
|
|
|
|
|
if db_rating == None and rating >= 0:
|
|
|
|
|
if title:
|
|
|
|
|
title = title.encode('utf-8', 'ignore')
|
|
|
|
|
ok1 = self.dialog.yesno(__language__(30520), __language__(30525) % (str(rating)), title)
|
|
|
|
|
else:
|
|
|
|
|
ok1 = True
|
|
|
|
|
elif db_rating and rating != db_rating:
|
|
|
|
|
if title:
|
|
|
|
|
title = title.encode('utf-8', 'ignore')
|
|
|
|
|
ok3 = self.dialog.yesno(__language__(30520), __language__(30526) % (str(db_rating), str(rating)),
|
|
|
|
|
title)
|
|
|
|
|
else:
|
|
|
|
|
ok3 = True
|
|
|
|
|
elif db_rating == 0 and rating != db_rating:
|
|
|
|
|
ok3 = True
|
|
|
|
|
elif db_rating != None and rating == db_rating:
|
|
|
|
|
showMessage(__language__(30520), __language__(30527) % (str(rating)))
|
|
|
|
|
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[WatchedDB][check]: rating: %s DB: %s, ok1: %s, ok3: %s' % (
|
2015-01-09 14:11:21 +03:00
|
|
|
|
str(rating), str(db_rating), str(ok1), str(ok3)))
|
|
|
|
|
|
|
|
|
|
if ok1:
|
|
|
|
|
self._add(id, rating)
|
|
|
|
|
return True
|
|
|
|
|
if ok3:
|
|
|
|
|
self._delete(id)
|
|
|
|
|
self._add(id, rating)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def onaccess(self):
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('[WatchedDB][onaccess]: Start')
|
2015-01-09 14:11:21 +03:00
|
|
|
|
TimeOut().go_online()
|
|
|
|
|
self._connect()
|
|
|
|
|
try:
|
|
|
|
|
self.cur.execute('select count(id) from watched')
|
|
|
|
|
except:
|
|
|
|
|
self.cur.execute('create table watched(addtime integer, rating integer, id varchar(32) PRIMARY KEY)')
|
|
|
|
|
self.cur.execute('select count(id) from watched')
|
|
|
|
|
x = self.cur.fetchone()
|
|
|
|
|
res = int(x[0])
|
|
|
|
|
self._close()
|
|
|
|
|
i = 0
|
|
|
|
|
|
|
|
|
|
if res > 0:
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('[WatchedDB][onaccess]: Found %s' % (str(res)))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
silentofflinesend = getSettingAsBool('silentofflinesend')
|
|
|
|
|
if not silentofflinesend:
|
|
|
|
|
ok2 = self.dialog.yesno(__language__(30521), __language__(30528) % (str(res)), __language__(30529))
|
|
|
|
|
else:
|
|
|
|
|
ok2 = True
|
|
|
|
|
if ok2:
|
|
|
|
|
for id, rating in self._get_all():
|
|
|
|
|
from addon import SyncXBMC
|
|
|
|
|
|
|
|
|
|
j = SyncXBMC(id, int(rating)).doaction()
|
|
|
|
|
if j:
|
|
|
|
|
i = i + int(j)
|
|
|
|
|
self._delete(id)
|
|
|
|
|
showMessage(__language__(30521), __language__(30530) % (i))
|
|
|
|
|
__settings__.setSetting("duo_last_id", '')
|
|
|
|
|
else:
|
|
|
|
|
ok2 = self.dialog.yesno(__language__(30521), __language__(30531) % (str(res)))
|
|
|
|
|
if ok2:
|
|
|
|
|
for id, rating in self._get_all():
|
|
|
|
|
self._delete(id)
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def _add(self, id, rating=0):
|
|
|
|
|
__settings__.setSetting("duo_last_id", '')
|
|
|
|
|
self._connect()
|
|
|
|
|
id = id.replace("'", "<&>").decode('utf-8', 'ignore')
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[WatchedDB][_add]: Adding %s with rate %d' % (id, rating))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
self.cur.execute('insert into watched(addtime, rating, id) values(?,?,?)', (int(time.time()), int(rating), id))
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
|
|
|
|
def _delete(self, id):
|
|
|
|
|
self._connect()
|
|
|
|
|
id = id.replace("'", "<&>").decode('utf-8', 'ignore')
|
|
|
|
|
self.cur.execute("delete from watched where id=('" + id + "')")
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
|
|
|
|
def count(self):
|
|
|
|
|
return len(self._get_all())
|
|
|
|
|
|
|
|
|
|
def _connect(self):
|
|
|
|
|
self.db = sqlite.connect(self.dbfilename)
|
|
|
|
|
self.cur = self.db.cursor()
|
|
|
|
|
|
|
|
|
|
def _close(self):
|
|
|
|
|
self.cur.close()
|
|
|
|
|
self.db.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def countSeasons(jdata):
|
|
|
|
|
seasons, epdict = [], {}
|
|
|
|
|
for id in jdata['episodes']:
|
|
|
|
|
seasonNumber = jdata['episodes'][id]['seasonNumber']
|
|
|
|
|
if seasonNumber not in seasons:
|
|
|
|
|
seasons.append(seasonNumber)
|
|
|
|
|
if jdata['episodes'][id]['episodeNumber']:
|
|
|
|
|
if str(jdata['episodes'][id]['seasonNumber']) not in epdict:
|
|
|
|
|
epdict[str(jdata['episodes'][id]['seasonNumber'])] = str(jdata['episodes'][id]['id'])
|
|
|
|
|
else:
|
|
|
|
|
epdict[str(jdata['episodes'][id]['seasonNumber'])] = epdict[str(
|
|
|
|
|
jdata['episodes'][id]['seasonNumber'])] + ',' + str(jdata['episodes'][id]['id'])
|
|
|
|
|
seasons.sort()
|
|
|
|
|
return seasons, epdict
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def fetchData(url, referer=None):
|
|
|
|
|
request = urllib2.Request(url)
|
|
|
|
|
if referer != None:
|
|
|
|
|
request.add_header('Referer', referer)
|
|
|
|
|
request.add_header('User-Agent', USERAGENT)
|
|
|
|
|
if __settings__.getSetting("auth"):
|
|
|
|
|
authString = '; ' + __settings__.getSetting("auth")
|
|
|
|
|
else:
|
|
|
|
|
authString = ''
|
|
|
|
|
request.add_header('Cookie', authString)
|
|
|
|
|
try:
|
|
|
|
|
connection = urllib2.urlopen(request)
|
|
|
|
|
result = connection.read()
|
|
|
|
|
connection.close()
|
|
|
|
|
return (result)
|
|
|
|
|
except (urllib2.HTTPError, urllib2.URLError) as e:
|
|
|
|
|
print " fetchData(" + url + ") exception: " + str(e)
|
|
|
|
|
return
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
|
def file_decode(filename):
|
2015-06-23 23:00:27 +03:00
|
|
|
|
if not __settings__.getSetting('delete_russian') == 'true':
|
2015-02-09 23:08:30 +03:00
|
|
|
|
try:
|
2015-06-23 23:00:27 +03:00
|
|
|
|
filename = filename.decode('utf-8') # ,'ignore')
|
2015-02-09 23:08:30 +03:00
|
|
|
|
except:
|
|
|
|
|
pass
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return filename
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
|
def file_encode(filename):
|
2015-06-23 23:00:27 +03:00
|
|
|
|
if not __settings__.getSetting('delete_russian') == 'true':
|
|
|
|
|
if sys.getfilesystemencoding() == 'mbcs' and isAsciiString(filename):
|
|
|
|
|
filename = filename.decode('cp1251').encode('utf-8')
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return filename
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
|
def isAsciiString(mediaName):
|
|
|
|
|
for index, char in enumerate(mediaName):
|
|
|
|
|
if ord(char) >= 128:
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
|
def getParameters(parameterString):
|
|
|
|
|
commands = {}
|
|
|
|
|
splitCommands = parameterString[parameterString.find('?') + 1:].split('&')
|
|
|
|
|
for command in splitCommands:
|
|
|
|
|
if (len(command) > 0):
|
|
|
|
|
splitCommand = command.split('=')
|
|
|
|
|
if (len(splitCommand) > 1):
|
|
|
|
|
name = splitCommand[0]
|
|
|
|
|
value = splitCommand[1]
|
|
|
|
|
commands[name] = value
|
|
|
|
|
return commands
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-09 14:11:21 +03:00
|
|
|
|
def isSubtitle(filename, filename2):
|
|
|
|
|
filename_if = filename[:len(filename) - len(filename.split('.')[-1]) - 1]
|
|
|
|
|
filename_if = filename_if.split('/')[-1].split('\\')[-1]
|
|
|
|
|
filename_if2 = filename2.split('/')[-1].split('\\')[-1][:len(filename_if)]
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('Compare ' + filename_if.lower() + ' and ' + filename_if2.lower() + ' and ' + filename2.lower().split('.')[-1])
|
2015-01-09 14:11:21 +03:00
|
|
|
|
ext = ['ass', 'mpsub', 'rum', 'sbt', 'sbv', 'srt', 'ssa', 'sub', 'sup', 'w32']
|
|
|
|
|
if filename2.lower().split('.')[-1] in ext and \
|
|
|
|
|
filename_if.lower() == filename_if2.lower():
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-11 13:05:44 +03:00
|
|
|
|
def delete_russian(ok=False, action='delete'):
|
2015-06-23 23:00:27 +03:00
|
|
|
|
i = 0
|
2015-01-09 14:11:21 +03:00
|
|
|
|
if not ok:
|
|
|
|
|
ok = xbmcgui.Dialog().yesno('< %s >' % Localization.localize('International Check - First Run'),
|
2015-06-23 23:00:27 +03:00
|
|
|
|
'Delete Russian stuff?',
|
|
|
|
|
Localization.localize('Delete Russian stuff?'))
|
2015-01-09 14:11:21 +03:00
|
|
|
|
if ok:
|
2015-06-23 23:00:27 +03:00
|
|
|
|
fileList = {
|
|
|
|
|
'contenters': ['CXZ.py', 'FastTorrent.py', 'KinoPoisk.py', 'RiperAM.py'],
|
|
|
|
|
'searchers': ['NNMClubRu.py', 'OpenSharing.py', 'RiperAM.py', 'RuTorOrg.py', 'RuTrackerOrg.py',
|
|
|
|
|
'TFileME.py']
|
2015-01-09 14:11:21 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for path in fileList.keys():
|
|
|
|
|
for filename in fileList[path]:
|
2015-06-23 23:00:27 +03:00
|
|
|
|
if action == 'delete':
|
|
|
|
|
filepath = os.path.join(ROOT, 'resources', path, filename)
|
2015-01-11 13:05:44 +03:00
|
|
|
|
if xbmcvfs.exists(filepath):
|
2015-06-23 23:00:27 +03:00
|
|
|
|
newfilepath = os.path.join(ROOT, 'resources', path, 'unused', filename)
|
2015-01-11 13:05:44 +03:00
|
|
|
|
xbmcvfs.copy(filepath, newfilepath)
|
|
|
|
|
xbmcvfs.delete(filepath)
|
2015-06-23 23:00:27 +03:00
|
|
|
|
elif action == 'return':
|
|
|
|
|
filepath = os.path.join(ROOT, 'resources', path, 'unused', filename)
|
2015-01-11 13:05:44 +03:00
|
|
|
|
if xbmcvfs.exists(filepath):
|
2015-06-23 23:00:27 +03:00
|
|
|
|
newfilepath = os.path.join(ROOT, 'resources', path, filename)
|
2015-01-11 13:05:44 +03:00
|
|
|
|
xbmcvfs.copy(filepath, newfilepath)
|
|
|
|
|
xbmcvfs.delete(filepath)
|
2015-06-23 23:00:27 +03:00
|
|
|
|
i = i + 1
|
2015-01-11 13:05:44 +03:00
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
if action == 'return':
|
2015-01-11 13:05:44 +03:00
|
|
|
|
return i
|
2015-01-09 14:11:21 +03:00
|
|
|
|
return True
|
|
|
|
|
else:
|
2015-01-12 23:10:20 +03:00
|
|
|
|
return False
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-12 23:10:20 +03:00
|
|
|
|
class DownloadDB:
|
2015-01-13 20:06:34 +03:00
|
|
|
|
def __init__(self, version=1.41):
|
2015-01-12 23:10:20 +03:00
|
|
|
|
self.name = 'download.db3'
|
|
|
|
|
self.version = version
|
|
|
|
|
|
|
|
|
|
def get_all(self):
|
|
|
|
|
self._connect()
|
2015-07-04 18:53:45 +03:00
|
|
|
|
self._execute(
|
|
|
|
|
'select addtime, title, path, type, jsoninfo, status, torrent, ind, lastupdate, storage from downloads order by addtime DESC')
|
2015-01-12 23:10:20 +03:00
|
|
|
|
x = self.cur.fetchall()
|
|
|
|
|
self._close()
|
|
|
|
|
return x if x else None
|
|
|
|
|
|
|
|
|
|
def get(self, title):
|
|
|
|
|
self._connect()
|
2015-07-04 18:53:45 +03:00
|
|
|
|
self._execute(
|
|
|
|
|
'select addtime, title, path, type, jsoninfo, status, torrent, ind, lastupdate, storage from downloads where title="' + decode(
|
|
|
|
|
title) + '"')
|
2015-01-12 23:10:20 +03:00
|
|
|
|
x = self.cur.fetchone()
|
|
|
|
|
self._close()
|
2015-01-13 20:06:34 +03:00
|
|
|
|
return x if x else None
|
|
|
|
|
|
|
|
|
|
def get_byaddtime(self, addtime):
|
|
|
|
|
self._connect()
|
2015-07-04 18:53:45 +03:00
|
|
|
|
self._execute(
|
2015-06-23 23:00:27 +03:00
|
|
|
|
'select addtime, title, path, type, jsoninfo, status, torrent, ind, lastupdate, storage from downloads where addtime="' + str(
|
|
|
|
|
addtime) + '"')
|
2015-01-13 20:06:34 +03:00
|
|
|
|
x = self.cur.fetchone()
|
|
|
|
|
self._close()
|
|
|
|
|
return x if x else None
|
2015-01-12 23:10:20 +03:00
|
|
|
|
|
2015-07-04 18:53:45 +03:00
|
|
|
|
def _execute(self, sql):
|
|
|
|
|
try:
|
|
|
|
|
self.cur.execute(sql)
|
2015-07-04 19:11:18 +03:00
|
|
|
|
except Exception, e:
|
|
|
|
|
if str(e)=='no such table: downloads':
|
|
|
|
|
cur = self.db.cursor()
|
|
|
|
|
cur.execute('pragma auto_vacuum=1')
|
|
|
|
|
cur.execute(
|
|
|
|
|
'create table downloads(addtime integer PRIMARY KEY, title varchar(32), path varchar(32), type varchar(32), jsoninfo varchar(32), status varchar(32), torrent varchar(32), ind integer, lastupdate integer, storage varchar(32))')
|
|
|
|
|
self.db.commit()
|
|
|
|
|
cur.close()
|
|
|
|
|
self.cur = self.db.cursor()
|
|
|
|
|
else:
|
|
|
|
|
self._close()
|
2015-07-16 20:32:50 +03:00
|
|
|
|
debug('[DownloadDB]: DELETE ' + str(self.filename))
|
2015-07-04 19:11:18 +03:00
|
|
|
|
xbmcvfs.delete(self.filename)
|
2015-07-04 18:53:45 +03:00
|
|
|
|
self._connect()
|
|
|
|
|
self.cur.execute(sql)
|
|
|
|
|
|
|
|
|
|
|
2015-01-13 17:24:53 +03:00
|
|
|
|
def get_status(self, title):
|
|
|
|
|
self._connect()
|
2015-07-04 18:53:45 +03:00
|
|
|
|
self._execute('select status from downloads where title="' + decode(title) + '"')
|
2015-01-13 17:24:53 +03:00
|
|
|
|
x = self.cur.fetchone()
|
|
|
|
|
self._close()
|
|
|
|
|
return x[0] if x else None
|
|
|
|
|
|
2015-01-13 20:06:34 +03:00
|
|
|
|
def add(self, title, path, type, info, status, torrent, ind, storage):
|
2015-01-12 23:10:20 +03:00
|
|
|
|
if not self.get(title):
|
|
|
|
|
self._connect()
|
2015-06-23 23:00:27 +03:00
|
|
|
|
self.cur.execute(
|
|
|
|
|
'insert into downloads(addtime, title, path, type, jsoninfo, status, torrent, ind, lastupdate, storage)'
|
|
|
|
|
' values(?,?,?,?,?,?,?,?,?,?)', (
|
|
|
|
|
int(time.time()), decode(title), decode(path), type, json.dumps(info), status, decode(torrent), ind,
|
|
|
|
|
int(time.time()), decode(storage)))
|
2015-01-12 23:10:20 +03:00
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def update(self, title, info={}):
|
|
|
|
|
try:
|
|
|
|
|
title = title.decode('utf-8')
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
self._connect()
|
2015-07-04 18:53:45 +03:00
|
|
|
|
self._execute(
|
2015-06-23 23:00:27 +03:00
|
|
|
|
'UPDATE downloads SET jsoninfo = "' + urllib.quote_plus(json.dumps(info)) + '", lastupdate=' + str(
|
|
|
|
|
int(time.time())) + ' where title="' + title + '"')
|
2015-01-12 23:10:20 +03:00
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
2015-01-13 17:24:53 +03:00
|
|
|
|
def update_status(self, addtime, status):
|
|
|
|
|
self._connect()
|
2015-07-04 18:53:45 +03:00
|
|
|
|
self._execute('UPDATE downloads SET status = "' + status + '" where addtime="' + str(addtime) + '"')
|
2015-01-13 17:24:53 +03:00
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
2015-01-12 23:10:20 +03:00
|
|
|
|
def delete(self, addtime):
|
|
|
|
|
self._connect()
|
2015-07-04 18:53:45 +03:00
|
|
|
|
self._execute('delete from downloads where addtime="' + str(addtime) + '"')
|
2015-01-12 23:10:20 +03:00
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
|
|
|
|
def clear(self):
|
|
|
|
|
self._connect()
|
2015-07-04 18:53:45 +03:00
|
|
|
|
self._execute('delete from downloads')
|
2015-01-12 23:10:20 +03:00
|
|
|
|
self.db.commit()
|
|
|
|
|
self._close()
|
|
|
|
|
|
|
|
|
|
def _connect(self):
|
|
|
|
|
dirname = xbmc.translatePath('special://temp')
|
|
|
|
|
for subdir in ('xbmcup', 'plugin.video.torrenter'):
|
|
|
|
|
dirname = os.path.join(dirname, subdir)
|
|
|
|
|
if not xbmcvfs.exists(dirname):
|
|
|
|
|
xbmcvfs.mkdir(dirname)
|
|
|
|
|
|
|
|
|
|
self.filename = os.path.join(dirname, self.name)
|
|
|
|
|
|
|
|
|
|
first = False
|
|
|
|
|
if not xbmcvfs.exists(self.filename):
|
|
|
|
|
first = True
|
|
|
|
|
|
|
|
|
|
self.db = sqlite.connect(self.filename, check_same_thread=False)
|
|
|
|
|
if not first:
|
|
|
|
|
self.cur = self.db.cursor()
|
|
|
|
|
try:
|
|
|
|
|
self.cur.execute('select version from db_ver')
|
|
|
|
|
row = self.cur.fetchone()
|
|
|
|
|
if not row or float(row[0]) != self.version:
|
|
|
|
|
self.cur.execute('drop table downloads')
|
|
|
|
|
self.cur.execute('drop table if exists db_ver')
|
|
|
|
|
first = True
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self.cur.close()
|
|
|
|
|
except:
|
|
|
|
|
self.cur.execute('drop table downloads')
|
|
|
|
|
first = True
|
|
|
|
|
self.db.commit()
|
|
|
|
|
self.cur.close()
|
|
|
|
|
|
|
|
|
|
if first:
|
|
|
|
|
cur = self.db.cursor()
|
|
|
|
|
cur.execute('pragma auto_vacuum=1')
|
|
|
|
|
cur.execute('create table db_ver(version real)')
|
|
|
|
|
cur.execute(
|
2015-01-13 20:06:34 +03:00
|
|
|
|
'create table downloads(addtime integer PRIMARY KEY, title varchar(32), path varchar(32), type varchar(32), jsoninfo varchar(32), status varchar(32), torrent varchar(32), ind integer, lastupdate integer, storage varchar(32))')
|
2015-06-23 23:00:27 +03:00
|
|
|
|
cur.execute('insert into db_ver(version) values(?)', (self.version,))
|
2015-01-12 23:10:20 +03:00
|
|
|
|
self.db.commit()
|
|
|
|
|
cur.close()
|
|
|
|
|
self.cur = self.db.cursor()
|
|
|
|
|
|
|
|
|
|
def _close(self):
|
|
|
|
|
self.cur.close()
|
2015-01-13 20:06:34 +03:00
|
|
|
|
self.db.close()
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-13 20:06:34 +03:00
|
|
|
|
def decode(string, ret=None):
|
2015-01-14 23:24:01 +03:00
|
|
|
|
try:
|
|
|
|
|
string = string.decode('utf-8')
|
|
|
|
|
return string
|
|
|
|
|
except:
|
|
|
|
|
if ret:
|
|
|
|
|
return ret
|
|
|
|
|
else:
|
2015-01-13 20:06:34 +03:00
|
|
|
|
return string
|
2015-01-14 23:24:01 +03:00
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-14 23:24:01 +03:00
|
|
|
|
def unquote(string, ret=None):
|
|
|
|
|
try:
|
|
|
|
|
return urllib.unquote_plus(string)
|
|
|
|
|
except:
|
|
|
|
|
if ret:
|
|
|
|
|
return ret
|
|
|
|
|
else:
|
2015-01-28 22:53:45 +03:00
|
|
|
|
return string
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-01-28 22:53:45 +03:00
|
|
|
|
def itemScrap(item, kwarg):
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# debug('[itemTVDB]:meta '+str(kwarg))
|
2015-01-28 22:53:45 +03:00
|
|
|
|
if 'title' in kwarg and kwarg['title']:
|
|
|
|
|
item.setLabel(kwarg['title'])
|
|
|
|
|
|
|
|
|
|
if 'label' in kwarg and kwarg['label']:
|
|
|
|
|
item.setLabel2(kwarg['label'])
|
|
|
|
|
|
|
|
|
|
if 'icon' in kwarg and kwarg['icon']:
|
|
|
|
|
item.setIconImage(kwarg['icon'])
|
|
|
|
|
|
|
|
|
|
if 'thumbnail' in kwarg and kwarg['thumbnail']:
|
|
|
|
|
item.setThumbnailImage(kwarg['thumbnail'])
|
|
|
|
|
|
|
|
|
|
if 'properties' in kwarg and kwarg['properties']:
|
|
|
|
|
for key, value in kwarg['properties'].iteritems():
|
|
|
|
|
item.setProperty(key, str(value))
|
|
|
|
|
|
|
|
|
|
if 'info' in kwarg and kwarg['properties']:
|
|
|
|
|
item.setInfo(type='Video', infoLabels=kwarg['info'])
|
|
|
|
|
|
2015-05-18 21:14:06 +03:00
|
|
|
|
return item
|
|
|
|
|
|
2015-06-23 23:00:27 +03:00
|
|
|
|
|
2015-05-18 21:14:06 +03:00
|
|
|
|
def get_ids_video(contentList):
|
2015-06-23 23:00:27 +03:00
|
|
|
|
ids_video = []
|
|
|
|
|
allowed_video_ext = ['avi', 'mp4', 'mkv', 'flv', 'mov', 'vob', 'wmv', 'ogm', 'asx', 'mpg', 'mpeg', 'avc', 'vp3',
|
|
|
|
|
'fli', 'flc', 'm4v', 'iso']
|
|
|
|
|
allowed_music_ext = ['mp3', 'flac', 'wma', 'ogg', 'm4a', 'aac', 'm4p', 'rm', 'ra']
|
|
|
|
|
for extlist in [allowed_video_ext, allowed_music_ext]:
|
2015-05-18 21:14:06 +03:00
|
|
|
|
for title, identifier in contentList:
|
|
|
|
|
try:
|
|
|
|
|
ext = title.split('.')[-1]
|
|
|
|
|
if ext.lower() in extlist:
|
|
|
|
|
ids_video.append(str(identifier))
|
|
|
|
|
except:
|
|
|
|
|
pass
|
2015-06-23 23:00:27 +03:00
|
|
|
|
if len(ids_video) > 1:
|
2015-05-18 21:14:06 +03:00
|
|
|
|
break
|
2015-07-16 20:32:50 +03:00
|
|
|
|
# print debug('[get_ids_video]:'+str(ids_video))
|
2015-05-18 21:14:06 +03:00
|
|
|
|
return ids_video
|
2015-07-01 23:15:29 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def first_run_230(delete_russian):
|
2015-07-12 02:01:29 +03:00
|
|
|
|
if not __settings__.getSetting('first_run_230')=='True':
|
|
|
|
|
__settings__.setSetting('first_run_230','True')
|
|
|
|
|
if not delete_russian:
|
|
|
|
|
yes=xbmcgui.Dialog().yesno('< %s >' % Localization.localize('Torrenter Update 2.3.0'),
|
2015-07-12 16:48:29 +03:00
|
|
|
|
Localization.localize('Would you like to install %s from "MyShows.me Kodi Repo" in Programs section?') % 'RuTrackerOrg',
|
2015-07-12 02:01:29 +03:00
|
|
|
|
Localization.localize('Open installation window?'))
|
|
|
|
|
if yes:
|
2015-07-12 13:28:33 +03:00
|
|
|
|
xbmc.executebuiltin('Dialog.Close(all,true)')
|
2015-07-12 02:01:29 +03:00
|
|
|
|
xbmc.executebuiltin('XBMC.ActivateWindow(Addonbrowser,addons://search/%s)' % ('Torrenter Searcher'))
|
|
|
|
|
|
|
|
|
|
def first_run_231():
|
|
|
|
|
if not __settings__.getSetting('first_run_231')=='True':
|
|
|
|
|
__settings__.setSetting('first_run_231','True')
|
|
|
|
|
ok = xbmcgui.Dialog().ok('< %s >' % Localization.localize('Torrenter Update 2.3.1'),
|
2015-07-12 13:28:33 +03:00
|
|
|
|
Localization.localize('We added Android ARM full support to Torrenter v2!'),
|
2015-07-12 16:14:12 +03:00
|
|
|
|
Localization.localize('I deleted pre-installed ones, install them in Search Control Window!'))
|
2015-07-12 13:28:33 +03:00
|
|
|
|
|
|
|
|
|
yes=xbmcgui.Dialog().yesno('< %s >' % Localization.localize('Torrenter Update 2.3.1'),
|
2015-07-12 16:14:12 +03:00
|
|
|
|
Localization.localize('You have no installed or active searchers! More info in Search Control Window!'),
|
2015-07-12 16:48:29 +03:00
|
|
|
|
Localization.localize('Would you like to install %s from "MyShows.me Kodi Repo" in Programs section?') % '',)
|
2015-07-12 13:28:33 +03:00
|
|
|
|
if yes:
|
|
|
|
|
xbmc.executebuiltin('Dialog.Close(all,true)')
|
|
|
|
|
xbmc.executebuiltin('XBMC.ActivateWindow(Addonbrowser,addons://search/%s)' % ('Torrenter Searcher'))
|
2015-07-12 16:14:12 +03:00
|
|
|
|
|
|
|
|
|
def noActiveSerachers():
|
|
|
|
|
yes=xbmcgui.Dialog().yesno('< %s >' % Localization.localize('Torrenter v2'),
|
|
|
|
|
Localization.localize('You have no installed or active searchers! More info in Search Control Window!'),
|
2015-07-12 16:48:29 +03:00
|
|
|
|
Localization.localize('Would you like to install %s from "MyShows.me Kodi Repo" in Programs section?') % '',)
|
2015-07-12 16:14:12 +03:00
|
|
|
|
if yes:
|
|
|
|
|
xbmc.executebuiltin('Dialog.Close(all,true)')
|
2015-07-15 19:14:22 +03:00
|
|
|
|
xbmc.executebuiltin('XBMC.ActivateWindow(Addonbrowser,addons://search/%s)' % ('Torrenter Searcher'))
|