1586 lines
57 KiB
Python
1586 lines
57 KiB
Python
|
# -*- coding: utf-8 -*-
|
|||
|
|
|||
|
import urllib2
|
|||
|
import re
|
|||
|
import socket
|
|||
|
import datetime
|
|||
|
import time
|
|||
|
import sys
|
|||
|
import os
|
|||
|
import json
|
|||
|
import urllib
|
|||
|
import hashlib
|
|||
|
|
|||
|
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")
|
|||
|
|
|||
|
|
|||
|
def clearStorage(userStorageDirectory):
|
|||
|
try:
|
|||
|
userStorageDirectory = userStorageDirectory.decode('utf-8')
|
|||
|
except:
|
|||
|
pass
|
|||
|
if xbmcvfs.exists(userStorageDirectory + os.sep):
|
|||
|
import shutil
|
|||
|
|
|||
|
temp = userStorageDirectory.rstrip('Torrenter').rstrip('/\\')
|
|||
|
shutil.move(os.path.join(userStorageDirectory, 'torrents'), os.path.join(temp, 'torrents'))
|
|||
|
shutil.rmtree(userStorageDirectory, ignore_errors=True)
|
|||
|
xbmcvfs.mkdir(userStorageDirectory)
|
|||
|
shutil.move(os.path.join(temp, 'torrents'), os.path.join(userStorageDirectory, 'torrents'))
|
|||
|
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()
|
|||
|
|
|||
|
|
|||
|
def Debug(msg, force=False):
|
|||
|
if (debug == 'true' or force):
|
|||
|
try:
|
|||
|
print "[Torrenter v2] " + msg
|
|||
|
except UnicodeEncodeError:
|
|||
|
print "[Torrenter v2] " + msg.encode("utf-8", "ignore")
|
|||
|
|
|||
|
|
|||
|
def showMessage(heading, message, times=10000, forced=False):
|
|||
|
xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s, "%s")' % (
|
|||
|
heading.replace('"', "'"), message.replace('"', "'"), times, icon))
|
|||
|
|
|||
|
|
|||
|
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()
|
|||
|
# Debug('[get_url]: arr"'+str(array)+'"')
|
|||
|
if array == '':
|
|||
|
# Debug('[get_url][2]: arr=""')
|
|||
|
array = True
|
|||
|
return array
|
|||
|
except urllib2.HTTPError as e:
|
|||
|
# Debug('[get_url]: HTTPError, e.code='+str(e.code))
|
|||
|
if e.code == 401:
|
|||
|
Debug('[get_url]: Denied! Wrong login or api is broken!')
|
|||
|
return
|
|||
|
elif e.code in [503]:
|
|||
|
Debug('[get_url]: Denied, HTTP Error, e.code=' + str(e.code))
|
|||
|
return
|
|||
|
else:
|
|||
|
showMessage('HTTP Error', str(e.code))
|
|||
|
Debug('[get_url]: HTTP Error, e.code=' + str(e.code))
|
|||
|
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
|
|||
|
|
|||
|
|
|||
|
def auto_scan():
|
|||
|
from torrents import ScanAll
|
|||
|
|
|||
|
scan = CacheDB('autoscan')
|
|||
|
if not scan.get(): scan.add()
|
|||
|
try:
|
|||
|
if scan.get() \
|
|||
|
and int(time.time()) - scan.get() > refresh_period * 3600:
|
|||
|
scan.delete()
|
|||
|
scan.add()
|
|||
|
ScanAll()
|
|||
|
except:
|
|||
|
showMessage(__language__(30279), __language__(30277))
|
|||
|
|
|||
|
|
|||
|
def DownloadCache():
|
|||
|
useTVDB = getSettingAsBool('tvdb')
|
|||
|
urls = [__baseurl__ + '/profile/shows/',
|
|||
|
__baseurl__ + '/profile/episodes/next/',
|
|||
|
__baseurl__ + '/profile/episodes/unwatched/',
|
|||
|
__baseurl__ + '/shows/top/all/',
|
|||
|
__baseurl__ + '/shows/top/male/',
|
|||
|
__baseurl__ + '/shows/top/female/', ]
|
|||
|
titles = []
|
|||
|
lang = [30100, 30107, 30106, 30108, 30109, 30110]
|
|||
|
for l in lang: titles.append(__language__(l))
|
|||
|
|
|||
|
data = Data(cookie_auth, __baseurl__ + '/profile/shows/').get()
|
|||
|
if data:
|
|||
|
jdata = json.loads(data)
|
|||
|
count = len(jdata)
|
|||
|
|
|||
|
dialog = xbmcgui.Dialog()
|
|||
|
ok = dialog.yesno(__language__(30548), __language__(30517) % count, __language__(30518))
|
|||
|
if ok:
|
|||
|
for showId in jdata:
|
|||
|
if ruName == 'true' and jdata[showId]['ruTitle']:
|
|||
|
title = jdata[showId]['ruTitle'].encode('utf-8')
|
|||
|
else:
|
|||
|
title = jdata[showId]['title']
|
|||
|
titles.append(title)
|
|||
|
urls.append(__baseurl__ + '/shows/' + showId)
|
|||
|
titles.append(title)
|
|||
|
urls.append(__baseurl__ + '/profile/shows/' + showId + '/')
|
|||
|
|
|||
|
if useTVDB:
|
|||
|
from search.scrapers import Scrapers
|
|||
|
|
|||
|
TVDB = Scrapers()
|
|||
|
|
|||
|
full_count = len(urls)
|
|||
|
progressBar = xbmcgui.DialogProgress()
|
|||
|
progressBar.create(__language__(30548), __language__(30518))
|
|||
|
for i in range(0, len(urls)):
|
|||
|
dat = Data(cookie_auth, urls[i]).get()
|
|||
|
if useTVDB:
|
|||
|
match = re.compile(__baseurl__ + '/shows/(\d{1,20}?$)').findall(urls[i])
|
|||
|
if match:
|
|||
|
jdat = json.loads(dat)
|
|||
|
TVDB.scraper('tvdb', {'label': titles[i], 'search': [jdat['title'], titles[i]],
|
|||
|
'year': str(jdat['year'])})
|
|||
|
iterator = int(round(i * 100 / full_count))
|
|||
|
progressBar.update(iterator, __language__(30549) % (i, full_count), titles[i])
|
|||
|
if progressBar.iscanceled():
|
|||
|
progressBar.update(0)
|
|||
|
progressBar.close()
|
|||
|
break
|
|||
|
return
|
|||
|
|
|||
|
|
|||
|
class Data():
|
|||
|
def __init__(self, cookie_auth, url, refresh_url=None):
|
|||
|
if not xbmcvfs.exists(__tmppath__):
|
|||
|
xbmcvfs.mkdirs(__tmppath__)
|
|||
|
self.cookie = cookie_auth
|
|||
|
self.filename = self.url2filename(url)
|
|||
|
self.refresh = False
|
|||
|
if refresh_url:
|
|||
|
CacheDB(unicode(refresh_url)).delete()
|
|||
|
if re.search('profile', refresh_url):
|
|||
|
CacheDB(unicode(__baseurl__ + '/profile/episodes/unwatched/')).delete()
|
|||
|
self.url = url
|
|||
|
self.cache = CacheDB(self.url)
|
|||
|
if self.filename:
|
|||
|
if not xbmcvfs.exists(self.filename) \
|
|||
|
or getSettingAsBool('forced_refresh_data') \
|
|||
|
or not self.cache.get() \
|
|||
|
or int(time.time()) - self.cache.get() > refresh_period * 3600 \
|
|||
|
or str(refresh_always) == 'true':
|
|||
|
self.refresh = True
|
|||
|
__settings__.setSetting("forced_refresh_data", "false")
|
|||
|
|
|||
|
def get(self, force_cache=False):
|
|||
|
if self.filename:
|
|||
|
if self.refresh == True and force_cache == False or not xbmcvfs.File(self.filename,
|
|||
|
'r').size() or not re.search(
|
|||
|
'=' + __settings__.getSetting("username") + ';', cookie_auth):
|
|||
|
self.write()
|
|||
|
self.fg = xbmcvfs.File(self.filename, 'r')
|
|||
|
try:
|
|||
|
self.data = self.fg.read()
|
|||
|
except:
|
|||
|
self.fg.close()
|
|||
|
self.fg = open(self.filename, 'r')
|
|||
|
self.data = self.fg.read()
|
|||
|
self.fg.close()
|
|||
|
x = re.match('.*?}$', self.data)
|
|||
|
if not x: self.data = self.data[0:len(self.data) - 1]
|
|||
|
return self.data
|
|||
|
else:
|
|||
|
return get_url(self.cookie, self.url)
|
|||
|
|
|||
|
def write(self):
|
|||
|
if self.cache.get(): self.cache.delete()
|
|||
|
self.data = get_url(self.cookie, self.url)
|
|||
|
if self.data:
|
|||
|
try:
|
|||
|
self.fw = xbmcvfs.File(self.filename, 'w')
|
|||
|
except:
|
|||
|
self.fw = open(self.filename, 'w')
|
|||
|
self.fw.write(self.data)
|
|||
|
self.fw.close()
|
|||
|
self.cache.add()
|
|||
|
elif self.data == False:
|
|||
|
Debug('[Data][write] Going offline cuz no self.data ' + str(self.data) + ' self.filename ' + self.filename)
|
|||
|
TimeOut().go_offline()
|
|||
|
|
|||
|
def url2filename(self, url):
|
|||
|
self.files = [r'shows.txt', r'showId_%s.txt', r'watched_showId_%s.txt', r'action_%s.txt', r'top_%s.txt']
|
|||
|
self.urls = [__baseurl__ + '/profile/shows/$', __baseurl__ + '/shows/(\d{1,20}?$)',
|
|||
|
__baseurl__ + '/profile/shows/(\d{1,20}?)/$', __baseurl__ + '/profile/episodes/(unwatched|next)/',
|
|||
|
__baseurl__ + '/shows/top/(all|male|female)/']
|
|||
|
self.i = -1
|
|||
|
for file in self.urls:
|
|||
|
self.i = self.i + 1
|
|||
|
self.match = re.compile(str(file)).findall(url)
|
|||
|
if self.match:
|
|||
|
self.var = str(self.match[0])
|
|||
|
if str(self.files[self.i]).endswith('%s.txt'):
|
|||
|
return os.path.join(__tmppath__, self.files[self.i] % (self.var))
|
|||
|
else:
|
|||
|
return os.path.join(__tmppath__, self.files[self.i])
|
|||
|
return None
|
|||
|
|
|||
|
|
|||
|
def friend_xbmc():
|
|||
|
login = __settings__.getSetting("username").decode('utf-8', 'ignore')
|
|||
|
filename = os.path.join(__tmppath__, '%s.txt' % (login))
|
|||
|
if xbmcvfs.File(filename, 'r').size():
|
|||
|
return True
|
|||
|
socket.setdefaulttimeout(3)
|
|||
|
scan = CacheDB(login)
|
|||
|
if scan.get() and int(time.time()) - scan.get() > refresh_period * 3600 or not scan.get():
|
|||
|
scan.delete()
|
|||
|
scan.add()
|
|||
|
url = 'http://myshows.me/xbmchub'
|
|||
|
ok = Data(cookie_auth, url, '').get()
|
|||
|
try:
|
|||
|
token = re.compile('<script type="text/javascript">var __token = \'(\w+)\'; </script>').findall(ok)[-1]
|
|||
|
post = '{"jsonrpc":"2.0","method":"ToggleFriendship","id":1,"params":{"userId":274684,"add":1,"__token":"' + token + '"}}'
|
|||
|
Debug('[friend_xbmc]: token is %s' % (token))
|
|||
|
ok = post_url_json(cookie_auth, __rpcurl__, post)
|
|||
|
if ok or not ok:
|
|||
|
try:
|
|||
|
fw = xbmcvfs.File(filename, 'w')
|
|||
|
except:
|
|||
|
fw = open(filename, 'w')
|
|||
|
fw.write(str(ok))
|
|||
|
fw.close()
|
|||
|
return True
|
|||
|
else:
|
|||
|
return False
|
|||
|
except:
|
|||
|
Debug('[friend_xbmc] Something went wrong!')
|
|||
|
return False
|
|||
|
|
|||
|
|
|||
|
def ontop(action='get', ontop=None):
|
|||
|
from torrents import prefix
|
|||
|
|
|||
|
if action in ('update'):
|
|||
|
if ontop:
|
|||
|
jdata = json.loads(Data(cookie_auth, __baseurl__ + '/profile/shows/').get())
|
|||
|
jstringdata = json.loads(ontop)
|
|||
|
showId = str(jstringdata['showId'])
|
|||
|
pre = prefix(showId=int(showId), seasonId=jstringdata['seasonId'])
|
|||
|
# if ruName=='true' and jdata[showId]['ruTitle']: title=pre+jdata[showId]['ruTitle']
|
|||
|
# else:
|
|||
|
title = pre + jdata[showId]['title']
|
|||
|
if jstringdata['seasonId']:
|
|||
|
mode = "25"
|
|||
|
title += ' Season ' + str(jstringdata['seasonId'])
|
|||
|
else:
|
|||
|
mode = "20"
|
|||
|
ontop = {'title': title, 'mode': mode, 'argv': {'stringdata': ontop}}
|
|||
|
#print unicode(ontop)
|
|||
|
__settings__.setSetting("ontop", str(ontop).encode('utf-8'))
|
|||
|
elif action == 'get':
|
|||
|
x = __settings__.getSetting("ontop")
|
|||
|
if x != "None" and x:
|
|||
|
y = {}
|
|||
|
y['mode'] = re.compile("'%s': '(\d+)'" % ('mode')).findall(x)[0]
|
|||
|
y['argv'] = {}
|
|||
|
y['argv']['stringdata'] = re.compile("{'%s': '(.+?)'}" % ('stringdata')).findall(x)[0]
|
|||
|
y['argv']['showId'] = re.compile('"%s": (\d+),' % ('showId')).findall(y['argv']['stringdata'])[0]
|
|||
|
try:
|
|||
|
y['argv']['seasonNumber'] = re.compile('"%s": (\d+),' % ('seasonId')).findall(y['argv']['stringdata'])[
|
|||
|
0]
|
|||
|
except:
|
|||
|
pass
|
|||
|
y['title'] = re.compile("'%s': u'(.+?)'" % ('title')).findall(x)[0].encode('utf-8')
|
|||
|
# print unicode(y)
|
|||
|
return y
|
|||
|
else:
|
|||
|
return None
|
|||
|
|
|||
|
|
|||
|
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)))
|
|||
|
Debug('[cutFileNames] ' + unicode(result))
|
|||
|
|
|||
|
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 = []
|
|||
|
Debug('[cutFileNames] [start] ' + start)
|
|||
|
Debug('[cutFileNames] [end] ' + end)
|
|||
|
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)
|
|||
|
Debug('[cutFileNames] [sorted l] ' + unicode(sorted(l, key=lambda x: x)), True)
|
|||
|
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])
|
|||
|
Debug('[sortext]: lol:' + str(lol))
|
|||
|
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)
|
|||
|
Debug('[sortext]: result:' + str(result))
|
|||
|
return result
|
|||
|
|
|||
|
|
|||
|
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
|
|||
|
# Debug('1 - %d %d' % (id1, id2))
|
|||
|
elif (ratio[id2] <= ratio[i] or id1 == id2) and i != id1:
|
|||
|
id2 = i
|
|||
|
# Debug('2 - %d %d' % (id1, id2))
|
|||
|
|
|||
|
Debug('[sweetpair]: id1 ' + l[id1] + ':' + str(ratio[id1]))
|
|||
|
Debug('[sweetpair]: id2 ' + l[id2] + ':' + str(ratio[id2]))
|
|||
|
|
|||
|
return [l[id1], l[id2]]
|
|||
|
|
|||
|
|
|||
|
def FileNamesPrepare(filename):
|
|||
|
my_season = None
|
|||
|
my_episode = None
|
|||
|
|
|||
|
try:
|
|||
|
if int(filename):
|
|||
|
my_episode = int(filename)
|
|||
|
Debug('[FileNamesPrepare] ' + str([my_season, my_episode, filename]))
|
|||
|
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
|
|||
|
Debug('[FileNamesPrepare] ' + str([my_season, my_episode, filename]))
|
|||
|
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'])
|
|||
|
# Debug('[filename2match] '+str(results))
|
|||
|
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])
|
|||
|
Debug('[filename2match] ' + str(results))
|
|||
|
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'
|
|||
|
styles['showFilesList'] = 'wide'
|
|||
|
elif view_style in [1, 4]:
|
|||
|
styles['searchOption'] = 'info'
|
|||
|
styles['drawContent'] = styles['torrentPlayer'] = styles['openTorrent'] = styles['drawtrackerList'] = 'info'
|
|||
|
styles['uTorrentBrowser'] = styles['History'] = 'wide'
|
|||
|
styles['showFilesList'] = styles['sectionMenu'] = 'wide'
|
|||
|
styles['List'] = styles['drawcontentList'] = 'info3'
|
|||
|
|
|||
|
if view_style == 1:
|
|||
|
styles['uTorrentBrowser'] = styles['torrentPlayer'] = styles['openTorrent'] = styles['History'] = 'wide'
|
|||
|
styles['sectionMenu'] = 'icons'
|
|||
|
|
|||
|
if view_style in [1, 3, 4]:
|
|||
|
num_skin = 0
|
|||
|
elif view_style == 2:
|
|||
|
num_skin = 1
|
|||
|
|
|||
|
style = styles.get(func)
|
|||
|
# Debug('[view_style]: lock '+str(style))
|
|||
|
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://', '')
|
|||
|
Debug('[smbtopath]:' + '\\\\' + path.replace('/', '\\'))
|
|||
|
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),
|
|||
|
]
|
|||
|
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:
|
|||
|
Debug('[RateShow] no watched_jdata1')
|
|||
|
return
|
|||
|
if not self.watched_jdata:
|
|||
|
Debug('[RateShow] no watched_jdata2')
|
|||
|
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']]
|
|||
|
# Debug('[ratedict]:'+str(ratedict))
|
|||
|
for i in ratedict:
|
|||
|
ratedict[i] = (round(float(sum(ratedict[i])) / len(ratedict[i]), 2), len(ratedict[i]))
|
|||
|
Debug('[ratedict]:' + str(ratedict))
|
|||
|
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'])
|
|||
|
# Debug('ratings:'+str(ratings)+'; seasonratings:'+str(seasonratings))
|
|||
|
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']
|
|||
|
# Debug('[listSE] '+str(listSE)+str(seasonNumber))
|
|||
|
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:
|
|||
|
Debug('[isRemoteTorr]: uTorrent is Remote!')
|
|||
|
return True
|
|||
|
elif __settings__.getSetting("torrent") == '1':
|
|||
|
if __settings__.getSetting("torrent_transmission_host") not in localhost:
|
|||
|
Debug('[isRemoteTorr]: Transmission is Remote!')
|
|||
|
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:
|
|||
|
Debug('[changeDBTitle]: XBMC JSON Result was empty.')
|
|||
|
return
|
|||
|
|
|||
|
if 'tvshows' in shows:
|
|||
|
shows = shows['tvshows']
|
|||
|
Debug("[changeDBTitle]: XBMC JSON Result: '%s'" % str(shows))
|
|||
|
else:
|
|||
|
Debug("[changeDBTitle]: Key 'tvshows' not found")
|
|||
|
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:
|
|||
|
Debug("[changeDBTitle]: XBMC JSON Result: '%s'" % str(result))
|
|||
|
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())):
|
|||
|
Debug('[TimeOut]: too soon to go back offline! %d s' % (
|
|||
|
(gone_online + self.online * 4) - int(round(time.time()))))
|
|||
|
return
|
|||
|
if self.timeout() == self.online:
|
|||
|
Debug('[TimeOut]: Gone offline! %d s' % ((gone_online + self.online * 4) - int(round(time.time()))))
|
|||
|
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()
|
|||
|
Debug('[TimeOut]: Gone online!')
|
|||
|
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
|
|||
|
# Debug('[TimeOut]: '+str(to))
|
|||
|
return to
|
|||
|
|
|||
|
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))')
|
|||
|
self.cur.execute('insert into db_ver(version) values(?)', (self.version, ))
|
|||
|
self.db.commit()
|
|||
|
self._close()
|
|||
|
|
|||
|
def ClearCache(self, silent=False):
|
|||
|
self._connect()
|
|||
|
self.cur.execute('delete from cache')
|
|||
|
self.db.commit()
|
|||
|
self._close()
|
|||
|
if not silent:
|
|||
|
xbmcgui.Dialog().ok(__language__(30208), __language__(30236))
|
|||
|
ontop('update')
|
|||
|
xbmc.executebuiltin("Action(back)")
|
|||
|
|
|||
|
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:
|
|||
|
def __init__(self, name, version=1.0):
|
|||
|
self.name = name + '.db3'
|
|||
|
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()
|
|||
|
#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
|
|||
|
|
|||
|
def set_providers(self, addtime, providers):
|
|||
|
self._connect()
|
|||
|
if isinstance(providers, dict):
|
|||
|
temp=[]
|
|||
|
for i in providers.keys():
|
|||
|
if providers.get(i):
|
|||
|
temp.append(i)
|
|||
|
providers=temp
|
|||
|
str_p=','.join(providers)
|
|||
|
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()
|
|||
|
providers=self.get_providers(addtime)
|
|||
|
keys=Searchers().dic().keys()
|
|||
|
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()
|
|||
|
|
|||
|
def add(self, url):
|
|||
|
try:
|
|||
|
url = url.decode('utf-8')
|
|||
|
except:
|
|||
|
pass
|
|||
|
if not self.get(url):
|
|||
|
self._connect()
|
|||
|
self.cur.execute('insert into history(addtime,string,fav,providers)'
|
|||
|
' values(?,?,?,?)', (int(time.time()), url, 0, ""))
|
|||
|
self.db.commit()
|
|||
|
self._close()
|
|||
|
|
|||
|
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)')
|
|||
|
cur.execute('insert into db_ver(version) values(?)', (self.version, ))
|
|||
|
self.db.commit()
|
|||
|
cur.close()
|
|||
|
self.cur = self.db.cursor()
|
|||
|
|
|||
|
def _close(self):
|
|||
|
self.cur.close()
|
|||
|
self.db.close()
|
|||
|
|
|||
|
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")
|
|||
|
|
|||
|
def list(self):
|
|||
|
searchersList = []
|
|||
|
dirList = os.listdir(ROOT + os.sep + 'resources' + os.sep + 'searchers')
|
|||
|
for searcherFile in dirList:
|
|||
|
if re.match('^(\w+)\.py$', searcherFile):
|
|||
|
searchersList.append(searcherFile.replace('.py', ''))
|
|||
|
return searchersList
|
|||
|
|
|||
|
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 = []
|
|||
|
for searcher in self.list():
|
|||
|
if self.old(searcher): get_active.append(searcher + '.py')
|
|||
|
print 'Active Searchers: '+str(get_active)
|
|||
|
return get_active
|
|||
|
|
|||
|
|
|||
|
class Contenters():
|
|||
|
def __init__(self):
|
|||
|
pass
|
|||
|
|
|||
|
def first_time(self, scrapperDB_ver, language='ru'):
|
|||
|
searcher = 'metadata'+language
|
|||
|
redl = False
|
|||
|
scrapperDB_ver=scrapperDB_ver[language]
|
|||
|
if scrapperDB_ver != __settings__.getSetting('scrapperDB_ver'+language) and self.getBoolSetting(searcher):
|
|||
|
__settings__.setSetting('scrapperDB_ver'+language, scrapperDB_ver)
|
|||
|
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():
|
|||
|
xbmcvfs.delete(os.path.join(dirname, i+'.'+language + '.db'))
|
|||
|
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'), )
|
|||
|
|
|||
|
if not self.getBoolSetting('oldc_' + searcher):
|
|||
|
self.setBoolSetting('oldc_' + searcher, True)
|
|||
|
__settings__.setSetting('scrapperDB_ver'+language, scrapperDB_ver)
|
|||
|
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():
|
|||
|
if scraper!='kinopoisk' or language=='ru':
|
|||
|
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()
|
|||
|
Debug('[WatchedDB][_get]: Checking ' + id)
|
|||
|
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)))
|
|||
|
|
|||
|
Debug('[WatchedDB][check]: rating: %s DB: %s, ok1: %s, ok3: %s' % (
|
|||
|
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):
|
|||
|
# Debug('[WatchedDB][onaccess]: Start')
|
|||
|
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:
|
|||
|
# Debug('[WatchedDB][onaccess]: Found %s' % (str(res)))
|
|||
|
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')
|
|||
|
Debug('[WatchedDB][_add]: Adding %s with rate %d' % (id, rating))
|
|||
|
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
|
|||
|
|
|||
|
def file_decode(filename):
|
|||
|
if not __settings__.getSetting('delete_russian')=='true':
|
|||
|
if sys.getfilesystemencoding()=='mbcs':
|
|||
|
try:
|
|||
|
filename=filename.decode('utf-8')#,'ignore')
|
|||
|
except:
|
|||
|
pass
|
|||
|
return filename
|
|||
|
|
|||
|
def file_encode(filename):
|
|||
|
if not __settings__.getSetting('delete_russian')=='true':
|
|||
|
if sys.getfilesystemencoding()=='mbcs' and isAsciiString(filename):
|
|||
|
filename=filename.decode('cp1251').encode('utf-8')
|
|||
|
return filename
|
|||
|
|
|||
|
def isAsciiString(mediaName):
|
|||
|
for index, char in enumerate(mediaName):
|
|||
|
if ord(char) >= 128:
|
|||
|
return False
|
|||
|
return True
|
|||
|
|
|||
|
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
|
|||
|
|
|||
|
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)]
|
|||
|
#Debug('Compare ' + filename_if.lower() + ' and ' + filename_if2.lower() + ' and ' + filename2.lower().split('.')[-1])
|
|||
|
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
|
|||
|
|
|||
|
def delete_russian(ok=False):
|
|||
|
if not ok:
|
|||
|
ok = xbmcgui.Dialog().yesno('< %s >' % Localization.localize('International Check - First Run'),
|
|||
|
'Delete Russian stuff?',
|
|||
|
Localization.localize('Delete Russian stuff?'))
|
|||
|
if ok:
|
|||
|
fileList={
|
|||
|
'contenters':['CXZ.py','FastTorrent.py','KinoPoisk.py','RiperAM.py'],
|
|||
|
'searchers':['NNMClubRu.py','OpenSharing.py','RiperAM.py','RuTorOrg.py','RuTrackerOrg.py','TFileME.py']
|
|||
|
}
|
|||
|
|
|||
|
for path in fileList.keys():
|
|||
|
for filename in fileList[path]:
|
|||
|
filepath=os.path.join(ROOT,'resources', path,filename)
|
|||
|
if xbmcvfs.exists(filepath):
|
|||
|
newfilepath=os.path.join(ROOT,'resources', path,'unused',filename)
|
|||
|
xbmcvfs.copy(filepath, newfilepath)
|
|||
|
xbmcvfs.delete(filepath)
|
|||
|
return True
|
|||
|
else:
|
|||
|
return False
|