(.*?)', source, re.DOTALL)
+ number_of_items = len(items)
+ if items:
+ for item in items:
+ match =re.compile('href="(.+?)"').findall(item)
+ if match:
+ if "sop://" or "torrentstream" or "acestream://" in match[-1]:
+ stream_quality = re.compile('>(.+?) kbps
.+?href="(.+?)"').findall(streamdata)
+ for tipo,link in p2pdirect:
+ if tipo == "SopCast" and "sop://" in link:
+ addDir("[B][SopCast][/B]- (no info)",link,401,os.path.join(current_dir,'icon.png'),43,False,parser='rojadirecta',parserfunction='resolve_and_play')
+ xbmc.executebuiltin("Container.SetViewMode(51)")
+
+def rojadirecta_resolver(name,url):
+ if "sop://" not in url and "acestream://" not in url:
+ if "http://" not in url:
+ url="http://"+url
+
+ if 'arenavision' in url:
+ headers = {
+ "Cookie" : "beget=begetok; has_js=1;"
+ }
+ try:
+ source = requests.get(url,headers=headers).text
+ except: source="";xbmcgui.Dialog().ok(translate(40000),translate(40128))
+ else:
+ try:
+ source = get_page_source(url)
+ except: source = "";xbmcgui.Dialog().ok(translate(40000),translate(40128))
+ matchredirect = re.compile('<(?:frame|FRAME|iframe) (?:SRC|src)="(.+?)"').findall(source)
+ matchsop = re.compile('sop://(.+?)"').findall(source)
+ if matchsop: sop.sopstreams(name,os.path.join(current_dir,'icon.png'),"sop://" + matchsop[0])
+ else:
+ match = re.compile('this.loadPlayer\("(.+?)"').findall(source)
+ if match: ace.acestreams(name,os.path.join(current_dir,'icon.png'),match[0])
+ else:
+ if matchredirect:
+ if '/' not in matchredirect[0]: redirect_url = url + '/' + matchredirect[0]
+ else: redirect_url = matchredirect[0]
+ rojadirecta_resolver(name,redirect_url)
+ else:
+ xbmcgui.Dialog().ok(translate(40000),translate(40022))
+ elif "sop://" in url: sop.sopstreams(name,os.path.join(current_dir,'icon.png'),url)
+ elif "acestream://" in url: ace.acestreams(name,os.path.join(current_dir,'icon.png'),url)
+ else: xbmcgui.Dialog().ok(translate(40000),translate(40022))
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/main.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/main.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..6ec1bf137fed719f10b74cfe5779a5fec9dcc778
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/main.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/arenavisionlogo.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/arenavisionlogo.png
new file mode 100644
index 0000000000000000000000000000000000000000..1688261492c80465065fef560e7e83ee9899dcf0
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/arenavisionlogo.png differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/futbolsinlimiteslogo.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/futbolsinlimiteslogo.png
new file mode 100644
index 0000000000000000000000000000000000000000..6dcc0cf8e945eb51787077c9fce28a2e7efde8e1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/futbolsinlimiteslogo.png differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/lacatedrallogo.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/lacatedrallogo.png
new file mode 100644
index 0000000000000000000000000000000000000000..97100396dd2e082632cb156a3ab9545fcf2c6f9d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/lacatedrallogo.png differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/vertigologo.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/vertigologo.png
new file mode 100644
index 0000000000000000000000000000000000000000..74fd88ed0ce338745e106ab6c71f15996bfa49db
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/vertigologo.png differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/vikingologo.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/vikingologo.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b3d695b0d314e5fc9e61ece0e3fd4f86e1002d3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/media/vikingologo.png differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/module.cfg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/module.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..952d5c072066051c64a3a862800b31de4d37d4fb
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/module.cfg
@@ -0,0 +1 @@
+{ 'name' : 'Rojadirecta.me'}
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/__init__.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/__init__.pyc b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/__init__.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ce45d7a3f185837d4db2279f82966221511e5a58
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/__init__.pyc differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/icon.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a0757b2bed25870861608faa99fccd2661ea5133
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/icon.png differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/main.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..1295f2bc68bd2c8cd1c6042980b16e70566a5ddf
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/main.py
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+
+"""
+This plugin is 3rd party and not part of p2p-streams addon
+
+Sopcast.ucoz
+
+"""
+import sys,os
+current_dir = os.path.dirname(os.path.realpath(__file__))
+basename = os.path.basename(current_dir)
+core_dir = current_dir.replace(basename,'').replace('parsers','')
+sys.path.append(core_dir)
+from peertopeerutils.webutils import *
+from peertopeerutils.pluginxbmc import *
+from peertopeerutils.directoryhandle import *
+import acestream as ace
+import sopcast as sop
+
+base_url = 'http://livefootballvideo.com/streaming'
+
+def module_tree(name,url,iconimage,mode,parser,parserfunction):
+ if not parserfunction: sopcast_ucoz()
+ elif parserfunction == 'play': sopcast_ucoz_play(name,url)
+
+def sopcast_ucoz():
+ conteudo=clean(get_page_source('http://sopcast.ucoz.com'))
+ listagem=re.compile('
(.+?)').findall(conteudo)
+ for urllist,titulo in listagem:
+ try:
+ match = re.compile('\((.*?)\.(.*?)\.(.*?)\. (.*?):(.*?) UTC\) (.*)').findall(titulo)
+ if match:
+ for dia,mes,ano,hora,minuto,evento in match:
+ import datetime
+ from utils import pytzimp
+ d = pytzimp.timezone(str(pytzimp.timezone('Europe/London'))).localize(datetime.datetime(int(ano), int(mes), int(dia), hour=int(hora), minute=int(minuto)))
+ timezona= settings.getSetting('timezone_new')
+ my_location=pytzimp.timezone(pytzimp.all_timezones[int(timezona)])
+ convertido=d.astimezone(my_location)
+ fmt = "%y-%m-%d %H:%M"
+ time=convertido.strftime(fmt)
+ addDir('[B][COLOR orange]' + time + '[/B][/COLOR]-' + evento,urllist,401,os.path.join(current_dir,'icon.png'),len(listagem),False,parser="sopcastucoz",parserfunction="play")
+ else:
+ addDir(titulo,urllist,401,'',len(listagem),False,parser="sopcastucoz",parserfunction="play")
+ except:
+ addDir(titulo,urllist,401,'',len(listagem),False,parser="sopcastucoz",parserfunction="play")
+
+def sopcast_ucoz_play(name,url):
+ conteudo=clean(get_page_source(url))
+ blogpost = re.findall('
(.*?)
(.+?)<').findall(blogpost[0])
+ for address in match:
+ if "sop://" in address:
+ titulo.append('Sopcast [' + address +']')
+ ender.append(address)
+ elif "(ace stream)" in address:
+ titulo.append('Acestream [' + address.replace(' (ace stream)','') +']')
+ ender.append(address.replace(' (ace stream)',''))
+ else: pass
+ if ender and titulo:
+ index = xbmcgui.Dialog().select(translate(40023), titulo)
+ if index > -1:
+ nomeescolha=titulo[index]
+ linkescolha=ender[index]
+ if re.search('acestream',nomeescolha,re.IGNORECASE) or re.search('TorrentStream',nomeescolha,re.IGNORECASE): ace.acestreams(nomeescolha,'',linkescolha)
+ elif re.search('sopcast',nomeescolha,re.IGNORECASE): sop.sopstreams(nomeescolha,'',linkescolha)
+ else: xbmcgui.Dialog().ok(translate(40000),translate(40024))
+ else:
+ xbmcgui.Dialog().ok(translate(40000),translate(40008))
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/module.cfg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/module.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..fe20663d344a065974b808968ea59cac61b12738
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/sopcastucoz/module.cfg
@@ -0,0 +1 @@
+{ 'name' : 'SopCast.ucoz'}
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvruall/__init__.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvruall/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvruall/icon.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvruall/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..e6871399bca25287493700015ec3d347b8534e79
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvruall/icon.png differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvruall/main.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvruall/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..fbddd8071a43299357fc1abbb10266d0e361f381
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvruall/main.py
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+
+"""
+This plugin is 3rd party and not it is not part of the p2p-streams addon
+
+Torrent-tv.ru (All categories)
+
+"""
+import sys,os
+current_dir = os.path.dirname(os.path.realpath(__file__))
+basename = os.path.basename(current_dir)
+core_dir = current_dir.replace(basename,'').replace('parsers','')
+sys.path.append(core_dir)
+from peertopeerutils.webutils import *
+from peertopeerutils.pluginxbmc import *
+from peertopeerutils.directoryhandle import *
+from peertopeerutils.timeutils import translate_months
+
+base_url = "http://super-pomoyka.us.to/trash/ttv-list/ttv.m3u"
+
+def module_tree(name,url,iconimage,mode,parser,parserfunction):
+ if not parserfunction: torrenttv()
+ elif parserfunction == 'channels': torrenttv_play(name,url)
+
+def torrenttv():
+ dict_torrent = {}
+ html_source = get_page_source(base_url)
+ match = re.compile('#EXTINF:-1,(.+?)\n(.*)').findall(html_source)
+ for title, acehash in match:
+ channel_name = re.compile('(.+?) \(').findall(title)
+ match_cat = re.compile('\((.+?)\)').findall(title)
+ for i in xrange(0,len(match_cat)):
+ if match_cat[i] == "Для взрослых" and settings.getSetting('hide_porn') == "true":
+ pass
+ elif match_cat[i] == "Ночной канал" and settings.getSetting('hide_porn') == "true":
+ pass
+ else:
+ if settings.getSetting('russian_translation') == "true": categorie = russiandictionary(match_cat[i])
+ else: categorie=match_cat[i]
+ if categorie not in dict_torrent.keys():
+ try:
+ dict_torrent[categorie] = [(channel_name[0],acehash)]
+ except: pass
+ else:
+ try:
+ dict_torrent[categorie].append((channel_name[0],acehash))
+ except: pass
+ for categories in dict_torrent.keys():
+ addDir(categories,str(dict_torrent),401,os.path.join(current_dir,"icon.png"),401,True,parser="torrenttvruall",parserfunction="channels")
+
+def torrenttv_play(name,url):
+ dict_torrent=eval(url)
+ for channel in dict_torrent[name]:
+ try: addDir(channel[0],channel[1],1,os.path.join(current_dir,"icon.png"),2,False)
+ except:pass
+
+def russiandictionary(string):
+ if string == "Eng": return translate(40077)
+ elif string == "Спорт": return translate(40078)
+ elif string == "Новостные": return translate(40079)
+ elif string == "Свадебный": return translate(40080)
+ elif string == "Общие": return translate(40081)
+ elif string == "Познавательные": return translate(40082)
+ elif string == "СНГ": return translate(40083)
+ elif string == "Мужские": return translate(40084)
+ elif string == "Ukraine": return translate(40085)
+ elif string == "резерв": return translate(40086)
+ elif string == "Донецк": return translate(40087)
+ elif string == "Региональные": return translate(40088)
+ elif string == "Для взрослых": return translate(40089)
+ elif string == "TV21": return translate(40090)
+ elif string == "Украина": return translate(40091)
+ elif string == "Детские": return translate(40092)
+ elif string == "Фильмы": return translate(40093)
+ elif string == "Ночной канал": return translate(40094)
+ elif string == "Европа": return translate(40095)
+ elif string == "укр": return translate(40096)
+ elif string == "Музыка": return translate(40097)
+ elif string == "Религиозные": return translate(40098)
+ elif string == "Развлекательные": return translate(40099)
+ elif string == "украина": return translate(40151)
+ elif string == "Казахстан": return "Kazakstan"
+ else: return string
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvruall/module.cfg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvruall/module.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..26a7d4f338b63baa43d73c991aec21740d22c7cb
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvruall/module.cfg
@@ -0,0 +1 @@
+{ 'name' : 'Torrent-TV.ru (All categories)'}
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvrusports/__init__.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvrusports/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvrusports/icon.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvrusports/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..e6871399bca25287493700015ec3d347b8534e79
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvrusports/icon.png differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvrusports/main.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvrusports/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..d689f7659ae6bb0b96a77e57078c5e182862b3ca
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvrusports/main.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+
+"""
+This plugin is 3rd party and not part of p2p-streams addon
+
+Torrent-TV.ru sports section
+
+"""
+import sys,os
+current_dir = os.path.dirname(os.path.realpath(__file__))
+basename = os.path.basename(current_dir)
+core_dir = current_dir.replace(basename,'').replace('parsers','')
+sys.path.append(core_dir)
+from peertopeerutils.webutils import *
+from peertopeerutils.pluginxbmc import *
+from peertopeerutils.directoryhandle import *
+
+base_url = 'http://super-pomoyka.us.to/trash/ttv-list/ttv.m3u'
+
+def module_tree(name,url,iconimage,mode,parser,parserfunction):
+ if not parserfunction: torrent_tv_sports()
+
+def torrent_tv_sports():
+ try:
+ source = mechanize_browser(base_url)
+ except: source = "";xbmcgui.Dialog().ok(translate(40000),translate(40128))
+ if source:
+ match= re.compile("#EXTINF:-1,Sky Sports News \(.+?\)\n(.*)").findall(source)
+ if match: addDir('Sky Sports News',match[0],1,os.path.join(current_dir,'icon.png'),len(match),False)
+ match= re.compile("#EXTINF:-1,(.+?)\(Спорт\)\n(.*)").findall(source)
+ for titulo,acestream in match:
+ clean = re.compile("\((.+?)\)").findall(titulo)
+ for categorie in clean:
+ titulo = titulo.replace("(" + categorie +")","")
+ addDir(titulo,acestream,1,os.path.join(current_dir,'icon.png'),len(match),False)
+ xbmc.executebuiltin("Container.SetViewMode(51)")
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvrusports/module.cfg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvrusports/module.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..125fc759fce66be8af921403748abe4f021ad90f
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/torrenttvrusports/module.cfg
@@ -0,0 +1 @@
+{ 'name' : 'Torrent-TV.ru (Sports)'}
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/__init__.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/__init__.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..2c29bccc874f5bf4a6b06ba6b6aed38042e6af58
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/__init__.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/directoryhandle.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/directoryhandle.py
new file mode 100644
index 0000000000000000000000000000000000000000..2973192e76e4bbdeb628dd99165216f162e32089
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/directoryhandle.py
@@ -0,0 +1,144 @@
+# -*- coding: utf-8 -*-
+
+""" p2p-streams (c) 2014 enen92 fightnight
+
+ This file contains the functions for xbmc addon directory handle
+
+ Functions:
+
+ addLink(name,url,iconimage,fan_art="%s/fanart.jpg"%settings.getAddonInfo("path")) -> Addlink function used in the 'whole' addon
+ addDir(name,url,mode,iconimage,total,pasta,fan_art="%s/fanart.jpg"%settings.getAddonInfo("path"),parser=None,parserfunction=None) -> AddDir function used in the whole addon
+ addDir_livestreams_common(name,url,mode,iconimage,folder,fannart=None) -> AddDir function used only by the livestreams module of the addon
+ addLink_livestreams(url,name,iconimage,fanart,description,genre,date,showcontext,playlist,regexs,total) -> AddLink function used only by the livestreams module of the addon
+
+
+"""
+
+import xbmc,xbmcgui,xbmcvfs,xbmcplugin,os,urllib,sys
+from pluginxbmc import *
+
+"""
+
+Common addDir functions for main addon
+
+"""
+
+def addLink(name,url,iconimage,fan_art="%s/fanart.jpg"%settings.getAddonInfo("path")):
+ liz=xbmcgui.ListItem(name, iconImage="DefaultVideo.png", thumbnailImage=iconimage)
+ liz.setInfo( type="Video", infoLabels={ "Title": name } )
+ liz.setProperty('fanart_image', fan_art)
+ return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=url,listitem=liz)
+
+def addDir(name,url,mode,iconimage,total,pasta,fan_art="%s/fanart.jpg"%settings.getAddonInfo("path"),parser=None,parserfunction=None):
+ if "plugin://" in sys.argv[0]: u = sys.argv[0]; sysargv = sys.argv[0]
+ else: u = 'plugin://plugin.video.p2p-streams/'; sysargv = 'plugin://plugin.video.p2p-streams/'
+ u += "?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&iconimage="+urllib.quote_plus(iconimage)
+ try: u += "&parser="+urllib.quote_plus(parser)
+ except: pass
+ try: u += "&parserfunction="+urllib.quote_plus(parserfunction)
+ except: pass
+ contextmen = []
+ liz=xbmcgui.ListItem(name,iconImage="DefaultFolder.png", thumbnailImage=iconimage)
+ liz.setInfo( type="Video", infoLabels={ "Title": name} )
+ liz.setProperty('fanart_image', fan_art)
+ if mode == 1 or mode == 2:
+ try:
+ dirs, files = xbmcvfs.listdir(os.path.join(pastaperfil,"Favourites"))
+ if url.replace(":","").replace("/","") + ".txt" in files: contextmen.append((translate(40146), 'XBMC.RunPlugin(%s?mode=202&url=%s&name=%s&iconimage=%s)' % (sys.argv[0], urllib.quote_plus(url),name,iconimage)))
+ else: contextmen.append((translate(40143), 'XBMC.RunPlugin(%s?mode=201&url=%s&name=%s&iconimage=%s)' % (sysargv, urllib.quote_plus(url),name,iconimage)))
+ except: pass
+ elif mode == 101:
+ try:
+ ficheiro = os.path.join(pastaperfil,"Lists",name.replace("[B][COLOR orange]","").replace("[/B][/COLOR]","") + ".txt")
+ if xbmcvfs.exists(ficheiro):
+ contextmen.append((translate(40149), 'XBMC.RunPlugin(%s?mode=108&url=%s&name=%s&iconimage=%s)' % (sysargv, urllib.quote_plus(url),ficheiro,iconimage)))
+ except: pass
+ elif mode == 401 and parser and not parserfunction:
+ contextmen.append((translate(400009), 'XBMC.RunPlugin(%s?mode=403&url=%s&name=%s&iconimage=%s)' % (sysargv, urllib.quote_plus(url),name,iconimage)))
+ contextmen.append((translate(400010), 'XBMC.RunPlugin(%s?mode=407&url=%s&name=%s&iconimage=%s&parser=%s)' % (sysargv, urllib.quote_plus(url),name,iconimage,parser)))
+ liz.addContextMenuItems(contextmen,replaceItems=False)
+ return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=pasta,totalItems=total)
+
+
+"""
+
+Common addDir/addLink functions for livestreams module (Divingmule)
+
+"""
+
+def addDir_livestreams_common(name,url,mode,iconimage,folder,fannart=None):
+ u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)
+ ok=True
+ contextmen = []
+ liz=xbmcgui.ListItem(name, iconImage="DefaultFolder.png", thumbnailImage=iconimage)
+ if fannart:
+ liz.setProperty('fanart_image', fannart)
+ else:
+ liz.setProperty('fanart_image', "%s/fanart.jpg"%settings.getAddonInfo("path"))
+ if mode == 1 or mode == 2:
+ try:
+ dirs, files = xbmcvfs.listdir(os.path.join(pastaperfil,"Favourites"))
+ if url.replace(":","").replace("/","") + ".txt" in files: contextmen.append((translate(40146), 'XBMC.RunPlugin(%s?mode=202&url=%s&name=%s&iconimage=%s)' % (sys.argv[0], urllib.quote_plus(url),name,iconimage)))
+ else: contextmen.append((translate(40143), 'XBMC.RunPlugin(%s?mode=201&url=%s&name=%s&iconimage=%s)' % (sys.argv[0], urllib.quote_plus(url),name,iconimage)))
+ except: pass
+ liz.addContextMenuItems(contextmen,replaceItems=False)
+ ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=folder)
+
+def addDir_livestreams(name,url,mode,iconimage,fanart,description,genre,date,credits,showcontext=False):
+ if not genre: genre='genre'
+ if not credits: credits='credits'
+ if not date: date = 'date'
+ if not description: description = 'description'
+ u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&fanart="+urllib.quote_plus(fanart)
+ ok=True
+ contextmen = []
+ if date == '':
+ date = None
+ else:
+ description += '\n\nDate: %s' %date
+ if ("RunPlugin" in url) or ("sop://" in url) or ("acestream://" in url) or (".acelive" in url) or (".torrent" in url): pasta = False
+ else: pasta = True
+ liz=xbmcgui.ListItem(name, iconImage="DefaultFolder.png", thumbnailImage=iconimage)
+ if mode == 106:
+ try:
+ dirs, files = xbmcvfs.listdir(os.path.join(pastaperfil,"Favourites"))
+ match = re.compile("url=(.+?)&mode").findall(url.replace(";",""))
+ if match:
+ if match[0].replace(":","").replace("/","").replace(";","") + ".txt" in files: contextmen.append((translate(40146), 'XBMC.RunPlugin(%s?mode=202&url=%s&name=%s&iconimage=%s)' % (sys.argv[0], urllib.quote_plus(url),name,iconimage)))
+ else: contextmen.append((translate(40143), 'XBMC.RunPlugin(%s?mode=201&url=%s&name=%s&iconimage=%s)' % (sys.argv[0], urllib.quote_plus(url),name,iconimage)))
+ except: pass
+ liz.addContextMenuItems(contextmen,replaceItems=False)
+ if fanart:
+ liz.setProperty('fanart_image', fanart)
+ else:
+ liz.setProperty('fanart_image', "%s/fanart.jpg"%settings.getAddonInfo("path"))
+ liz.setInfo(type="Video", infoLabels={ "Title": name, "Plot": description, "Genre": genre, "dateadded": date, "credits": credits })
+ ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=pasta)
+ return ok
+
+def addLink_livestreams(url,name,iconimage,fanart,description,genre,date,showcontext,playlist,regexs,total):
+ try:
+ name = name.encode('utf-8')
+ except: pass
+ contextmen = []
+ ok = True
+ if regexs: mode = '104'
+ else: mode = '105'
+ u=sys.argv[0]+"?"
+ u += "url="+urllib.quote_plus(url)+"&mode="+mode
+ if regexs:
+ u += "®exs="+regexs
+ if date == '':
+ date = None
+ else:
+ description += '\n\nDate: %s' %date
+ liz=xbmcgui.ListItem(name, iconImage="DefaultVideo.png", thumbnailImage=iconimage)
+ liz.setInfo(type="Video", infoLabels={ "Title": name, "Plot": description, "Genre": genre, "dateadded": date })
+ liz.addContextMenuItems(contextmen,replaceItems=False)
+ if fanart:
+ liz.setProperty('fanart_image', fanart)
+ else:
+ liz.setProperty('fanart_image', "%s/fanart.jpg"%settings.getAddonInfo("path"))
+ liz.setProperty('IsPlayable', 'true')
+ ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,totalItems=total)
+ return ok
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/directoryhandle.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/directoryhandle.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..46720dcbb3d4ccd7c9103f0d7f1c54f6f5da8a48
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/directoryhandle.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/iofile.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/iofile.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b3268cde9703023f5c259e187b2d9fff3341dc6
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/iofile.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+
+""" p2p-streams (c) 2014 enen92 fightnight
+
+ This file contains the functions for file handling
+
+ Functions:
+
+ readfile(filename) -> Function to read text files given the full path
+ savefile(filename, contents) -> Function to write/save text files given the text file name
+ save(filename,contents) -> Function to write/save text to a file given the text file full path
+
+"""
+
+import os
+
+def readfile(filename):
+ f = open(filename, "r")
+ string = f.read()
+ return string
+
+def savefile(filename, contents):
+ try:
+ destination = os.path.join(pastaperfil, filename)
+ fh = open(destination, 'wb')
+ fh.write(contents)
+ fh.close()
+ return
+ except:
+ print("Could not write to: %s" % filename)
+ return
+
+def save(filename,contents):
+ fh = open(filename, 'w')
+ fh.write(contents)
+ fh.close()
+ return
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/iofile.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/iofile.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..2318d17d4744d4793e2ad360bac8ddee27218d1d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/iofile.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/keymapeditor.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/keymapeditor.py
new file mode 100644
index 0000000000000000000000000000000000000000..e71c8b6e3188e064be3c04e532c96edcc61d8b0c
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/keymapeditor.py
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+
+""" p2p-streams (c) 2014 enen92 fightnight
+
+ This file contains functions from the keymap editor addon by takoi
+
+"""
+from peertopeerutils.pluginxbmc import *
+import xbmc,os,shutil
+from xbmcgui import Dialog, WindowXMLDialog
+from threading import Timer
+import xml.etree.ElementTree as ET
+
+default = xbmc.translatePath('special://xbmc/system/keymaps/keyboard.xml')
+userdata = xbmc.translatePath('special://userdata/keymaps')
+gen_file = os.path.join(userdata, 'gen.xml')
+
+
+def run():
+ ## load mappings ##
+ try:
+ setup_keymap_folder()
+ except Exception:
+ pass
+
+ defaultkeymap = read_keymap(default)
+ userkeymap = []
+ if os.path.exists(gen_file):
+ try:
+ userkeymap = read_keymap(gen_file)
+ except Exception:
+ pass
+ newkey = KeyListener.record_key()
+ if newkey:
+ new = ('global', u'RunPlugin(plugin://plugin.video.p2p-streams/?mode=7)', newkey)
+ userkeymap.append(new)
+ if os.path.exists(gen_file):
+ shutil.copyfile(gen_file, gen_file + ".old")
+ write_keymap(userkeymap, gen_file)
+ xbmc.executebuiltin("action(reloadkeymaps)")
+ xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(600026), 1,addonpath+"/icon.png"))
+
+
+class KeyListener(WindowXMLDialog):
+ TIMEOUT = 5
+
+ def __new__(cls):
+ return super(KeyListener, cls).__new__(cls, "DialogKaiToast.xml", "")
+
+ def __init__(self):
+ self.key = None
+
+ def onInit(self):
+ try:
+ self.getControl(401).addLabel(translate(70034))
+ self.getControl(402).addLabel(translate(70035) % self.TIMEOUT)
+ except AttributeError:
+ self.getControl(401).setLabel(translate(70034))
+ self.getControl(402).setLabel(translate(70035) % self.TIMEOUT)
+
+ def onAction(self, action):
+ code = action.getButtonCode()
+ self.key = None if code == 0 else str(code)
+ self.close()
+
+ @staticmethod
+ def record_key():
+ dialog = KeyListener()
+ timeout = Timer(KeyListener.TIMEOUT, dialog.close)
+ timeout.start()
+ dialog.doModal()
+ timeout.cancel()
+ key = dialog.key
+ del dialog
+ return key
+
+def read_keymap(filename):
+ ret = []
+ with open(filename, 'r') as xml:
+ tree = ET.iterparse(xml)
+ for _, keymap in tree:
+ for context in keymap:
+ for device in context:
+ for mapping in device:
+ key = mapping.get('id') or mapping.tag
+ action = mapping.text
+ if action:
+ ret.append((context.tag.lower(), action.lower(), key.lower()))
+ return ret
+
+def setup_keymap_folder():
+ if not os.path.exists(userdata):
+ os.makedirs(userdata)
+ else:
+ #make sure there are no user defined keymaps
+ for name in os.listdir(userdata):
+ if name.endswith('.xml') and name != os.path.basename(gen_file):
+ src = os.path.join(userdata, name)
+ for i in xrange(100):
+ dst = os.path.join(userdata, "%s.bak.%d" % (name, i))
+ if os.path.exists(dst):
+ continue
+ shutil.move(src, dst)
+ #successfully renamed
+ break
+
+def write_keymap(keymap, filename):
+ contexts = list(set([c for c, a, k in keymap]))
+ builder = ET.TreeBuilder()
+ builder.start("keymap", {})
+ for context in contexts:
+ builder.start(context, {})
+ builder.start("keyboard", {})
+ for c, a, k in keymap:
+ if c == context:
+ builder.start("key", {"id":k})
+ builder.data(a)
+ builder.end("key")
+ builder.end("keyboard")
+ builder.end(context)
+ builder.end("keymap")
+ element = builder.close()
+ ET.ElementTree(element).write(filename, 'utf-8')
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pluginxbmc.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pluginxbmc.py
new file mode 100644
index 0000000000000000000000000000000000000000..720265b458c38bce571281ffdc5fed27a5e65c65
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pluginxbmc.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+
+""" p2p-streams (c) 2014 enen92 fightnight
+
+ This file contains the common variables used by the addon
+
+ Functions:
+
+ translate(text) -> Translate a string based on the addon language strings
+
+"""
+
+import xbmc,xbmcplugin,xbmcgui,xbmcaddon
+
+linkwiki="http://bit.ly/1r5uGQT"
+addon_id = 'plugin.video.p2p-streams'
+art = '/resources/art/'
+settings = xbmcaddon.Addon(id=addon_id)
+addonpath = settings.getAddonInfo('path').decode('utf-8')
+versao = settings.getAddonInfo('version')
+pastaperfil = xbmc.translatePath(settings.getAddonInfo('profile')).decode('utf-8')
+iconpequeno=addonpath + art + 'iconpq.jpg'
+mensagemok = xbmcgui.Dialog().ok
+mensagemprogresso = xbmcgui.DialogProgress()
+pastaperfil = xbmc.translatePath(settings.getAddonInfo('profile')).decode('utf-8')
+MainURL = 'https://code.google.com/p/p2p-strm/'
+addon_icon = settings.getAddonInfo('icon')
+
+def translate(text):
+ return settings.getLocalizedString(text).encode('utf-8')
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pluginxbmc.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pluginxbmc.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..17fac2f2d2b37d89c827e470bdac943a721d3f59
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pluginxbmc.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/__init__.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e993a4517531120e81c42cca8ee13e184c6e8264
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/__init__.py
@@ -0,0 +1,1510 @@
+'''
+datetime.tzinfo timezone definitions generated from the
+Olson timezone database:
+
+ ftp://elsie.nci.nih.gov/pub/tz*.tar.gz
+
+See the datetime section of the Python Library Reference for information
+on how to use these modules.
+'''
+
+# The Olson database is updated several times a year.
+OLSON_VERSION = '2014b'
+VERSION = '2014.2' # Switching to pip compatible version numbering.
+__version__ = VERSION
+
+OLSEN_VERSION = OLSON_VERSION # Old releases had this misspelling
+
+__all__ = [
+ 'timezone', 'utc', 'country_timezones', 'country_names',
+ 'AmbiguousTimeError', 'InvalidTimeError',
+ 'NonExistentTimeError', 'UnknownTimeZoneError',
+ 'all_timezones', 'all_timezones_set',
+ 'common_timezones', 'common_timezones_set',
+ ]
+
+import sys, datetime, os.path, gettext
+
+try:
+ from pkg_resources import resource_stream
+except ImportError:
+ resource_stream = None
+
+from pytz.exceptions import AmbiguousTimeError
+from pytz.exceptions import InvalidTimeError
+from pytz.exceptions import NonExistentTimeError
+from pytz.exceptions import UnknownTimeZoneError
+from pytz.lazy import LazyDict, LazyList, LazySet
+from pytz.tzinfo import unpickler
+from pytz.tzfile import build_tzinfo, _byte_string
+
+
+try:
+ unicode
+
+except NameError: # Python 3.x
+
+ # Python 3.x doesn't have unicode(), making writing code
+ # for Python 2.3 and Python 3.x a pain.
+ unicode = str
+
+ def ascii(s):
+ r"""
+ >>> ascii('Hello')
+ 'Hello'
+ >>> ascii('\N{TRADE MARK SIGN}') #doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ...
+ UnicodeEncodeError: ...
+ """
+ s.encode('US-ASCII') # Raise an exception if not ASCII
+ return s # But return the original string - not a byte string.
+
+else: # Python 2.x
+
+ def ascii(s):
+ r"""
+ >>> ascii('Hello')
+ 'Hello'
+ >>> ascii(u'Hello')
+ 'Hello'
+ >>> ascii(u'\N{TRADE MARK SIGN}') #doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ...
+ UnicodeEncodeError: ...
+ """
+ return s.encode('US-ASCII')
+
+
+def open_resource(name):
+ """Open a resource from the zoneinfo subdir for reading.
+
+ Uses the pkg_resources module if available and no standard file
+ found at the calculated location.
+ """
+ name_parts = name.lstrip('/').split('/')
+ for part in name_parts:
+ if part == os.path.pardir or os.path.sep in part:
+ raise ValueError('Bad path segment: %r' % part)
+ filename = os.path.join(os.path.dirname(__file__),
+ 'zoneinfo', *name_parts)
+ if not os.path.exists(filename) and resource_stream is not None:
+ # http://bugs.launchpad.net/bugs/383171 - we avoid using this
+ # unless absolutely necessary to help when a broken version of
+ # pkg_resources is installed.
+ return resource_stream(__name__, 'zoneinfo/' + name)
+ return open(filename, 'rb')
+
+
+def resource_exists(name):
+ """Return true if the given resource exists"""
+ try:
+ open_resource(name).close()
+ return True
+ except IOError:
+ return False
+
+
+# Enable this when we get some translations?
+# We want an i18n API that is useful to programs using Python's gettext
+# module, as well as the Zope3 i18n package. Perhaps we should just provide
+# the POT file and translations, and leave it up to callers to make use
+# of them.
+#
+# t = gettext.translation(
+# 'pytz', os.path.join(os.path.dirname(__file__), 'locales'),
+# fallback=True
+# )
+# def _(timezone_name):
+# """Translate a timezone name using the current locale, returning Unicode"""
+# return t.ugettext(timezone_name)
+
+
+_tzinfo_cache = {}
+
+def timezone(zone):
+ r''' Return a datetime.tzinfo implementation for the given timezone
+
+ >>> from datetime import datetime, timedelta
+ >>> utc = timezone('UTC')
+ >>> eastern = timezone('US/Eastern')
+ >>> eastern.zone
+ 'US/Eastern'
+ >>> timezone(unicode('US/Eastern')) is eastern
+ True
+ >>> utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
+ >>> loc_dt = utc_dt.astimezone(eastern)
+ >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
+ >>> loc_dt.strftime(fmt)
+ '2002-10-27 01:00:00 EST (-0500)'
+ >>> (loc_dt - timedelta(minutes=10)).strftime(fmt)
+ '2002-10-27 00:50:00 EST (-0500)'
+ >>> eastern.normalize(loc_dt - timedelta(minutes=10)).strftime(fmt)
+ '2002-10-27 01:50:00 EDT (-0400)'
+ >>> (loc_dt + timedelta(minutes=10)).strftime(fmt)
+ '2002-10-27 01:10:00 EST (-0500)'
+
+ Raises UnknownTimeZoneError if passed an unknown zone.
+
+ >>> try:
+ ... timezone('Asia/Shangri-La')
+ ... except UnknownTimeZoneError:
+ ... print('Unknown')
+ Unknown
+
+ >>> try:
+ ... timezone(unicode('\N{TRADE MARK SIGN}'))
+ ... except UnknownTimeZoneError:
+ ... print('Unknown')
+ Unknown
+
+ '''
+ if zone.upper() == 'UTC':
+ return utc
+
+ try:
+ zone = ascii(zone)
+ except UnicodeEncodeError:
+ # All valid timezones are ASCII
+ raise UnknownTimeZoneError(zone)
+
+ zone = _unmunge_zone(zone)
+ if zone not in _tzinfo_cache:
+ if zone in all_timezones_set:
+ fp = open_resource(zone)
+ try:
+ _tzinfo_cache[zone] = build_tzinfo(zone, fp)
+ finally:
+ fp.close()
+ else:
+ raise UnknownTimeZoneError(zone)
+
+ return _tzinfo_cache[zone]
+
+
+def _unmunge_zone(zone):
+ """Undo the time zone name munging done by older versions of pytz."""
+ return zone.replace('_plus_', '+').replace('_minus_', '-')
+
+
+ZERO = datetime.timedelta(0)
+HOUR = datetime.timedelta(hours=1)
+
+
+class UTC(datetime.tzinfo):
+ """UTC
+
+ Optimized UTC implementation. It unpickles using the single module global
+ instance defined beneath this class declaration.
+ """
+ zone = "UTC"
+
+ _utcoffset = ZERO
+ _dst = ZERO
+ _tzname = zone
+
+ def fromutc(self, dt):
+ if dt.tzinfo is None:
+ return self.localize(dt)
+ return super(utc.__class__, self).fromutc(dt)
+
+ def utcoffset(self, dt):
+ return ZERO
+
+ def tzname(self, dt):
+ return "UTC"
+
+ def dst(self, dt):
+ return ZERO
+
+ def __reduce__(self):
+ return _UTC, ()
+
+ def localize(self, dt, is_dst=False):
+ '''Convert naive time to local time'''
+ if dt.tzinfo is not None:
+ raise ValueError('Not naive datetime (tzinfo is already set)')
+ return dt.replace(tzinfo=self)
+
+ def normalize(self, dt, is_dst=False):
+ '''Correct the timezone information on the given datetime'''
+ if dt.tzinfo is self:
+ return dt
+ if dt.tzinfo is None:
+ raise ValueError('Naive time - no tzinfo set')
+ return dt.astimezone(self)
+
+ def __repr__(self):
+ return ""
+
+ def __str__(self):
+ return "UTC"
+
+
+UTC = utc = UTC() # UTC is a singleton
+
+
+def _UTC():
+ """Factory function for utc unpickling.
+
+ Makes sure that unpickling a utc instance always returns the same
+ module global.
+
+ These examples belong in the UTC class above, but it is obscured; or in
+ the README.txt, but we are not depending on Python 2.4 so integrating
+ the README.txt examples with the unit tests is not trivial.
+
+ >>> import datetime, pickle
+ >>> dt = datetime.datetime(2005, 3, 1, 14, 13, 21, tzinfo=utc)
+ >>> naive = dt.replace(tzinfo=None)
+ >>> p = pickle.dumps(dt, 1)
+ >>> naive_p = pickle.dumps(naive, 1)
+ >>> len(p) - len(naive_p)
+ 17
+ >>> new = pickle.loads(p)
+ >>> new == dt
+ True
+ >>> new is dt
+ False
+ >>> new.tzinfo is dt.tzinfo
+ True
+ >>> utc is UTC is timezone('UTC')
+ True
+ >>> utc is timezone('GMT')
+ False
+ """
+ return utc
+_UTC.__safe_for_unpickling__ = True
+
+
+def _p(*args):
+ """Factory function for unpickling pytz tzinfo instances.
+
+ Just a wrapper around tzinfo.unpickler to save a few bytes in each pickle
+ by shortening the path.
+ """
+ return unpickler(*args)
+_p.__safe_for_unpickling__ = True
+
+
+
+class _CountryTimezoneDict(LazyDict):
+ """Map ISO 3166 country code to a list of timezone names commonly used
+ in that country.
+
+ iso3166_code is the two letter code used to identify the country.
+
+ >>> def print_list(list_of_strings):
+ ... 'We use a helper so doctests work under Python 2.3 -> 3.x'
+ ... for s in list_of_strings:
+ ... print(s)
+
+ >>> print_list(country_timezones['nz'])
+ Pacific/Auckland
+ Pacific/Chatham
+ >>> print_list(country_timezones['ch'])
+ Europe/Zurich
+ >>> print_list(country_timezones['CH'])
+ Europe/Zurich
+ >>> print_list(country_timezones[unicode('ch')])
+ Europe/Zurich
+ >>> print_list(country_timezones['XXX'])
+ Traceback (most recent call last):
+ ...
+ KeyError: 'XXX'
+
+ Previously, this information was exposed as a function rather than a
+ dictionary. This is still supported::
+
+ >>> print_list(country_timezones('nz'))
+ Pacific/Auckland
+ Pacific/Chatham
+ """
+ def __call__(self, iso3166_code):
+ """Backwards compatibility."""
+ return self[iso3166_code]
+
+ def _fill(self):
+ data = {}
+ zone_tab = open_resource('zone.tab')
+ try:
+ for line in zone_tab:
+ line = line.decode('US-ASCII')
+ if line.startswith('#'):
+ continue
+ code, coordinates, zone = line.split(None, 4)[:3]
+ if zone not in all_timezones_set:
+ continue
+ try:
+ data[code].append(zone)
+ except KeyError:
+ data[code] = [zone]
+ self.data = data
+ finally:
+ zone_tab.close()
+
+country_timezones = _CountryTimezoneDict()
+
+
+class _CountryNameDict(LazyDict):
+ '''Dictionary proving ISO3166 code -> English name.
+
+ >>> print(country_names['au'])
+ Australia
+ '''
+ def _fill(self):
+ data = {}
+ zone_tab = open_resource('iso3166.tab')
+ try:
+ for line in zone_tab.readlines():
+ line = line.decode('US-ASCII')
+ if line.startswith('#'):
+ continue
+ code, name = line.split(None, 1)
+ data[code] = name.strip()
+ self.data = data
+ finally:
+ zone_tab.close()
+
+country_names = _CountryNameDict()
+
+
+# Time-zone info based solely on fixed offsets
+
+class _FixedOffset(datetime.tzinfo):
+
+ zone = None # to match the standard pytz API
+
+ def __init__(self, minutes):
+ if abs(minutes) >= 1440:
+ raise ValueError("absolute offset is too large", minutes)
+ self._minutes = minutes
+ self._offset = datetime.timedelta(minutes=minutes)
+
+ def utcoffset(self, dt):
+ return self._offset
+
+ def __reduce__(self):
+ return FixedOffset, (self._minutes, )
+
+ def dst(self, dt):
+ return ZERO
+
+ def tzname(self, dt):
+ return None
+
+ def __repr__(self):
+ return 'pytz.FixedOffset(%d)' % self._minutes
+
+ def localize(self, dt, is_dst=False):
+ '''Convert naive time to local time'''
+ if dt.tzinfo is not None:
+ raise ValueError('Not naive datetime (tzinfo is already set)')
+ return dt.replace(tzinfo=self)
+
+ def normalize(self, dt, is_dst=False):
+ '''Correct the timezone information on the given datetime'''
+ if dt.tzinfo is None:
+ raise ValueError('Naive time - no tzinfo set')
+ return dt.replace(tzinfo=self)
+
+
+def FixedOffset(offset, _tzinfos = {}):
+ """return a fixed-offset timezone based off a number of minutes.
+
+ >>> one = FixedOffset(-330)
+ >>> one
+ pytz.FixedOffset(-330)
+ >>> one.utcoffset(datetime.datetime.now())
+ datetime.timedelta(-1, 66600)
+ >>> one.dst(datetime.datetime.now())
+ datetime.timedelta(0)
+
+ >>> two = FixedOffset(1380)
+ >>> two
+ pytz.FixedOffset(1380)
+ >>> two.utcoffset(datetime.datetime.now())
+ datetime.timedelta(0, 82800)
+ >>> two.dst(datetime.datetime.now())
+ datetime.timedelta(0)
+
+ The datetime.timedelta must be between the range of -1 and 1 day,
+ non-inclusive.
+
+ >>> FixedOffset(1440)
+ Traceback (most recent call last):
+ ...
+ ValueError: ('absolute offset is too large', 1440)
+
+ >>> FixedOffset(-1440)
+ Traceback (most recent call last):
+ ...
+ ValueError: ('absolute offset is too large', -1440)
+
+ An offset of 0 is special-cased to return UTC.
+
+ >>> FixedOffset(0) is UTC
+ True
+
+ There should always be only one instance of a FixedOffset per timedelta.
+ This should be true for multiple creation calls.
+
+ >>> FixedOffset(-330) is one
+ True
+ >>> FixedOffset(1380) is two
+ True
+
+ It should also be true for pickling.
+
+ >>> import pickle
+ >>> pickle.loads(pickle.dumps(one)) is one
+ True
+ >>> pickle.loads(pickle.dumps(two)) is two
+ True
+ """
+ if offset == 0:
+ return UTC
+
+ info = _tzinfos.get(offset)
+ if info is None:
+ # We haven't seen this one before. we need to save it.
+
+ # Use setdefault to avoid a race condition and make sure we have
+ # only one
+ info = _tzinfos.setdefault(offset, _FixedOffset(offset))
+
+ return info
+
+FixedOffset.__safe_for_unpickling__ = True
+
+
+def _test():
+ import doctest, os, sys
+ sys.path.insert(0, os.pardir)
+ import pytz
+ return doctest.testmod(pytz)
+
+if __name__ == '__main__':
+ _test()
+
+all_timezones = \
+['Africa/Abidjan',
+ 'Africa/Accra',
+ 'Africa/Addis_Ababa',
+ 'Africa/Algiers',
+ 'Africa/Asmara',
+ 'Africa/Asmera',
+ 'Africa/Bamako',
+ 'Africa/Bangui',
+ 'Africa/Banjul',
+ 'Africa/Bissau',
+ 'Africa/Blantyre',
+ 'Africa/Brazzaville',
+ 'Africa/Bujumbura',
+ 'Africa/Cairo',
+ 'Africa/Casablanca',
+ 'Africa/Ceuta',
+ 'Africa/Conakry',
+ 'Africa/Dakar',
+ 'Africa/Dar_es_Salaam',
+ 'Africa/Djibouti',
+ 'Africa/Douala',
+ 'Africa/El_Aaiun',
+ 'Africa/Freetown',
+ 'Africa/Gaborone',
+ 'Africa/Harare',
+ 'Africa/Johannesburg',
+ 'Africa/Juba',
+ 'Africa/Kampala',
+ 'Africa/Khartoum',
+ 'Africa/Kigali',
+ 'Africa/Kinshasa',
+ 'Africa/Lagos',
+ 'Africa/Libreville',
+ 'Africa/Lome',
+ 'Africa/Luanda',
+ 'Africa/Lubumbashi',
+ 'Africa/Lusaka',
+ 'Africa/Malabo',
+ 'Africa/Maputo',
+ 'Africa/Maseru',
+ 'Africa/Mbabane',
+ 'Africa/Mogadishu',
+ 'Africa/Monrovia',
+ 'Africa/Nairobi',
+ 'Africa/Ndjamena',
+ 'Africa/Niamey',
+ 'Africa/Nouakchott',
+ 'Africa/Ouagadougou',
+ 'Africa/Porto-Novo',
+ 'Africa/Sao_Tome',
+ 'Africa/Timbuktu',
+ 'Africa/Tripoli',
+ 'Africa/Tunis',
+ 'Africa/Windhoek',
+ 'America/Adak',
+ 'America/Anchorage',
+ 'America/Anguilla',
+ 'America/Antigua',
+ 'America/Araguaina',
+ 'America/Argentina/Buenos_Aires',
+ 'America/Argentina/Catamarca',
+ 'America/Argentina/ComodRivadavia',
+ 'America/Argentina/Cordoba',
+ 'America/Argentina/Jujuy',
+ 'America/Argentina/La_Rioja',
+ 'America/Argentina/Mendoza',
+ 'America/Argentina/Rio_Gallegos',
+ 'America/Argentina/Salta',
+ 'America/Argentina/San_Juan',
+ 'America/Argentina/San_Luis',
+ 'America/Argentina/Tucuman',
+ 'America/Argentina/Ushuaia',
+ 'America/Aruba',
+ 'America/Asuncion',
+ 'America/Atikokan',
+ 'America/Atka',
+ 'America/Bahia',
+ 'America/Bahia_Banderas',
+ 'America/Barbados',
+ 'America/Belem',
+ 'America/Belize',
+ 'America/Blanc-Sablon',
+ 'America/Boa_Vista',
+ 'America/Bogota',
+ 'America/Boise',
+ 'America/Buenos_Aires',
+ 'America/Cambridge_Bay',
+ 'America/Campo_Grande',
+ 'America/Cancun',
+ 'America/Caracas',
+ 'America/Catamarca',
+ 'America/Cayenne',
+ 'America/Cayman',
+ 'America/Chicago',
+ 'America/Chihuahua',
+ 'America/Coral_Harbour',
+ 'America/Cordoba',
+ 'America/Costa_Rica',
+ 'America/Creston',
+ 'America/Cuiaba',
+ 'America/Curacao',
+ 'America/Danmarkshavn',
+ 'America/Dawson',
+ 'America/Dawson_Creek',
+ 'America/Denver',
+ 'America/Detroit',
+ 'America/Dominica',
+ 'America/Edmonton',
+ 'America/Eirunepe',
+ 'America/El_Salvador',
+ 'America/Ensenada',
+ 'America/Fort_Wayne',
+ 'America/Fortaleza',
+ 'America/Glace_Bay',
+ 'America/Godthab',
+ 'America/Goose_Bay',
+ 'America/Grand_Turk',
+ 'America/Grenada',
+ 'America/Guadeloupe',
+ 'America/Guatemala',
+ 'America/Guayaquil',
+ 'America/Guyana',
+ 'America/Halifax',
+ 'America/Havana',
+ 'America/Hermosillo',
+ 'America/Indiana/Indianapolis',
+ 'America/Indiana/Knox',
+ 'America/Indiana/Marengo',
+ 'America/Indiana/Petersburg',
+ 'America/Indiana/Tell_City',
+ 'America/Indiana/Vevay',
+ 'America/Indiana/Vincennes',
+ 'America/Indiana/Winamac',
+ 'America/Indianapolis',
+ 'America/Inuvik',
+ 'America/Iqaluit',
+ 'America/Jamaica',
+ 'America/Jujuy',
+ 'America/Juneau',
+ 'America/Kentucky/Louisville',
+ 'America/Kentucky/Monticello',
+ 'America/Knox_IN',
+ 'America/Kralendijk',
+ 'America/La_Paz',
+ 'America/Lima',
+ 'America/Los_Angeles',
+ 'America/Louisville',
+ 'America/Lower_Princes',
+ 'America/Maceio',
+ 'America/Managua',
+ 'America/Manaus',
+ 'America/Marigot',
+ 'America/Martinique',
+ 'America/Matamoros',
+ 'America/Mazatlan',
+ 'America/Mendoza',
+ 'America/Menominee',
+ 'America/Merida',
+ 'America/Metlakatla',
+ 'America/Mexico_City',
+ 'America/Miquelon',
+ 'America/Moncton',
+ 'America/Monterrey',
+ 'America/Montevideo',
+ 'America/Montreal',
+ 'America/Montserrat',
+ 'America/Nassau',
+ 'America/New_York',
+ 'America/Nipigon',
+ 'America/Nome',
+ 'America/Noronha',
+ 'America/North_Dakota/Beulah',
+ 'America/North_Dakota/Center',
+ 'America/North_Dakota/New_Salem',
+ 'America/Ojinaga',
+ 'America/Panama',
+ 'America/Pangnirtung',
+ 'America/Paramaribo',
+ 'America/Phoenix',
+ 'America/Port-au-Prince',
+ 'America/Port_of_Spain',
+ 'America/Porto_Acre',
+ 'America/Porto_Velho',
+ 'America/Puerto_Rico',
+ 'America/Rainy_River',
+ 'America/Rankin_Inlet',
+ 'America/Recife',
+ 'America/Regina',
+ 'America/Resolute',
+ 'America/Rio_Branco',
+ 'America/Rosario',
+ 'America/Santa_Isabel',
+ 'America/Santarem',
+ 'America/Santiago',
+ 'America/Santo_Domingo',
+ 'America/Sao_Paulo',
+ 'America/Scoresbysund',
+ 'America/Shiprock',
+ 'America/Sitka',
+ 'America/St_Barthelemy',
+ 'America/St_Johns',
+ 'America/St_Kitts',
+ 'America/St_Lucia',
+ 'America/St_Thomas',
+ 'America/St_Vincent',
+ 'America/Swift_Current',
+ 'America/Tegucigalpa',
+ 'America/Thule',
+ 'America/Thunder_Bay',
+ 'America/Tijuana',
+ 'America/Toronto',
+ 'America/Tortola',
+ 'America/Vancouver',
+ 'America/Virgin',
+ 'America/Whitehorse',
+ 'America/Winnipeg',
+ 'America/Yakutat',
+ 'America/Yellowknife',
+ 'Antarctica/Casey',
+ 'Antarctica/Davis',
+ 'Antarctica/DumontDUrville',
+ 'Antarctica/Macquarie',
+ 'Antarctica/Mawson',
+ 'Antarctica/McMurdo',
+ 'Antarctica/Palmer',
+ 'Antarctica/Rothera',
+ 'Antarctica/South_Pole',
+ 'Antarctica/Syowa',
+ 'Antarctica/Troll',
+ 'Antarctica/Vostok',
+ 'Arctic/Longyearbyen',
+ 'Asia/Aden',
+ 'Asia/Almaty',
+ 'Asia/Amman',
+ 'Asia/Anadyr',
+ 'Asia/Aqtau',
+ 'Asia/Aqtobe',
+ 'Asia/Ashgabat',
+ 'Asia/Ashkhabad',
+ 'Asia/Baghdad',
+ 'Asia/Bahrain',
+ 'Asia/Baku',
+ 'Asia/Bangkok',
+ 'Asia/Beirut',
+ 'Asia/Bishkek',
+ 'Asia/Brunei',
+ 'Asia/Calcutta',
+ 'Asia/Choibalsan',
+ 'Asia/Chongqing',
+ 'Asia/Chungking',
+ 'Asia/Colombo',
+ 'Asia/Dacca',
+ 'Asia/Damascus',
+ 'Asia/Dhaka',
+ 'Asia/Dili',
+ 'Asia/Dubai',
+ 'Asia/Dushanbe',
+ 'Asia/Gaza',
+ 'Asia/Harbin',
+ 'Asia/Hebron',
+ 'Asia/Ho_Chi_Minh',
+ 'Asia/Hong_Kong',
+ 'Asia/Hovd',
+ 'Asia/Irkutsk',
+ 'Asia/Istanbul',
+ 'Asia/Jakarta',
+ 'Asia/Jayapura',
+ 'Asia/Jerusalem',
+ 'Asia/Kabul',
+ 'Asia/Kamchatka',
+ 'Asia/Karachi',
+ 'Asia/Kashgar',
+ 'Asia/Kathmandu',
+ 'Asia/Katmandu',
+ 'Asia/Khandyga',
+ 'Asia/Kolkata',
+ 'Asia/Krasnoyarsk',
+ 'Asia/Kuala_Lumpur',
+ 'Asia/Kuching',
+ 'Asia/Kuwait',
+ 'Asia/Macao',
+ 'Asia/Macau',
+ 'Asia/Magadan',
+ 'Asia/Makassar',
+ 'Asia/Manila',
+ 'Asia/Muscat',
+ 'Asia/Nicosia',
+ 'Asia/Novokuznetsk',
+ 'Asia/Novosibirsk',
+ 'Asia/Omsk',
+ 'Asia/Oral',
+ 'Asia/Phnom_Penh',
+ 'Asia/Pontianak',
+ 'Asia/Pyongyang',
+ 'Asia/Qatar',
+ 'Asia/Qyzylorda',
+ 'Asia/Rangoon',
+ 'Asia/Riyadh',
+ 'Asia/Saigon',
+ 'Asia/Sakhalin',
+ 'Asia/Samarkand',
+ 'Asia/Seoul',
+ 'Asia/Shanghai',
+ 'Asia/Singapore',
+ 'Asia/Taipei',
+ 'Asia/Tashkent',
+ 'Asia/Tbilisi',
+ 'Asia/Tehran',
+ 'Asia/Tel_Aviv',
+ 'Asia/Thimbu',
+ 'Asia/Thimphu',
+ 'Asia/Tokyo',
+ 'Asia/Ujung_Pandang',
+ 'Asia/Ulaanbaatar',
+ 'Asia/Ulan_Bator',
+ 'Asia/Urumqi',
+ 'Asia/Ust-Nera',
+ 'Asia/Vientiane',
+ 'Asia/Vladivostok',
+ 'Asia/Yakutsk',
+ 'Asia/Yekaterinburg',
+ 'Asia/Yerevan',
+ 'Atlantic/Azores',
+ 'Atlantic/Bermuda',
+ 'Atlantic/Canary',
+ 'Atlantic/Cape_Verde',
+ 'Atlantic/Faeroe',
+ 'Atlantic/Faroe',
+ 'Atlantic/Jan_Mayen',
+ 'Atlantic/Madeira',
+ 'Atlantic/Reykjavik',
+ 'Atlantic/South_Georgia',
+ 'Atlantic/St_Helena',
+ 'Atlantic/Stanley',
+ 'Australia/ACT',
+ 'Australia/Adelaide',
+ 'Australia/Brisbane',
+ 'Australia/Broken_Hill',
+ 'Australia/Canberra',
+ 'Australia/Currie',
+ 'Australia/Darwin',
+ 'Australia/Eucla',
+ 'Australia/Hobart',
+ 'Australia/LHI',
+ 'Australia/Lindeman',
+ 'Australia/Lord_Howe',
+ 'Australia/Melbourne',
+ 'Australia/NSW',
+ 'Australia/North',
+ 'Australia/Perth',
+ 'Australia/Queensland',
+ 'Australia/South',
+ 'Australia/Sydney',
+ 'Australia/Tasmania',
+ 'Australia/Victoria',
+ 'Australia/West',
+ 'Australia/Yancowinna',
+ 'Brazil/Acre',
+ 'Brazil/DeNoronha',
+ 'Brazil/East',
+ 'Brazil/West',
+ 'CET',
+ 'CST6CDT',
+ 'Canada/Atlantic',
+ 'Canada/Central',
+ 'Canada/East-Saskatchewan',
+ 'Canada/Eastern',
+ 'Canada/Mountain',
+ 'Canada/Newfoundland',
+ 'Canada/Pacific',
+ 'Canada/Saskatchewan',
+ 'Canada/Yukon',
+ 'Chile/Continental',
+ 'Chile/EasterIsland',
+ 'Cuba',
+ 'EET',
+ 'EST',
+ 'EST5EDT',
+ 'Egypt',
+ 'Eire',
+ 'Etc/GMT',
+ 'Etc/GMT+0',
+ 'Etc/GMT+1',
+ 'Etc/GMT+10',
+ 'Etc/GMT+11',
+ 'Etc/GMT+12',
+ 'Etc/GMT+2',
+ 'Etc/GMT+3',
+ 'Etc/GMT+4',
+ 'Etc/GMT+5',
+ 'Etc/GMT+6',
+ 'Etc/GMT+7',
+ 'Etc/GMT+8',
+ 'Etc/GMT+9',
+ 'Etc/GMT-0',
+ 'Etc/GMT-1',
+ 'Etc/GMT-10',
+ 'Etc/GMT-11',
+ 'Etc/GMT-12',
+ 'Etc/GMT-13',
+ 'Etc/GMT-14',
+ 'Etc/GMT-2',
+ 'Etc/GMT-3',
+ 'Etc/GMT-4',
+ 'Etc/GMT-5',
+ 'Etc/GMT-6',
+ 'Etc/GMT-7',
+ 'Etc/GMT-8',
+ 'Etc/GMT-9',
+ 'Etc/GMT0',
+ 'Etc/Greenwich',
+ 'Etc/UCT',
+ 'Etc/UTC',
+ 'Etc/Universal',
+ 'Etc/Zulu',
+ 'Europe/Amsterdam',
+ 'Europe/Andorra',
+ 'Europe/Athens',
+ 'Europe/Belfast',
+ 'Europe/Belgrade',
+ 'Europe/Berlin',
+ 'Europe/Bratislava',
+ 'Europe/Brussels',
+ 'Europe/Bucharest',
+ 'Europe/Budapest',
+ 'Europe/Busingen',
+ 'Europe/Chisinau',
+ 'Europe/Copenhagen',
+ 'Europe/Dublin',
+ 'Europe/Gibraltar',
+ 'Europe/Guernsey',
+ 'Europe/Helsinki',
+ 'Europe/Isle_of_Man',
+ 'Europe/Istanbul',
+ 'Europe/Jersey',
+ 'Europe/Kaliningrad',
+ 'Europe/Kiev',
+ 'Europe/Lisbon',
+ 'Europe/Ljubljana',
+ 'Europe/London',
+ 'Europe/Luxembourg',
+ 'Europe/Madrid',
+ 'Europe/Malta',
+ 'Europe/Mariehamn',
+ 'Europe/Minsk',
+ 'Europe/Monaco',
+ 'Europe/Moscow',
+ 'Europe/Nicosia',
+ 'Europe/Oslo',
+ 'Europe/Paris',
+ 'Europe/Podgorica',
+ 'Europe/Prague',
+ 'Europe/Riga',
+ 'Europe/Rome',
+ 'Europe/Samara',
+ 'Europe/San_Marino',
+ 'Europe/Sarajevo',
+ 'Europe/Simferopol',
+ 'Europe/Skopje',
+ 'Europe/Sofia',
+ 'Europe/Stockholm',
+ 'Europe/Tallinn',
+ 'Europe/Tirane',
+ 'Europe/Tiraspol',
+ 'Europe/Uzhgorod',
+ 'Europe/Vaduz',
+ 'Europe/Vatican',
+ 'Europe/Vienna',
+ 'Europe/Vilnius',
+ 'Europe/Volgograd',
+ 'Europe/Warsaw',
+ 'Europe/Zagreb',
+ 'Europe/Zaporozhye',
+ 'Europe/Zurich',
+ 'GB',
+ 'GB-Eire',
+ 'GMT',
+ 'GMT+0',
+ 'GMT-0',
+ 'GMT0',
+ 'Greenwich',
+ 'HST',
+ 'Hongkong',
+ 'Iceland',
+ 'Indian/Antananarivo',
+ 'Indian/Chagos',
+ 'Indian/Christmas',
+ 'Indian/Cocos',
+ 'Indian/Comoro',
+ 'Indian/Kerguelen',
+ 'Indian/Mahe',
+ 'Indian/Maldives',
+ 'Indian/Mauritius',
+ 'Indian/Mayotte',
+ 'Indian/Reunion',
+ 'Iran',
+ 'Israel',
+ 'Jamaica',
+ 'Japan',
+ 'Kwajalein',
+ 'Libya',
+ 'MET',
+ 'MST',
+ 'MST7MDT',
+ 'Mexico/BajaNorte',
+ 'Mexico/BajaSur',
+ 'Mexico/General',
+ 'NZ',
+ 'NZ-CHAT',
+ 'Navajo',
+ 'PRC',
+ 'PST8PDT',
+ 'Pacific/Apia',
+ 'Pacific/Auckland',
+ 'Pacific/Chatham',
+ 'Pacific/Chuuk',
+ 'Pacific/Easter',
+ 'Pacific/Efate',
+ 'Pacific/Enderbury',
+ 'Pacific/Fakaofo',
+ 'Pacific/Fiji',
+ 'Pacific/Funafuti',
+ 'Pacific/Galapagos',
+ 'Pacific/Gambier',
+ 'Pacific/Guadalcanal',
+ 'Pacific/Guam',
+ 'Pacific/Honolulu',
+ 'Pacific/Johnston',
+ 'Pacific/Kiritimati',
+ 'Pacific/Kosrae',
+ 'Pacific/Kwajalein',
+ 'Pacific/Majuro',
+ 'Pacific/Marquesas',
+ 'Pacific/Midway',
+ 'Pacific/Nauru',
+ 'Pacific/Niue',
+ 'Pacific/Norfolk',
+ 'Pacific/Noumea',
+ 'Pacific/Pago_Pago',
+ 'Pacific/Palau',
+ 'Pacific/Pitcairn',
+ 'Pacific/Pohnpei',
+ 'Pacific/Ponape',
+ 'Pacific/Port_Moresby',
+ 'Pacific/Rarotonga',
+ 'Pacific/Saipan',
+ 'Pacific/Samoa',
+ 'Pacific/Tahiti',
+ 'Pacific/Tarawa',
+ 'Pacific/Tongatapu',
+ 'Pacific/Truk',
+ 'Pacific/Wake',
+ 'Pacific/Wallis',
+ 'Pacific/Yap',
+ 'Poland',
+ 'Portugal',
+ 'ROC',
+ 'ROK',
+ 'Singapore',
+ 'Turkey',
+ 'UCT',
+ 'US/Alaska',
+ 'US/Aleutian',
+ 'US/Arizona',
+ 'US/Central',
+ 'US/East-Indiana',
+ 'US/Eastern',
+ 'US/Hawaii',
+ 'US/Indiana-Starke',
+ 'US/Michigan',
+ 'US/Mountain',
+ 'US/Pacific',
+ 'US/Pacific-New',
+ 'US/Samoa',
+ 'UTC',
+ 'Universal',
+ 'W-SU',
+ 'WET',
+ 'Zulu']
+all_timezones = LazyList(
+ tz for tz in all_timezones if resource_exists(tz))
+
+all_timezones_set = LazySet(all_timezones)
+common_timezones = \
+['Africa/Abidjan',
+ 'Africa/Accra',
+ 'Africa/Addis_Ababa',
+ 'Africa/Algiers',
+ 'Africa/Asmara',
+ 'Africa/Bamako',
+ 'Africa/Bangui',
+ 'Africa/Banjul',
+ 'Africa/Bissau',
+ 'Africa/Blantyre',
+ 'Africa/Brazzaville',
+ 'Africa/Bujumbura',
+ 'Africa/Cairo',
+ 'Africa/Casablanca',
+ 'Africa/Ceuta',
+ 'Africa/Conakry',
+ 'Africa/Dakar',
+ 'Africa/Dar_es_Salaam',
+ 'Africa/Djibouti',
+ 'Africa/Douala',
+ 'Africa/El_Aaiun',
+ 'Africa/Freetown',
+ 'Africa/Gaborone',
+ 'Africa/Harare',
+ 'Africa/Johannesburg',
+ 'Africa/Juba',
+ 'Africa/Kampala',
+ 'Africa/Khartoum',
+ 'Africa/Kigali',
+ 'Africa/Kinshasa',
+ 'Africa/Lagos',
+ 'Africa/Libreville',
+ 'Africa/Lome',
+ 'Africa/Luanda',
+ 'Africa/Lubumbashi',
+ 'Africa/Lusaka',
+ 'Africa/Malabo',
+ 'Africa/Maputo',
+ 'Africa/Maseru',
+ 'Africa/Mbabane',
+ 'Africa/Mogadishu',
+ 'Africa/Monrovia',
+ 'Africa/Nairobi',
+ 'Africa/Ndjamena',
+ 'Africa/Niamey',
+ 'Africa/Nouakchott',
+ 'Africa/Ouagadougou',
+ 'Africa/Porto-Novo',
+ 'Africa/Sao_Tome',
+ 'Africa/Tripoli',
+ 'Africa/Tunis',
+ 'Africa/Windhoek',
+ 'America/Adak',
+ 'America/Anchorage',
+ 'America/Anguilla',
+ 'America/Antigua',
+ 'America/Araguaina',
+ 'America/Argentina/Buenos_Aires',
+ 'America/Argentina/Catamarca',
+ 'America/Argentina/Cordoba',
+ 'America/Argentina/Jujuy',
+ 'America/Argentina/La_Rioja',
+ 'America/Argentina/Mendoza',
+ 'America/Argentina/Rio_Gallegos',
+ 'America/Argentina/Salta',
+ 'America/Argentina/San_Juan',
+ 'America/Argentina/San_Luis',
+ 'America/Argentina/Tucuman',
+ 'America/Argentina/Ushuaia',
+ 'America/Aruba',
+ 'America/Asuncion',
+ 'America/Atikokan',
+ 'America/Bahia',
+ 'America/Bahia_Banderas',
+ 'America/Barbados',
+ 'America/Belem',
+ 'America/Belize',
+ 'America/Blanc-Sablon',
+ 'America/Boa_Vista',
+ 'America/Bogota',
+ 'America/Boise',
+ 'America/Cambridge_Bay',
+ 'America/Campo_Grande',
+ 'America/Cancun',
+ 'America/Caracas',
+ 'America/Cayenne',
+ 'America/Cayman',
+ 'America/Chicago',
+ 'America/Chihuahua',
+ 'America/Costa_Rica',
+ 'America/Creston',
+ 'America/Cuiaba',
+ 'America/Curacao',
+ 'America/Danmarkshavn',
+ 'America/Dawson',
+ 'America/Dawson_Creek',
+ 'America/Denver',
+ 'America/Detroit',
+ 'America/Dominica',
+ 'America/Edmonton',
+ 'America/Eirunepe',
+ 'America/El_Salvador',
+ 'America/Fortaleza',
+ 'America/Glace_Bay',
+ 'America/Godthab',
+ 'America/Goose_Bay',
+ 'America/Grand_Turk',
+ 'America/Grenada',
+ 'America/Guadeloupe',
+ 'America/Guatemala',
+ 'America/Guayaquil',
+ 'America/Guyana',
+ 'America/Halifax',
+ 'America/Havana',
+ 'America/Hermosillo',
+ 'America/Indiana/Indianapolis',
+ 'America/Indiana/Knox',
+ 'America/Indiana/Marengo',
+ 'America/Indiana/Petersburg',
+ 'America/Indiana/Tell_City',
+ 'America/Indiana/Vevay',
+ 'America/Indiana/Vincennes',
+ 'America/Indiana/Winamac',
+ 'America/Inuvik',
+ 'America/Iqaluit',
+ 'America/Jamaica',
+ 'America/Juneau',
+ 'America/Kentucky/Louisville',
+ 'America/Kentucky/Monticello',
+ 'America/Kralendijk',
+ 'America/La_Paz',
+ 'America/Lima',
+ 'America/Los_Angeles',
+ 'America/Lower_Princes',
+ 'America/Maceio',
+ 'America/Managua',
+ 'America/Manaus',
+ 'America/Marigot',
+ 'America/Martinique',
+ 'America/Matamoros',
+ 'America/Mazatlan',
+ 'America/Menominee',
+ 'America/Merida',
+ 'America/Metlakatla',
+ 'America/Mexico_City',
+ 'America/Miquelon',
+ 'America/Moncton',
+ 'America/Monterrey',
+ 'America/Montevideo',
+ 'America/Montreal',
+ 'America/Montserrat',
+ 'America/Nassau',
+ 'America/New_York',
+ 'America/Nipigon',
+ 'America/Nome',
+ 'America/Noronha',
+ 'America/North_Dakota/Beulah',
+ 'America/North_Dakota/Center',
+ 'America/North_Dakota/New_Salem',
+ 'America/Ojinaga',
+ 'America/Panama',
+ 'America/Pangnirtung',
+ 'America/Paramaribo',
+ 'America/Phoenix',
+ 'America/Port-au-Prince',
+ 'America/Port_of_Spain',
+ 'America/Porto_Velho',
+ 'America/Puerto_Rico',
+ 'America/Rainy_River',
+ 'America/Rankin_Inlet',
+ 'America/Recife',
+ 'America/Regina',
+ 'America/Resolute',
+ 'America/Rio_Branco',
+ 'America/Santa_Isabel',
+ 'America/Santarem',
+ 'America/Santiago',
+ 'America/Santo_Domingo',
+ 'America/Sao_Paulo',
+ 'America/Scoresbysund',
+ 'America/Sitka',
+ 'America/St_Barthelemy',
+ 'America/St_Johns',
+ 'America/St_Kitts',
+ 'America/St_Lucia',
+ 'America/St_Thomas',
+ 'America/St_Vincent',
+ 'America/Swift_Current',
+ 'America/Tegucigalpa',
+ 'America/Thule',
+ 'America/Thunder_Bay',
+ 'America/Tijuana',
+ 'America/Toronto',
+ 'America/Tortola',
+ 'America/Vancouver',
+ 'America/Whitehorse',
+ 'America/Winnipeg',
+ 'America/Yakutat',
+ 'America/Yellowknife',
+ 'Antarctica/Casey',
+ 'Antarctica/Davis',
+ 'Antarctica/DumontDUrville',
+ 'Antarctica/Macquarie',
+ 'Antarctica/Mawson',
+ 'Antarctica/McMurdo',
+ 'Antarctica/Palmer',
+ 'Antarctica/Rothera',
+ 'Antarctica/Syowa',
+ 'Antarctica/Troll',
+ 'Antarctica/Vostok',
+ 'Arctic/Longyearbyen',
+ 'Asia/Aden',
+ 'Asia/Almaty',
+ 'Asia/Amman',
+ 'Asia/Anadyr',
+ 'Asia/Aqtau',
+ 'Asia/Aqtobe',
+ 'Asia/Ashgabat',
+ 'Asia/Baghdad',
+ 'Asia/Bahrain',
+ 'Asia/Baku',
+ 'Asia/Bangkok',
+ 'Asia/Beirut',
+ 'Asia/Bishkek',
+ 'Asia/Brunei',
+ 'Asia/Choibalsan',
+ 'Asia/Chongqing',
+ 'Asia/Colombo',
+ 'Asia/Damascus',
+ 'Asia/Dhaka',
+ 'Asia/Dili',
+ 'Asia/Dubai',
+ 'Asia/Dushanbe',
+ 'Asia/Gaza',
+ 'Asia/Harbin',
+ 'Asia/Hebron',
+ 'Asia/Ho_Chi_Minh',
+ 'Asia/Hong_Kong',
+ 'Asia/Hovd',
+ 'Asia/Irkutsk',
+ 'Asia/Jakarta',
+ 'Asia/Jayapura',
+ 'Asia/Jerusalem',
+ 'Asia/Kabul',
+ 'Asia/Kamchatka',
+ 'Asia/Karachi',
+ 'Asia/Kashgar',
+ 'Asia/Kathmandu',
+ 'Asia/Khandyga',
+ 'Asia/Kolkata',
+ 'Asia/Krasnoyarsk',
+ 'Asia/Kuala_Lumpur',
+ 'Asia/Kuching',
+ 'Asia/Kuwait',
+ 'Asia/Macau',
+ 'Asia/Magadan',
+ 'Asia/Makassar',
+ 'Asia/Manila',
+ 'Asia/Muscat',
+ 'Asia/Nicosia',
+ 'Asia/Novokuznetsk',
+ 'Asia/Novosibirsk',
+ 'Asia/Omsk',
+ 'Asia/Oral',
+ 'Asia/Phnom_Penh',
+ 'Asia/Pontianak',
+ 'Asia/Pyongyang',
+ 'Asia/Qatar',
+ 'Asia/Qyzylorda',
+ 'Asia/Rangoon',
+ 'Asia/Riyadh',
+ 'Asia/Sakhalin',
+ 'Asia/Samarkand',
+ 'Asia/Seoul',
+ 'Asia/Shanghai',
+ 'Asia/Singapore',
+ 'Asia/Taipei',
+ 'Asia/Tashkent',
+ 'Asia/Tbilisi',
+ 'Asia/Tehran',
+ 'Asia/Thimphu',
+ 'Asia/Tokyo',
+ 'Asia/Ulaanbaatar',
+ 'Asia/Urumqi',
+ 'Asia/Ust-Nera',
+ 'Asia/Vientiane',
+ 'Asia/Vladivostok',
+ 'Asia/Yakutsk',
+ 'Asia/Yekaterinburg',
+ 'Asia/Yerevan',
+ 'Atlantic/Azores',
+ 'Atlantic/Bermuda',
+ 'Atlantic/Canary',
+ 'Atlantic/Cape_Verde',
+ 'Atlantic/Faroe',
+ 'Atlantic/Madeira',
+ 'Atlantic/Reykjavik',
+ 'Atlantic/South_Georgia',
+ 'Atlantic/St_Helena',
+ 'Atlantic/Stanley',
+ 'Australia/Adelaide',
+ 'Australia/Brisbane',
+ 'Australia/Broken_Hill',
+ 'Australia/Currie',
+ 'Australia/Darwin',
+ 'Australia/Eucla',
+ 'Australia/Hobart',
+ 'Australia/Lindeman',
+ 'Australia/Lord_Howe',
+ 'Australia/Melbourne',
+ 'Australia/Perth',
+ 'Australia/Sydney',
+ 'Canada/Atlantic',
+ 'Canada/Central',
+ 'Canada/Eastern',
+ 'Canada/Mountain',
+ 'Canada/Newfoundland',
+ 'Canada/Pacific',
+ 'Europe/Amsterdam',
+ 'Europe/Andorra',
+ 'Europe/Athens',
+ 'Europe/Belgrade',
+ 'Europe/Berlin',
+ 'Europe/Bratislava',
+ 'Europe/Brussels',
+ 'Europe/Bucharest',
+ 'Europe/Budapest',
+ 'Europe/Busingen',
+ 'Europe/Chisinau',
+ 'Europe/Copenhagen',
+ 'Europe/Dublin',
+ 'Europe/Gibraltar',
+ 'Europe/Guernsey',
+ 'Europe/Helsinki',
+ 'Europe/Isle_of_Man',
+ 'Europe/Istanbul',
+ 'Europe/Jersey',
+ 'Europe/Kaliningrad',
+ 'Europe/Kiev',
+ 'Europe/Lisbon',
+ 'Europe/Ljubljana',
+ 'Europe/London',
+ 'Europe/Luxembourg',
+ 'Europe/Madrid',
+ 'Europe/Malta',
+ 'Europe/Mariehamn',
+ 'Europe/Minsk',
+ 'Europe/Monaco',
+ 'Europe/Moscow',
+ 'Europe/Oslo',
+ 'Europe/Paris',
+ 'Europe/Podgorica',
+ 'Europe/Prague',
+ 'Europe/Riga',
+ 'Europe/Rome',
+ 'Europe/Samara',
+ 'Europe/San_Marino',
+ 'Europe/Sarajevo',
+ 'Europe/Simferopol',
+ 'Europe/Skopje',
+ 'Europe/Sofia',
+ 'Europe/Stockholm',
+ 'Europe/Tallinn',
+ 'Europe/Tirane',
+ 'Europe/Uzhgorod',
+ 'Europe/Vaduz',
+ 'Europe/Vatican',
+ 'Europe/Vienna',
+ 'Europe/Vilnius',
+ 'Europe/Volgograd',
+ 'Europe/Warsaw',
+ 'Europe/Zagreb',
+ 'Europe/Zaporozhye',
+ 'Europe/Zurich',
+ 'GMT',
+ 'Indian/Antananarivo',
+ 'Indian/Chagos',
+ 'Indian/Christmas',
+ 'Indian/Cocos',
+ 'Indian/Comoro',
+ 'Indian/Kerguelen',
+ 'Indian/Mahe',
+ 'Indian/Maldives',
+ 'Indian/Mauritius',
+ 'Indian/Mayotte',
+ 'Indian/Reunion',
+ 'Pacific/Apia',
+ 'Pacific/Auckland',
+ 'Pacific/Chatham',
+ 'Pacific/Chuuk',
+ 'Pacific/Easter',
+ 'Pacific/Efate',
+ 'Pacific/Enderbury',
+ 'Pacific/Fakaofo',
+ 'Pacific/Fiji',
+ 'Pacific/Funafuti',
+ 'Pacific/Galapagos',
+ 'Pacific/Gambier',
+ 'Pacific/Guadalcanal',
+ 'Pacific/Guam',
+ 'Pacific/Honolulu',
+ 'Pacific/Johnston',
+ 'Pacific/Kiritimati',
+ 'Pacific/Kosrae',
+ 'Pacific/Kwajalein',
+ 'Pacific/Majuro',
+ 'Pacific/Marquesas',
+ 'Pacific/Midway',
+ 'Pacific/Nauru',
+ 'Pacific/Niue',
+ 'Pacific/Norfolk',
+ 'Pacific/Noumea',
+ 'Pacific/Pago_Pago',
+ 'Pacific/Palau',
+ 'Pacific/Pitcairn',
+ 'Pacific/Pohnpei',
+ 'Pacific/Port_Moresby',
+ 'Pacific/Rarotonga',
+ 'Pacific/Saipan',
+ 'Pacific/Tahiti',
+ 'Pacific/Tarawa',
+ 'Pacific/Tongatapu',
+ 'Pacific/Wake',
+ 'Pacific/Wallis',
+ 'US/Alaska',
+ 'US/Arizona',
+ 'US/Central',
+ 'US/Eastern',
+ 'US/Hawaii',
+ 'US/Mountain',
+ 'US/Pacific',
+ 'UTC']
+common_timezones = LazyList(
+ tz for tz in common_timezones if tz in all_timezones)
+
+common_timezones_set = LazySet(common_timezones)
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/__init__.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..9f037414605fd2155ff8c31c9f4e21e33523ea5e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/__init__.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/exceptions.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/exceptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..0376108e14bbfc38f65e55a3b8ec45248b8b9b92
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/exceptions.py
@@ -0,0 +1,48 @@
+'''
+Custom exceptions raised by pytz.
+'''
+
+__all__ = [
+ 'UnknownTimeZoneError', 'InvalidTimeError', 'AmbiguousTimeError',
+ 'NonExistentTimeError',
+ ]
+
+
+class UnknownTimeZoneError(KeyError):
+ '''Exception raised when pytz is passed an unknown timezone.
+
+ >>> isinstance(UnknownTimeZoneError(), LookupError)
+ True
+
+ This class is actually a subclass of KeyError to provide backwards
+ compatibility with code relying on the undocumented behavior of earlier
+ pytz releases.
+
+ >>> isinstance(UnknownTimeZoneError(), KeyError)
+ True
+ '''
+ pass
+
+
+class InvalidTimeError(Exception):
+ '''Base class for invalid time exceptions.'''
+
+
+class AmbiguousTimeError(InvalidTimeError):
+ '''Exception raised when attempting to create an ambiguous wallclock time.
+
+ At the end of a DST transition period, a particular wallclock time will
+ occur twice (once before the clocks are set back, once after). Both
+ possibilities may be correct, unless further information is supplied.
+
+ See DstTzInfo.normalize() for more info
+ '''
+
+
+class NonExistentTimeError(InvalidTimeError):
+ '''Exception raised when attempting to create a wallclock time that
+ cannot exist.
+
+ At the start of a DST transition period, the wallclock time jumps forward.
+ The instants jumped over never occur.
+ '''
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/lazy.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/lazy.py
new file mode 100644
index 0000000000000000000000000000000000000000..f7fc597cf60e169ead5aa52a321aafdec4e6ab17
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/lazy.py
@@ -0,0 +1,168 @@
+from threading import RLock
+try:
+ from UserDict import DictMixin
+except ImportError:
+ from collections import Mapping as DictMixin
+
+
+# With lazy loading, we might end up with multiple threads triggering
+# it at the same time. We need a lock.
+_fill_lock = RLock()
+
+
+class LazyDict(DictMixin):
+ """Dictionary populated on first use."""
+ data = None
+ def __getitem__(self, key):
+ if self.data is None:
+ _fill_lock.acquire()
+ try:
+ if self.data is None:
+ self._fill()
+ finally:
+ _fill_lock.release()
+ return self.data[key.upper()]
+
+ def __contains__(self, key):
+ if self.data is None:
+ _fill_lock.acquire()
+ try:
+ if self.data is None:
+ self._fill()
+ finally:
+ _fill_lock.release()
+ return key in self.data
+
+ def __iter__(self):
+ if self.data is None:
+ _fill_lock.acquire()
+ try:
+ if self.data is None:
+ self._fill()
+ finally:
+ _fill_lock.release()
+ return iter(self.data)
+
+ def __len__(self):
+ if self.data is None:
+ _fill_lock.acquire()
+ try:
+ if self.data is None:
+ self._fill()
+ finally:
+ _fill_lock.release()
+ return len(self.data)
+
+ def keys(self):
+ if self.data is None:
+ _fill_lock.acquire()
+ try:
+ if self.data is None:
+ self._fill()
+ finally:
+ _fill_lock.release()
+ return self.data.keys()
+
+
+class LazyList(list):
+ """List populated on first use."""
+
+ _props = [
+ '__str__', '__repr__', '__unicode__',
+ '__hash__', '__sizeof__', '__cmp__',
+ '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__',
+ 'append', 'count', 'index', 'extend', 'insert', 'pop', 'remove',
+ 'reverse', 'sort', '__add__', '__radd__', '__iadd__', '__mul__',
+ '__rmul__', '__imul__', '__contains__', '__len__', '__nonzero__',
+ '__getitem__', '__setitem__', '__delitem__', '__iter__',
+ '__reversed__', '__getslice__', '__setslice__', '__delslice__']
+
+ def __new__(cls, fill_iter=None):
+
+ if fill_iter is None:
+ return list()
+
+ # We need a new class as we will be dynamically messing with its
+ # methods.
+ class LazyList(list):
+ pass
+
+ fill_iter = [fill_iter]
+
+ def lazy(name):
+ def _lazy(self, *args, **kw):
+ _fill_lock.acquire()
+ try:
+ if len(fill_iter) > 0:
+ list.extend(self, fill_iter.pop())
+ for method_name in cls._props:
+ delattr(LazyList, method_name)
+ finally:
+ _fill_lock.release()
+ return getattr(list, name)(self, *args, **kw)
+ return _lazy
+
+ for name in cls._props:
+ setattr(LazyList, name, lazy(name))
+
+ new_list = LazyList()
+ return new_list
+
+# Not all versions of Python declare the same magic methods.
+# Filter out properties that don't exist in this version of Python
+# from the list.
+LazyList._props = [prop for prop in LazyList._props if hasattr(list, prop)]
+
+
+class LazySet(set):
+ """Set populated on first use."""
+
+ _props = (
+ '__str__', '__repr__', '__unicode__',
+ '__hash__', '__sizeof__', '__cmp__',
+ '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__',
+ '__contains__', '__len__', '__nonzero__',
+ '__getitem__', '__setitem__', '__delitem__', '__iter__',
+ '__sub__', '__and__', '__xor__', '__or__',
+ '__rsub__', '__rand__', '__rxor__', '__ror__',
+ '__isub__', '__iand__', '__ixor__', '__ior__',
+ 'add', 'clear', 'copy', 'difference', 'difference_update',
+ 'discard', 'intersection', 'intersection_update', 'isdisjoint',
+ 'issubset', 'issuperset', 'pop', 'remove',
+ 'symmetric_difference', 'symmetric_difference_update',
+ 'union', 'update')
+
+ def __new__(cls, fill_iter=None):
+
+ if fill_iter is None:
+ return set()
+
+ class LazySet(set):
+ pass
+
+ fill_iter = [fill_iter]
+
+ def lazy(name):
+ def _lazy(self, *args, **kw):
+ _fill_lock.acquire()
+ try:
+ if len(fill_iter) > 0:
+ for i in fill_iter.pop():
+ set.add(self, i)
+ for method_name in cls._props:
+ delattr(LazySet, method_name)
+ finally:
+ _fill_lock.release()
+ return getattr(set, name)(self, *args, **kw)
+ return _lazy
+
+ for name in cls._props:
+ setattr(LazySet, name, lazy(name))
+
+ new_set = LazySet()
+ return new_set
+
+# Not all versions of Python declare the same magic methods.
+# Filter out properties that don't exist in this version of Python
+# from the list.
+LazySet._props = [prop for prop in LazySet._props if hasattr(set, prop)]
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/reference.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/reference.py
new file mode 100644
index 0000000000000000000000000000000000000000..3dda13e75cd45d2d74a8db29568e6ff9f9f60e59
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/reference.py
@@ -0,0 +1,127 @@
+'''
+Reference tzinfo implementations from the Python docs.
+Used for testing against as they are only correct for the years
+1987 to 2006. Do not use these for real code.
+'''
+
+from datetime import tzinfo, timedelta, datetime
+from pytz import utc, UTC, HOUR, ZERO
+
+# A class building tzinfo objects for fixed-offset time zones.
+# Note that FixedOffset(0, "UTC") is a different way to build a
+# UTC tzinfo object.
+
+class FixedOffset(tzinfo):
+ """Fixed offset in minutes east from UTC."""
+
+ def __init__(self, offset, name):
+ self.__offset = timedelta(minutes = offset)
+ self.__name = name
+
+ def utcoffset(self, dt):
+ return self.__offset
+
+ def tzname(self, dt):
+ return self.__name
+
+ def dst(self, dt):
+ return ZERO
+
+# A class capturing the platform's idea of local time.
+
+import time as _time
+
+STDOFFSET = timedelta(seconds = -_time.timezone)
+if _time.daylight:
+ DSTOFFSET = timedelta(seconds = -_time.altzone)
+else:
+ DSTOFFSET = STDOFFSET
+
+DSTDIFF = DSTOFFSET - STDOFFSET
+
+class LocalTimezone(tzinfo):
+
+ def utcoffset(self, dt):
+ if self._isdst(dt):
+ return DSTOFFSET
+ else:
+ return STDOFFSET
+
+ def dst(self, dt):
+ if self._isdst(dt):
+ return DSTDIFF
+ else:
+ return ZERO
+
+ def tzname(self, dt):
+ return _time.tzname[self._isdst(dt)]
+
+ def _isdst(self, dt):
+ tt = (dt.year, dt.month, dt.day,
+ dt.hour, dt.minute, dt.second,
+ dt.weekday(), 0, -1)
+ stamp = _time.mktime(tt)
+ tt = _time.localtime(stamp)
+ return tt.tm_isdst > 0
+
+Local = LocalTimezone()
+
+# A complete implementation of current DST rules for major US time zones.
+
+def first_sunday_on_or_after(dt):
+ days_to_go = 6 - dt.weekday()
+ if days_to_go:
+ dt += timedelta(days_to_go)
+ return dt
+
+# In the US, DST starts at 2am (standard time) on the first Sunday in April.
+DSTSTART = datetime(1, 4, 1, 2)
+# and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct.
+# which is the first Sunday on or after Oct 25.
+DSTEND = datetime(1, 10, 25, 1)
+
+class USTimeZone(tzinfo):
+
+ def __init__(self, hours, reprname, stdname, dstname):
+ self.stdoffset = timedelta(hours=hours)
+ self.reprname = reprname
+ self.stdname = stdname
+ self.dstname = dstname
+
+ def __repr__(self):
+ return self.reprname
+
+ def tzname(self, dt):
+ if self.dst(dt):
+ return self.dstname
+ else:
+ return self.stdname
+
+ def utcoffset(self, dt):
+ return self.stdoffset + self.dst(dt)
+
+ def dst(self, dt):
+ if dt is None or dt.tzinfo is None:
+ # An exception may be sensible here, in one or both cases.
+ # It depends on how you want to treat them. The default
+ # fromutc() implementation (called by the default astimezone()
+ # implementation) passes a datetime with dt.tzinfo is self.
+ return ZERO
+ assert dt.tzinfo is self
+
+ # Find first Sunday in April & the last in October.
+ start = first_sunday_on_or_after(DSTSTART.replace(year=dt.year))
+ end = first_sunday_on_or_after(DSTEND.replace(year=dt.year))
+
+ # Can't compare naive to aware objects, so strip the timezone from
+ # dt first.
+ if start <= dt.replace(tzinfo=None) < end:
+ return HOUR
+ else:
+ return ZERO
+
+Eastern = USTimeZone(-5, "Eastern", "EST", "EDT")
+Central = USTimeZone(-6, "Central", "CST", "CDT")
+Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
+Pacific = USTimeZone(-8, "Pacific", "PST", "PDT")
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/tzfile.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/tzfile.py
new file mode 100644
index 0000000000000000000000000000000000000000..9c007c80995a6ffa2ac9276388357fb5c4d21335
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/tzfile.py
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+'''
+$Id: tzfile.py,v 1.8 2004/06/03 00:15:24 zenzen Exp $
+'''
+
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from io import StringIO
+from datetime import datetime, timedelta
+from struct import unpack, calcsize
+
+from pytz.tzinfo import StaticTzInfo, DstTzInfo, memorized_ttinfo
+from pytz.tzinfo import memorized_datetime, memorized_timedelta
+
+def _byte_string(s):
+ """Cast a string or byte string to an ASCII byte string."""
+ return s.encode('US-ASCII')
+
+_NULL = _byte_string('\0')
+
+def _std_string(s):
+ """Cast a string or byte string to an ASCII string."""
+ return str(s.decode('US-ASCII'))
+
+def build_tzinfo(zone, fp):
+ head_fmt = '>4s c 15x 6l'
+ head_size = calcsize(head_fmt)
+ (magic, format, ttisgmtcnt, ttisstdcnt,leapcnt, timecnt,
+ typecnt, charcnt) = unpack(head_fmt, fp.read(head_size))
+
+ # Make sure it is a tzfile(5) file
+ assert magic == _byte_string('TZif'), 'Got magic %s' % repr(magic)
+
+ # Read out the transition times, localtime indices and ttinfo structures.
+ data_fmt = '>%(timecnt)dl %(timecnt)dB %(ttinfo)s %(charcnt)ds' % dict(
+ timecnt=timecnt, ttinfo='lBB'*typecnt, charcnt=charcnt)
+ data_size = calcsize(data_fmt)
+ data = unpack(data_fmt, fp.read(data_size))
+
+ # make sure we unpacked the right number of values
+ assert len(data) == 2 * timecnt + 3 * typecnt + 1
+ transitions = [memorized_datetime(trans)
+ for trans in data[:timecnt]]
+ lindexes = list(data[timecnt:2 * timecnt])
+ ttinfo_raw = data[2 * timecnt:-1]
+ tznames_raw = data[-1]
+ del data
+
+ # Process ttinfo into separate structs
+ ttinfo = []
+ tznames = {}
+ i = 0
+ while i < len(ttinfo_raw):
+ # have we looked up this timezone name yet?
+ tzname_offset = ttinfo_raw[i+2]
+ if tzname_offset not in tznames:
+ nul = tznames_raw.find(_NULL, tzname_offset)
+ if nul < 0:
+ nul = len(tznames_raw)
+ tznames[tzname_offset] = _std_string(
+ tznames_raw[tzname_offset:nul])
+ ttinfo.append((ttinfo_raw[i],
+ bool(ttinfo_raw[i+1]),
+ tznames[tzname_offset]))
+ i += 3
+
+ # Now build the timezone object
+ if len(transitions) == 0:
+ ttinfo[0][0], ttinfo[0][2]
+ cls = type(zone, (StaticTzInfo,), dict(
+ zone=zone,
+ _utcoffset=memorized_timedelta(ttinfo[0][0]),
+ _tzname=ttinfo[0][2]))
+ else:
+ # Early dates use the first standard time ttinfo
+ i = 0
+ while ttinfo[i][1]:
+ i += 1
+ if ttinfo[i] == ttinfo[lindexes[0]]:
+ transitions[0] = datetime.min
+ else:
+ transitions.insert(0, datetime.min)
+ lindexes.insert(0, i)
+
+ # calculate transition info
+ transition_info = []
+ for i in range(len(transitions)):
+ inf = ttinfo[lindexes[i]]
+ utcoffset = inf[0]
+ if not inf[1]:
+ dst = 0
+ else:
+ for j in range(i-1, -1, -1):
+ prev_inf = ttinfo[lindexes[j]]
+ if not prev_inf[1]:
+ break
+ dst = inf[0] - prev_inf[0] # dst offset
+
+ # Bad dst? Look further. DST > 24 hours happens when
+ # a timzone has moved across the international dateline.
+ if dst <= 0 or dst > 3600*3:
+ for j in range(i+1, len(transitions)):
+ stdinf = ttinfo[lindexes[j]]
+ if not stdinf[1]:
+ dst = inf[0] - stdinf[0]
+ if dst > 0:
+ break # Found a useful std time.
+
+ tzname = inf[2]
+
+ # Round utcoffset and dst to the nearest minute or the
+ # datetime library will complain. Conversions to these timezones
+ # might be up to plus or minus 30 seconds out, but it is
+ # the best we can do.
+ utcoffset = int((utcoffset + 30) // 60) * 60
+ dst = int((dst + 30) // 60) * 60
+ transition_info.append(memorized_ttinfo(utcoffset, dst, tzname))
+
+ cls = type(zone, (DstTzInfo,), dict(
+ zone=zone,
+ _utc_transition_times=transitions,
+ _transition_info=transition_info))
+
+ return cls()
+
+if __name__ == '__main__':
+ import os.path
+ from pprint import pprint
+ base = os.path.join(os.path.dirname(__file__), 'zoneinfo')
+ tz = build_tzinfo('Australia/Melbourne',
+ open(os.path.join(base,'Australia','Melbourne'), 'rb'))
+ tz = build_tzinfo('US/Eastern',
+ open(os.path.join(base,'US','Eastern'), 'rb'))
+ pprint(tz._utc_transition_times)
+ #print tz.asPython(4)
+ #print tz.transitions_mapping
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/tzinfo.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/tzinfo.py
new file mode 100644
index 0000000000000000000000000000000000000000..d53e9ff172c090d8773cd8dfc41546d6afb9db80
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/tzinfo.py
@@ -0,0 +1,563 @@
+'''Base classes and helpers for building zone specific tzinfo classes'''
+
+from datetime import datetime, timedelta, tzinfo
+from bisect import bisect_right
+try:
+ set
+except NameError:
+ from sets import Set as set
+
+import pytz
+from pytz.exceptions import AmbiguousTimeError, NonExistentTimeError
+
+__all__ = []
+
+_timedelta_cache = {}
+def memorized_timedelta(seconds):
+ '''Create only one instance of each distinct timedelta'''
+ try:
+ return _timedelta_cache[seconds]
+ except KeyError:
+ delta = timedelta(seconds=seconds)
+ _timedelta_cache[seconds] = delta
+ return delta
+
+_epoch = datetime.utcfromtimestamp(0)
+_datetime_cache = {0: _epoch}
+def memorized_datetime(seconds):
+ '''Create only one instance of each distinct datetime'''
+ try:
+ return _datetime_cache[seconds]
+ except KeyError:
+ # NB. We can't just do datetime.utcfromtimestamp(seconds) as this
+ # fails with negative values under Windows (Bug #90096)
+ dt = _epoch + timedelta(seconds=seconds)
+ _datetime_cache[seconds] = dt
+ return dt
+
+_ttinfo_cache = {}
+def memorized_ttinfo(*args):
+ '''Create only one instance of each distinct tuple'''
+ try:
+ return _ttinfo_cache[args]
+ except KeyError:
+ ttinfo = (
+ memorized_timedelta(args[0]),
+ memorized_timedelta(args[1]),
+ args[2]
+ )
+ _ttinfo_cache[args] = ttinfo
+ return ttinfo
+
+_notime = memorized_timedelta(0)
+
+def _to_seconds(td):
+ '''Convert a timedelta to seconds'''
+ return td.seconds + td.days * 24 * 60 * 60
+
+
+class BaseTzInfo(tzinfo):
+ # Overridden in subclass
+ _utcoffset = None
+ _tzname = None
+ zone = None
+
+ def __str__(self):
+ return self.zone
+
+
+class StaticTzInfo(BaseTzInfo):
+ '''A timezone that has a constant offset from UTC
+
+ These timezones are rare, as most locations have changed their
+ offset at some point in their history
+ '''
+ def fromutc(self, dt):
+ '''See datetime.tzinfo.fromutc'''
+ if dt.tzinfo is not None and dt.tzinfo is not self:
+ raise ValueError('fromutc: dt.tzinfo is not self')
+ return (dt + self._utcoffset).replace(tzinfo=self)
+
+ def utcoffset(self, dt, is_dst=None):
+ '''See datetime.tzinfo.utcoffset
+
+ is_dst is ignored for StaticTzInfo, and exists only to
+ retain compatibility with DstTzInfo.
+ '''
+ return self._utcoffset
+
+ def dst(self, dt, is_dst=None):
+ '''See datetime.tzinfo.dst
+
+ is_dst is ignored for StaticTzInfo, and exists only to
+ retain compatibility with DstTzInfo.
+ '''
+ return _notime
+
+ def tzname(self, dt, is_dst=None):
+ '''See datetime.tzinfo.tzname
+
+ is_dst is ignored for StaticTzInfo, and exists only to
+ retain compatibility with DstTzInfo.
+ '''
+ return self._tzname
+
+ def localize(self, dt, is_dst=False):
+ '''Convert naive time to local time'''
+ if dt.tzinfo is not None:
+ raise ValueError('Not naive datetime (tzinfo is already set)')
+ return dt.replace(tzinfo=self)
+
+ def normalize(self, dt, is_dst=False):
+ '''Correct the timezone information on the given datetime.
+
+ This is normally a no-op, as StaticTzInfo timezones never have
+ ambiguous cases to correct:
+
+ >>> from pytz import timezone
+ >>> gmt = timezone('GMT')
+ >>> isinstance(gmt, StaticTzInfo)
+ True
+ >>> dt = datetime(2011, 5, 8, 1, 2, 3, tzinfo=gmt)
+ >>> gmt.normalize(dt) is dt
+ True
+
+ The supported method of converting between timezones is to use
+ datetime.astimezone(). Currently normalize() also works:
+
+ >>> la = timezone('America/Los_Angeles')
+ >>> dt = la.localize(datetime(2011, 5, 7, 1, 2, 3))
+ >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
+ >>> gmt.normalize(dt).strftime(fmt)
+ '2011-05-07 08:02:03 GMT (+0000)'
+ '''
+ if dt.tzinfo is self:
+ return dt
+ if dt.tzinfo is None:
+ raise ValueError('Naive time - no tzinfo set')
+ return dt.astimezone(self)
+
+ def __repr__(self):
+ return '' % (self.zone,)
+
+ def __reduce__(self):
+ # Special pickle to zone remains a singleton and to cope with
+ # database changes.
+ return pytz._p, (self.zone,)
+
+
+class DstTzInfo(BaseTzInfo):
+ '''A timezone that has a variable offset from UTC
+
+ The offset might change if daylight saving time comes into effect,
+ or at a point in history when the region decides to change their
+ timezone definition.
+ '''
+ # Overridden in subclass
+ _utc_transition_times = None # Sorted list of DST transition times in UTC
+ _transition_info = None # [(utcoffset, dstoffset, tzname)] corresponding
+ # to _utc_transition_times entries
+ zone = None
+
+ # Set in __init__
+ _tzinfos = None
+ _dst = None # DST offset
+
+ def __init__(self, _inf=None, _tzinfos=None):
+ if _inf:
+ self._tzinfos = _tzinfos
+ self._utcoffset, self._dst, self._tzname = _inf
+ else:
+ _tzinfos = {}
+ self._tzinfos = _tzinfos
+ self._utcoffset, self._dst, self._tzname = self._transition_info[0]
+ _tzinfos[self._transition_info[0]] = self
+ for inf in self._transition_info[1:]:
+ if inf not in _tzinfos:
+ _tzinfos[inf] = self.__class__(inf, _tzinfos)
+
+ def fromutc(self, dt):
+ '''See datetime.tzinfo.fromutc'''
+ if (dt.tzinfo is not None
+ and getattr(dt.tzinfo, '_tzinfos', None) is not self._tzinfos):
+ raise ValueError('fromutc: dt.tzinfo is not self')
+ dt = dt.replace(tzinfo=None)
+ idx = max(0, bisect_right(self._utc_transition_times, dt) - 1)
+ inf = self._transition_info[idx]
+ return (dt + inf[0]).replace(tzinfo=self._tzinfos[inf])
+
+ def normalize(self, dt):
+ '''Correct the timezone information on the given datetime
+
+ If date arithmetic crosses DST boundaries, the tzinfo
+ is not magically adjusted. This method normalizes the
+ tzinfo to the correct one.
+
+ To test, first we need to do some setup
+
+ >>> from pytz import timezone
+ >>> utc = timezone('UTC')
+ >>> eastern = timezone('US/Eastern')
+ >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
+
+ We next create a datetime right on an end-of-DST transition point,
+ the instant when the wallclocks are wound back one hour.
+
+ >>> utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
+ >>> loc_dt = utc_dt.astimezone(eastern)
+ >>> loc_dt.strftime(fmt)
+ '2002-10-27 01:00:00 EST (-0500)'
+
+ Now, if we subtract a few minutes from it, note that the timezone
+ information has not changed.
+
+ >>> before = loc_dt - timedelta(minutes=10)
+ >>> before.strftime(fmt)
+ '2002-10-27 00:50:00 EST (-0500)'
+
+ But we can fix that by calling the normalize method
+
+ >>> before = eastern.normalize(before)
+ >>> before.strftime(fmt)
+ '2002-10-27 01:50:00 EDT (-0400)'
+
+ The supported method of converting between timezones is to use
+ datetime.astimezone(). Currently, normalize() also works:
+
+ >>> th = timezone('Asia/Bangkok')
+ >>> am = timezone('Europe/Amsterdam')
+ >>> dt = th.localize(datetime(2011, 5, 7, 1, 2, 3))
+ >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
+ >>> am.normalize(dt).strftime(fmt)
+ '2011-05-06 20:02:03 CEST (+0200)'
+ '''
+ if dt.tzinfo is None:
+ raise ValueError('Naive time - no tzinfo set')
+
+ # Convert dt in localtime to UTC
+ offset = dt.tzinfo._utcoffset
+ dt = dt.replace(tzinfo=None)
+ dt = dt - offset
+ # convert it back, and return it
+ return self.fromutc(dt)
+
+ def localize(self, dt, is_dst=False):
+ '''Convert naive time to local time.
+
+ This method should be used to construct localtimes, rather
+ than passing a tzinfo argument to a datetime constructor.
+
+ is_dst is used to determine the correct timezone in the ambigous
+ period at the end of daylight saving time.
+
+ >>> from pytz import timezone
+ >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
+ >>> amdam = timezone('Europe/Amsterdam')
+ >>> dt = datetime(2004, 10, 31, 2, 0, 0)
+ >>> loc_dt1 = amdam.localize(dt, is_dst=True)
+ >>> loc_dt2 = amdam.localize(dt, is_dst=False)
+ >>> loc_dt1.strftime(fmt)
+ '2004-10-31 02:00:00 CEST (+0200)'
+ >>> loc_dt2.strftime(fmt)
+ '2004-10-31 02:00:00 CET (+0100)'
+ >>> str(loc_dt2 - loc_dt1)
+ '1:00:00'
+
+ Use is_dst=None to raise an AmbiguousTimeError for ambiguous
+ times at the end of daylight saving time
+
+ >>> try:
+ ... loc_dt1 = amdam.localize(dt, is_dst=None)
+ ... except AmbiguousTimeError:
+ ... print('Ambiguous')
+ Ambiguous
+
+ is_dst defaults to False
+
+ >>> amdam.localize(dt) == amdam.localize(dt, False)
+ True
+
+ is_dst is also used to determine the correct timezone in the
+ wallclock times jumped over at the start of daylight saving time.
+
+ >>> pacific = timezone('US/Pacific')
+ >>> dt = datetime(2008, 3, 9, 2, 0, 0)
+ >>> ploc_dt1 = pacific.localize(dt, is_dst=True)
+ >>> ploc_dt2 = pacific.localize(dt, is_dst=False)
+ >>> ploc_dt1.strftime(fmt)
+ '2008-03-09 02:00:00 PDT (-0700)'
+ >>> ploc_dt2.strftime(fmt)
+ '2008-03-09 02:00:00 PST (-0800)'
+ >>> str(ploc_dt2 - ploc_dt1)
+ '1:00:00'
+
+ Use is_dst=None to raise a NonExistentTimeError for these skipped
+ times.
+
+ >>> try:
+ ... loc_dt1 = pacific.localize(dt, is_dst=None)
+ ... except NonExistentTimeError:
+ ... print('Non-existent')
+ Non-existent
+ '''
+ if dt.tzinfo is not None:
+ raise ValueError('Not naive datetime (tzinfo is already set)')
+
+ # Find the two best possibilities.
+ possible_loc_dt = set()
+ for delta in [timedelta(days=-1), timedelta(days=1)]:
+ loc_dt = dt + delta
+ idx = max(0, bisect_right(
+ self._utc_transition_times, loc_dt) - 1)
+ inf = self._transition_info[idx]
+ tzinfo = self._tzinfos[inf]
+ loc_dt = tzinfo.normalize(dt.replace(tzinfo=tzinfo))
+ if loc_dt.replace(tzinfo=None) == dt:
+ possible_loc_dt.add(loc_dt)
+
+ if len(possible_loc_dt) == 1:
+ return possible_loc_dt.pop()
+
+ # If there are no possibly correct timezones, we are attempting
+ # to convert a time that never happened - the time period jumped
+ # during the start-of-DST transition period.
+ if len(possible_loc_dt) == 0:
+ # If we refuse to guess, raise an exception.
+ if is_dst is None:
+ raise NonExistentTimeError(dt)
+
+ # If we are forcing the pre-DST side of the DST transition, we
+ # obtain the correct timezone by winding the clock forward a few
+ # hours.
+ elif is_dst:
+ return self.localize(
+ dt + timedelta(hours=6), is_dst=True) - timedelta(hours=6)
+
+ # If we are forcing the post-DST side of the DST transition, we
+ # obtain the correct timezone by winding the clock back.
+ else:
+ return self.localize(
+ dt - timedelta(hours=6), is_dst=False) + timedelta(hours=6)
+
+
+ # If we get this far, we have multiple possible timezones - this
+ # is an ambiguous case occuring during the end-of-DST transition.
+
+ # If told to be strict, raise an exception since we have an
+ # ambiguous case
+ if is_dst is None:
+ raise AmbiguousTimeError(dt)
+
+ # Filter out the possiblilities that don't match the requested
+ # is_dst
+ filtered_possible_loc_dt = [
+ p for p in possible_loc_dt
+ if bool(p.tzinfo._dst) == is_dst
+ ]
+
+ # Hopefully we only have one possibility left. Return it.
+ if len(filtered_possible_loc_dt) == 1:
+ return filtered_possible_loc_dt[0]
+
+ if len(filtered_possible_loc_dt) == 0:
+ filtered_possible_loc_dt = list(possible_loc_dt)
+
+ # If we get this far, we have in a wierd timezone transition
+ # where the clocks have been wound back but is_dst is the same
+ # in both (eg. Europe/Warsaw 1915 when they switched to CET).
+ # At this point, we just have to guess unless we allow more
+ # hints to be passed in (such as the UTC offset or abbreviation),
+ # but that is just getting silly.
+ #
+ # Choose the earliest (by UTC) applicable timezone.
+ sorting_keys = {}
+ for local_dt in filtered_possible_loc_dt:
+ key = local_dt.replace(tzinfo=None) - local_dt.tzinfo._utcoffset
+ sorting_keys[key] = local_dt
+ first_key = sorted(sorting_keys)[0]
+ return sorting_keys[first_key]
+
+ def utcoffset(self, dt, is_dst=None):
+ '''See datetime.tzinfo.utcoffset
+
+ The is_dst parameter may be used to remove ambiguity during DST
+ transitions.
+
+ >>> from pytz import timezone
+ >>> tz = timezone('America/St_Johns')
+ >>> ambiguous = datetime(2009, 10, 31, 23, 30)
+
+ >>> tz.utcoffset(ambiguous, is_dst=False)
+ datetime.timedelta(-1, 73800)
+
+ >>> tz.utcoffset(ambiguous, is_dst=True)
+ datetime.timedelta(-1, 77400)
+
+ >>> try:
+ ... tz.utcoffset(ambiguous)
+ ... except AmbiguousTimeError:
+ ... print('Ambiguous')
+ Ambiguous
+
+ '''
+ if dt is None:
+ return None
+ elif dt.tzinfo is not self:
+ dt = self.localize(dt, is_dst)
+ return dt.tzinfo._utcoffset
+ else:
+ return self._utcoffset
+
+ def dst(self, dt, is_dst=None):
+ '''See datetime.tzinfo.dst
+
+ The is_dst parameter may be used to remove ambiguity during DST
+ transitions.
+
+ >>> from pytz import timezone
+ >>> tz = timezone('America/St_Johns')
+
+ >>> normal = datetime(2009, 9, 1)
+
+ >>> tz.dst(normal)
+ datetime.timedelta(0, 3600)
+ >>> tz.dst(normal, is_dst=False)
+ datetime.timedelta(0, 3600)
+ >>> tz.dst(normal, is_dst=True)
+ datetime.timedelta(0, 3600)
+
+ >>> ambiguous = datetime(2009, 10, 31, 23, 30)
+
+ >>> tz.dst(ambiguous, is_dst=False)
+ datetime.timedelta(0)
+ >>> tz.dst(ambiguous, is_dst=True)
+ datetime.timedelta(0, 3600)
+ >>> try:
+ ... tz.dst(ambiguous)
+ ... except AmbiguousTimeError:
+ ... print('Ambiguous')
+ Ambiguous
+
+ '''
+ if dt is None:
+ return None
+ elif dt.tzinfo is not self:
+ dt = self.localize(dt, is_dst)
+ return dt.tzinfo._dst
+ else:
+ return self._dst
+
+ def tzname(self, dt, is_dst=None):
+ '''See datetime.tzinfo.tzname
+
+ The is_dst parameter may be used to remove ambiguity during DST
+ transitions.
+
+ >>> from pytz import timezone
+ >>> tz = timezone('America/St_Johns')
+
+ >>> normal = datetime(2009, 9, 1)
+
+ >>> tz.tzname(normal)
+ 'NDT'
+ >>> tz.tzname(normal, is_dst=False)
+ 'NDT'
+ >>> tz.tzname(normal, is_dst=True)
+ 'NDT'
+
+ >>> ambiguous = datetime(2009, 10, 31, 23, 30)
+
+ >>> tz.tzname(ambiguous, is_dst=False)
+ 'NST'
+ >>> tz.tzname(ambiguous, is_dst=True)
+ 'NDT'
+ >>> try:
+ ... tz.tzname(ambiguous)
+ ... except AmbiguousTimeError:
+ ... print('Ambiguous')
+ Ambiguous
+ '''
+ if dt is None:
+ return self.zone
+ elif dt.tzinfo is not self:
+ dt = self.localize(dt, is_dst)
+ return dt.tzinfo._tzname
+ else:
+ return self._tzname
+
+ def __repr__(self):
+ if self._dst:
+ dst = 'DST'
+ else:
+ dst = 'STD'
+ if self._utcoffset > _notime:
+ return '' % (
+ self.zone, self._tzname, self._utcoffset, dst
+ )
+ else:
+ return '' % (
+ self.zone, self._tzname, self._utcoffset, dst
+ )
+
+ def __reduce__(self):
+ # Special pickle to zone remains a singleton and to cope with
+ # database changes.
+ return pytz._p, (
+ self.zone,
+ _to_seconds(self._utcoffset),
+ _to_seconds(self._dst),
+ self._tzname
+ )
+
+
+
+def unpickler(zone, utcoffset=None, dstoffset=None, tzname=None):
+ """Factory function for unpickling pytz tzinfo instances.
+
+ This is shared for both StaticTzInfo and DstTzInfo instances, because
+ database changes could cause a zones implementation to switch between
+ these two base classes and we can't break pickles on a pytz version
+ upgrade.
+ """
+ # Raises a KeyError if zone no longer exists, which should never happen
+ # and would be a bug.
+ tz = pytz.timezone(zone)
+
+ # A StaticTzInfo - just return it
+ if utcoffset is None:
+ return tz
+
+ # This pickle was created from a DstTzInfo. We need to
+ # determine which of the list of tzinfo instances for this zone
+ # to use in order to restore the state of any datetime instances using
+ # it correctly.
+ utcoffset = memorized_timedelta(utcoffset)
+ dstoffset = memorized_timedelta(dstoffset)
+ try:
+ return tz._tzinfos[(utcoffset, dstoffset, tzname)]
+ except KeyError:
+ # The particular state requested in this timezone no longer exists.
+ # This indicates a corrupt pickle, or the timezone database has been
+ # corrected violently enough to make this particular
+ # (utcoffset,dstoffset) no longer exist in the zone, or the
+ # abbreviation has been changed.
+ pass
+
+ # See if we can find an entry differing only by tzname. Abbreviations
+ # get changed from the initial guess by the database maintainers to
+ # match reality when this information is discovered.
+ for localized_tz in tz._tzinfos.values():
+ if (localized_tz._utcoffset == utcoffset
+ and localized_tz._dst == dstoffset):
+ return localized_tz
+
+ # This (utcoffset, dstoffset) information has been removed from the
+ # zone. Add it back. This might occur when the database maintainers have
+ # corrected incorrect information. datetime instances using this
+ # incorrect information will continue to do so, exactly as they were
+ # before being pickled. This is purely an overly paranoid safety net - I
+ # doubt this will ever been needed in real life.
+ inf = (utcoffset, dstoffset, tzname)
+ tz._tzinfos[inf] = tz.__class__(inf, tz._tzinfos)
+ return tz._tzinfos[inf]
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Abidjan b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Abidjan
new file mode 100644
index 0000000000000000000000000000000000000000..65d19ec2651aeb46c42ce7a74ae6ecbf3001edbb
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Abidjan differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Accra b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Accra
new file mode 100644
index 0000000000000000000000000000000000000000..8c473eda0b706288e0b7f518935013a065474ec1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Accra differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Addis_Ababa b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Addis_Ababa
new file mode 100644
index 0000000000000000000000000000000000000000..5a95ab66625c7a21fd346938677587774d4bf0a1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Addis_Ababa differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Algiers b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Algiers
new file mode 100644
index 0000000000000000000000000000000000000000..c88883117117a90aea874a31d346ff65acda6e38
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Algiers differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Asmara b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Asmara
new file mode 100644
index 0000000000000000000000000000000000000000..d1e876e2ff93d4ca4aaff51a12d8dfae9e232bac
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Asmara differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Asmera b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Asmera
new file mode 100644
index 0000000000000000000000000000000000000000..d1e876e2ff93d4ca4aaff51a12d8dfae9e232bac
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Asmera differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Bamako b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Bamako
new file mode 100644
index 0000000000000000000000000000000000000000..da18d7137740abeff3e856eefd86ff70d104ee09
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Bamako differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Bangui b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Bangui
new file mode 100644
index 0000000000000000000000000000000000000000..883e597eb0f3200e78929bb034821cdef1392afa
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Bangui differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Banjul b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Banjul
new file mode 100644
index 0000000000000000000000000000000000000000..a85a7d87261f7728c30f9579a2580bdfc86f5b83
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Banjul differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Bissau b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Bissau
new file mode 100644
index 0000000000000000000000000000000000000000..ab4a195a880472c2d257edf81123977fac50a5cf
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Bissau differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Blantyre b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Blantyre
new file mode 100644
index 0000000000000000000000000000000000000000..2972580dad6a37f9e7728bb828905fbb62df03b6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Blantyre differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Brazzaville b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Brazzaville
new file mode 100644
index 0000000000000000000000000000000000000000..abb0c08700a29d787d8682e020c7cf6fcac69cb0
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Brazzaville differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Bujumbura b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Bujumbura
new file mode 100644
index 0000000000000000000000000000000000000000..cac56524574480a440cb06b171274ad1e1292e58
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Bujumbura differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Cairo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Cairo
new file mode 100644
index 0000000000000000000000000000000000000000..1c6a2fc8fa68d8e2e33d48e1faa018488f250f06
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Cairo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Casablanca b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Casablanca
new file mode 100644
index 0000000000000000000000000000000000000000..51cf51bdad45ee194acda159db887212ccb3730b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Casablanca differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Ceuta b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Ceuta
new file mode 100644
index 0000000000000000000000000000000000000000..c9b0c08bc86caeafd6952e092fb4f22434305ec4
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Ceuta differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Conakry b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Conakry
new file mode 100644
index 0000000000000000000000000000000000000000..75b8523fb2991ed402751e087afe8898e4bfb25d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Conakry differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Dakar b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Dakar
new file mode 100644
index 0000000000000000000000000000000000000000..31104133c293ab4358a8b52e7b6f66cd22150d6b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Dakar differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Dar_es_Salaam b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Dar_es_Salaam
new file mode 100644
index 0000000000000000000000000000000000000000..720d76c8300f94058c0948bd257bd6ee59c56070
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Dar_es_Salaam differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Djibouti b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Djibouti
new file mode 100644
index 0000000000000000000000000000000000000000..297d93a3e464f417f88e8719af0ca9410294b4ad
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Djibouti differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Douala b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Douala
new file mode 100644
index 0000000000000000000000000000000000000000..8627f2e05e95e60f75766d0100db6224616289bc
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Douala differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/El_Aaiun b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/El_Aaiun
new file mode 100644
index 0000000000000000000000000000000000000000..08ad52d25a1013a5f30c641dcae0f51b48ebe827
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/El_Aaiun differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Freetown b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Freetown
new file mode 100644
index 0000000000000000000000000000000000000000..720b8e3c905ea30f521204e3c75c29e55a5edcf8
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Freetown differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Gaborone b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Gaborone
new file mode 100644
index 0000000000000000000000000000000000000000..e2abcb664372359aa174fb5aefc4a1a780bddc52
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Gaborone differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Harare b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Harare
new file mode 100644
index 0000000000000000000000000000000000000000..258b393637294912a6d6c78973c09424136ed50e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Harare differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Johannesburg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Johannesburg
new file mode 100644
index 0000000000000000000000000000000000000000..d1bec7381574ba1932725e3462430f89903e6d5f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Johannesburg differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Juba b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Juba
new file mode 100644
index 0000000000000000000000000000000000000000..6f62fd764cef89254550b1e8204ffc6c98932605
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Juba differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Kampala b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Kampala
new file mode 100644
index 0000000000000000000000000000000000000000..b018ba26f2f35b040446ea625c521ec37b067c9d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Kampala differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Khartoum b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Khartoum
new file mode 100644
index 0000000000000000000000000000000000000000..6f62fd764cef89254550b1e8204ffc6c98932605
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Khartoum differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Kigali b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Kigali
new file mode 100644
index 0000000000000000000000000000000000000000..c9623c56e853995bd8c250f00f954131a0b3e1fa
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Kigali differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Kinshasa b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Kinshasa
new file mode 100644
index 0000000000000000000000000000000000000000..e8481f3476aad980237ac04c0f1aecd46e947e2b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Kinshasa differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Lagos b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Lagos
new file mode 100644
index 0000000000000000000000000000000000000000..cbdc0450fc3b97bc436f6d90798a30ebe0ac30b9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Lagos differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Libreville b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Libreville
new file mode 100644
index 0000000000000000000000000000000000000000..d7691ae56f56a0c15e753bf3c5e64b3b2b577d93
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Libreville differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Lome b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Lome
new file mode 100644
index 0000000000000000000000000000000000000000..297ec5dae3787fd9d0a549b19af4d403f4032301
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Lome differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Luanda b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Luanda
new file mode 100644
index 0000000000000000000000000000000000000000..576b2043cfb39ae472ea29d99d76150342f9cf06
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Luanda differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Lubumbashi b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Lubumbashi
new file mode 100644
index 0000000000000000000000000000000000000000..d3fab52a6ce769f80420b5ec8e95c645c14b97d9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Lubumbashi differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Lusaka b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Lusaka
new file mode 100644
index 0000000000000000000000000000000000000000..87d7a95fc7f19a45ba90bb27009c65616a0b521d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Lusaka differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Malabo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Malabo
new file mode 100644
index 0000000000000000000000000000000000000000..c70de1f99d9f6c8af5e8f6691ddeb3ac822fdd74
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Malabo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Maputo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Maputo
new file mode 100644
index 0000000000000000000000000000000000000000..31cfad771a5c7c609e495da650e3ffbcf07c974d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Maputo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Maseru b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Maseru
new file mode 100644
index 0000000000000000000000000000000000000000..117006eead2af9510ba7adc56f1d49398c9c4cb3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Maseru differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Mbabane b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Mbabane
new file mode 100644
index 0000000000000000000000000000000000000000..be6ed60baaf85c3760f7f974b128490c5052f52f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Mbabane differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Mogadishu b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Mogadishu
new file mode 100644
index 0000000000000000000000000000000000000000..bd08463429debfd950433c6fc8c1d53d5e732013
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Mogadishu differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Monrovia b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Monrovia
new file mode 100644
index 0000000000000000000000000000000000000000..bd2fa4e6318ad3316214e0131b9d0d6c1aefffba
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Monrovia differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Nairobi b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Nairobi
new file mode 100644
index 0000000000000000000000000000000000000000..72676bb987d485a91f0cf7386ce9f104130f49d8
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Nairobi differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Ndjamena b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Ndjamena
new file mode 100644
index 0000000000000000000000000000000000000000..8779590e04a66e4287cabe801aee9c8d2d793892
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Ndjamena differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Niamey b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Niamey
new file mode 100644
index 0000000000000000000000000000000000000000..799381c310ca4fbea88f666c3621eb2327b21176
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Niamey differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Nouakchott b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Nouakchott
new file mode 100644
index 0000000000000000000000000000000000000000..ead817afcdd36739143a04d5f2963a4efd664037
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Nouakchott differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Ouagadougou b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Ouagadougou
new file mode 100644
index 0000000000000000000000000000000000000000..df782a489c29635c51dc35db5a4c65187128f2a3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Ouagadougou differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Porto-Novo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Porto-Novo
new file mode 100644
index 0000000000000000000000000000000000000000..600a30d82ac61cf1f96b97ccac31e448fd49d757
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Porto-Novo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Sao_Tome b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Sao_Tome
new file mode 100644
index 0000000000000000000000000000000000000000..ddf7fb42e4e9630c72d27d99f38dd5ca55fa733e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Sao_Tome differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Timbuktu b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Timbuktu
new file mode 100644
index 0000000000000000000000000000000000000000..da18d7137740abeff3e856eefd86ff70d104ee09
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Timbuktu differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Tripoli b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Tripoli
new file mode 100644
index 0000000000000000000000000000000000000000..bd885315f84f8615da866553c9c0086ad430ad01
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Tripoli differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Tunis b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Tunis
new file mode 100644
index 0000000000000000000000000000000000000000..dd559ee763401a47ae9a68883bc254b628aa1b30
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Tunis differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Windhoek b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Windhoek
new file mode 100644
index 0000000000000000000000000000000000000000..6f22b0a7df8c38f3f936efb75995bffb394c595e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Africa/Windhoek differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Adak b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Adak
new file mode 100644
index 0000000000000000000000000000000000000000..391ec98ec0f31cd595ed05a9b91a41c4cdb25d31
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Adak differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Anchorage b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Anchorage
new file mode 100644
index 0000000000000000000000000000000000000000..d14735026a09cff0104e479fa6543301d482deed
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Anchorage differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Anguilla b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Anguilla
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Anguilla differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Antigua b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Antigua
new file mode 100644
index 0000000000000000000000000000000000000000..608b635977bde87ab1e17875905d25b8fe1245a6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Antigua differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Araguaina b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Araguaina
new file mode 100644
index 0000000000000000000000000000000000000000..ceb7977cf5f86728a82496244b0e6a5d0e33d025
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Araguaina differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Buenos_Aires b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Buenos_Aires
new file mode 100644
index 0000000000000000000000000000000000000000..5a52a51fc85a32108cca83676a4a78404568288b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Buenos_Aires differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Catamarca b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Catamarca
new file mode 100644
index 0000000000000000000000000000000000000000..b9c987bb56894c23ca7a74d02d792585e3f4fe00
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Catamarca differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/ComodRivadavia b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/ComodRivadavia
new file mode 100644
index 0000000000000000000000000000000000000000..b9c987bb56894c23ca7a74d02d792585e3f4fe00
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/ComodRivadavia differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Cordoba b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Cordoba
new file mode 100644
index 0000000000000000000000000000000000000000..a703e957d5ebe02e0651d77ddfff4d3f7b8b851b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Cordoba differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Jujuy b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Jujuy
new file mode 100644
index 0000000000000000000000000000000000000000..86800f0344a08623a9b526db0953de0da2c5db90
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Jujuy differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/La_Rioja b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/La_Rioja
new file mode 100644
index 0000000000000000000000000000000000000000..333819a15f79909ac5163a69b136f60b4591e2a9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/La_Rioja differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Mendoza b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Mendoza
new file mode 100644
index 0000000000000000000000000000000000000000..76afd5909e0ed14e11c249473b34744ef58170c3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Mendoza differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Rio_Gallegos b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Rio_Gallegos
new file mode 100644
index 0000000000000000000000000000000000000000..65d0230a2d06ca8b94cfeb60aee0ba3b1a3faf0d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Rio_Gallegos differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Salta b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Salta
new file mode 100644
index 0000000000000000000000000000000000000000..963917a01a2639bd782d7f3580647153dc4edc5c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Salta differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/San_Juan b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/San_Juan
new file mode 100644
index 0000000000000000000000000000000000000000..fe7007b85ca4a22659c2c3093d078893fa2f466d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/San_Juan differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/San_Luis b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/San_Luis
new file mode 100644
index 0000000000000000000000000000000000000000..e19478819e7337ab1b3951b7b0576c467d66f2fc
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/San_Luis differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Tucuman b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Tucuman
new file mode 100644
index 0000000000000000000000000000000000000000..be7bd271639a551eff3b1bedb3b0646beab4e9b7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Tucuman differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Ushuaia b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Ushuaia
new file mode 100644
index 0000000000000000000000000000000000000000..18590effb093a4429c23fbcedaadf5ec0fae774e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Argentina/Ushuaia differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Aruba b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Aruba
new file mode 100644
index 0000000000000000000000000000000000000000..2d01c18860497141758685c332e130628cf1d793
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Aruba differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Asuncion b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Asuncion
new file mode 100644
index 0000000000000000000000000000000000000000..59f78918faaaafb2838b1088d1c234007cc1430f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Asuncion differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Atikokan b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Atikokan
new file mode 100644
index 0000000000000000000000000000000000000000..1b49e37c943b55e971162900aa3c7ed4d2d6698f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Atikokan differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Atka b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Atka
new file mode 100644
index 0000000000000000000000000000000000000000..391ec98ec0f31cd595ed05a9b91a41c4cdb25d31
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Atka differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Bahia b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Bahia
new file mode 100644
index 0000000000000000000000000000000000000000..403d9d1060ea23b39094ac2a3f1ffdf5933d6729
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Bahia differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Bahia_Banderas b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Bahia_Banderas
new file mode 100644
index 0000000000000000000000000000000000000000..cd531078d0e8a4752bc242e83836dfdf0ae307ca
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Bahia_Banderas differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Barbados b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Barbados
new file mode 100644
index 0000000000000000000000000000000000000000..7bb7ac4d6ab698cc62fde7d1a357be3c06e34e8c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Barbados differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Belem b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Belem
new file mode 100644
index 0000000000000000000000000000000000000000..9c37b6a5c49329a57f19a067050dabcc64349773
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Belem differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Belize b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Belize
new file mode 100644
index 0000000000000000000000000000000000000000..a18cd39058fa03214b8c2af911a08bb3c9ed4ea8
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Belize differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Blanc-Sablon b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Blanc-Sablon
new file mode 100644
index 0000000000000000000000000000000000000000..8a33789afcbb422ff086f021a0716992e463eb11
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Blanc-Sablon differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Boa_Vista b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Boa_Vista
new file mode 100644
index 0000000000000000000000000000000000000000..cb15afbf5c30b621cca99a112062791449a959e1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Boa_Vista differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Bogota b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Bogota
new file mode 100644
index 0000000000000000000000000000000000000000..bddda98a2c929dc113b02cad6345e2f99cd684d9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Bogota differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Boise b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Boise
new file mode 100644
index 0000000000000000000000000000000000000000..441afe55c4130c024b3375695f6137a0334c65bb
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Boise differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Buenos_Aires b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Buenos_Aires
new file mode 100644
index 0000000000000000000000000000000000000000..5a52a51fc85a32108cca83676a4a78404568288b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Buenos_Aires differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cambridge_Bay b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cambridge_Bay
new file mode 100644
index 0000000000000000000000000000000000000000..99c77c5b2083727df05d5a274fe15929e5613980
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cambridge_Bay differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Campo_Grande b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Campo_Grande
new file mode 100644
index 0000000000000000000000000000000000000000..46840981043ea98f2af981e7e24e1f085ac0a4fe
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Campo_Grande differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cancun b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cancun
new file mode 100644
index 0000000000000000000000000000000000000000..90993faa70518700e2df6eace3e27334ce1b6bc3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cancun differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Caracas b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Caracas
new file mode 100644
index 0000000000000000000000000000000000000000..d96a5c00bffe1c7873a23319fdfa965a6ed6c769
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Caracas differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Catamarca b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Catamarca
new file mode 100644
index 0000000000000000000000000000000000000000..b9c987bb56894c23ca7a74d02d792585e3f4fe00
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Catamarca differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cayenne b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cayenne
new file mode 100644
index 0000000000000000000000000000000000000000..7109a98ec5cecf1c930240d6d67aedc82548a9cd
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cayenne differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cayman b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cayman
new file mode 100644
index 0000000000000000000000000000000000000000..98d9b98d3b84da0200d0a70f8ae8a0fade90afff
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cayman differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Chicago b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Chicago
new file mode 100644
index 0000000000000000000000000000000000000000..71aae7246a30bb9e43118539fd6171372cf3f49f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Chicago differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Chihuahua b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Chihuahua
new file mode 100644
index 0000000000000000000000000000000000000000..b2687241cd05b6904a7d95bae697642becbe5b1a
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Chihuahua differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Coral_Harbour b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Coral_Harbour
new file mode 100644
index 0000000000000000000000000000000000000000..1b49e37c943b55e971162900aa3c7ed4d2d6698f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Coral_Harbour differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cordoba b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cordoba
new file mode 100644
index 0000000000000000000000000000000000000000..a703e957d5ebe02e0651d77ddfff4d3f7b8b851b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cordoba differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Costa_Rica b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Costa_Rica
new file mode 100644
index 0000000000000000000000000000000000000000..018d945b11aa09ebd61f0bc06ee02ff9e17024e0
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Costa_Rica differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Creston b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Creston
new file mode 100644
index 0000000000000000000000000000000000000000..1cf719ae837475e9dfe22e1b7513a80906d5f789
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Creston differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cuiaba b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cuiaba
new file mode 100644
index 0000000000000000000000000000000000000000..232ef670ff53dd575954275d367e9fa30129e73d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Cuiaba differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Curacao b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Curacao
new file mode 100644
index 0000000000000000000000000000000000000000..2d01c18860497141758685c332e130628cf1d793
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Curacao differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Danmarkshavn b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Danmarkshavn
new file mode 100644
index 0000000000000000000000000000000000000000..9feacfb1c9fffe62128c678397cac470dcd40f91
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Danmarkshavn differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Dawson b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Dawson
new file mode 100644
index 0000000000000000000000000000000000000000..fab060999850a62ccd916fc80d216c94daad8d2b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Dawson differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Dawson_Creek b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Dawson_Creek
new file mode 100644
index 0000000000000000000000000000000000000000..c3fb166b0887753eb80b078c47bf4c5876774662
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Dawson_Creek differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Denver b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Denver
new file mode 100644
index 0000000000000000000000000000000000000000..f8908febf220f27b3efa68bcc119633c8efee299
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Denver differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Detroit b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Detroit
new file mode 100644
index 0000000000000000000000000000000000000000..da53d46df347ac70897f4f5c51feb83b6a878627
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Detroit differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Dominica b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Dominica
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Dominica differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Edmonton b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Edmonton
new file mode 100644
index 0000000000000000000000000000000000000000..3fa0579891a9762b7c131ec5ece5d6d02495bfc0
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Edmonton differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Eirunepe b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Eirunepe
new file mode 100644
index 0000000000000000000000000000000000000000..c93d917091ef7e33b1aa61b0ef23932c22943b88
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Eirunepe differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/El_Salvador b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/El_Salvador
new file mode 100644
index 0000000000000000000000000000000000000000..ac774e83f46bb2967f587ea3175d6d2d95a15387
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/El_Salvador differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Ensenada b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Ensenada
new file mode 100644
index 0000000000000000000000000000000000000000..fffdc24bfc4c076584787843a5a6b457a23c5bf2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Ensenada differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Fort_Wayne b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Fort_Wayne
new file mode 100644
index 0000000000000000000000000000000000000000..aa3dfc43730ed25bde9c967039951f5c2fc15cc9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Fort_Wayne differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Fortaleza b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Fortaleza
new file mode 100644
index 0000000000000000000000000000000000000000..2598c53559d35e4d39870a068d5a9a77f05f7fe1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Fortaleza differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Glace_Bay b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Glace_Bay
new file mode 100644
index 0000000000000000000000000000000000000000..48412a4cbf9241ea83887876b1b8b22c367ff4fd
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Glace_Bay differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Godthab b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Godthab
new file mode 100644
index 0000000000000000000000000000000000000000..5cb97910f8f7ddf4f339884ed234a7ad7e729c6c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Godthab differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Goose_Bay b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Goose_Bay
new file mode 100644
index 0000000000000000000000000000000000000000..83e5a9b398fd1b600e8f0a72995855dc274d0bd3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Goose_Bay differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Grand_Turk b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Grand_Turk
new file mode 100644
index 0000000000000000000000000000000000000000..0dfd686fd554a432816437b4d420d145f5c018b3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Grand_Turk differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Grenada b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Grenada
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Grenada differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Guadeloupe b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Guadeloupe
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Guadeloupe differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Guatemala b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Guatemala
new file mode 100644
index 0000000000000000000000000000000000000000..6118b5ce2d95b66dc88cc40c7470a53105dbd6c4
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Guatemala differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Guayaquil b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Guayaquil
new file mode 100644
index 0000000000000000000000000000000000000000..e6de7f8da2977ffc71f5ec86db56bcbff137966c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Guayaquil differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Guyana b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Guyana
new file mode 100644
index 0000000000000000000000000000000000000000..5f98c4a0e88b3bdfa80996461f4662dd4d0adfce
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Guyana differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Halifax b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Halifax
new file mode 100644
index 0000000000000000000000000000000000000000..756099abe6cee44295a5566ad6cd0c352fb82e64
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Halifax differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Havana b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Havana
new file mode 100644
index 0000000000000000000000000000000000000000..c2623e05f5453263767b99ae026ef406a6bb36ee
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Havana differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Hermosillo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Hermosillo
new file mode 100644
index 0000000000000000000000000000000000000000..26c269d9674847059472850a5287339df9213bff
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Hermosillo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Indianapolis b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Indianapolis
new file mode 100644
index 0000000000000000000000000000000000000000..aa3dfc43730ed25bde9c967039951f5c2fc15cc9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Indianapolis differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Knox b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Knox
new file mode 100644
index 0000000000000000000000000000000000000000..33169f4596381b700b3598dabf7706dce25f65ba
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Knox differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Marengo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Marengo
new file mode 100644
index 0000000000000000000000000000000000000000..255b739718d2b92211495e027e57a79dfa47b63b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Marengo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Petersburg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Petersburg
new file mode 100644
index 0000000000000000000000000000000000000000..c611106d57e4adfe4bb396fb120fecff84d9fa70
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Petersburg differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Tell_City b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Tell_City
new file mode 100644
index 0000000000000000000000000000000000000000..97e319e34350ec5e3e4c677d453938e329afd3f4
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Tell_City differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Vevay b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Vevay
new file mode 100644
index 0000000000000000000000000000000000000000..de6167c08291f6cc510f655f2e7dc178d62b0119
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Vevay differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Vincennes b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Vincennes
new file mode 100644
index 0000000000000000000000000000000000000000..b79f6725b62a3c16ef4abecf92a92b67b33d5579
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Vincennes differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Winamac b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Winamac
new file mode 100644
index 0000000000000000000000000000000000000000..b2611e75ee8b16039112e267428017cbf1176eb4
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indiana/Winamac differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indianapolis b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indianapolis
new file mode 100644
index 0000000000000000000000000000000000000000..aa3dfc43730ed25bde9c967039951f5c2fc15cc9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Indianapolis differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Inuvik b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Inuvik
new file mode 100644
index 0000000000000000000000000000000000000000..c17af37f5f6008d461b8fcf445099e1ed795db1d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Inuvik differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Iqaluit b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Iqaluit
new file mode 100644
index 0000000000000000000000000000000000000000..cea5c2e0f30fb1b562d2982d874c4141ddff4f8d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Iqaluit differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Jamaica b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Jamaica
new file mode 100644
index 0000000000000000000000000000000000000000..b89c18787ece60e0471f2c810eb4e8935d8b1f63
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Jamaica differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Jujuy b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Jujuy
new file mode 100644
index 0000000000000000000000000000000000000000..86800f0344a08623a9b526db0953de0da2c5db90
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Jujuy differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Juneau b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Juneau
new file mode 100644
index 0000000000000000000000000000000000000000..48bd37e88e273741eb5b7df37417932f670a5e00
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Juneau differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Kentucky/Louisville b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Kentucky/Louisville
new file mode 100644
index 0000000000000000000000000000000000000000..65e7e190495160865526ee670ff86ae4df373875
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Kentucky/Louisville differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Kentucky/Monticello b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Kentucky/Monticello
new file mode 100644
index 0000000000000000000000000000000000000000..fc2f1b0df86ece6228927ba6062f03ad43bac2cf
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Kentucky/Monticello differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Knox_IN b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Knox_IN
new file mode 100644
index 0000000000000000000000000000000000000000..33169f4596381b700b3598dabf7706dce25f65ba
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Knox_IN differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Kralendijk b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Kralendijk
new file mode 100644
index 0000000000000000000000000000000000000000..2d01c18860497141758685c332e130628cf1d793
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Kralendijk differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/La_Paz b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/La_Paz
new file mode 100644
index 0000000000000000000000000000000000000000..2a5a15e4c4f03d57dad3c821a9127d1b58a9b197
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/La_Paz differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Lima b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Lima
new file mode 100644
index 0000000000000000000000000000000000000000..a37eeff7de59cabb56b583eec024d09e7ee6e2c4
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Lima differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Los_Angeles b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Los_Angeles
new file mode 100644
index 0000000000000000000000000000000000000000..3b7ce1dceebf9fa9db859068da1fa7eba6df1cfa
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Los_Angeles differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Louisville b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Louisville
new file mode 100644
index 0000000000000000000000000000000000000000..65e7e190495160865526ee670ff86ae4df373875
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Louisville differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Lower_Princes b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Lower_Princes
new file mode 100644
index 0000000000000000000000000000000000000000..2d01c18860497141758685c332e130628cf1d793
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Lower_Princes differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Maceio b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Maceio
new file mode 100644
index 0000000000000000000000000000000000000000..b5201e81d42f9256adcb7125469509a08d77ba41
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Maceio differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Managua b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Managua
new file mode 100644
index 0000000000000000000000000000000000000000..f1c35040ce46c190d6def6984a7391616ce93a28
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Managua differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Manaus b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Manaus
new file mode 100644
index 0000000000000000000000000000000000000000..1129211841393d0423797f2afee0ac6c696a405f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Manaus differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Marigot b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Marigot
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Marigot differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Martinique b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Martinique
new file mode 100644
index 0000000000000000000000000000000000000000..c223ef5c2011dfe531514dba8262ba3be5552625
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Martinique differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Matamoros b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Matamoros
new file mode 100644
index 0000000000000000000000000000000000000000..5c59984def290712e183eea0655eaf8dc7a133b2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Matamoros differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Mazatlan b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Mazatlan
new file mode 100644
index 0000000000000000000000000000000000000000..43ee12d84a7c7e47aaa92406d01a539ccf93079d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Mazatlan differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Mendoza b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Mendoza
new file mode 100644
index 0000000000000000000000000000000000000000..76afd5909e0ed14e11c249473b34744ef58170c3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Mendoza differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Menominee b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Menominee
new file mode 100644
index 0000000000000000000000000000000000000000..438f5ff0b846447eab7ef45c8ef19d49db69f12f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Menominee differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Merida b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Merida
new file mode 100644
index 0000000000000000000000000000000000000000..b46298e1f202ee4ec22ba3cf9f8079c83ebd6c7d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Merida differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Metlakatla b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Metlakatla
new file mode 100644
index 0000000000000000000000000000000000000000..4145b9a58164680ce931c1db83eaf92f713bcf74
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Metlakatla differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Mexico_City b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Mexico_City
new file mode 100644
index 0000000000000000000000000000000000000000..1434ab08804dac08e4f595967d8c325691f08aef
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Mexico_City differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Miquelon b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Miquelon
new file mode 100644
index 0000000000000000000000000000000000000000..52cd391ebb47d355fbd854acf204050d6336d51d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Miquelon differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Moncton b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Moncton
new file mode 100644
index 0000000000000000000000000000000000000000..b51125ebf1121965254ac60b6ef3afc0bf05913e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Moncton differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Monterrey b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Monterrey
new file mode 100644
index 0000000000000000000000000000000000000000..7dc50577749baded06400fbe5d2e8dbf2579253e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Monterrey differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Montevideo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Montevideo
new file mode 100644
index 0000000000000000000000000000000000000000..4745f0dfb2d918f6320c1c57a218f0a445e0a71d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Montevideo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Montreal b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Montreal
new file mode 100644
index 0000000000000000000000000000000000000000..47633bd49f89e35d20ed118cb813e7c7bc9ca335
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Montreal differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Montserrat b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Montserrat
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Montserrat differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Nassau b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Nassau
new file mode 100644
index 0000000000000000000000000000000000000000..5091eb5d8d3aedf24ddf9ee26a1aefd837e3b4bb
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Nassau differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/New_York b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/New_York
new file mode 100644
index 0000000000000000000000000000000000000000..b2c2377f4e87960bb2adafda2a4ac6385cadceea
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/New_York differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Nipigon b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Nipigon
new file mode 100644
index 0000000000000000000000000000000000000000..619f1f75905e67974e3e5da4031ef9f0418bcaf1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Nipigon differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Nome b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Nome
new file mode 100644
index 0000000000000000000000000000000000000000..b682bfd9cd899e670ed89de3fbe79a0d06e14911
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Nome differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Noronha b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Noronha
new file mode 100644
index 0000000000000000000000000000000000000000..c60239009e4695a66be6f44df8d332115be14764
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Noronha differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/North_Dakota/Beulah b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/North_Dakota/Beulah
new file mode 100644
index 0000000000000000000000000000000000000000..c1e3b025b916172bb8464c3de234656e12551c06
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/North_Dakota/Beulah differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/North_Dakota/Center b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/North_Dakota/Center
new file mode 100644
index 0000000000000000000000000000000000000000..786ba1778acb3787701c32d0797fd85ea6039cd4
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/North_Dakota/Center differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/North_Dakota/New_Salem b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/North_Dakota/New_Salem
new file mode 100644
index 0000000000000000000000000000000000000000..3488e466d5225d7f5185e7c910bab0f1bfd62eba
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/North_Dakota/New_Salem differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Ojinaga b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Ojinaga
new file mode 100644
index 0000000000000000000000000000000000000000..37d78301bd100b7c34b183a7e355021f55cb366e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Ojinaga differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Panama b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Panama
new file mode 100644
index 0000000000000000000000000000000000000000..3a4ff2aecf898647d8f22a8c9021bd83ce5d0003
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Panama differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Pangnirtung b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Pangnirtung
new file mode 100644
index 0000000000000000000000000000000000000000..80a6009381ef1cc8f8cbd2551f0665733e6ffb6d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Pangnirtung differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Paramaribo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Paramaribo
new file mode 100644
index 0000000000000000000000000000000000000000..6f889ccaf1ffc6caac36d024ea0be15df86bbb77
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Paramaribo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Phoenix b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Phoenix
new file mode 100644
index 0000000000000000000000000000000000000000..67589026c21c6bcb83587d25342c93f10570bc24
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Phoenix differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Port-au-Prince b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Port-au-Prince
new file mode 100644
index 0000000000000000000000000000000000000000..3f86e8ab756db6006b3b35a89720f5044eeb1342
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Port-au-Prince differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Port_of_Spain b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Port_of_Spain
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Port_of_Spain differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Porto_Acre b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Porto_Acre
new file mode 100644
index 0000000000000000000000000000000000000000..21cf598ff1f35c8314de4186e225c03a9dfd87e7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Porto_Acre differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Porto_Velho b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Porto_Velho
new file mode 100644
index 0000000000000000000000000000000000000000..12774792326b5bb730494e6d2139c30d98eafb71
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Porto_Velho differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Puerto_Rico b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Puerto_Rico
new file mode 100644
index 0000000000000000000000000000000000000000..eada37a111c074859e5d8b5600fb1d98e8df4df1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Puerto_Rico differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Rainy_River b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Rainy_River
new file mode 100644
index 0000000000000000000000000000000000000000..e006a30dbf358cc4bfa9bd2d9cd780697a9c5ca7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Rainy_River differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Rankin_Inlet b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Rankin_Inlet
new file mode 100644
index 0000000000000000000000000000000000000000..99195714c4b30750dedc3be8f70d79fd6ffbf4a6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Rankin_Inlet differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Recife b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Recife
new file mode 100644
index 0000000000000000000000000000000000000000..0903a77195358dee8d7cc3baca3ecd4ecdd7218f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Recife differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Regina b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Regina
new file mode 100644
index 0000000000000000000000000000000000000000..20c9c84df491e4072ec4c5d2c931a7433d9fd394
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Regina differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Resolute b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Resolute
new file mode 100644
index 0000000000000000000000000000000000000000..7713f5bead4314819aa3feefaaecc9f0ab2a5ebe
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Resolute differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Rio_Branco b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Rio_Branco
new file mode 100644
index 0000000000000000000000000000000000000000..21cf598ff1f35c8314de4186e225c03a9dfd87e7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Rio_Branco differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Rosario b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Rosario
new file mode 100644
index 0000000000000000000000000000000000000000..a703e957d5ebe02e0651d77ddfff4d3f7b8b851b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Rosario differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Santa_Isabel b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Santa_Isabel
new file mode 100644
index 0000000000000000000000000000000000000000..80a2f2d5b1df0d3001c0a811a425d9ec0900bea2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Santa_Isabel differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Santarem b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Santarem
new file mode 100644
index 0000000000000000000000000000000000000000..45419528f9df01abda7f9c98663ea1d69e5ea920
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Santarem differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Santiago b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Santiago
new file mode 100644
index 0000000000000000000000000000000000000000..7cf0a1e1877bd423d43a7e60457fe92f47f9ace3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Santiago differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Santo_Domingo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Santo_Domingo
new file mode 100644
index 0000000000000000000000000000000000000000..23ace9adc3e21ee0fc2b64f87f4f5c578d135b55
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Santo_Domingo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Sao_Paulo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Sao_Paulo
new file mode 100644
index 0000000000000000000000000000000000000000..8df63a17bd46413c2c5c4751d96b504cdaae30e2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Sao_Paulo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Scoresbysund b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Scoresbysund
new file mode 100644
index 0000000000000000000000000000000000000000..fae3757ce9da5e6f1340ebe09f4a86767bfc081e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Scoresbysund differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Shiprock b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Shiprock
new file mode 100644
index 0000000000000000000000000000000000000000..f8908febf220f27b3efa68bcc119633c8efee299
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Shiprock differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Sitka b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Sitka
new file mode 100644
index 0000000000000000000000000000000000000000..f2ae47a323e7ae30dc82ab37bb67ef6ca0464b54
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Sitka differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Barthelemy b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Barthelemy
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Barthelemy differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Johns b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Johns
new file mode 100644
index 0000000000000000000000000000000000000000..e7a18d601d0255c26885313540cbe755e009a77d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Johns differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Kitts b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Kitts
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Kitts differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Lucia b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Lucia
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Lucia differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Thomas b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Thomas
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Thomas differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Vincent b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Vincent
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/St_Vincent differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Swift_Current b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Swift_Current
new file mode 100644
index 0000000000000000000000000000000000000000..8e9ef255eeb11515b84126d9ee5c0c6b3c72f2a0
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Swift_Current differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Tegucigalpa b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Tegucigalpa
new file mode 100644
index 0000000000000000000000000000000000000000..477e93950c2f09b8c338033c07a53d4ef5c01912
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Tegucigalpa differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Thule b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Thule
new file mode 100644
index 0000000000000000000000000000000000000000..2969ebe59bd26701a6dcf6f71a42b0b427072e58
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Thule differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Thunder_Bay b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Thunder_Bay
new file mode 100644
index 0000000000000000000000000000000000000000..34f750b4df72db9977cdcef0921cdd5eff95b799
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Thunder_Bay differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Tijuana b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Tijuana
new file mode 100644
index 0000000000000000000000000000000000000000..fffdc24bfc4c076584787843a5a6b457a23c5bf2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Tijuana differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Toronto b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Toronto
new file mode 100644
index 0000000000000000000000000000000000000000..1698477a48773fb8f306dc4e8f106011d4d1a60b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Toronto differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Tortola b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Tortola
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Tortola differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Vancouver b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Vancouver
new file mode 100644
index 0000000000000000000000000000000000000000..0c1fa52690498b3cd087a90ba9ba4d4f0467d532
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Vancouver differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Virgin b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Virgin
new file mode 100644
index 0000000000000000000000000000000000000000..bdedd1bd9bc85cbcf8259b6eee3aaa5ab041e954
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Virgin differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Whitehorse b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Whitehorse
new file mode 100644
index 0000000000000000000000000000000000000000..15216d55ff54fa59031ae33e898950fed4ff15e9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Whitehorse differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Winnipeg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Winnipeg
new file mode 100644
index 0000000000000000000000000000000000000000..2d22791686e86b2f17a0f7fa53ad71f03a3384fc
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Winnipeg differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Yakutat b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Yakutat
new file mode 100644
index 0000000000000000000000000000000000000000..80716027731ebb0d504165e7012ac4a3464664a3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Yakutat differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Yellowknife b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Yellowknife
new file mode 100644
index 0000000000000000000000000000000000000000..947bec914be3721c864580ae1ad150aebafcc957
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/America/Yellowknife differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Casey b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Casey
new file mode 100644
index 0000000000000000000000000000000000000000..8ebf0598ff90ab24c884305f36947b002058691a
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Casey differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Davis b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Davis
new file mode 100644
index 0000000000000000000000000000000000000000..cd7acad690b66f1ea56ce556858988a73135109b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Davis differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/DumontDUrville b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/DumontDUrville
new file mode 100644
index 0000000000000000000000000000000000000000..5ea18e6e776a126cbf395230c282edaa4a30551d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/DumontDUrville differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Macquarie b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Macquarie
new file mode 100644
index 0000000000000000000000000000000000000000..cbad31bb948aad3dc5f6aa12bad4a679111e1343
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Macquarie differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Mawson b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Mawson
new file mode 100644
index 0000000000000000000000000000000000000000..48e24e1e5ef8db1b70ab5233744037522bd06209
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Mawson differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/McMurdo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/McMurdo
new file mode 100644
index 0000000000000000000000000000000000000000..a40767df93d3da9502281672a7b4663f6f815199
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/McMurdo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Palmer b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Palmer
new file mode 100644
index 0000000000000000000000000000000000000000..a1bcf2784b2e8b4c2b026fe0105992bc849f39d6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Palmer differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Rothera b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Rothera
new file mode 100644
index 0000000000000000000000000000000000000000..b5dc735639dfd75c1cb177a8f12464585cbff9fe
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Rothera differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/South_Pole b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/South_Pole
new file mode 100644
index 0000000000000000000000000000000000000000..a40767df93d3da9502281672a7b4663f6f815199
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/South_Pole differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Syowa b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Syowa
new file mode 100644
index 0000000000000000000000000000000000000000..ba6e5f38877944730ce397d7ca1608cb2a9623f7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Syowa differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Troll b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Troll
new file mode 100644
index 0000000000000000000000000000000000000000..ad6c8b4f6c01ae27aa239ff811bbce60419077b6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Troll differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Vostok b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Vostok
new file mode 100644
index 0000000000000000000000000000000000000000..e19e2b7cdb553f02f48be8454bd0170f4c311e6c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Antarctica/Vostok differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Arctic/Longyearbyen b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Arctic/Longyearbyen
new file mode 100644
index 0000000000000000000000000000000000000000..6326961453f404a4a886362ee8b684b56fd5b4f1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Arctic/Longyearbyen differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Aden b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Aden
new file mode 100644
index 0000000000000000000000000000000000000000..5948b310b94cee6ecd799a91f4107b3b58853d2a
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Aden differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Almaty b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Almaty
new file mode 100644
index 0000000000000000000000000000000000000000..52f941e266a97069cc0c5ffba74808ee2acfa560
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Almaty differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Amman b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Amman
new file mode 100644
index 0000000000000000000000000000000000000000..281b304e2f8bd4e9bfa58ccc1c799d3ab12f1da8
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Amman differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Anadyr b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Anadyr
new file mode 100644
index 0000000000000000000000000000000000000000..2841a6376d9f9694ab79586449398d15a57d20a5
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Anadyr differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Aqtau b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Aqtau
new file mode 100644
index 0000000000000000000000000000000000000000..27a3d50d373900078a7088e74e08ce25e002eda7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Aqtau differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Aqtobe b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Aqtobe
new file mode 100644
index 0000000000000000000000000000000000000000..3683be2db87b36a072090d2a32622182d23c9b5f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Aqtobe differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ashgabat b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ashgabat
new file mode 100644
index 0000000000000000000000000000000000000000..589dbc18ea2d733aa736b32ab888abda675118ab
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ashgabat differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ashkhabad b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ashkhabad
new file mode 100644
index 0000000000000000000000000000000000000000..589dbc18ea2d733aa736b32ab888abda675118ab
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ashkhabad differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Baghdad b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Baghdad
new file mode 100644
index 0000000000000000000000000000000000000000..3ad361495ce53b051219d0043eba265ef81130ce
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Baghdad differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Bahrain b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Bahrain
new file mode 100644
index 0000000000000000000000000000000000000000..d87b7ce73915d8135e07945eec99d84d3d706880
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Bahrain differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Baku b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Baku
new file mode 100644
index 0000000000000000000000000000000000000000..72ae96e9cc952d2aad5ffdf5284b9a62c24f2154
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Baku differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Bangkok b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Bangkok
new file mode 100644
index 0000000000000000000000000000000000000000..44a1018ef6385dea4a0fbc4fc6a9cc0726ad067c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Bangkok differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Beirut b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Beirut
new file mode 100644
index 0000000000000000000000000000000000000000..c1270bc1adce9bd9407a7427992036de8accfcaf
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Beirut differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Bishkek b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Bishkek
new file mode 100644
index 0000000000000000000000000000000000000000..fc827d887134f83f37b9e92f45bd9debab7e4ef8
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Bishkek differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Brunei b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Brunei
new file mode 100644
index 0000000000000000000000000000000000000000..d6e713d436fb05ccf2112eecda9943acfb86ccf2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Brunei differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Calcutta b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Calcutta
new file mode 100644
index 0000000000000000000000000000000000000000..bc909c92c14d0e35a1733204663dda841d768b19
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Calcutta differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Choibalsan b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Choibalsan
new file mode 100644
index 0000000000000000000000000000000000000000..043b7ed5c2d721900d8f45f7a7ab122096d7ccb6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Choibalsan differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Chongqing b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Chongqing
new file mode 100644
index 0000000000000000000000000000000000000000..8a7a28a480a405b75fd1684d757b0db5646b8eb2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Chongqing differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Chungking b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Chungking
new file mode 100644
index 0000000000000000000000000000000000000000..8a7a28a480a405b75fd1684d757b0db5646b8eb2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Chungking differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Colombo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Colombo
new file mode 100644
index 0000000000000000000000000000000000000000..c71c0503d9998b579b22417f416c00672902e9c8
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Colombo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dacca b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dacca
new file mode 100644
index 0000000000000000000000000000000000000000..52e98ffc2c14d438032e6c2af40fd88433424eb2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dacca differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Damascus b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Damascus
new file mode 100644
index 0000000000000000000000000000000000000000..4b610b5a0836df1e06033c1b28afd4152e2493eb
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Damascus differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dhaka b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dhaka
new file mode 100644
index 0000000000000000000000000000000000000000..52e98ffc2c14d438032e6c2af40fd88433424eb2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dhaka differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dili b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dili
new file mode 100644
index 0000000000000000000000000000000000000000..e5b743a6fc1274ed94781724974e96d06a77ae22
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dili differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dubai b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dubai
new file mode 100644
index 0000000000000000000000000000000000000000..53f70d57a15a664efcc942a4e1644b0fd0b31c9e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dubai differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dushanbe b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dushanbe
new file mode 100644
index 0000000000000000000000000000000000000000..c65ff2a7b3e5020f2427309c65caa2e950565690
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Dushanbe differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Gaza b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Gaza
new file mode 100644
index 0000000000000000000000000000000000000000..fed3f9d43338b5b8ee27ed3dcfadb65eb4c61e4b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Gaza differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Harbin b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Harbin
new file mode 100644
index 0000000000000000000000000000000000000000..11e352a511061f835f106d48e500a54e85a01663
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Harbin differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Hebron b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Hebron
new file mode 100644
index 0000000000000000000000000000000000000000..a4234dc67e13f371061bdf9d1763b9e9df0fb476
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Hebron differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ho_Chi_Minh b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ho_Chi_Minh
new file mode 100644
index 0000000000000000000000000000000000000000..6401a10256bb3d7c420494dbcce37b3013522194
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ho_Chi_Minh differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Hong_Kong b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Hong_Kong
new file mode 100644
index 0000000000000000000000000000000000000000..8e5c5813666a4d023bc9f7f7bd0e53ca1a61dd85
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Hong_Kong differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Hovd b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Hovd
new file mode 100644
index 0000000000000000000000000000000000000000..27fab05c1912c17dea8ed52c2bf9f66ba99e5749
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Hovd differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Irkutsk b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Irkutsk
new file mode 100644
index 0000000000000000000000000000000000000000..7c38e7fd6b2863c2a7ec9fb0bc64705c88d49953
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Irkutsk differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Istanbul b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Istanbul
new file mode 100644
index 0000000000000000000000000000000000000000..50a2838e9bdadcceb3d6e84d0b94ce6b994fa4ce
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Istanbul differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Jakarta b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Jakarta
new file mode 100644
index 0000000000000000000000000000000000000000..66450d637022c93fbe8d3c9fb1c61d76e685762e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Jakarta differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Jayapura b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Jayapura
new file mode 100644
index 0000000000000000000000000000000000000000..e28f9def305af9b6b9486fdf6ee9d6b318aedbe6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Jayapura differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Jerusalem b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Jerusalem
new file mode 100644
index 0000000000000000000000000000000000000000..8676bfb0266c1c5d2e3e712fccd4b8221d26bb32
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Jerusalem differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kabul b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kabul
new file mode 100644
index 0000000000000000000000000000000000000000..7392c0497a75a943ee6ffeb9b3eb19b2fd17d22f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kabul differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kamchatka b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kamchatka
new file mode 100644
index 0000000000000000000000000000000000000000..090bf488957b2fa56419a25c2b378ea9b5ce366c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kamchatka differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Karachi b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Karachi
new file mode 100644
index 0000000000000000000000000000000000000000..a8ff8cb769d1cb07cd1cae49d0120c074d812a63
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Karachi differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kashgar b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kashgar
new file mode 100644
index 0000000000000000000000000000000000000000..25e64945cffaa986df97c9b87293c6737e7103d6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kashgar differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kathmandu b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kathmandu
new file mode 100644
index 0000000000000000000000000000000000000000..65c7b63258337e69f9262e0f1aad23fe384bc60d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kathmandu differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Katmandu b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Katmandu
new file mode 100644
index 0000000000000000000000000000000000000000..65c7b63258337e69f9262e0f1aad23fe384bc60d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Katmandu differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Khandyga b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Khandyga
new file mode 100644
index 0000000000000000000000000000000000000000..39d2c2df80d3b8e28c3ec49ea2bb8d29dd2aefdb
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Khandyga differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kolkata b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kolkata
new file mode 100644
index 0000000000000000000000000000000000000000..bc909c92c14d0e35a1733204663dda841d768b19
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kolkata differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Krasnoyarsk b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Krasnoyarsk
new file mode 100644
index 0000000000000000000000000000000000000000..580e8dd2f43ed3f49cba503c6397fa38348b08ed
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Krasnoyarsk differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kuala_Lumpur b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kuala_Lumpur
new file mode 100644
index 0000000000000000000000000000000000000000..41bba37b0c5f62d76af6037ad86d42f7026383e3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kuala_Lumpur differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kuching b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kuching
new file mode 100644
index 0000000000000000000000000000000000000000..272f46546e9dbfeef15e9f6db0ebcecf6de73360
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kuching differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kuwait b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kuwait
new file mode 100644
index 0000000000000000000000000000000000000000..1dab31cba01d73f62cf595984cca284cdf2ae0bd
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Kuwait differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Macao b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Macao
new file mode 100644
index 0000000000000000000000000000000000000000..7c937795787238ba47b51ad3cd4722f3a484074f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Macao differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Macau b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Macau
new file mode 100644
index 0000000000000000000000000000000000000000..7c937795787238ba47b51ad3cd4722f3a484074f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Macau differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Magadan b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Magadan
new file mode 100644
index 0000000000000000000000000000000000000000..e3c76b57f59f590e82cae053dafd15140a0c6322
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Magadan differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Makassar b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Makassar
new file mode 100644
index 0000000000000000000000000000000000000000..eb7d42ef4d83f30d2087f55afba5878448ad17fc
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Makassar differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Manila b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Manila
new file mode 100644
index 0000000000000000000000000000000000000000..0e90ba6326a2e879f280184d6f481ab46fc80ab1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Manila differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Muscat b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Muscat
new file mode 100644
index 0000000000000000000000000000000000000000..daee4cc82a0e363ff39f7bdc2dae005f3663e6d6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Muscat differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Nicosia b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Nicosia
new file mode 100644
index 0000000000000000000000000000000000000000..f7f10ab7665e94ca44fd8cd98a362cd4b304eff1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Nicosia differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Novokuznetsk b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Novokuznetsk
new file mode 100644
index 0000000000000000000000000000000000000000..f78c1f88bf659dc263bc62a3eccd1d77f1c9507f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Novokuznetsk differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Novosibirsk b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Novosibirsk
new file mode 100644
index 0000000000000000000000000000000000000000..c401a9817dab892d4858e6b2d30f15a7982720ad
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Novosibirsk differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Omsk b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Omsk
new file mode 100644
index 0000000000000000000000000000000000000000..a3dbb4bb1c5ad68e460fde645e3303b804932535
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Omsk differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Oral b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Oral
new file mode 100644
index 0000000000000000000000000000000000000000..8da2a1dee74d07f108a25abe650b669b3899624e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Oral differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Phnom_Penh b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Phnom_Penh
new file mode 100644
index 0000000000000000000000000000000000000000..5a52722a16123f192e06553a51c513d11605c67b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Phnom_Penh differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Pontianak b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Pontianak
new file mode 100644
index 0000000000000000000000000000000000000000..54b3d5081d0baf34c4e067341c9d76c9ebb818eb
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Pontianak differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Pyongyang b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Pyongyang
new file mode 100644
index 0000000000000000000000000000000000000000..9dbd3c1ae0061fa6dfa04364b4ca65754eed71e3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Pyongyang differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Qatar b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Qatar
new file mode 100644
index 0000000000000000000000000000000000000000..49668c2583c83ca4db7f304af8e4155711d39bfb
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Qatar differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Qyzylorda b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Qyzylorda
new file mode 100644
index 0000000000000000000000000000000000000000..fc3bf46bccc52f5b437d94424b6a55446b65a961
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Qyzylorda differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Rangoon b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Rangoon
new file mode 100644
index 0000000000000000000000000000000000000000..68591c56e707a5b81aeaa4848df06ca1d713a114
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Rangoon differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Riyadh b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Riyadh
new file mode 100644
index 0000000000000000000000000000000000000000..6ebe393d0b866580e22349b749152995c6ebcaa7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Riyadh differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Saigon b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Saigon
new file mode 100644
index 0000000000000000000000000000000000000000..6401a10256bb3d7c420494dbcce37b3013522194
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Saigon differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Sakhalin b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Sakhalin
new file mode 100644
index 0000000000000000000000000000000000000000..f5105a363cfd6639e28553307f40229e09de5967
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Sakhalin differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Samarkand b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Samarkand
new file mode 100644
index 0000000000000000000000000000000000000000..191c07c12755da5e8fc626a01671f7a575527207
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Samarkand differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Seoul b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Seoul
new file mode 100644
index 0000000000000000000000000000000000000000..96bb0c36d7e3fc455f868a4cd379bbadf6889bd6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Seoul differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Shanghai b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Shanghai
new file mode 100644
index 0000000000000000000000000000000000000000..af6d6fbbd298f4698b748004b6d3c2c847dd6ad6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Shanghai differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Singapore b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Singapore
new file mode 100644
index 0000000000000000000000000000000000000000..a6f2db8f3a887fa0f19283b52c2f801329bb4f53
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Singapore differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Taipei b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Taipei
new file mode 100644
index 0000000000000000000000000000000000000000..70cfb27ca91f3e9dcacf7941b8432c7a10560c69
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Taipei differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tashkent b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tashkent
new file mode 100644
index 0000000000000000000000000000000000000000..5bc806238a9e38e5b8b30adec7e87cec6aad936a
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tashkent differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tbilisi b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tbilisi
new file mode 100644
index 0000000000000000000000000000000000000000..d7e40548acec366bb1999324eeef7116a02788f9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tbilisi differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tehran b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tehran
new file mode 100644
index 0000000000000000000000000000000000000000..62d316190d42b9753bab0a8bd7db7fd6cda1c061
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tehran differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tel_Aviv b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tel_Aviv
new file mode 100644
index 0000000000000000000000000000000000000000..8676bfb0266c1c5d2e3e712fccd4b8221d26bb32
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tel_Aviv differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Thimbu b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Thimbu
new file mode 100644
index 0000000000000000000000000000000000000000..90294aea202619ab9697a161be8a42753b9067a7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Thimbu differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Thimphu b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Thimphu
new file mode 100644
index 0000000000000000000000000000000000000000..90294aea202619ab9697a161be8a42753b9067a7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Thimphu differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tokyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tokyo
new file mode 100644
index 0000000000000000000000000000000000000000..058c1e99ba26b1ab7855b81895c8d577e2f582a6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Tokyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ujung_Pandang b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ujung_Pandang
new file mode 100644
index 0000000000000000000000000000000000000000..eb7d42ef4d83f30d2087f55afba5878448ad17fc
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ujung_Pandang differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ulaanbaatar b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ulaanbaatar
new file mode 100644
index 0000000000000000000000000000000000000000..39bdd89416a5998472dad71d0a19bf079279e711
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ulaanbaatar differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ulan_Bator b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ulan_Bator
new file mode 100644
index 0000000000000000000000000000000000000000..39bdd89416a5998472dad71d0a19bf079279e711
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ulan_Bator differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Urumqi b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Urumqi
new file mode 100644
index 0000000000000000000000000000000000000000..f46ff380a0558ed590f3e02b26bcd2d991de0119
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Urumqi differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ust-Nera b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ust-Nera
new file mode 100644
index 0000000000000000000000000000000000000000..ae89650f10aa7f25e91e2fea1926aa6d6b89615d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Ust-Nera differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Vientiane b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Vientiane
new file mode 100644
index 0000000000000000000000000000000000000000..7d39589f19e8aade5581698bc41ef256984481ee
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Vientiane differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Vladivostok b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Vladivostok
new file mode 100644
index 0000000000000000000000000000000000000000..1cae6d0fd9880e7de01c294cbecf820dde247f9f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Vladivostok differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Yakutsk b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Yakutsk
new file mode 100644
index 0000000000000000000000000000000000000000..461901f6f83bac90e1c1b4781469148325e6e6ae
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Yakutsk differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Yekaterinburg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Yekaterinburg
new file mode 100644
index 0000000000000000000000000000000000000000..aca50c6e1d8bf0395f6275f1046ca34a9670f56b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Yekaterinburg differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Yerevan b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Yerevan
new file mode 100644
index 0000000000000000000000000000000000000000..c4ab2197f803986ebe700b1cddbda26008dbdcb4
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Asia/Yerevan differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Azores b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Azores
new file mode 100644
index 0000000000000000000000000000000000000000..19e40040672aca4a74011b89614eda7eff77e2e5
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Azores differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Bermuda b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Bermuda
new file mode 100644
index 0000000000000000000000000000000000000000..3a5c6dbf7a9ad95ce3a2d7c1bf26e203b6fac30d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Bermuda differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Canary b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Canary
new file mode 100644
index 0000000000000000000000000000000000000000..972388be7176991cad31d91ac7241b45a7c32e84
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Canary differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Cape_Verde b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Cape_Verde
new file mode 100644
index 0000000000000000000000000000000000000000..5238ac8a6704a159bb67e0e19a674f62e2c6c9ae
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Cape_Verde differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Faeroe b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Faeroe
new file mode 100644
index 0000000000000000000000000000000000000000..4dab7ef0859c244b916d61b7489d7371881e0ca2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Faeroe differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Faroe b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Faroe
new file mode 100644
index 0000000000000000000000000000000000000000..4dab7ef0859c244b916d61b7489d7371881e0ca2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Faroe differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Jan_Mayen b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Jan_Mayen
new file mode 100644
index 0000000000000000000000000000000000000000..6326961453f404a4a886362ee8b684b56fd5b4f1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Jan_Mayen differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Madeira b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Madeira
new file mode 100644
index 0000000000000000000000000000000000000000..2175096cf122745c2756c4223a70e989040f6cb3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Madeira differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Reykjavik b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Reykjavik
new file mode 100644
index 0000000000000000000000000000000000000000..e97f13a652019dc5ed5ea2fae293404d90ff2027
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Reykjavik differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/South_Georgia b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/South_Georgia
new file mode 100644
index 0000000000000000000000000000000000000000..ab2c8236b00bbb5ad967570d1e7e46faecdd4fd5
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/South_Georgia differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/St_Helena b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/St_Helena
new file mode 100644
index 0000000000000000000000000000000000000000..d365e3ddf349472f852a9b437fa945a20df772c7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/St_Helena differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Stanley b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Stanley
new file mode 100644
index 0000000000000000000000000000000000000000..34f9d022cd5aa2b03b601fbcb75f8897be6e50d5
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Atlantic/Stanley differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/ACT b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/ACT
new file mode 100644
index 0000000000000000000000000000000000000000..d95c245e5ee1cb22a2b88fa63bee6736a4d0a8ba
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/ACT differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Adelaide b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Adelaide
new file mode 100644
index 0000000000000000000000000000000000000000..b350cb6660a68969e89860ecefa57e708405ce71
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Adelaide differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Brisbane b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Brisbane
new file mode 100644
index 0000000000000000000000000000000000000000..3e899a163f51980c2f92952b002d4cc672a35dda
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Brisbane differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Broken_Hill b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Broken_Hill
new file mode 100644
index 0000000000000000000000000000000000000000..d8f3155c84dff3c25e1590a0c1aa086cc9d51a39
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Broken_Hill differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Canberra b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Canberra
new file mode 100644
index 0000000000000000000000000000000000000000..d95c245e5ee1cb22a2b88fa63bee6736a4d0a8ba
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Canberra differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Currie b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Currie
new file mode 100644
index 0000000000000000000000000000000000000000..43ca1e455803da69a06c0289048138fad5772e9f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Currie differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Darwin b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Darwin
new file mode 100644
index 0000000000000000000000000000000000000000..c44512fbb73ba306be6c2ad6cb6f2615a95d7695
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Darwin differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Eucla b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Eucla
new file mode 100644
index 0000000000000000000000000000000000000000..e78c2d42514ef555ce0201bc22f0e7ba8200abde
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Eucla differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Hobart b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Hobart
new file mode 100644
index 0000000000000000000000000000000000000000..c4604e5386ef6aaec79f1dbc1e8af557ef63ca96
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Hobart differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/LHI b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/LHI
new file mode 100644
index 0000000000000000000000000000000000000000..1f542d3700d59c575750e55470ea66114db86309
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/LHI differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Lindeman b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Lindeman
new file mode 100644
index 0000000000000000000000000000000000000000..05c3c1c324cc7f5a2d5980fd51eefc2ecb514a7a
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Lindeman differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Lord_Howe b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Lord_Howe
new file mode 100644
index 0000000000000000000000000000000000000000..1f542d3700d59c575750e55470ea66114db86309
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Lord_Howe differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Melbourne b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Melbourne
new file mode 100644
index 0000000000000000000000000000000000000000..af3152f6c4cbe753d541bb3b8b90aa3ed88d782b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Melbourne differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/NSW b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/NSW
new file mode 100644
index 0000000000000000000000000000000000000000..d95c245e5ee1cb22a2b88fa63bee6736a4d0a8ba
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/NSW differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/North b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/North
new file mode 100644
index 0000000000000000000000000000000000000000..c44512fbb73ba306be6c2ad6cb6f2615a95d7695
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/North differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Perth b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Perth
new file mode 100644
index 0000000000000000000000000000000000000000..1c7ebb795cb7b10a4153c9ba18802c741b43d313
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Perth differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Queensland b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Queensland
new file mode 100644
index 0000000000000000000000000000000000000000..3e899a163f51980c2f92952b002d4cc672a35dda
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Queensland differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/South b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/South
new file mode 100644
index 0000000000000000000000000000000000000000..b350cb6660a68969e89860ecefa57e708405ce71
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/South differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Sydney b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Sydney
new file mode 100644
index 0000000000000000000000000000000000000000..d95c245e5ee1cb22a2b88fa63bee6736a4d0a8ba
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Sydney differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Tasmania b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Tasmania
new file mode 100644
index 0000000000000000000000000000000000000000..c4604e5386ef6aaec79f1dbc1e8af557ef63ca96
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Tasmania differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Victoria b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Victoria
new file mode 100644
index 0000000000000000000000000000000000000000..af3152f6c4cbe753d541bb3b8b90aa3ed88d782b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Victoria differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/West b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/West
new file mode 100644
index 0000000000000000000000000000000000000000..1c7ebb795cb7b10a4153c9ba18802c741b43d313
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/West differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Yancowinna b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Yancowinna
new file mode 100644
index 0000000000000000000000000000000000000000..d8f3155c84dff3c25e1590a0c1aa086cc9d51a39
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Australia/Yancowinna differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Brazil/Acre b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Brazil/Acre
new file mode 100644
index 0000000000000000000000000000000000000000..21cf598ff1f35c8314de4186e225c03a9dfd87e7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Brazil/Acre differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Brazil/DeNoronha b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Brazil/DeNoronha
new file mode 100644
index 0000000000000000000000000000000000000000..c60239009e4695a66be6f44df8d332115be14764
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Brazil/DeNoronha differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Brazil/East b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Brazil/East
new file mode 100644
index 0000000000000000000000000000000000000000..8df63a17bd46413c2c5c4751d96b504cdaae30e2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Brazil/East differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Brazil/West b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Brazil/West
new file mode 100644
index 0000000000000000000000000000000000000000..1129211841393d0423797f2afee0ac6c696a405f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Brazil/West differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/CET b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/CET
new file mode 100644
index 0000000000000000000000000000000000000000..4c4f8ef9aed8bf567ce727c33ba1b97da6f6ee7d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/CET differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/CST6CDT b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/CST6CDT
new file mode 100644
index 0000000000000000000000000000000000000000..5c8a1d9a3ea46457985198597d90f95462a70168
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/CST6CDT differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Atlantic b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Atlantic
new file mode 100644
index 0000000000000000000000000000000000000000..756099abe6cee44295a5566ad6cd0c352fb82e64
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Atlantic differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Central b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Central
new file mode 100644
index 0000000000000000000000000000000000000000..2d22791686e86b2f17a0f7fa53ad71f03a3384fc
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Central differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/East-Saskatchewan b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/East-Saskatchewan
new file mode 100644
index 0000000000000000000000000000000000000000..20c9c84df491e4072ec4c5d2c931a7433d9fd394
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/East-Saskatchewan differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Eastern b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Eastern
new file mode 100644
index 0000000000000000000000000000000000000000..1698477a48773fb8f306dc4e8f106011d4d1a60b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Eastern differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Mountain b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Mountain
new file mode 100644
index 0000000000000000000000000000000000000000..3fa0579891a9762b7c131ec5ece5d6d02495bfc0
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Mountain differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Newfoundland b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Newfoundland
new file mode 100644
index 0000000000000000000000000000000000000000..e7a18d601d0255c26885313540cbe755e009a77d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Newfoundland differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Pacific b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Pacific
new file mode 100644
index 0000000000000000000000000000000000000000..0c1fa52690498b3cd087a90ba9ba4d4f0467d532
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Pacific differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Saskatchewan b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Saskatchewan
new file mode 100644
index 0000000000000000000000000000000000000000..20c9c84df491e4072ec4c5d2c931a7433d9fd394
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Saskatchewan differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Yukon b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Yukon
new file mode 100644
index 0000000000000000000000000000000000000000..15216d55ff54fa59031ae33e898950fed4ff15e9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Canada/Yukon differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Chile/Continental b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Chile/Continental
new file mode 100644
index 0000000000000000000000000000000000000000..7cf0a1e1877bd423d43a7e60457fe92f47f9ace3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Chile/Continental differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Chile/EasterIsland b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Chile/EasterIsland
new file mode 100644
index 0000000000000000000000000000000000000000..1e2f484b79ee5791ea604efe7c6c5d254915d169
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Chile/EasterIsland differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Cuba b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Cuba
new file mode 100644
index 0000000000000000000000000000000000000000..c2623e05f5453263767b99ae026ef406a6bb36ee
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Cuba differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/EET b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/EET
new file mode 100644
index 0000000000000000000000000000000000000000..beb273a24838c96e81f0469e3827bea20ff930c3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/EET differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/EST b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/EST
new file mode 100644
index 0000000000000000000000000000000000000000..074a4fc76ad816447121db6cd004aa83ea41d437
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/EST differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/EST5EDT b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/EST5EDT
new file mode 100644
index 0000000000000000000000000000000000000000..54541fc271644e44973989a27f3846a16800caf5
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/EST5EDT differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Egypt b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Egypt
new file mode 100644
index 0000000000000000000000000000000000000000..1c6a2fc8fa68d8e2e33d48e1faa018488f250f06
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Egypt differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Eire b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Eire
new file mode 100644
index 0000000000000000000000000000000000000000..3dec02693d78bbad11809142cc4b6c0502c45129
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Eire differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT
new file mode 100644
index 0000000000000000000000000000000000000000..2ee14295f108ab15ee013cd912e7688407fa3cde
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+0 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+0
new file mode 100644
index 0000000000000000000000000000000000000000..2ee14295f108ab15ee013cd912e7688407fa3cde
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+0 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+1 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+1
new file mode 100644
index 0000000000000000000000000000000000000000..67b88c96237f4db4bdc6b28d99379432081df56f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+1 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+10 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+10
new file mode 100644
index 0000000000000000000000000000000000000000..d564b28a6f8c3fe191ed3e585b05847376843f9e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+10 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+11 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+11
new file mode 100644
index 0000000000000000000000000000000000000000..52eb573057b7424cb7af65d245871af872758b5c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+11 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+12 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+12
new file mode 100644
index 0000000000000000000000000000000000000000..c54cead625d26f33c5f5f8d268a710378702ad2b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+12 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+2 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+2
new file mode 100644
index 0000000000000000000000000000000000000000..e43b63f66b6c081a1fde636a3705e30ceba613d2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+2 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+3 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+3
new file mode 100644
index 0000000000000000000000000000000000000000..f029bac683c71af8e4c29a0d4411b816bc434c96
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+3 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+4 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+4
new file mode 100644
index 0000000000000000000000000000000000000000..0ad0ee3229bd1a4dae7670cfc3c0514d6da97aae
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+4 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+5 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+5
new file mode 100644
index 0000000000000000000000000000000000000000..e53f3febecf64fa59b36cc90405bcb6afc79e692
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+5 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+6 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+6
new file mode 100644
index 0000000000000000000000000000000000000000..b41149616a316b2647b3bfbf65ffb55fdfefb3a9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+6 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+7 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+7
new file mode 100644
index 0000000000000000000000000000000000000000..32fa6dcb42ccb1f685fb3cdb363b52ea61294ca0
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+7 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+8 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+8
new file mode 100644
index 0000000000000000000000000000000000000000..512578ca6d7c1e49ff5fdb0ec788e61fb414c27c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+8 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+9 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+9
new file mode 100644
index 0000000000000000000000000000000000000000..d3e47e7b24e591d3d50c317d8e5c6c849a2273b8
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT+9 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-0 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-0
new file mode 100644
index 0000000000000000000000000000000000000000..2ee14295f108ab15ee013cd912e7688407fa3cde
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-0 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-1 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-1
new file mode 100644
index 0000000000000000000000000000000000000000..9a6adebc882e42b4a9d0baafefbeac8014f83317
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-1 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-10 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-10
new file mode 100644
index 0000000000000000000000000000000000000000..37b93fb9d15dd9247b52e77117ea81620258fcb9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-10 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-11 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-11
new file mode 100644
index 0000000000000000000000000000000000000000..f1af0e290c988923609d96c86c23f03ea10b6671
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-11 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-12 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-12
new file mode 100644
index 0000000000000000000000000000000000000000..0fa4a8dc03ddc0a96f2dcd7adda6bf2a883bc038
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-12 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-13 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-13
new file mode 100644
index 0000000000000000000000000000000000000000..0a5dbe16cde2e1871091a929bdcb23f1b7536ca7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-13 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-14 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-14
new file mode 100644
index 0000000000000000000000000000000000000000..41c6a1d1ca0a7bd4f391c13e069307859dff1924
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-14 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-2 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-2
new file mode 100644
index 0000000000000000000000000000000000000000..9f63268d09e0b2dff05a1ee179beab9b51ccbccc
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-2 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-3 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-3
new file mode 100644
index 0000000000000000000000000000000000000000..38ccd8a6108b6e1001a80414f799a10a6e1ae166
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-3 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-4 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-4
new file mode 100644
index 0000000000000000000000000000000000000000..43badfb220c42d1577a376c2ce455faa3b35cc7b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-4 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-5 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-5
new file mode 100644
index 0000000000000000000000000000000000000000..c88cf210c3ba7b6607e57b976ff35e74d7a24d70
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-5 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-6 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-6
new file mode 100644
index 0000000000000000000000000000000000000000..c1a0634cf5ca81e8d51493b3e7ed1ce53bff6eed
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-6 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-7 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-7
new file mode 100644
index 0000000000000000000000000000000000000000..bc152efdaf3c9c522cefa7f304db8a4facb1fb63
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-7 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-8 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-8
new file mode 100644
index 0000000000000000000000000000000000000000..2c0de20faa3e59e78a549f005f011ee4305b1e11
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-8 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-9 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-9
new file mode 100644
index 0000000000000000000000000000000000000000..8a3bd45af31a743e973fcd3deff998c07409b87e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT-9 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT0 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT0
new file mode 100644
index 0000000000000000000000000000000000000000..2ee14295f108ab15ee013cd912e7688407fa3cde
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/GMT0 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/Greenwich b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/Greenwich
new file mode 100644
index 0000000000000000000000000000000000000000..2ee14295f108ab15ee013cd912e7688407fa3cde
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/Greenwich differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/UCT b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/UCT
new file mode 100644
index 0000000000000000000000000000000000000000..a88c4b665b3ec94711c735fc7593f460668958cd
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/UCT differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/UTC b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/UTC
new file mode 100644
index 0000000000000000000000000000000000000000..5583f5b0c6e6949372648a7d75502e4d01b44931
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/UTC differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/Universal b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/Universal
new file mode 100644
index 0000000000000000000000000000000000000000..5583f5b0c6e6949372648a7d75502e4d01b44931
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/Universal differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/Zulu b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/Zulu
new file mode 100644
index 0000000000000000000000000000000000000000..5583f5b0c6e6949372648a7d75502e4d01b44931
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Etc/Zulu differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Amsterdam b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Amsterdam
new file mode 100644
index 0000000000000000000000000000000000000000..30ca3243a5abc6f8a427edfd64a92b9e066d0198
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Amsterdam differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Andorra b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Andorra
new file mode 100644
index 0000000000000000000000000000000000000000..cf9533a3e4d5acb318419d5829880e7197a13a16
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Andorra differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Athens b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Athens
new file mode 100644
index 0000000000000000000000000000000000000000..726e56c3fe180c9212646e05bee82dfcbdd671bc
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Athens differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Belfast b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Belfast
new file mode 100644
index 0000000000000000000000000000000000000000..fe63ff7e7f1e9b47c45c62a7768e3924f8572c40
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Belfast differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Belgrade b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Belgrade
new file mode 100644
index 0000000000000000000000000000000000000000..5f0389f03919e0b56de9cf4bf89b591a0e8e9c2c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Belgrade differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Berlin b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Berlin
new file mode 100644
index 0000000000000000000000000000000000000000..96059c7854e1f571ddf97fd285a28df361c4c99d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Berlin differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Bratislava b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Bratislava
new file mode 100644
index 0000000000000000000000000000000000000000..9ab78e9156f206440fe847d28e80d2807bc62a8e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Bratislava differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Brussels b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Brussels
new file mode 100644
index 0000000000000000000000000000000000000000..2791edeba35c008274b308c1d08bf13e5f11ee64
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Brussels differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Bucharest b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Bucharest
new file mode 100644
index 0000000000000000000000000000000000000000..de2a5f0af1a4d0077692edd8332f46227ac6f747
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Bucharest differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Budapest b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Budapest
new file mode 100644
index 0000000000000000000000000000000000000000..1b787b16cea3331865da27115642fd1e3461ad0a
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Budapest differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Busingen b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Busingen
new file mode 100644
index 0000000000000000000000000000000000000000..440f158c14133ee13e1c102607d7fe551bd2fc95
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Busingen differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Chisinau b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Chisinau
new file mode 100644
index 0000000000000000000000000000000000000000..983cc707167654f15ee699872672384a4637157a
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Chisinau differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Copenhagen b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Copenhagen
new file mode 100644
index 0000000000000000000000000000000000000000..af7e9269e5e4517167db0f74284cff125104bd93
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Copenhagen differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Dublin b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Dublin
new file mode 100644
index 0000000000000000000000000000000000000000..3dec02693d78bbad11809142cc4b6c0502c45129
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Dublin differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Gibraltar b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Gibraltar
new file mode 100644
index 0000000000000000000000000000000000000000..f3dbeb65ecce3bd5bca37c1dc7804cdfb0923a8e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Gibraltar differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Guernsey b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Guernsey
new file mode 100644
index 0000000000000000000000000000000000000000..fe63ff7e7f1e9b47c45c62a7768e3924f8572c40
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Guernsey differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Helsinki b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Helsinki
new file mode 100644
index 0000000000000000000000000000000000000000..19d7babd531f6623710debe40497c4a50e4e613e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Helsinki differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Isle_of_Man b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Isle_of_Man
new file mode 100644
index 0000000000000000000000000000000000000000..fe63ff7e7f1e9b47c45c62a7768e3924f8572c40
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Isle_of_Man differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Istanbul b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Istanbul
new file mode 100644
index 0000000000000000000000000000000000000000..50a2838e9bdadcceb3d6e84d0b94ce6b994fa4ce
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Istanbul differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Jersey b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Jersey
new file mode 100644
index 0000000000000000000000000000000000000000..fe63ff7e7f1e9b47c45c62a7768e3924f8572c40
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Jersey differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Kaliningrad b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Kaliningrad
new file mode 100644
index 0000000000000000000000000000000000000000..fa6bab8620370007ccb2a308c44b84ba8b596286
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Kaliningrad differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Kiev b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Kiev
new file mode 100644
index 0000000000000000000000000000000000000000..7a941649d8b80aef70d9f24521ed180a0898055d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Kiev differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Lisbon b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Lisbon
new file mode 100644
index 0000000000000000000000000000000000000000..168accf060c3837af1bd64361bd0dc157dec0ae9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Lisbon differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Ljubljana b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Ljubljana
new file mode 100644
index 0000000000000000000000000000000000000000..5f0389f03919e0b56de9cf4bf89b591a0e8e9c2c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Ljubljana differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/London b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/London
new file mode 100644
index 0000000000000000000000000000000000000000..fe63ff7e7f1e9b47c45c62a7768e3924f8572c40
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/London differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Luxembourg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Luxembourg
new file mode 100644
index 0000000000000000000000000000000000000000..6c194a5cdcb22da9319183df65478ec4e55555fc
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Luxembourg differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Madrid b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Madrid
new file mode 100644
index 0000000000000000000000000000000000000000..931195955a1b17d8b0d60c027845decbcc68b0d1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Madrid differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Malta b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Malta
new file mode 100644
index 0000000000000000000000000000000000000000..5f518a1f1773e00b8b3ebe8a3a32c8ae69256b67
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Malta differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Mariehamn b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Mariehamn
new file mode 100644
index 0000000000000000000000000000000000000000..19d7babd531f6623710debe40497c4a50e4e613e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Mariehamn differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Minsk b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Minsk
new file mode 100644
index 0000000000000000000000000000000000000000..ba9971c6313838b0bd33ca5c8703d22a4b7d6bf1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Minsk differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Monaco b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Monaco
new file mode 100644
index 0000000000000000000000000000000000000000..664f6161ab6c74de956253c7ba8f82eac3b8d327
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Monaco differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Moscow b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Moscow
new file mode 100644
index 0000000000000000000000000000000000000000..6068f8b9e584385eb1096c4f9603da74aa3e4095
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Moscow differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Nicosia b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Nicosia
new file mode 100644
index 0000000000000000000000000000000000000000..f7f10ab7665e94ca44fd8cd98a362cd4b304eff1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Nicosia differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Oslo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Oslo
new file mode 100644
index 0000000000000000000000000000000000000000..6326961453f404a4a886362ee8b684b56fd5b4f1
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Oslo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Paris b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Paris
new file mode 100644
index 0000000000000000000000000000000000000000..fd8ea7dbae9efe7782aa52c5babe4ece87fe773b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Paris differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Podgorica b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Podgorica
new file mode 100644
index 0000000000000000000000000000000000000000..5f0389f03919e0b56de9cf4bf89b591a0e8e9c2c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Podgorica differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Prague b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Prague
new file mode 100644
index 0000000000000000000000000000000000000000..9ab78e9156f206440fe847d28e80d2807bc62a8e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Prague differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Riga b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Riga
new file mode 100644
index 0000000000000000000000000000000000000000..abea45d309b7dcddccd776c47c13adf5d8b93180
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Riga differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Rome b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Rome
new file mode 100644
index 0000000000000000000000000000000000000000..28ddffe0d93ee1ad7d1f3f67492f7f3b85406e6d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Rome differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Samara b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Samara
new file mode 100644
index 0000000000000000000000000000000000000000..fe5060094b501f885ba1e62292467300ef7c52ff
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Samara differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/San_Marino b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/San_Marino
new file mode 100644
index 0000000000000000000000000000000000000000..28ddffe0d93ee1ad7d1f3f67492f7f3b85406e6d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/San_Marino differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Sarajevo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Sarajevo
new file mode 100644
index 0000000000000000000000000000000000000000..5f0389f03919e0b56de9cf4bf89b591a0e8e9c2c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Sarajevo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Simferopol b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Simferopol
new file mode 100644
index 0000000000000000000000000000000000000000..a1f07fd52a8defe38ca966ff831a5d87a602a8cb
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Simferopol differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Skopje b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Skopje
new file mode 100644
index 0000000000000000000000000000000000000000..5f0389f03919e0b56de9cf4bf89b591a0e8e9c2c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Skopje differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Sofia b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Sofia
new file mode 100644
index 0000000000000000000000000000000000000000..d8032335b20aeb201c8c3851844fac5baa815071
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Sofia differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Stockholm b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Stockholm
new file mode 100644
index 0000000000000000000000000000000000000000..3bc6dbd9d12b44e0a04642a346aac17aac65a34a
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Stockholm differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Tallinn b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Tallinn
new file mode 100644
index 0000000000000000000000000000000000000000..4ba4424121aeac25767ee83ef57ca579df2b4a96
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Tallinn differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Tirane b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Tirane
new file mode 100644
index 0000000000000000000000000000000000000000..0b86017d243f1b7bbb41d6b4feefcb2b7edfc7d8
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Tirane differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Tiraspol b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Tiraspol
new file mode 100644
index 0000000000000000000000000000000000000000..983cc707167654f15ee699872672384a4637157a
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Tiraspol differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Uzhgorod b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Uzhgorod
new file mode 100644
index 0000000000000000000000000000000000000000..7032ab9b34f97640d1ef631dc4cc790abeeed606
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Uzhgorod differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Vaduz b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Vaduz
new file mode 100644
index 0000000000000000000000000000000000000000..440f158c14133ee13e1c102607d7fe551bd2fc95
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Vaduz differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Vatican b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Vatican
new file mode 100644
index 0000000000000000000000000000000000000000..28ddffe0d93ee1ad7d1f3f67492f7f3b85406e6d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Vatican differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Vienna b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Vienna
new file mode 100644
index 0000000000000000000000000000000000000000..8e4c9a9b5f09d011505a0e0e773f60911d011d2a
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Vienna differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Vilnius b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Vilnius
new file mode 100644
index 0000000000000000000000000000000000000000..b6545b24949cad3554f41ca3c31dfc5237e1b562
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Vilnius differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Volgograd b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Volgograd
new file mode 100644
index 0000000000000000000000000000000000000000..b91e4fbff6b4508668625770fd38880b186bcc57
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Volgograd differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Warsaw b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Warsaw
new file mode 100644
index 0000000000000000000000000000000000000000..3797b1cb653206febf14619e62e6b82cf4bdcf40
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Warsaw differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Zagreb b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Zagreb
new file mode 100644
index 0000000000000000000000000000000000000000..5f0389f03919e0b56de9cf4bf89b591a0e8e9c2c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Zagreb differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Zaporozhye b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Zaporozhye
new file mode 100644
index 0000000000000000000000000000000000000000..2ccf8998b24f3493e68670c5d08c51ad759bf7f6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Zaporozhye differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Zurich b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Zurich
new file mode 100644
index 0000000000000000000000000000000000000000..440f158c14133ee13e1c102607d7fe551bd2fc95
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Europe/Zurich differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Factory b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Factory
new file mode 100644
index 0000000000000000000000000000000000000000..a65f97edd26d012ce00cf0e2cc5bbce807844eec
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Factory differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GB b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GB
new file mode 100644
index 0000000000000000000000000000000000000000..fe63ff7e7f1e9b47c45c62a7768e3924f8572c40
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GB differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GB-Eire b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GB-Eire
new file mode 100644
index 0000000000000000000000000000000000000000..fe63ff7e7f1e9b47c45c62a7768e3924f8572c40
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GB-Eire differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GMT b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GMT
new file mode 100644
index 0000000000000000000000000000000000000000..2ee14295f108ab15ee013cd912e7688407fa3cde
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GMT differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GMT+0 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GMT+0
new file mode 100644
index 0000000000000000000000000000000000000000..2ee14295f108ab15ee013cd912e7688407fa3cde
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GMT+0 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GMT-0 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GMT-0
new file mode 100644
index 0000000000000000000000000000000000000000..2ee14295f108ab15ee013cd912e7688407fa3cde
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GMT-0 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GMT0 b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GMT0
new file mode 100644
index 0000000000000000000000000000000000000000..2ee14295f108ab15ee013cd912e7688407fa3cde
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/GMT0 differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Greenwich b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Greenwich
new file mode 100644
index 0000000000000000000000000000000000000000..2ee14295f108ab15ee013cd912e7688407fa3cde
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Greenwich differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/HST b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/HST
new file mode 100644
index 0000000000000000000000000000000000000000..616c31bc5ea69cbc5ba90dba190a0f500fe8cc35
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/HST differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Hongkong b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Hongkong
new file mode 100644
index 0000000000000000000000000000000000000000..8e5c5813666a4d023bc9f7f7bd0e53ca1a61dd85
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Hongkong differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Iceland b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Iceland
new file mode 100644
index 0000000000000000000000000000000000000000..e97f13a652019dc5ed5ea2fae293404d90ff2027
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Iceland differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Antananarivo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Antananarivo
new file mode 100644
index 0000000000000000000000000000000000000000..ef6e745c451764f63ba545ff0f3a57f9948de940
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Antananarivo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Chagos b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Chagos
new file mode 100644
index 0000000000000000000000000000000000000000..864d3e29a2b0c9d4d3f35b8d71fb2f3038354f94
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Chagos differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Christmas b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Christmas
new file mode 100644
index 0000000000000000000000000000000000000000..686d5b3c65423d0297f5ff7def3647d0e75515c7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Christmas differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Cocos b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Cocos
new file mode 100644
index 0000000000000000000000000000000000000000..6f7d869f0fb3e54ba9d5b4a0042740fa38a90139
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Cocos differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Comoro b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Comoro
new file mode 100644
index 0000000000000000000000000000000000000000..297c6db63c0689a0ad0d71c9110baee20c9bbb05
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Comoro differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Kerguelen b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Kerguelen
new file mode 100644
index 0000000000000000000000000000000000000000..1f42bbc1ffcba50b2fcb07f959ac5ff30e4dc0c3
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Kerguelen differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Mahe b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Mahe
new file mode 100644
index 0000000000000000000000000000000000000000..d048242cac78343ef9bb795d8e65bb9feb434855
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Mahe differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Maldives b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Maldives
new file mode 100644
index 0000000000000000000000000000000000000000..65e7eeee8db784070548f3ded2ab7b1ba800d65c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Maldives differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Mauritius b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Mauritius
new file mode 100644
index 0000000000000000000000000000000000000000..54f222010893fdfe0f34d92c2695f394bfab3b1f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Mauritius differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Mayotte b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Mayotte
new file mode 100644
index 0000000000000000000000000000000000000000..8401a37aa0ba974b3ea7f748a32d58c65bdd5149
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Mayotte differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Reunion b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Reunion
new file mode 100644
index 0000000000000000000000000000000000000000..9b3830ec31a1f7b12d0b3f8e8e7a521f3a7ceef5
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Indian/Reunion differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Iran b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Iran
new file mode 100644
index 0000000000000000000000000000000000000000..62d316190d42b9753bab0a8bd7db7fd6cda1c061
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Iran differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Israel b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Israel
new file mode 100644
index 0000000000000000000000000000000000000000..8676bfb0266c1c5d2e3e712fccd4b8221d26bb32
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Israel differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Jamaica b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Jamaica
new file mode 100644
index 0000000000000000000000000000000000000000..b89c18787ece60e0471f2c810eb4e8935d8b1f63
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Jamaica differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Japan b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Japan
new file mode 100644
index 0000000000000000000000000000000000000000..058c1e99ba26b1ab7855b81895c8d577e2f582a6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Japan differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Kwajalein b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Kwajalein
new file mode 100644
index 0000000000000000000000000000000000000000..b57237272d541866919b5115bde6e7bc2ce0797e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Kwajalein differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Libya b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Libya
new file mode 100644
index 0000000000000000000000000000000000000000..bd885315f84f8615da866553c9c0086ad430ad01
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Libya differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/MET b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/MET
new file mode 100644
index 0000000000000000000000000000000000000000..71963d533e444362250dec5465ec58517ab6c09d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/MET differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/MST b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/MST
new file mode 100644
index 0000000000000000000000000000000000000000..da3e926d23e76bc4ded05861c01c1f494b9c8d27
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/MST differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/MST7MDT b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/MST7MDT
new file mode 100644
index 0000000000000000000000000000000000000000..726a7e57176567044d585800c37cbc917b441d22
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/MST7MDT differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Mexico/BajaNorte b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Mexico/BajaNorte
new file mode 100644
index 0000000000000000000000000000000000000000..fffdc24bfc4c076584787843a5a6b457a23c5bf2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Mexico/BajaNorte differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Mexico/BajaSur b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Mexico/BajaSur
new file mode 100644
index 0000000000000000000000000000000000000000..43ee12d84a7c7e47aaa92406d01a539ccf93079d
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Mexico/BajaSur differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Mexico/General b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Mexico/General
new file mode 100644
index 0000000000000000000000000000000000000000..1434ab08804dac08e4f595967d8c325691f08aef
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Mexico/General differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/NZ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/NZ
new file mode 100644
index 0000000000000000000000000000000000000000..a40767df93d3da9502281672a7b4663f6f815199
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/NZ differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/NZ-CHAT b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/NZ-CHAT
new file mode 100644
index 0000000000000000000000000000000000000000..6329e4fce0e5e7cd61329685a3e80adaa2107fb9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/NZ-CHAT differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Navajo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Navajo
new file mode 100644
index 0000000000000000000000000000000000000000..f8908febf220f27b3efa68bcc119633c8efee299
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Navajo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/PRC b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/PRC
new file mode 100644
index 0000000000000000000000000000000000000000..af6d6fbbd298f4698b748004b6d3c2c847dd6ad6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/PRC differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/PST8PDT b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/PST8PDT
new file mode 100644
index 0000000000000000000000000000000000000000..6242ac04c09fd4e4952cd16503e954dcbdacec2e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/PST8PDT differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Apia b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Apia
new file mode 100644
index 0000000000000000000000000000000000000000..efe6d5a1de7f1e3e9841dc7392a87c18cb4e3236
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Apia differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Auckland b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Auckland
new file mode 100644
index 0000000000000000000000000000000000000000..a40767df93d3da9502281672a7b4663f6f815199
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Auckland differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Chatham b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Chatham
new file mode 100644
index 0000000000000000000000000000000000000000..6329e4fce0e5e7cd61329685a3e80adaa2107fb9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Chatham differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Chuuk b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Chuuk
new file mode 100644
index 0000000000000000000000000000000000000000..0ef473871d5569e7db3b4a5a49de10c314f6449c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Chuuk differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Easter b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Easter
new file mode 100644
index 0000000000000000000000000000000000000000..1e2f484b79ee5791ea604efe7c6c5d254915d169
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Easter differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Efate b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Efate
new file mode 100644
index 0000000000000000000000000000000000000000..c46154a8056cecd7310434e01bb646c72b253716
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Efate differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Enderbury b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Enderbury
new file mode 100644
index 0000000000000000000000000000000000000000..69e75d754e2cab32744dc8a25acc9dce914d4c2f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Enderbury differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Fakaofo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Fakaofo
new file mode 100644
index 0000000000000000000000000000000000000000..22902f98fee25197b56855ec9fadd5a87255dc90
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Fakaofo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Fiji b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Fiji
new file mode 100644
index 0000000000000000000000000000000000000000..cf5af8dcef2aad6bbfb03f6f8ebc54715b95fa24
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Fiji differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Funafuti b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Funafuti
new file mode 100644
index 0000000000000000000000000000000000000000..66cf5e1df3fc941a7ea9213958c1fe29de440dd6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Funafuti differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Galapagos b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Galapagos
new file mode 100644
index 0000000000000000000000000000000000000000..7504cc66f5006ace130bd71e12cac7bff2dca37b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Galapagos differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Gambier b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Gambier
new file mode 100644
index 0000000000000000000000000000000000000000..fc49c03f6e043bf58534f6f4191717e6be1983d7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Gambier differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Guadalcanal b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Guadalcanal
new file mode 100644
index 0000000000000000000000000000000000000000..3a4ec12e56d7663327bf083dbf819ddd86eb7b81
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Guadalcanal differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Guam b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Guam
new file mode 100644
index 0000000000000000000000000000000000000000..a05292f4bacfb1b9468afd759ca08abe0e36f9ef
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Guam differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Honolulu b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Honolulu
new file mode 100644
index 0000000000000000000000000000000000000000..1b4684b9b47fac79b03841013853d50a5a53abd7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Honolulu differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Johnston b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Johnston
new file mode 100644
index 0000000000000000000000000000000000000000..1b4684b9b47fac79b03841013853d50a5a53abd7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Johnston differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Kiritimati b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Kiritimati
new file mode 100644
index 0000000000000000000000000000000000000000..7131453c55407adc34e83b416603dad85950af1f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Kiritimati differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Kosrae b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Kosrae
new file mode 100644
index 0000000000000000000000000000000000000000..61b7561589cb7897117aa8a4b1f8c8d606a34884
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Kosrae differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Kwajalein b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Kwajalein
new file mode 100644
index 0000000000000000000000000000000000000000..b57237272d541866919b5115bde6e7bc2ce0797e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Kwajalein differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Majuro b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Majuro
new file mode 100644
index 0000000000000000000000000000000000000000..eab93a2af9905e0b3865af9f85f93daf2b90ee39
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Majuro differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Marquesas b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Marquesas
new file mode 100644
index 0000000000000000000000000000000000000000..cd2d5b073afffce74f34a5f984c3e5b7c95086f9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Marquesas differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Midway b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Midway
new file mode 100644
index 0000000000000000000000000000000000000000..8889a26fa7c87074fcf89c15b5bb5ac3c7cd3246
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Midway differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Nauru b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Nauru
new file mode 100644
index 0000000000000000000000000000000000000000..1d8179bcb50d105c5c6ccff136832eae9310f911
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Nauru differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Niue b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Niue
new file mode 100644
index 0000000000000000000000000000000000000000..b9f18a544ab4cffee02a84dfdcec9872675b377c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Niue differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Norfolk b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Norfolk
new file mode 100644
index 0000000000000000000000000000000000000000..2e989c25561771e870d4b45ab405fe7105b2cfb2
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Norfolk differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Noumea b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Noumea
new file mode 100644
index 0000000000000000000000000000000000000000..ae9e138fa566f2053c96d6c9689474068d3d03d4
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Noumea differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Pago_Pago b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Pago_Pago
new file mode 100644
index 0000000000000000000000000000000000000000..fa084ba584c6364bec21116e0f05dabe9609e98b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Pago_Pago differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Palau b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Palau
new file mode 100644
index 0000000000000000000000000000000000000000..efc556b140241380ed92f829d51cd6fc5a85c5e6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Palau differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Pitcairn b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Pitcairn
new file mode 100644
index 0000000000000000000000000000000000000000..51f01c6410da8f9b518d07c1f040d830d0f1200e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Pitcairn differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Pohnpei b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Pohnpei
new file mode 100644
index 0000000000000000000000000000000000000000..f175ea587502fb875d165ea4ac3ad4b657b58b99
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Pohnpei differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Ponape b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Ponape
new file mode 100644
index 0000000000000000000000000000000000000000..f175ea587502fb875d165ea4ac3ad4b657b58b99
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Ponape differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Port_Moresby b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Port_Moresby
new file mode 100644
index 0000000000000000000000000000000000000000..8d4d12ccb09468721bb4473d729f55ba725b93d5
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Port_Moresby differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Rarotonga b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Rarotonga
new file mode 100644
index 0000000000000000000000000000000000000000..581299788a6129d4565a8dbbb0fdd53f20e2116e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Rarotonga differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Saipan b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Saipan
new file mode 100644
index 0000000000000000000000000000000000000000..519c86e9668357fb0c59454b02db8c0474e01e7f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Saipan differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Samoa b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Samoa
new file mode 100644
index 0000000000000000000000000000000000000000..fa084ba584c6364bec21116e0f05dabe9609e98b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Samoa differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Tahiti b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Tahiti
new file mode 100644
index 0000000000000000000000000000000000000000..22f86974672e85bb658773a16e997c6663db19e8
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Tahiti differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Tarawa b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Tarawa
new file mode 100644
index 0000000000000000000000000000000000000000..065dcd819473ff70bb1171eb97be0d2efac50f75
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Tarawa differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Tongatapu b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Tongatapu
new file mode 100644
index 0000000000000000000000000000000000000000..01ab6b87ef92e1a1ba7191614e73d4fab354b1c6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Tongatapu differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Truk b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Truk
new file mode 100644
index 0000000000000000000000000000000000000000..0ef473871d5569e7db3b4a5a49de10c314f6449c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Truk differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Wake b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Wake
new file mode 100644
index 0000000000000000000000000000000000000000..f89c52829a00a2ea80b5fdb75e45dd6fcf477644
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Wake differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Wallis b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Wallis
new file mode 100644
index 0000000000000000000000000000000000000000..9aaf558f1da27b610556ed6f3a544a0a16fcd68e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Wallis differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Yap b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Yap
new file mode 100644
index 0000000000000000000000000000000000000000..0ef473871d5569e7db3b4a5a49de10c314f6449c
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Pacific/Yap differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Poland b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Poland
new file mode 100644
index 0000000000000000000000000000000000000000..3797b1cb653206febf14619e62e6b82cf4bdcf40
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Poland differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Portugal b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Portugal
new file mode 100644
index 0000000000000000000000000000000000000000..168accf060c3837af1bd64361bd0dc157dec0ae9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Portugal differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/ROC b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/ROC
new file mode 100644
index 0000000000000000000000000000000000000000..70cfb27ca91f3e9dcacf7941b8432c7a10560c69
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/ROC differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/ROK b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/ROK
new file mode 100644
index 0000000000000000000000000000000000000000..96bb0c36d7e3fc455f868a4cd379bbadf6889bd6
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/ROK differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Singapore b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Singapore
new file mode 100644
index 0000000000000000000000000000000000000000..a6f2db8f3a887fa0f19283b52c2f801329bb4f53
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Singapore differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Turkey b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Turkey
new file mode 100644
index 0000000000000000000000000000000000000000..50a2838e9bdadcceb3d6e84d0b94ce6b994fa4ce
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Turkey differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/UCT b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/UCT
new file mode 100644
index 0000000000000000000000000000000000000000..a88c4b665b3ec94711c735fc7593f460668958cd
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/UCT differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Alaska b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Alaska
new file mode 100644
index 0000000000000000000000000000000000000000..d14735026a09cff0104e479fa6543301d482deed
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Alaska differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Aleutian b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Aleutian
new file mode 100644
index 0000000000000000000000000000000000000000..391ec98ec0f31cd595ed05a9b91a41c4cdb25d31
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Aleutian differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Arizona b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Arizona
new file mode 100644
index 0000000000000000000000000000000000000000..67589026c21c6bcb83587d25342c93f10570bc24
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Arizona differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Central b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Central
new file mode 100644
index 0000000000000000000000000000000000000000..71aae7246a30bb9e43118539fd6171372cf3f49f
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Central differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/East-Indiana b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/East-Indiana
new file mode 100644
index 0000000000000000000000000000000000000000..aa3dfc43730ed25bde9c967039951f5c2fc15cc9
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/East-Indiana differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Eastern b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Eastern
new file mode 100644
index 0000000000000000000000000000000000000000..b2c2377f4e87960bb2adafda2a4ac6385cadceea
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Eastern differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Hawaii b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Hawaii
new file mode 100644
index 0000000000000000000000000000000000000000..1b4684b9b47fac79b03841013853d50a5a53abd7
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Hawaii differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Indiana-Starke b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Indiana-Starke
new file mode 100644
index 0000000000000000000000000000000000000000..33169f4596381b700b3598dabf7706dce25f65ba
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Indiana-Starke differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Michigan b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Michigan
new file mode 100644
index 0000000000000000000000000000000000000000..da53d46df347ac70897f4f5c51feb83b6a878627
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Michigan differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Mountain b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Mountain
new file mode 100644
index 0000000000000000000000000000000000000000..f8908febf220f27b3efa68bcc119633c8efee299
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Mountain differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Pacific b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Pacific
new file mode 100644
index 0000000000000000000000000000000000000000..3b7ce1dceebf9fa9db859068da1fa7eba6df1cfa
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Pacific differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Pacific-New b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Pacific-New
new file mode 100644
index 0000000000000000000000000000000000000000..3b7ce1dceebf9fa9db859068da1fa7eba6df1cfa
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Pacific-New differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Samoa b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Samoa
new file mode 100644
index 0000000000000000000000000000000000000000..fa084ba584c6364bec21116e0f05dabe9609e98b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/US/Samoa differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/UTC b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/UTC
new file mode 100644
index 0000000000000000000000000000000000000000..5583f5b0c6e6949372648a7d75502e4d01b44931
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/UTC differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Universal b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Universal
new file mode 100644
index 0000000000000000000000000000000000000000..5583f5b0c6e6949372648a7d75502e4d01b44931
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Universal differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/W-SU b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/W-SU
new file mode 100644
index 0000000000000000000000000000000000000000..6068f8b9e584385eb1096c4f9603da74aa3e4095
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/W-SU differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/WET b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/WET
new file mode 100644
index 0000000000000000000000000000000000000000..444a1933d72525ab3045980eab2fbf79266cf158
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/WET differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Zulu b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Zulu
new file mode 100644
index 0000000000000000000000000000000000000000..5583f5b0c6e6949372648a7d75502e4d01b44931
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/Zulu differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/iso3166.tab b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/iso3166.tab
new file mode 100644
index 0000000000000000000000000000000000000000..a1e4b42e4443d41adf845f42347affbc718b894c
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/iso3166.tab
@@ -0,0 +1,275 @@
+# ISO 3166 alpha-2 country codes
+#
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+#
+# From Paul Eggert (2013-05-27):
+#
+# This file contains a table with the following columns:
+# 1. ISO 3166-1 alpha-2 country code, current as of
+# ISO 3166-1 Newsletter VI-15 (2013-05-10). See: Updates on ISO 3166
+# http://www.iso.org/iso/home/standards/country_codes/updates_on_iso_3166.htm
+# 2. The usual English name for the coded region,
+# chosen so that alphabetic sorting of subsets produces helpful lists.
+# This is not the same as the English name in the ISO 3166 tables.
+#
+# Columns are separated by a single tab.
+# The table is sorted by country code.
+#
+# Lines beginning with `#' are comments.
+#
+# This table is intended as an aid for users, to help them select time
+# zone data appropriate for their practical needs. It is not intended
+# to take or endorse any position on legal or territorial claims.
+#
+#country-
+#code name of country, territory, area, or subdivision
+AD Andorra
+AE United Arab Emirates
+AF Afghanistan
+AG Antigua & Barbuda
+AI Anguilla
+AL Albania
+AM Armenia
+AO Angola
+AQ Antarctica
+AR Argentina
+AS Samoa (American)
+AT Austria
+AU Australia
+AW Aruba
+AX Aaland Islands
+AZ Azerbaijan
+BA Bosnia & Herzegovina
+BB Barbados
+BD Bangladesh
+BE Belgium
+BF Burkina Faso
+BG Bulgaria
+BH Bahrain
+BI Burundi
+BJ Benin
+BL St Barthelemy
+BM Bermuda
+BN Brunei
+BO Bolivia
+BQ Caribbean Netherlands
+BR Brazil
+BS Bahamas
+BT Bhutan
+BV Bouvet Island
+BW Botswana
+BY Belarus
+BZ Belize
+CA Canada
+CC Cocos (Keeling) Islands
+CD Congo (Dem. Rep.)
+CF Central African Rep.
+CG Congo (Rep.)
+CH Switzerland
+CI Cote d'Ivoire
+CK Cook Islands
+CL Chile
+CM Cameroon
+CN China
+CO Colombia
+CR Costa Rica
+CU Cuba
+CV Cape Verde
+CW Curacao
+CX Christmas Island
+CY Cyprus
+CZ Czech Republic
+DE Germany
+DJ Djibouti
+DK Denmark
+DM Dominica
+DO Dominican Republic
+DZ Algeria
+EC Ecuador
+EE Estonia
+EG Egypt
+EH Western Sahara
+ER Eritrea
+ES Spain
+ET Ethiopia
+FI Finland
+FJ Fiji
+FK Falkland Islands
+FM Micronesia
+FO Faroe Islands
+FR France
+GA Gabon
+GB Britain (UK)
+GD Grenada
+GE Georgia
+GF French Guiana
+GG Guernsey
+GH Ghana
+GI Gibraltar
+GL Greenland
+GM Gambia
+GN Guinea
+GP Guadeloupe
+GQ Equatorial Guinea
+GR Greece
+GS South Georgia & the South Sandwich Islands
+GT Guatemala
+GU Guam
+GW Guinea-Bissau
+GY Guyana
+HK Hong Kong
+HM Heard Island & McDonald Islands
+HN Honduras
+HR Croatia
+HT Haiti
+HU Hungary
+ID Indonesia
+IE Ireland
+IL Israel
+IM Isle of Man
+IN India
+IO British Indian Ocean Territory
+IQ Iraq
+IR Iran
+IS Iceland
+IT Italy
+JE Jersey
+JM Jamaica
+JO Jordan
+JP Japan
+KE Kenya
+KG Kyrgyzstan
+KH Cambodia
+KI Kiribati
+KM Comoros
+KN St Kitts & Nevis
+KP Korea (North)
+KR Korea (South)
+KW Kuwait
+KY Cayman Islands
+KZ Kazakhstan
+LA Laos
+LB Lebanon
+LC St Lucia
+LI Liechtenstein
+LK Sri Lanka
+LR Liberia
+LS Lesotho
+LT Lithuania
+LU Luxembourg
+LV Latvia
+LY Libya
+MA Morocco
+MC Monaco
+MD Moldova
+ME Montenegro
+MF St Martin (French part)
+MG Madagascar
+MH Marshall Islands
+MK Macedonia
+ML Mali
+MM Myanmar (Burma)
+MN Mongolia
+MO Macau
+MP Northern Mariana Islands
+MQ Martinique
+MR Mauritania
+MS Montserrat
+MT Malta
+MU Mauritius
+MV Maldives
+MW Malawi
+MX Mexico
+MY Malaysia
+MZ Mozambique
+NA Namibia
+NC New Caledonia
+NE Niger
+NF Norfolk Island
+NG Nigeria
+NI Nicaragua
+NL Netherlands
+NO Norway
+NP Nepal
+NR Nauru
+NU Niue
+NZ New Zealand
+OM Oman
+PA Panama
+PE Peru
+PF French Polynesia
+PG Papua New Guinea
+PH Philippines
+PK Pakistan
+PL Poland
+PM St Pierre & Miquelon
+PN Pitcairn
+PR Puerto Rico
+PS Palestine
+PT Portugal
+PW Palau
+PY Paraguay
+QA Qatar
+RE Reunion
+RO Romania
+RS Serbia
+RU Russia
+RW Rwanda
+SA Saudi Arabia
+SB Solomon Islands
+SC Seychelles
+SD Sudan
+SE Sweden
+SG Singapore
+SH St Helena
+SI Slovenia
+SJ Svalbard & Jan Mayen
+SK Slovakia
+SL Sierra Leone
+SM San Marino
+SN Senegal
+SO Somalia
+SR Suriname
+SS South Sudan
+ST Sao Tome & Principe
+SV El Salvador
+SX St Maarten (Dutch part)
+SY Syria
+SZ Swaziland
+TC Turks & Caicos Is
+TD Chad
+TF French Southern & Antarctic Lands
+TG Togo
+TH Thailand
+TJ Tajikistan
+TK Tokelau
+TL East Timor
+TM Turkmenistan
+TN Tunisia
+TO Tonga
+TR Turkey
+TT Trinidad & Tobago
+TV Tuvalu
+TW Taiwan
+TZ Tanzania
+UA Ukraine
+UG Uganda
+UM US minor outlying islands
+US United States
+UY Uruguay
+UZ Uzbekistan
+VA Vatican City
+VC St Vincent
+VE Venezuela
+VG Virgin Islands (UK)
+VI Virgin Islands (US)
+VN Vietnam
+VU Vanuatu
+WF Wallis & Futuna
+WS Samoa (western)
+YE Yemen
+YT Mayotte
+ZA South Africa
+ZM Zambia
+ZW Zimbabwe
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/localtime b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/localtime
new file mode 100644
index 0000000000000000000000000000000000000000..2ee14295f108ab15ee013cd912e7688407fa3cde
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/localtime differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/posixrules b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/posixrules
new file mode 100644
index 0000000000000000000000000000000000000000..b2c2377f4e87960bb2adafda2a4ac6385cadceea
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/posixrules differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/zone.tab b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/zone.tab
new file mode 100644
index 0000000000000000000000000000000000000000..923d6ac5be90ea4f48edfb317b2b0dea9d813b86
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/pytzimp/zoneinfo/zone.tab
@@ -0,0 +1,452 @@
+# TZ zone descriptions
+#
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+#
+# From Paul Eggert (2013-08-14):
+#
+# This file contains a table where each row stands for an area that is
+# the intersection of a region identified by a country code and of a
+# zone where civil clocks have agreed since 1970. The columns of the
+# table are as follows:
+#
+# 1. ISO 3166 2-character country code. See the file 'iso3166.tab'.
+# 2. Latitude and longitude of the area's principal location
+# in ISO 6709 sign-degrees-minutes-seconds format,
+# either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS,
+# first latitude (+ is north), then longitude (+ is east).
+# 3. Zone name used in value of TZ environment variable.
+# Please see the 'Theory' file for how zone names are chosen.
+# If multiple zones overlap a country, each has a row in the
+# table, with column 1 being duplicated.
+# 4. Comments; present if and only if the country has multiple rows.
+#
+# Columns are separated by a single tab.
+# The table is sorted first by country, then an order within the country that
+# (1) makes some geographical sense, and
+# (2) puts the most populous areas first, where that does not contradict (1).
+#
+# Lines beginning with '#' are comments.
+#
+# This table is intended as an aid for users, to help them select time
+# zone data appropriate for their practical needs. It is not intended
+# to take or endorse any position on legal or territorial claims.
+#
+#country-
+#code coordinates TZ comments
+AD +4230+00131 Europe/Andorra
+AE +2518+05518 Asia/Dubai
+AF +3431+06912 Asia/Kabul
+AG +1703-06148 America/Antigua
+AI +1812-06304 America/Anguilla
+AL +4120+01950 Europe/Tirane
+AM +4011+04430 Asia/Yerevan
+AO -0848+01314 Africa/Luanda
+AQ -7750+16636 Antarctica/McMurdo McMurdo, South Pole, Scott (New Zealand time)
+AQ -6734-06808 Antarctica/Rothera Rothera Station, Adelaide Island
+AQ -6448-06406 Antarctica/Palmer Palmer Station, Anvers Island
+AQ -6736+06253 Antarctica/Mawson Mawson Station, Holme Bay
+AQ -6835+07758 Antarctica/Davis Davis Station, Vestfold Hills
+AQ -6617+11031 Antarctica/Casey Casey Station, Bailey Peninsula
+AQ -7824+10654 Antarctica/Vostok Vostok Station, Lake Vostok
+AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville Station, Terre Adelie
+AQ -690022+0393524 Antarctica/Syowa Syowa Station, E Ongul I
+AQ -720041+0023206 Antarctica/Troll Troll Station, Queen Maud Land
+AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF)
+AR -3124-06411 America/Argentina/Cordoba most locations (CB, CC, CN, ER, FM, MN, SE, SF)
+AR -2447-06525 America/Argentina/Salta (SA, LP, NQ, RN)
+AR -2411-06518 America/Argentina/Jujuy Jujuy (JY)
+AR -2649-06513 America/Argentina/Tucuman Tucuman (TM)
+AR -2828-06547 America/Argentina/Catamarca Catamarca (CT), Chubut (CH)
+AR -2926-06651 America/Argentina/La_Rioja La Rioja (LR)
+AR -3132-06831 America/Argentina/San_Juan San Juan (SJ)
+AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ)
+AR -3319-06621 America/Argentina/San_Luis San Luis (SL)
+AR -5138-06913 America/Argentina/Rio_Gallegos Santa Cruz (SC)
+AR -5448-06818 America/Argentina/Ushuaia Tierra del Fuego (TF)
+AS -1416-17042 Pacific/Pago_Pago
+AT +4813+01620 Europe/Vienna
+AU -3133+15905 Australia/Lord_Howe Lord Howe Island
+AU -5430+15857 Antarctica/Macquarie Macquarie Island
+AU -4253+14719 Australia/Hobart Tasmania - most locations
+AU -3956+14352 Australia/Currie Tasmania - King Island
+AU -3749+14458 Australia/Melbourne Victoria
+AU -3352+15113 Australia/Sydney New South Wales - most locations
+AU -3157+14127 Australia/Broken_Hill New South Wales - Yancowinna
+AU -2728+15302 Australia/Brisbane Queensland - most locations
+AU -2016+14900 Australia/Lindeman Queensland - Holiday Islands
+AU -3455+13835 Australia/Adelaide South Australia
+AU -1228+13050 Australia/Darwin Northern Territory
+AU -3157+11551 Australia/Perth Western Australia - most locations
+AU -3143+12852 Australia/Eucla Western Australia - Eucla area
+AW +1230-06958 America/Aruba
+AX +6006+01957 Europe/Mariehamn
+AZ +4023+04951 Asia/Baku
+BA +4352+01825 Europe/Sarajevo
+BB +1306-05937 America/Barbados
+BD +2343+09025 Asia/Dhaka
+BE +5050+00420 Europe/Brussels
+BF +1222-00131 Africa/Ouagadougou
+BG +4241+02319 Europe/Sofia
+BH +2623+05035 Asia/Bahrain
+BI -0323+02922 Africa/Bujumbura
+BJ +0629+00237 Africa/Porto-Novo
+BL +1753-06251 America/St_Barthelemy
+BM +3217-06446 Atlantic/Bermuda
+BN +0456+11455 Asia/Brunei
+BO -1630-06809 America/La_Paz
+BQ +120903-0681636 America/Kralendijk
+BR -0351-03225 America/Noronha Atlantic islands
+BR -0127-04829 America/Belem Amapa, E Para
+BR -0343-03830 America/Fortaleza NE Brazil (MA, PI, CE, RN, PB)
+BR -0803-03454 America/Recife Pernambuco
+BR -0712-04812 America/Araguaina Tocantins
+BR -0940-03543 America/Maceio Alagoas, Sergipe
+BR -1259-03831 America/Bahia Bahia
+BR -2332-04637 America/Sao_Paulo S & SE Brazil (GO, DF, MG, ES, RJ, SP, PR, SC, RS)
+BR -2027-05437 America/Campo_Grande Mato Grosso do Sul
+BR -1535-05605 America/Cuiaba Mato Grosso
+BR -0226-05452 America/Santarem W Para
+BR -0846-06354 America/Porto_Velho Rondonia
+BR +0249-06040 America/Boa_Vista Roraima
+BR -0308-06001 America/Manaus E Amazonas
+BR -0640-06952 America/Eirunepe W Amazonas
+BR -0958-06748 America/Rio_Branco Acre
+BS +2505-07721 America/Nassau
+BT +2728+08939 Asia/Thimphu
+BW -2439+02555 Africa/Gaborone
+BY +5354+02734 Europe/Minsk
+BZ +1730-08812 America/Belize
+CA +4734-05243 America/St_Johns Newfoundland Time, including SE Labrador
+CA +4439-06336 America/Halifax Atlantic Time - Nova Scotia (most places), PEI
+CA +4612-05957 America/Glace_Bay Atlantic Time - Nova Scotia - places that did not observe DST 1966-1971
+CA +4606-06447 America/Moncton Atlantic Time - New Brunswick
+CA +5320-06025 America/Goose_Bay Atlantic Time - Labrador - most locations
+CA +5125-05707 America/Blanc-Sablon Atlantic Standard Time - Quebec - Lower North Shore
+CA +4339-07923 America/Toronto Eastern Time - Ontario & Quebec - most locations
+CA +4901-08816 America/Nipigon Eastern Time - Ontario & Quebec - places that did not observe DST 1967-1973
+CA +4823-08915 America/Thunder_Bay Eastern Time - Thunder Bay, Ontario
+CA +6344-06828 America/Iqaluit Eastern Time - east Nunavut - most locations
+CA +6608-06544 America/Pangnirtung Eastern Time - Pangnirtung, Nunavut
+CA +744144-0944945 America/Resolute Central Standard Time - Resolute, Nunavut
+CA +484531-0913718 America/Atikokan Eastern Standard Time - Atikokan, Ontario and Southampton I, Nunavut
+CA +624900-0920459 America/Rankin_Inlet Central Time - central Nunavut
+CA +4953-09709 America/Winnipeg Central Time - Manitoba & west Ontario
+CA +4843-09434 America/Rainy_River Central Time - Rainy River & Fort Frances, Ontario
+CA +5024-10439 America/Regina Central Standard Time - Saskatchewan - most locations
+CA +5017-10750 America/Swift_Current Central Standard Time - Saskatchewan - midwest
+CA +5333-11328 America/Edmonton Mountain Time - Alberta, east British Columbia & west Saskatchewan
+CA +690650-1050310 America/Cambridge_Bay Mountain Time - west Nunavut
+CA +6227-11421 America/Yellowknife Mountain Time - central Northwest Territories
+CA +682059-1334300 America/Inuvik Mountain Time - west Northwest Territories
+CA +4906-11631 America/Creston Mountain Standard Time - Creston, British Columbia
+CA +5946-12014 America/Dawson_Creek Mountain Standard Time - Dawson Creek & Fort Saint John, British Columbia
+CA +4916-12307 America/Vancouver Pacific Time - west British Columbia
+CA +6043-13503 America/Whitehorse Pacific Time - south Yukon
+CA +6404-13925 America/Dawson Pacific Time - north Yukon
+CC -1210+09655 Indian/Cocos
+CD -0418+01518 Africa/Kinshasa west Dem. Rep. of Congo
+CD -1140+02728 Africa/Lubumbashi east Dem. Rep. of Congo
+CF +0422+01835 Africa/Bangui
+CG -0416+01517 Africa/Brazzaville
+CH +4723+00832 Europe/Zurich
+CI +0519-00402 Africa/Abidjan
+CK -2114-15946 Pacific/Rarotonga
+CL -3327-07040 America/Santiago most locations
+CL -2709-10926 Pacific/Easter Easter Island & Sala y Gomez
+CM +0403+00942 Africa/Douala
+CN +3114+12128 Asia/Shanghai east China - Beijing, Guangdong, Shanghai, etc.
+CN +4545+12641 Asia/Harbin Heilongjiang (except Mohe), Jilin
+CN +2934+10635 Asia/Chongqing central China - Sichuan, Yunnan, Guangxi, Shaanxi, Guizhou, etc.
+CN +4348+08735 Asia/Urumqi most of Tibet & Xinjiang
+CN +3929+07559 Asia/Kashgar west Tibet & Xinjiang
+CO +0436-07405 America/Bogota
+CR +0956-08405 America/Costa_Rica
+CU +2308-08222 America/Havana
+CV +1455-02331 Atlantic/Cape_Verde
+CW +1211-06900 America/Curacao
+CX -1025+10543 Indian/Christmas
+CY +3510+03322 Asia/Nicosia
+CZ +5005+01426 Europe/Prague
+DE +5230+01322 Europe/Berlin most locations
+DE +4742+00841 Europe/Busingen Busingen
+DJ +1136+04309 Africa/Djibouti
+DK +5540+01235 Europe/Copenhagen
+DM +1518-06124 America/Dominica
+DO +1828-06954 America/Santo_Domingo
+DZ +3647+00303 Africa/Algiers
+EC -0210-07950 America/Guayaquil mainland
+EC -0054-08936 Pacific/Galapagos Galapagos Islands
+EE +5925+02445 Europe/Tallinn
+EG +3003+03115 Africa/Cairo
+EH +2709-01312 Africa/El_Aaiun
+ER +1520+03853 Africa/Asmara
+ES +4024-00341 Europe/Madrid mainland
+ES +3553-00519 Africa/Ceuta Ceuta & Melilla
+ES +2806-01524 Atlantic/Canary Canary Islands
+ET +0902+03842 Africa/Addis_Ababa
+FI +6010+02458 Europe/Helsinki
+FJ -1808+17825 Pacific/Fiji
+FK -5142-05751 Atlantic/Stanley
+FM +0725+15147 Pacific/Chuuk Chuuk (Truk) and Yap
+FM +0658+15813 Pacific/Pohnpei Pohnpei (Ponape)
+FM +0519+16259 Pacific/Kosrae Kosrae
+FO +6201-00646 Atlantic/Faroe
+FR +4852+00220 Europe/Paris
+GA +0023+00927 Africa/Libreville
+GB +513030-0000731 Europe/London
+GD +1203-06145 America/Grenada
+GE +4143+04449 Asia/Tbilisi
+GF +0456-05220 America/Cayenne
+GG +4927-00232 Europe/Guernsey
+GH +0533-00013 Africa/Accra
+GI +3608-00521 Europe/Gibraltar
+GL +6411-05144 America/Godthab most locations
+GL +7646-01840 America/Danmarkshavn east coast, north of Scoresbysund
+GL +7029-02158 America/Scoresbysund Scoresbysund / Ittoqqortoormiit
+GL +7634-06847 America/Thule Thule / Pituffik
+GM +1328-01639 Africa/Banjul
+GN +0931-01343 Africa/Conakry
+GP +1614-06132 America/Guadeloupe
+GQ +0345+00847 Africa/Malabo
+GR +3758+02343 Europe/Athens
+GS -5416-03632 Atlantic/South_Georgia
+GT +1438-09031 America/Guatemala
+GU +1328+14445 Pacific/Guam
+GW +1151-01535 Africa/Bissau
+GY +0648-05810 America/Guyana
+HK +2217+11409 Asia/Hong_Kong
+HN +1406-08713 America/Tegucigalpa
+HR +4548+01558 Europe/Zagreb
+HT +1832-07220 America/Port-au-Prince
+HU +4730+01905 Europe/Budapest
+ID -0610+10648 Asia/Jakarta Java & Sumatra
+ID -0002+10920 Asia/Pontianak west & central Borneo
+ID -0507+11924 Asia/Makassar east & south Borneo, Sulawesi (Celebes), Bali, Nusa Tengarra, west Timor
+ID -0232+14042 Asia/Jayapura west New Guinea (Irian Jaya) & Malukus (Moluccas)
+IE +5320-00615 Europe/Dublin
+IL +314650+0351326 Asia/Jerusalem
+IM +5409-00428 Europe/Isle_of_Man
+IN +2232+08822 Asia/Kolkata
+IO -0720+07225 Indian/Chagos
+IQ +3321+04425 Asia/Baghdad
+IR +3540+05126 Asia/Tehran
+IS +6409-02151 Atlantic/Reykjavik
+IT +4154+01229 Europe/Rome
+JE +4912-00207 Europe/Jersey
+JM +175805-0764736 America/Jamaica
+JO +3157+03556 Asia/Amman
+JP +353916+1394441 Asia/Tokyo
+KE -0117+03649 Africa/Nairobi
+KG +4254+07436 Asia/Bishkek
+KH +1133+10455 Asia/Phnom_Penh
+KI +0125+17300 Pacific/Tarawa Gilbert Islands
+KI -0308-17105 Pacific/Enderbury Phoenix Islands
+KI +0152-15720 Pacific/Kiritimati Line Islands
+KM -1141+04316 Indian/Comoro
+KN +1718-06243 America/St_Kitts
+KP +3901+12545 Asia/Pyongyang
+KR +3733+12658 Asia/Seoul
+KW +2920+04759 Asia/Kuwait
+KY +1918-08123 America/Cayman
+KZ +4315+07657 Asia/Almaty most locations
+KZ +4448+06528 Asia/Qyzylorda Qyzylorda (Kyzylorda, Kzyl-Orda)
+KZ +5017+05710 Asia/Aqtobe Aqtobe (Aktobe)
+KZ +4431+05016 Asia/Aqtau Atyrau (Atirau, Gur'yev), Mangghystau (Mankistau)
+KZ +5113+05121 Asia/Oral West Kazakhstan
+LA +1758+10236 Asia/Vientiane
+LB +3353+03530 Asia/Beirut
+LC +1401-06100 America/St_Lucia
+LI +4709+00931 Europe/Vaduz
+LK +0656+07951 Asia/Colombo
+LR +0618-01047 Africa/Monrovia
+LS -2928+02730 Africa/Maseru
+LT +5441+02519 Europe/Vilnius
+LU +4936+00609 Europe/Luxembourg
+LV +5657+02406 Europe/Riga
+LY +3254+01311 Africa/Tripoli
+MA +3339-00735 Africa/Casablanca
+MC +4342+00723 Europe/Monaco
+MD +4700+02850 Europe/Chisinau
+ME +4226+01916 Europe/Podgorica
+MF +1804-06305 America/Marigot
+MG -1855+04731 Indian/Antananarivo
+MH +0709+17112 Pacific/Majuro most locations
+MH +0905+16720 Pacific/Kwajalein Kwajalein
+MK +4159+02126 Europe/Skopje
+ML +1239-00800 Africa/Bamako
+MM +1647+09610 Asia/Rangoon
+MN +4755+10653 Asia/Ulaanbaatar most locations
+MN +4801+09139 Asia/Hovd Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan
+MN +4804+11430 Asia/Choibalsan Dornod, Sukhbaatar
+MO +2214+11335 Asia/Macau
+MP +1512+14545 Pacific/Saipan
+MQ +1436-06105 America/Martinique
+MR +1806-01557 Africa/Nouakchott
+MS +1643-06213 America/Montserrat
+MT +3554+01431 Europe/Malta
+MU -2010+05730 Indian/Mauritius
+MV +0410+07330 Indian/Maldives
+MW -1547+03500 Africa/Blantyre
+MX +1924-09909 America/Mexico_City Central Time - most locations
+MX +2105-08646 America/Cancun Central Time - Quintana Roo
+MX +2058-08937 America/Merida Central Time - Campeche, Yucatan
+MX +2540-10019 America/Monterrey Mexican Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas away from US border
+MX +2550-09730 America/Matamoros US Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas near US border
+MX +2313-10625 America/Mazatlan Mountain Time - S Baja, Nayarit, Sinaloa
+MX +2838-10605 America/Chihuahua Mexican Mountain Time - Chihuahua away from US border
+MX +2934-10425 America/Ojinaga US Mountain Time - Chihuahua near US border
+MX +2904-11058 America/Hermosillo Mountain Standard Time - Sonora
+MX +3232-11701 America/Tijuana US Pacific Time - Baja California near US border
+MX +3018-11452 America/Santa_Isabel Mexican Pacific Time - Baja California away from US border
+MX +2048-10515 America/Bahia_Banderas Mexican Central Time - Bahia de Banderas
+MY +0310+10142 Asia/Kuala_Lumpur peninsular Malaysia
+MY +0133+11020 Asia/Kuching Sabah & Sarawak
+MZ -2558+03235 Africa/Maputo
+NA -2234+01706 Africa/Windhoek
+NC -2216+16627 Pacific/Noumea
+NE +1331+00207 Africa/Niamey
+NF -2903+16758 Pacific/Norfolk
+NG +0627+00324 Africa/Lagos
+NI +1209-08617 America/Managua
+NL +5222+00454 Europe/Amsterdam
+NO +5955+01045 Europe/Oslo
+NP +2743+08519 Asia/Kathmandu
+NR -0031+16655 Pacific/Nauru
+NU -1901-16955 Pacific/Niue
+NZ -3652+17446 Pacific/Auckland most locations
+NZ -4357-17633 Pacific/Chatham Chatham Islands
+OM +2336+05835 Asia/Muscat
+PA +0858-07932 America/Panama
+PE -1203-07703 America/Lima
+PF -1732-14934 Pacific/Tahiti Society Islands
+PF -0900-13930 Pacific/Marquesas Marquesas Islands
+PF -2308-13457 Pacific/Gambier Gambier Islands
+PG -0930+14710 Pacific/Port_Moresby
+PH +1435+12100 Asia/Manila
+PK +2452+06703 Asia/Karachi
+PL +5215+02100 Europe/Warsaw
+PM +4703-05620 America/Miquelon
+PN -2504-13005 Pacific/Pitcairn
+PR +182806-0660622 America/Puerto_Rico
+PS +3130+03428 Asia/Gaza Gaza Strip
+PS +313200+0350542 Asia/Hebron West Bank
+PT +3843-00908 Europe/Lisbon mainland
+PT +3238-01654 Atlantic/Madeira Madeira Islands
+PT +3744-02540 Atlantic/Azores Azores
+PW +0720+13429 Pacific/Palau
+PY -2516-05740 America/Asuncion
+QA +2517+05132 Asia/Qatar
+RE -2052+05528 Indian/Reunion
+RO +4426+02606 Europe/Bucharest
+RS +4450+02030 Europe/Belgrade
+RU +5443+02030 Europe/Kaliningrad Moscow-01 - Kaliningrad
+RU +5545+03735 Europe/Moscow Moscow+00 - west Russia
+RU +4844+04425 Europe/Volgograd Moscow+00 - Caspian Sea
+RU +5312+05009 Europe/Samara Moscow+00 - Samara, Udmurtia
+RU +4457+03406 Europe/Simferopol Moscow+00 - Crimea
+RU +5651+06036 Asia/Yekaterinburg Moscow+02 - Urals
+RU +5500+07324 Asia/Omsk Moscow+03 - west Siberia
+RU +5502+08255 Asia/Novosibirsk Moscow+03 - Novosibirsk
+RU +5345+08707 Asia/Novokuznetsk Moscow+03 - Novokuznetsk
+RU +5601+09250 Asia/Krasnoyarsk Moscow+04 - Yenisei River
+RU +5216+10420 Asia/Irkutsk Moscow+05 - Lake Baikal
+RU +6200+12940 Asia/Yakutsk Moscow+06 - Lena River
+RU +623923+1353314 Asia/Khandyga Moscow+06 - Tomponsky, Ust-Maysky
+RU +4310+13156 Asia/Vladivostok Moscow+07 - Amur River
+RU +4658+14242 Asia/Sakhalin Moscow+07 - Sakhalin Island
+RU +643337+1431336 Asia/Ust-Nera Moscow+07 - Oymyakonsky
+RU +5934+15048 Asia/Magadan Moscow+08 - Magadan
+RU +5301+15839 Asia/Kamchatka Moscow+08 - Kamchatka
+RU +6445+17729 Asia/Anadyr Moscow+08 - Bering Sea
+RW -0157+03004 Africa/Kigali
+SA +2438+04643 Asia/Riyadh
+SB -0932+16012 Pacific/Guadalcanal
+SC -0440+05528 Indian/Mahe
+SD +1536+03232 Africa/Khartoum
+SE +5920+01803 Europe/Stockholm
+SG +0117+10351 Asia/Singapore
+SH -1555-00542 Atlantic/St_Helena
+SI +4603+01431 Europe/Ljubljana
+SJ +7800+01600 Arctic/Longyearbyen
+SK +4809+01707 Europe/Bratislava
+SL +0830-01315 Africa/Freetown
+SM +4355+01228 Europe/San_Marino
+SN +1440-01726 Africa/Dakar
+SO +0204+04522 Africa/Mogadishu
+SR +0550-05510 America/Paramaribo
+SS +0451+03136 Africa/Juba
+ST +0020+00644 Africa/Sao_Tome
+SV +1342-08912 America/El_Salvador
+SX +180305-0630250 America/Lower_Princes
+SY +3330+03618 Asia/Damascus
+SZ -2618+03106 Africa/Mbabane
+TC +2128-07108 America/Grand_Turk
+TD +1207+01503 Africa/Ndjamena
+TF -492110+0701303 Indian/Kerguelen
+TG +0608+00113 Africa/Lome
+TH +1345+10031 Asia/Bangkok
+TJ +3835+06848 Asia/Dushanbe
+TK -0922-17114 Pacific/Fakaofo
+TL -0833+12535 Asia/Dili
+TM +3757+05823 Asia/Ashgabat
+TN +3648+01011 Africa/Tunis
+TO -2110-17510 Pacific/Tongatapu
+TR +4101+02858 Europe/Istanbul
+TT +1039-06131 America/Port_of_Spain
+TV -0831+17913 Pacific/Funafuti
+TW +2503+12130 Asia/Taipei
+TZ -0648+03917 Africa/Dar_es_Salaam
+UA +5026+03031 Europe/Kiev most locations
+UA +4837+02218 Europe/Uzhgorod Ruthenia
+UA +4750+03510 Europe/Zaporozhye Zaporozh'ye, E Lugansk / Zaporizhia, E Luhansk
+UG +0019+03225 Africa/Kampala
+UM +1645-16931 Pacific/Johnston Johnston Atoll
+UM +2813-17722 Pacific/Midway Midway Islands
+UM +1917+16637 Pacific/Wake Wake Island
+US +404251-0740023 America/New_York Eastern Time
+US +421953-0830245 America/Detroit Eastern Time - Michigan - most locations
+US +381515-0854534 America/Kentucky/Louisville Eastern Time - Kentucky - Louisville area
+US +364947-0845057 America/Kentucky/Monticello Eastern Time - Kentucky - Wayne County
+US +394606-0860929 America/Indiana/Indianapolis Eastern Time - Indiana - most locations
+US +384038-0873143 America/Indiana/Vincennes Eastern Time - Indiana - Daviess, Dubois, Knox & Martin Counties
+US +410305-0863611 America/Indiana/Winamac Eastern Time - Indiana - Pulaski County
+US +382232-0862041 America/Indiana/Marengo Eastern Time - Indiana - Crawford County
+US +382931-0871643 America/Indiana/Petersburg Eastern Time - Indiana - Pike County
+US +384452-0850402 America/Indiana/Vevay Eastern Time - Indiana - Switzerland County
+US +415100-0873900 America/Chicago Central Time
+US +375711-0864541 America/Indiana/Tell_City Central Time - Indiana - Perry County
+US +411745-0863730 America/Indiana/Knox Central Time - Indiana - Starke County
+US +450628-0873651 America/Menominee Central Time - Michigan - Dickinson, Gogebic, Iron & Menominee Counties
+US +470659-1011757 America/North_Dakota/Center Central Time - North Dakota - Oliver County
+US +465042-1012439 America/North_Dakota/New_Salem Central Time - North Dakota - Morton County (except Mandan area)
+US +471551-1014640 America/North_Dakota/Beulah Central Time - North Dakota - Mercer County
+US +394421-1045903 America/Denver Mountain Time
+US +433649-1161209 America/Boise Mountain Time - south Idaho & east Oregon
+US +332654-1120424 America/Phoenix Mountain Standard Time - Arizona (except Navajo)
+US +340308-1181434 America/Los_Angeles Pacific Time
+US +611305-1495401 America/Anchorage Alaska Time
+US +581807-1342511 America/Juneau Alaska Time - Alaska panhandle
+US +571035-1351807 America/Sitka Alaska Time - southeast Alaska panhandle
+US +593249-1394338 America/Yakutat Alaska Time - Alaska panhandle neck
+US +643004-1652423 America/Nome Alaska Time - west Alaska
+US +515248-1763929 America/Adak Aleutian Islands
+US +550737-1313435 America/Metlakatla Metlakatla Time - Annette Island
+US +211825-1575130 Pacific/Honolulu Hawaii
+UY -3453-05611 America/Montevideo
+UZ +3940+06648 Asia/Samarkand west Uzbekistan
+UZ +4120+06918 Asia/Tashkent east Uzbekistan
+VA +415408+0122711 Europe/Vatican
+VC +1309-06114 America/St_Vincent
+VE +1030-06656 America/Caracas
+VG +1827-06437 America/Tortola
+VI +1821-06456 America/St_Thomas
+VN +1045+10640 Asia/Ho_Chi_Minh
+VU -1740+16825 Pacific/Efate
+WF -1318-17610 Pacific/Wallis
+WS -1350-17144 Pacific/Apia
+YE +1245+04512 Asia/Aden
+YT -1247+04514 Indian/Mayotte
+ZA -2615+02800 Africa/Johannesburg
+ZM -1525+02817 Africa/Lusaka
+ZW -1750+03103 Africa/Harare
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/timeutils.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/timeutils.py
new file mode 100644
index 0000000000000000000000000000000000000000..ca5e1c6a2658005cfffaf23fd9aad567e5c59539
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/timeutils.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+
+""" p2p-streams (c) 2014 enen92 fightnight
+
+ This file contains functions related to time manipulation
+
+ Functions:
+
+ translate_months(month) -> Receives the month name in english and returns an integer corresponding to the month number. Used in parsers.
+
+"""
+
+def translate_months(month):
+ if month == "January": return 1
+ elif month == "February": return 2
+ elif month == "March": return 3
+ elif month == "April": return 4
+ elif month == "May": return 5
+ elif month == "June": return 6
+ elif month == "July": return 7
+ elif month == "August": return 8
+ elif month == "September": return 9
+ elif month == "October": return 10
+ elif month == "November": return 11
+ elif month == "December": return 12
+ else: return
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/utilities.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/utilities.py
new file mode 100644
index 0000000000000000000000000000000000000000..07108a794ebaec9445bf15b5d03b8add0cd1862c
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/utilities.py
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+
+""" p2p-streams (c) 2014 enen92 fightnight
+
+ This file contains common utilites
+
+ Functions:
+
+ handle_wait(time_to_wait,title,text,segunda='') -> Timer with dialog progress capabilities
+ clean_text(text) -> Function to remove specific characters from a string
+ getDirectorySize(directory) -> returns a directory size recursively
+ recursive_overwrite(src, dest, ignore=None) -> Copy and replace an entire directory recursively
+
+"""
+
+import xbmc,xbmcplugin,xbmcgui,xbmcaddon,re,os,shutil
+from pluginxbmc import *
+
+def handle_wait(time_to_wait,title,text,segunda=''):
+ ret = mensagemprogresso.create(' '+title)
+ secs=0
+ percent=0
+ increment = int(100 / time_to_wait)
+ cancelled = False
+ while secs < time_to_wait:
+ secs = secs + 1
+ percent = increment*secs
+ secs_left = str((time_to_wait - secs))
+ if segunda=='': remaining_display = translate(40188) + str(secs_left) + translate(40189)
+ else: remaining_display=segunda
+ mensagemprogresso.update(percent,text,remaining_display)
+ xbmc.sleep(1000)
+ if (mensagemprogresso.iscanceled()):
+ cancelled = True
+ break
+ if cancelled == True:
+ return False
+ else:
+ mensagemprogresso.close()
+ return False
+
+def clean_text(text):
+ command={'\r':'','\n':'','\t':'',' ':' ','"':'"',''':'',''':"'",'ã':'ã','&170;':'ª','é':'é','ç':'ç','ó':'ó','â':'â','ñ':'ñ','á':'á','í':'í','õ':'õ','É':'É','ú':'ú','&':'&','Á':'Á','Ã':'Ã','Ê':'Ê','Ç':'Ç','Ó':'Ó','Õ':'Õ','Ô':'Ó','Ú':'Ú'}
+ regex = re.compile("|".join(map(re.escape, command.keys())))
+ return regex.sub(lambda mo: command[mo.group(0)], text)
+
+def getDirectorySize(directory):
+ dir_size = 0
+ for (path, dirs, files) in os.walk(directory):
+ for file in files:
+ filename = os.path.join(path, file)
+ dir_size += os.path.getsize(filename)
+ return dir_size
+
+def recursive_overwrite(src, dest, ignore=None):
+ if os.path.isdir(src):
+ if not os.path.isdir(dest):
+ os.makedirs(dest)
+ files = os.listdir(src)
+ if ignore is not None:
+ ignored = ignore(src, files)
+ else:
+ ignored = set()
+ for f in files:
+ if f not in ignored:
+ recursive_overwrite(os.path.join(src, f),
+ os.path.join(dest, f),
+ ignore)
+ else:
+ shutil.copyfile(src, dest)
+ return
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/utilities.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/utilities.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..72060af55d352089b5c4f077f78696598d899307
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/utilities.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/webutils.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/webutils.py
new file mode 100644
index 0000000000000000000000000000000000000000..4ecea0759f4e1e42984ee84385546d00224c032e
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/webutils.py
@@ -0,0 +1,107 @@
+# -*- coding: utf-8 -*-
+
+""" p2p-streams (c) 2014 enen92 fightnight
+
+ This file contains web utilities
+
+ Classes:
+
+ download_tools() -> Contains a downloader, a extraction function and a remove function
+
+ Functions:
+
+ get_page_source -> Get a webpage source code through urllib2
+ mechanize_browser(url) -> Get a webpage source code through mechanize module. To avoid DDOS protections.
+ makeRequest(url, headers=None) -> check if a page is up and retrieve its source code
+ clean(text) -> Remove specific characters from the page source
+ url_isup(url, headers=None) -> Check if url is up. Returns True or False.
+
+"""
+
+import xbmc,xbmcplugin,xbmcgui,xbmcaddon,urllib,urllib2,tarfile,os,sys,re
+from pluginxbmc import *
+
+user_agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36'
+
+class download_tools():
+ def Downloader(self,url,dest,description,heading):
+ dp = xbmcgui.DialogProgress()
+ dp.create(heading,description,'')
+ dp.update(0)
+ urllib.urlretrieve(url,dest,lambda nb, bs, fs, url=url: self._pbhook(nb,bs,fs,dp))
+
+ def _pbhook(self,numblocks, blocksize, filesize,dp=None):
+ try:
+ percent = int((int(numblocks)*int(blocksize)*100)/int(filesize))
+ dp.update(percent)
+ except:
+ percent = 100
+ dp.update(percent)
+ if dp.iscanceled():
+ dp.close()
+
+ def extract(self,file_tar,destination):
+ dp = xbmcgui.DialogProgress()
+ dp.create(translate(40000),translate(40044))
+ tar = tarfile.open(file_tar)
+ tar.extractall(destination)
+ dp.update(100)
+ tar.close()
+ dp.close()
+
+ def remove(self,file_):
+ dp = xbmcgui.DialogProgress()
+ dp.create(translate(40000),translate(40045))
+ os.remove(file_)
+ dp.update(100)
+ dp.close()
+
+def get_page_source(url):
+ req = urllib2.Request(url)
+ req.add_header('User-Agent', user_agent)
+ response = urllib2.urlopen(req)
+ link=response.read()
+ response.close()
+ return link
+
+def mechanize_browser(url):
+ import mechanize
+ br = mechanize.Browser()
+ br.set_handle_equiv(True)
+ br.set_handle_redirect(True)
+ br.set_handle_referer(True)
+ br.set_handle_robots(False)
+ br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]
+ r = br.open(url)
+ html = r.read()
+ html_source= br.response().read()
+ return html_source
+
+def makeRequest(url, headers=None):
+ try:
+ if not headers:
+ headers = {'User-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0'}
+ req = urllib2.Request(url,None,headers)
+ response = urllib2.urlopen(req)
+ data = response.read()
+ response.close()
+ return data
+ except:
+ mensagemok(translate(40000),translate(40122))
+ sys.exit(0)
+
+def url_isup(url, headers=None):
+ try:
+ if not headers:
+ headers = {'User-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0'}
+ req = urllib2.Request(url,None,headers)
+ response = urllib2.urlopen(req)
+ data = response.read()
+ response.close()
+ return True
+ except: return False
+
+def clean(text):
+ command={'\r':'','\n':'','\t':'',' ':' ','"':'"',''':'',''':"'",'ã':'ã','&170;':'ª','é':'é','ç':'ç','ó':'ó','â':'â','ñ':'ñ','á':'á','í':'í','õ':'õ','É':'É','ú':'ú','&':'&','Á':'Á','Ã':'Ã','Ê':'Ê','Ç':'Ç','Ó':'Ó','Õ':'Õ','Ô':'Ó','Ú':'Ú'}
+ regex = re.compile("|".join(map(re.escape, command.keys())))
+ return regex.sub(lambda mo: command[mo.group(0)], text)
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/webutils.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/webutils.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..ce5bd676bbe90c17a200b4d5cf9163736267a1cc
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/peertopeerutils/webutils.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/resolver.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/resolver.py
new file mode 100644
index 0000000000000000000000000000000000000000..9760fc883d8eed288c5000ba20a63eb0d5520bf6
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/resolver.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+
+""" p2p-streams (c) 2014 enen92 fightnight
+
+ This file contains functions to link acestream or sopcast depending on the given argument (id or url).
+ It is used for the items in the main menu
+
+ Functions:
+
+ go_to_id(p2p_type) -> Receives the type of stream (sop or ace) and activates the keyboard to receive the next argument. This can be the sop id, the acestream hash or the sop url.
+
+"""
+
+import xbmc,sys
+from peertopeerutils.pluginxbmc import *
+import sopcast as sop
+import acestream as ace
+
+def go_to_id(p2p_type):
+ if p2p_type=='ace':
+ keyb = xbmc.Keyboard('', translate(40033))
+ keyb.doModal()
+ if (keyb.isConfirmed()):
+ search = keyb.getText()
+ if search=='': sys.exit(0)
+ else:
+ channel_id = search
+ ace.acestreams(translate(40035) + ' ( ' + str(channel_id) + ')','',str(channel_id))
+ elif p2p_type=='sop_id':
+ channel_id = xbmcgui.Dialog().numeric(0, translate(40033))
+ sop.sopstreams(translate(40035) + ' ( ' + str(channel_id) + ')','',str(channel_id))
+ elif p2p_type=='sop_url':
+ keyb = xbmc.Keyboard('sop://', translate(40034) + ' sop://')
+ keyb.doModal()
+ if (keyb.isConfirmed()):
+ search = keyb.getText()
+ if search=='': sys.exit(0)
+ else:
+ channel_id = search
+ sop.sopstreams(translate(40036) + ' ( ' + str(channel_id) + ')','',str(channel_id))
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/resolver.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/resolver.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..8ea8a08ffcdd82be6ca98ef29b42ee75ab4bc348
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/resolver.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/sopcast.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/sopcast.py
new file mode 100644
index 0000000000000000000000000000000000000000..beb13fd14138fbd5a16184db7566480c483e0469
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/sopcast.py
@@ -0,0 +1,436 @@
+# -*- coding: utf-8 -*-
+
+""" p2p-streams (c) 2014 enen92 fightnight
+
+ The code present on this file had as
+ initial input the X-Sopcast plugin code
+ by Cristi-Atlanta
+
+"""
+
+import xbmc,xbmcgui,xbmcplugin,urllib2,os,sys,subprocess,xbmcvfs,socket,re,requests,shutil
+from thread import start_new_thread
+from peertopeerutils.pluginxbmc import *
+from peertopeerutils.utilities import handle_wait
+from history import add_to_history
+
+""" Sopcast Dependent variables are listed below"""
+
+LISTA_SOP='http://www.sopcast.com/chlist.xml'
+SPSC_BINARY = "sp-sc-auth"
+LOCAL_PORT = settings.getSetting('local_port')
+VIDEO_PORT = settings.getSetting('video_port')
+BUFER_SIZE = int(settings.getSetting('buffer_size'))
+if(settings.getSetting('auto_ip')=='true'):
+ LOCAL_IP=xbmc.getIPAddress()
+else: LOCAL_IP=settings.getSetting('localhost')
+VIDEO_STREAM = "http://"+LOCAL_IP+":"+str(VIDEO_PORT)+"/"
+
+
+"""
+Addon functions related to sopcast
+
+Main functions:
+sopstreams(name,iconimage,sop) -> This function processes the id/sop url received as argument and does the magic for windows. If the OS is not windows, it sends the processed url to sopstreams_function
+sopstreams_builtin(name,iconimage,sop) -> This function processes the url received from sopstreams and does the magic for all *nix based OS's.
+
+Classes:
+SopWindowsPlayer -> Inheritance of XBMC Player class used only for Windows
+streamplayer -> Inheritance of XBMC Player class used for Linux/osx/Android
+
+Sopcast Utils:
+sop_sleep(time , spsc_pid) -> sopcast_binary pid sleep function. For all supported OS's except Windows.
+handle_wait_socket(time_to_wait,title,text,segunda='') -> Timer to check if sopcast local server has started (attempt to connect on sopcast local server port). This function is Windows only.
+break_sopcast() -> intentionally break the sopcast player in windows to avoid double sound created by the running sopcastp2p service
+osx_sopcast_downloader() -> Sopcast downloader thread to avoid curl bugs in OSX
+
+
+"""
+
+
+""" Sopcast Main functions"""
+
+def sopstreams(name,iconimage,sop):
+ if not iconimage: iconimage = os.path.join(addonpath,'resources','art','sopcast_logo.jpg')
+ if "sop://" not in sop: sop = "sop://broker.sopcast.com:3912/" + sop
+ else: pass
+ print("Starting Player Sop URL: " + str(sop))
+ labelname=name
+ if settings.getSetting('addon_history') == "true":
+ try: add_to_history(labelname, str(sop),2, iconimage)
+ except: pass
+ if not xbmc.getCondVisibility('system.platform.windows'):
+ if xbmc.getCondVisibility('System.Platform.Android') or settings.getSetting('force_android') == "true":
+ if settings.getSetting('external-sopcast') == "0":
+ versionNumber = int(xbmc.getInfoLabel("System.BuildVersion" )[0:2])
+ if versionNumber >= 13:
+ xbmc.executebuiltin('XBMC.StartAndroidActivity("org.sopcast.android","android.intent.action.VIEW","",'+sop+')')
+ else: mensagemok(translate(40000),translate(40196),translate(40197))
+ else: sopstreams_builtin(name,iconimage,sop)
+ else: sopstreams_builtin(name,iconimage,sop)
+ else:
+ cmd = ['sc','sdshow','sopcastp2p']
+ import subprocess
+ proc = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True)
+ config = True
+ for line in proc.stdout:
+ if " 1060:" in line.rstrip():
+ config = False
+ print("Sopcast configuration is not done!")
+ if config == False: mensagemok(translate(40000),translate(40180),translate(40181), translate(40182))
+ else:
+ import _winreg
+ aReg = _winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE)
+
+ #Dirty hack to break sopcast h264 codec so double sound can be avoided
+
+ try:
+ aKey = _winreg.OpenKey(aReg, r'SOFTWARE\SopCast\Player\InstallPath',0, _winreg.KEY_READ)
+ name, value, type = _winreg.EnumValue(aKey, 0)
+ codec_file = os.path.join(os.path.join(value.replace("SopCast.exe","")),'codec','sop.ocx')
+ _winreg.CloseKey(aKey)
+ if xbmcvfs.exists(codec_file): xbmcvfs.rename(codec_file,os.path.join(os.path.join(value.replace("SopCast.exe","")),'codec','sop.ocx.old'))
+ except:pass
+ aReg = _winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE)
+ aKey = _winreg.OpenKey(aReg, r'SYSTEM\CurrentControlSet\Services\sopcastp2p\Parameters', 3, _winreg.KEY_WRITE)
+ _winreg.SetValueEx(aKey,"AppParameters",0, _winreg.REG_SZ, sop)
+ _winreg.CloseKey(aKey)
+ cmd = ['sc','start','sopcastp2p']
+ import subprocess
+ proc = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True)
+ servicecreator = False
+ for line in proc.stdout:
+ print("result line: " + line.rstrip())
+ res = handle_wait_socket(int(settings.getSetting('socket_time')),translate(40000),translate(40183))
+
+ if res == True:
+ print("Server created - waiting x seconds for confirmation")
+ try: sock.close()
+ except: pass
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ handle_wait(int(settings.getSetting('stream_time')),translate(40000),translate(40184),segunda='')
+ try:
+ result = sock.connect(('127.0.0.1',8902))
+ connected = True
+ except: connected = False
+ if connected == True:
+ playlist = xbmc.PlayList(1)
+ playlist.clear()
+ listitem = xbmcgui.ListItem(labelname, iconImage=iconimage, thumbnailImage=iconimage)
+ listitem.setLabel(labelname)
+ listitem.setInfo("Video", {"Title":labelname})
+ listitem.setProperty('mimetype', 'video/x-msvideo')
+ listitem.setProperty('IsPlayable', 'true')
+ windows_sop_url = "http://127.0.0.1:8902/tv.asf"
+ listitem.setPath(path=windows_sop_url)
+ playlist.add(windows_sop_url, listitem)
+ xbmcplugin.setResolvedUrl(int(sys.argv[1]),True,listitem)
+ player = SopWindowsPlayer()
+ if int(sys.argv[1]) < 0:
+ player.play(playlist)
+ while player._playbackLock:
+ xbmc.sleep(5000)
+ else: xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(40040), 1,os.path.join(addonpath,"icon.png")))
+ else: xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(40040), 1,os.path.join(addonpath,"icon.png")))
+ print("Player reached the end")
+ cmd = ['sc','stop','sopcastp2p']
+ import subprocess
+ proc = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True)
+ servicecreator = False
+ for line in proc.stdout:
+ print("result line" + line.rstrip())
+ #dirty hack to break sopcast.exe player codec - renaming the file later
+ import _winreg
+ aReg = _winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE)
+ try:
+ aKey = _winreg.OpenKey(aReg, r'SOFTWARE\SopCast\Player\InstallPath',0, _winreg.KEY_READ)
+ name, value, type = _winreg.EnumValue(aKey, 0)
+ codec_file = os.path.join(os.path.join(value.replace("SopCast.exe","")),'codec','sop.ocx.old')
+ _winreg.CloseKey(aKey)
+ if xbmcvfs.exists(codec_file): xbmcvfs.rename(codec_file,os.path.join(os.path.join(value.replace("SopCast.exe","")),'codec','sop.ocx'))
+ except:pass
+
+
+def sopstreams_builtin(name,iconimage,sop):
+ try:
+ global spsc
+ if xbmc.getCondVisibility('System.Platform.Linux') and settings.getSetting('force_android') == "false":
+
+ if os.uname()[4] == "armv6l" or os.uname()[4] == "armv7l" or settings.getSetting('openelecx86_64') == "true":
+ if settings.getSetting('jynxbox_arm7') == "true":
+ cmd = [os.path.join(pastaperfil,'sopcast','ld-linux.so.3'),'--library-path',os.path.join(pastaperfil,'sopcast','libqemu'),os.path.join(pastaperfil,'sopcast','qemu-i386'),os.path.join(pastaperfil,'sopcast','lib/ld-linux.so.2'),"--library-path",os.path.join(pastaperfil,'sopcast',"lib"),os.path.join(pastaperfil,'sopcast','sp-sc-auth'),sop,str(LOCAL_PORT),str(VIDEO_PORT)]
+ else:
+ cmd = [os.path.join(pastaperfil,'sopcast','qemu-i386'),os.path.join(pastaperfil,'sopcast','lib/ld-linux.so.2'),"--library-path",os.path.join(pastaperfil,'sopcast',"lib"),os.path.join(pastaperfil,'sopcast','sp-sc-auth'),sop,str(LOCAL_PORT),str(VIDEO_PORT)]
+ elif settings.getSetting('openeleci386') == "true":
+ cmd = [os.path.join(pastaperfil,'sopcast','lib/ld-linux.so.2'),"--library-path",os.path.join(pastaperfil,'sopcast',"lib"),os.path.join(pastaperfil,'sopcast','sp-sc-auth'),sop,str(LOCAL_PORT),str(VIDEO_PORT)]
+ else:
+ cmd = [os.path.join(pastaperfil,'sopcast','ld-linux.so.2'),'--library-path',os.path.join(pastaperfil,'sopcast','lib'),os.path.join(pastaperfil,'sopcast',SPSC_BINARY), sop, str(LOCAL_PORT), str(VIDEO_PORT)]
+
+ elif xbmc.getCondVisibility('System.Platform.OSX'):
+ cmd = [os.path.join(pastaperfil,'sopcast','sp-sc-auth'), str(sop), str(LOCAL_PORT), str(VIDEO_PORT)]
+
+ elif xbmc.getCondVisibility('System.Platform.Android') or settings.getSetting('force_android') == "true":
+ cmd = [str(settings.getSetting('android_sopclient')), str(sop), str(LOCAL_PORT), str(VIDEO_PORT)]
+
+ print(cmd)
+
+ #Check if another instance of the sopcast executable might still be running on the same port. Attempt to connect to server and video ports giving the user the choice before creating a new subprocess
+ try:
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.connect((LOCAL_IP, int(LOCAL_PORT)))
+ sock.close()
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.connect((LOCAL_IP, int(VIDEO_PORT)))
+ sock.close()
+ existing_instance = True
+ except: existing_instance = False
+ if existing_instance == True:
+ option = xbmcgui.Dialog().yesno(translate(40000), translate(70000),translate(70001))
+ if not option:
+ if xbmc.getCondVisibility('System.Platform.Android') or settings.getSetting('force_android') == "true":
+ xbmc_user = os.getlogin()
+ procshut = subprocess.Popen(['ps','|','grep','sopclient'],shell=False,stdout=subprocess.PIPE)
+ for line in procshut.stdout:
+ match = re.findall(r'\S+', line.rstrip())
+ if match:
+ if 'sopclient' in match[-1] and len(match)>2:
+ if xbmc_user == match[0]:
+ os.system("kill " + match[1])
+ xbmc.sleep(200)
+ else:
+ os.system("su -c kill " + match[1])
+ xbmc.sleep(200)
+ elif xbmc.getCondVisibility('System.Platform.Linux'):
+ os.system("kill $(ps aux | grep '[s]p-sc-auth' | awk '{print $1}')") #openelec
+ os.system("kill $(ps aux | grep '[s]p-sc-auth' | awk '{print $2}')")
+ elif xbmc.getCondVisibility('System.Platform.OSX'):
+ os.system("kill $(ps aux | grep '[s]p-sc-auth')")
+ else: pass
+ else: pass
+
+ #opening the subprocess
+ if settings.getSetting('sop_debug_mode') == "false":
+ spsc = subprocess.Popen(cmd, shell=False, bufsize=BUFER_SIZE,stdin=None, stdout=None, stderr=None)
+ else:
+ spsc = subprocess.Popen(cmd, shell=False, bufsize=BUFER_SIZE,stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ listitem = xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage)
+ listitem.setLabel(name)
+ listitem.setInfo('video', {'Title': name})
+ url = "http://"+LOCAL_IP+":"+str(VIDEO_PORT)+"/"
+ xbmc.sleep(int(settings.getSetting('wait_time')))
+ res=False
+ counter=50
+ ret = mensagemprogresso.create(translate(40000),"SopCast",translate(40039))
+ mensagemprogresso.update(0)
+ warning = 0
+ while counter > 0 and spsc.pid:
+ if mensagemprogresso.iscanceled():
+ mensagemprogress.close()
+ try: os.kill(self.spsc_pid,9)
+ except: pass
+ break
+ xbmc.sleep(400)
+ counter -= 1
+ mensagemprogresso.update(int((1-(counter/50.0))*100))
+ try:
+ urllib2.urlopen(url)
+ counter=0
+ res=sop_sleep(200 , spsc.pid)
+ break
+ except:
+ if warning == 0:
+ print("Other instance of sopcast is still running")
+ warning += 1
+ else: pass
+
+ if res:
+ mensagemprogresso.update(100)
+ if not xbmc.getCondVisibility('System.Platform.OSX'):
+ listitem.setPath(path=url)
+ xbmcplugin.setResolvedUrl(int(sys.argv[1]),True,listitem)
+ player = streamplayer(xbmc.PLAYER_CORE_AUTO , spsc_pid=spsc.pid , listitem=listitem)
+ if int(sys.argv[1]) < 0:
+ player.play(url, listitem)
+ while player._playbackLock:
+ xbmc.sleep(500)
+ else:
+ xbmc.sleep(200)
+ video_file = os.path.join(pastaperfil,'sopcast.avi')
+ start_new_thread(osx_sopcast_downloader,())
+ handle_wait(int(settings.getSetting('stream_time_osx')),translate(40000),translate(40184),segunda='')
+ listitem.setPath(path=video_file)
+ xbmcplugin.setResolvedUrl(int(sys.argv[1]),True,listitem)
+ player = streamplayer(xbmc.PLAYER_CORE_AUTO , spsc_pid=spsc.pid , listitem=listitem)
+ player.play(video_file, listitem)
+ while player._playbackLock:
+ xbmc.sleep(500)
+ else:
+ xbmc.sleep(200)
+ xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(40040), 1,os.path.join(addonpath,"icon.png")))
+
+ except: pass
+ if settings.getSetting('sop_debug_mode') == "true":
+ try:
+ stdout, stderr = spsc.communicate()
+ print(stdout,stderr)
+ except: pass
+ try: os.kill(self.spsc_pid,9)
+ except: pass
+ xbmc.sleep(100)
+ try:os.system("killall -9 "+SPSC_BINARY)
+ except:pass
+ xbmc.sleep(100)
+ try:spsc.kill()
+ except:pass
+ xbmc.sleep(100)
+ try:spsc.wait()
+ except:pass
+ xbmc.sleep(100)
+ try: os.kill(spsc.pid,9)
+ except: pass
+ mensagemprogresso.close()
+ print("Player ended at last")
+
+
+""" Sopcast Player classes """
+
+
+class SopWindowsPlayer(xbmc.Player):
+ def __init__(self):
+ self._playbackLock = True
+ if settings.getSetting('force_dvplayer') == 'true': xbmc.Player(xbmc.PLAYER_CORE_DVDPLAYER)
+ print("Player created")
+
+ def onPlayBackStarted(self):
+ print("Player has started")
+
+ def onPlayBackStopped(self):
+ print("Player stoped")
+ self._playbackLock = False
+ import subprocess
+ cmd = ['sc','stop','sopcastp2p']
+ proc = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True)
+ for line in proc.stdout:
+ print(line.rstrip())
+
+
+ def onPlayBackEnded(self):
+ self.onPlayBackStopped()
+ print("Player ended")
+
+
+
+class streamplayer(xbmc.Player):
+ def __init__( self , *args, **kwargs):
+ self.spsc_pid=kwargs.get('spsc_pid')
+ self.listitem=kwargs.get('listitem')
+ self._playbackLock = True
+
+ def onPlayBackStarted(self):
+ mensagemprogresso.close()
+ if xbmc.Player(xbmc.PLAYER_CORE_AUTO).getPlayingFile() != "http://"+LOCAL_IP+":"+str(VIDEO_PORT)+"/" and 'sopcast' not in xbmc.Player(xbmc.PLAYER_CORE_AUTO).getPlayingFile():
+ try: os.kill(self.spsc_pid,9)
+ except: pass
+ else: pass
+
+ def onPlayBackEnded(self):
+ url = "http://"+LOCAL_IP+":"+str(VIDEO_PORT)+"/"
+ xbmc.sleep(300)
+ if os.path.exists("/proc/"+str(self.spsc_pid)) and xbmc.getCondVisibility("Window.IsActive(epg.xml)") and settings.getSetting('safe_stop')=="true":
+ if not xbmc.Player(xbmc.PLAYER_CORE_AUTO).isPlaying():
+ player = streamplayer(xbmc.PLAYER_CORE_AUTO , spsc_pid=self.spsc_pid , listitem=self.listitem)
+ player.play(url, self.listitem)
+ try:
+ xbmcvfs.delete(os.path.join(pastaperfil,'sopcast.avi'))
+ except:
+ pass
+
+ def onPlayBackStopped(self):
+ self._playbackLock = False
+ url = "http://"+LOCAL_IP+":"+str(VIDEO_PORT)+"/"
+ xbmc.sleep(300)
+ if os.path.exists("/proc/"+str(self.spsc_pid)) and xbmc.getCondVisibility("Window.IsActive(epg.xml)") and settings.getSetting('safe_stop')=="true":
+ if not xbmc.Player(xbmc.PLAYER_CORE_AUTO).isPlaying():
+ player = streamplayer(xbmc.PLAYER_CORE_AUTO , spsc_pid=self.spsc_pid , listitem=self.listitem)
+ player.play(url, self.listitem)
+ else:
+ try: os.kill(self.spsc_pid,9)
+ except: pass
+ try:
+ xbmcvfs.delete(os.path.join(pastaperfil,'sopcast.avi'))
+ except:
+ pass
+
+""" Sopcast Utils"""
+
+def handle_wait_socket(time_to_wait,title,text,segunda=''):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ connected = False
+ ret = mensagemprogresso.create(' '+title)
+ secs=0
+ percent=0
+ increment = int(100 / time_to_wait)
+ cancelled = False
+ while secs < time_to_wait:
+ try:
+ result = sock.connect(('127.0.0.1',8902))
+ connected = True
+ print("Connected to port 8902, server is working")
+ break
+ sock.close()
+ except:
+ print("Stil trying to connect")
+ secs = secs + 1
+ percent = increment*secs
+ secs_left = str((time_to_wait - secs))
+ if segunda=='': remaining_display = translate(40187) + " " + str(percent) + " %"
+ else: remaining_display=segunda
+ mensagemprogresso.update(percent,text,remaining_display)
+ xbmc.sleep(1000)
+ if (mensagemprogresso.iscanceled()):
+ cancelled = True
+ break
+ if cancelled == True:
+ return False
+ elif connected == True:
+ mensagemprogresso.close()
+ return True
+ else:
+ mensagemprogresso.close()
+ return False
+
+def sop_sleep(time , spsc_pid):
+ counter=0
+ increment=200
+ path="/proc/%s" % str(spsc_pid)
+ try:
+ while counter < time and spsc_pid>0 and not xbmc.abortRequested:
+ counter += increment
+ xbmc.sleep(increment)
+ except: return True
+
+ if counter < time: return False
+ else: return True
+
+#dirty hack to break sopcast.exe player codec to avoid double sound
+def break_sopcast():
+ if xbmc.getCondVisibility('system.platform.windows'):
+ import _winreg
+ aReg = _winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE)
+ try:
+ aKey = _winreg.OpenKey(aReg, r'SOFTWARE\SopCast\Player\InstallPath',0, _winreg.KEY_READ)
+ name, value, type = _winreg.EnumValue(aKey, 0)
+ codec_file = os.path.join(os.path.join(value.replace("SopCast.exe","")),'codec','sop.ocx.old')
+ _winreg.CloseKey(aKey)
+ if xbmcvfs.exists(codec_file): xbmcvfs.rename(codec_file,os.path.join(os.path.join(value.replace("SopCast.exe","")),'codec','sop.ocx'))
+ except:pass
+
+def osx_sopcast_downloader():
+ print VIDEO_STREAM
+ print "started osx downloader thread"
+ response = requests.get(VIDEO_STREAM, stream=True)
+ print response.headers
+ video_file = os.path.join(pastaperfil,'sopcast.avi')
+ with open(video_file, 'wb') as out_file:
+ shutil.copyfileobj(response.raw, out_file)
+ print "ended thread"
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/sopcast.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/sopcast.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..468549fa7ee90f304f4a50de46d6a11b709f2d14
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/sopcast.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/Dutch/strings.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/Dutch/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..04557ed2881a44c15912e2277cddb4560f9cb2d3
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/Dutch/strings.xml
@@ -0,0 +1,351 @@
+
+
+
+ P2P-STREAMS
+
+
+
+ Algemeen
+ [COLOR blue]Algemene configuratie[/COLOR]
+ Download modules bij opstarten
+ Forceer detectie als android
+ -Addon Website-parsers
+ Selecteer je tijdzone
+ Openelec x86_64 platform
+ Verberg porno
+ Zet vertaling van Russisch aan
+ [COLOR blue]SopCast configuraties[/COLOR]
+ Speler type
+ Sopclient android: bestand locatie
+ Auto-vind IP adres
+ Verbindings IP
+ Locale poort
+ Video poort
+ Buffer grootte
+ Wachttijd Speler
+ Debug modus
+ Server creatie timeout
+ Stream speler timeout
+ [COLOR blue]Acestream configuraties[/COLOR]
+ Acestream - speler type
+ Verbinding poort
+ Verbinding poort (speler)
+ Automatische pauze modus
+ Alternatieve locatie/commando voor Aceengine
+ Behoud op schijf gedownloade bestanden
+ Download locatie
+ Stop AceEngine als speler stopt
+ Toon Acestream engine status in videoosd
+ Debug modus
+ Stop modus voor AceStreams
+ Lijsten/Parsers
+ Lijsten
+ Zet sopcast.org officiële lijst aan
+ Parsers
+ Voer een python script uit
+ Synchroniseer parsers nu
+ Zet parser auto-synchronisatie aan
+ Synchroniseer interval voor parsers
+ Force use DVD Player for ace and sop playback
+ Alternative CMD
+ -Addon History
+ Enable addon history
+ Items to save
+ Clean addon history
+ Enter to parser list on boot
+
+
+ -Addon xml lijst
+ -Addon Favorieten
+ Speel Acestream hash / Torrent URL
+ Laad lokaal .torrent bestand
+ Speel SopCast ID
+ Speel SopCast URL
+ Niet beschikbaar voor jouw besturingssysteem!
+ [COLOR orange]Geavanceerde [/COLOR]
+ Fout!
+
+
+ Je kun alleen externe spelers gebruiken voor versies
+ hoger dan XBMC 13.0 Gotham!
+ (Windows) SopCast configuratie is niet voltooid!
+ Activeer 'Download modules bij opstarten' in de addon instellingen
+ en herstart de addon (als administrator!)
+ SopCast - Controleren of dienst gecreeërd is. Moment aub...
+ Server gecreeërd. Proberen af te spelen...
+ Kanaal initialisatie mislukt
+ Stream laden. Wacht 20 seconden aub.
+ Wachten op timeout...
+ SopCast instantie draait nog steeds op de achtergrond
+ Wil je het afspelen?
+
+
+ Starten...
+ Wacht op respons
+ Verbinden
+ Start AceStream Engine.
+ Initiële wachttijd:
+ seconden
+ Afspelen
+ Link ontvangen
+ Bestand opslaan
+ Downloaden
+ Laden...
+ Hash laden.
+ AS Engine wachten
+ Afspelen torrent.
+ Geen respons
+ Verifiëren data
+ Voor-bufferen
+ Downloaden
+ Bufferen
+
+
+ Acestream Engine
+ Statistieken
+ Actie:
+ Download:
+ Upload:
+ Seeds:
+ Downloaded:
+ Uploaded:
+
+
+ Kies je lokale torrent bestand.
+ AceStream starten(ValdikSS proxy mode)
+ Als afspelen faalt, probeer de speler te verhogen
+ timeout!
+ Acestream module niet geïnstalleerd.
+ Torrent niet beschikbaar of ongeldig.
+
+
+ Kan jouw besturingssysteem niet detecteren
+ Selecteer het uit de lijst
+ Downloaden SopCast modules.
+ Downloaden AceStream modules.
+ De addon voor Linux armv7 is experimenteel.
+ Selecteer het besturinssysteem uit de volgende lijst.
+ Downloadeng SopCast en AceStream modules.
+ Gebruik je OpenELEC x86_x64?
+ Gebruik je OpenELEC i386?
+ (Linux) Je moet de acestream-engine handmatig installeren.
+ Instructies:
+ Volg de instructies en probeer het nogmaals.
+ Kodi moet draaien als administrator.
+ om SopCast te kunnen configureren in Windows.
+ Controleren of SopCast geïnstalleerd is...
+ Klaar!
+ SopCast is niet geïnstalleerd!
+ Download het van SopCast.org en installeer het!
+ Windows gebruikers ID verkrijgen...
+ Kon geen gebruikerslijst verkrijgen
+ Starten SRVany download...
+ Downloaden SRVany...
+ Creëren 'sopcastp2p' dienst...
+ Kan dienst niet creëren!
+ Aanpassen regedit...
+ Fout: Kan regedit niet aanpassen.
+ Proberen om dienst machtigingen te verkrijgen...
+ Fout: Kan geen dienst machtigingen te verkrijgen.
+ Proberen om dienst machtigingen in te stellen...
+ Fout: Kan geen dienst machtigingen in te stellen.
+ Starten permissions file download...
+ Downloaden machtigingen bestand (Regini)...
+ Starten Regini (Regedit machtigingen)...
+ Sopcast: Alles succesvol voltooid!
+ Niet beschikbaar voor jou Mac's architectuur/string>
+ Standaard zal Sopcast de Kodi speler gebruiken.
+ Wil je een externe applicatie gebruiken?
+ Alles voltooid voor SopCast!
+ Klik ok om SopCast.apk te downloaden
+ Selecteer de map waar je apks wilt opslaan
+ Downloaden SopCast.apk
+ SopCast.apk gedownload naar map:
+ Installeer het alstublieft!
+ AppID niet gedetecteerd
+ Het is noodzakelijk om acestreamengine.apk te hebben
+ geïnstalleerd om Acestreams te kunnen draaien.
+ Het zal nu worden gedownload!
+ Downloaden AcestreamEngine.apk
+ Acestream.apk gedownload naar map:
+ Acestream: Helemaal klaar!
+ Vergeet niet dat de AcestreamEngine app
+ aan moet staan voordat je begint
+ met een Acestream!
+ Downloading AcestreamEngine bundle for Android
+ By default p2p-streams will use its included Acestream Engine
+ Do you want to download and use the app instead?
+ Do you want to download Ace Player?
+ This will enable you to use the external player option.
+ Downloading Ace Player
+ Aceplayer.apk downladed to folder:
+ Do you want to use the external player as default?
+
+
+ Verwijder ts.lock file
+ Importeer aanbevolen advancedsettings.xml
+ Maak reservekopie van advancedsettings.xml
+ Verwijder advancedsettings.xml
+ Herstel reservekopie van advancedsettings.xml bestand
+ Cachemembuffersize huidige waarde [
+ Poort
+ VOD buffer (on-demand) (s)
+ Live buffer (live streams) (s)
+ Download limiet (Kb/s) (0=geen limiet)
+ Upload limiet (Kb/s) (0=geen limiet)
+ Max aantal verbindingen (0=geen limiet)
+ Max aantal verbindingen per stream (0=geen limiet)
+ Opschonen engine cache
+ Graag configuratie opnieuw down om de nieuwe modules te verkrijgen
+ Selecteer een van de advancedsettings.xml
+ Advancedsettings.xml gedownload
+ Xml is geïmporteerd. Herstart Kodi aub!
+ Reservekopie maken gelukt. Herstart Kodi aub!
+ Herstellen reservekopie gelukt. Herstart Kodi aub!
+ XML verwijderd. Herstart Kodi aub!
+ Vul een geheel getal in
+ Instelling is gewijzigd
+ Ongeldige waarde. Alleen gehele getallen toegestaan!
+ ts.lock verwijderen gelukt
+ Do you want to change your Acestream cache folder?
+ Choose new Acestream cache folder
+ Cachefolder location
+ P2P-Streams force stop hook:
+ Apply costum stop function
+ Do you want to replace the current skin stop button by our costumized stop function?
+ Current skin:
+ This will only apply to the current skin
+ If it gets updated you might need to repeat this procedure
+ If you uninstall this addon you need to revert those changes otherwise you will break the Kodi default stop function!
+ Are you sure you want to continue?
+ Do you want to map a button on your remote to the stop function?
+ Cache allocation
+
+
+ Press the key you want to assign now
+ Timeout in %.0f seconds...
+
+
+ [B][COLOR orange]Sopcast.org lijst[/COLOR][/B] (http://sopcast.org/chlist.xml)
+ [B]+ Andere lijst toevoegen[/B]
+ Selecteer een lijst type:
+ Remote
+ Lokaal
+ Selecteer jouw xml lijst:
+ Geef jouw lijst een naam.
+ Lijst succesvol toegevoegd
+ Voer de lijst url in
+ Geen geldige url
+ Lijst succesvol verwijderd!
+
+
+ Je hebt geen favorieten!
+ Sucessvol toegevoegd aan favorieten
+ Sucessvol verwijderd uit favorieten
+ Manually add a favourite
+ Insert ace or sop url
+ Insert a name for your channel
+
+
+ Toevoegen aan addon favorieten
+ Verwijder uit addon favorieten
+ Verwijder lijst
+ Verwijder parser
+ Synchroniseer parser code
+
+
+ Over:
+ seconden
+
+
+ Inhoud module uitpakken. Moment aub.
+ Verwijderen bestanden.
+ Niet in staat url te verkrijgen.
+
+
+ Voer een ID in
+ Voer een URL in
+ Directe ID
+ D URL
+
+
+ [B]Voeg een website-parser plugin toe[/B]
+ Plugin locatie?
+ Selecteer de tarball (.tar.gz)
+ Parser successvol geïnstalleerd
+ Er is een fout opgetreden tijdens installeren van de parser
+ Voer de plugin url in
+ Niet geldig. tar.gz suffix is vereist.
+ Downloaden parser
+ Parser succesvol verwijderd
+ Synchroniseren parsers
+ Controleren...
+ Geüpdate!
+ Is al laatste versie.
+ Fout: geen geldige url voor parser repo
+ Updaten...
+ Parser succesvol geüpdate!
+ Downloaden script...
+ Script succesvol uitgevoerd
+ Any plugins you may find here are 3rd party.
+ They are not developed nor part of the core addon.
+ Do not ask for support regarding any of them.
+ All parser traces deleted
+ Remove all parser traces
+
+
+ *Nu Live*
+ Amerikaans Football
+ Voetbal
+ Basketbal
+ Ijshockey
+ Honkbal
+ Tennis
+ Motor Sport
+ Rugby
+ Golf
+ Cricket
+ Wielrennen
+ Overige
+ Acestream of Sopcast links niet gevonden.
+ Stream lijst
+ Niet gevonden.
+ Engels
+ Sport
+ Nieuws
+ Trouwen
+ Algemeen
+ Onderwijs
+ CIS
+ Mannen Kanalen
+ Winkelen
+ Gereserveerd
+ Donetsk
+ Regionaal
+ Porno
+ Sec.21 TV
+ Oekraïense kanalen
+ Kinderen
+ Films
+ Nacht gerelateerd
+ Europa
+ Ukr
+ Muziek
+ Religie
+ Feesten
+ Oekraïne
+ Januari
+ Februari
+ Maart
+ April
+ Mei
+ Juni
+ Juli
+ Augustus
+ September
+ Oktober
+ November
+ December
+ Dag:
+
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/English/strings.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/English/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9f81f297b33d686b279788d6e4f68d3aa7114e53
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/English/strings.xml
@@ -0,0 +1,354 @@
+
+
+
+ P2P-STREAMS
+
+
+
+ General
+ [COLOR blue]General configurations[/COLOR]
+ Download modules on boot
+ Force detect as android
+ -Addon Website-parsers
+ Select your timezone
+ Openelec x86_64 platform
+ Hide porn
+ Enable russian string translation
+ [COLOR blue]SopCast configurations[/COLOR]
+ Player type
+ Sopclient android: file location
+ Auto-find IP address
+ Connection IP
+ Local port
+ Video port
+ Buffer size
+ Player waiting time
+ Debug mode
+ Server creation timeout
+ Stream player timeout
+ [COLOR blue]Acestream configurations[/COLOR]
+ Acestream - player type
+ Connection port
+ Connection port (player)
+ Automatic pause mode
+ Alternative path/cmd for Aceengine
+ Keep downloaded files in disk
+ Download path
+ Kill AceEngine if player stops
+ Show Acestream engine status on videoosd
+ Debug mode
+ Stop mode for AceStreams
+ Lists/Parsers
+ Lists
+ Enable sopcast.org official list
+ Parsers
+ Run a python script
+ Sync parsers now
+ Enable parser auto-sync
+ Sync interval for parsers
+ Force use DVD Player for ace and sop playback
+ Alternative CMD
+ -Addon History
+ Enable addon history
+ Items to save
+ Clean addon history
+ Enter to parser list on boot
+
+
+ -Addon xml lists
+ -Addon Favourites
+ Play Acestream hash / Torrent URL
+ Load local .torrent file
+ Play SopCast ID
+ Play SopCast URL
+ Not available for your OS!
+ [COLOR orange]Advanced tools menu[/COLOR]
+ An error has occured
+
+
+ You can only use external players for versions
+ above XBMC 13.0 Gotham!
+ (Windows) SopCast configuration was not done!
+ Activate 'Download modules on boot' in the addon settings
+ and re-enter the addon (as administrator!)
+ SopCast - Checking if service was created. Please wait...
+ Server created. Attempting to play...
+ Channel initialization failed
+ Loading stream. Please wait till 20 seconds.
+ Waiting till timeout...
+ SopCast instance still running on the background
+ Do you want to play it?
+
+
+ Starting...
+ Awaiting response
+ Connecting
+ Starting AceStream Engine.
+ Inital wait:
+ seconds
+ Playing
+ Link received
+ Saving file
+ Downloading
+ Loading...
+ Loading hash.
+ AS Engine waiting
+ Playing torrent.
+ No response
+ Verifying data
+ Pre-buffering
+ Downloading
+ Buffering
+
+
+ Acestream Engine
+ Stats
+ Action:
+ Download:
+ Upload:
+ Seeds:
+ Downloaded:
+ Uploaded:
+
+
+ Choose your local torrent file.
+ Starting AceStream (ValdikSS proxy mode)
+ If the playback fails try to increase the player
+ timeout!
+ Acestream module not installed.
+ Torrent not available or invalid.
+
+
+ Unable to detect your operating system
+ Select it from the list
+ Downloading SopCast modules.
+ Downloading AceStream modules.
+ The addon for Linux armv7 is experimental.
+ Select the OS from the next list.
+ Downloading SopCast and AceStream modules.
+ Are you using OpenELEC x86_x64?
+ Are you usng OpenELEC i386?
+ (Linux) You need to install acestream-engine manually.
+ Tutorial:
+ Follow the tutorial and try again.
+ Kodi has to be running as administrator.
+ to configure SopCast in Windows.
+ Checking if SopCast is installed...
+ Done!
+ SopCast is not installed!
+ Download it from SopCast.org and install it!
+ Getting Windows user ID's...
+ Unable to get users list
+ Starting SRVany download...
+ Downloading SRVany...
+ Creating 'sopcastp2p' service...
+ Unable to create the service!
+ Modifying regedit...
+ Error: Unable to modify regedit.
+ Trying to get service permissions...
+ Error: Unable to change permissions.
+ Trying to set service permissions...
+ Error: Unable to change service permissons.
+ Starting permissions file download...
+ Downloading permissions file (Regini)...
+ Running Regini (Regedit permissions)...
+ Sopcast: All done sucessfully!
+ Not available for your Mac's architecture
+ By default Sopcast will use the Kodi player.
+ Do you want to use an external application?
+ All done for SopCast!
+ Click ok to download SopCast.apk
+ Select the folder to save the apks
+ Downloading SopCast.apk
+ SopCast.apk downloaded to folder:
+ Please install it!
+ AppID not detected
+ It is necessary to have acestreamengine.apk
+ installed to run Acestreams.
+ It will be downloaded now!
+ Downloading AcestreamEngine.apk
+ Acestream.apk downloaded to folder:
+ Acestream: All done!
+ Don't forget AcestreamEngine app
+ should be running before starting
+ any Acestream!
+ Downloading AcestreamEngine bundle for Android
+ By default p2p-streams will use its included Acestream Engine
+ Do you want to download and use the app instead?
+ Do you want to download Ace Player?
+ This will enable you to use the external player option.
+ Downloading Ace Player
+ Aceplayer.apk downladed to folder:
+ Do you want to use the external player as default?
+
+
+
+ Remove ts.lock file
+ Import recommended advancedsettings.xml
+ Backup advancedsettings.xml
+ Delete advancedsettings.xml
+ Recover backup of the advancedsettings.xml file
+ Cachemembuffersize current value [
+ Port
+ VOD buffer (on-demand) (s)
+ Live buffer (live streams) (s)
+ Download limit (Kb/s) (0=no limit)
+ Upload limit (Kb/s) (0=no limit)
+ Max number of connections (0=no limit)
+ Max number of connections per stream (0=no limit)
+ Clean engine cache
+ Please re-do the configuration to get the new modules
+ Select one of the advancedsettings.xml
+ Downloaded advancedsettings.xml
+ Xml has been imported. Please restart Kodi!
+ Backup sucessfull. Please restart Kodi!
+ Backup recovered sucessfully. Restart Kodi!
+ XML deleted. Please restart Kodi!
+ Insert an integer value
+ Setting changed successfully
+ Invalid value. Only integers allowed!
+ ts.lock remove successfully
+ Do you want to change your Acestream cache folder?
+ Choose new Acestream cache folder
+ Cachefolder location
+ P2P-Streams force stop hook:
+ Apply costum stop function
+ Do you want to replace the current skin stop button by our costumized stop function?
+ Current skin:
+ This will only apply to the current skin
+ If it gets updated you might need to repeat this procedure
+ If you uninstall this addon you need to revert those changes otherwise you will break Kodi's default stop function!
+ Are you sure you want to continue?
+ Do you want to map a button on your remote to the stop function?
+ Cache allocation
+
+
+ Press the key you want to assign now
+ Timeout in %.0f seconds...
+
+
+
+ [B][COLOR orange]Sopcast.org list[/COLOR][/B] (http://sopcast.org/chlist.xml)
+ [B]+ Add another list[/B]
+ Select one list type:
+ Remote
+ Local
+ Select your xml list:
+ Give a name to the list.
+ List added successfully
+ Input the list url
+ Not a valid url
+ List removed successfully!
+
+
+ You don't have favourites!
+ Sucessfully added to favourites
+ Sucessfully removed from favourites
+ Manually add a favourite
+ Insert ace or sop url
+ Insert a name for your channel
+
+
+ Add to addon favourites
+ Remove from addon favourites
+ Remove list
+ Remove parser
+ Sync parser code
+
+
+ Left:
+ seconds
+
+
+ Extracting module contents. Please wait.
+ Removing files.
+ Unable to get the xml.
+
+
+ Input an ID
+ Input a URL
+ Direct ID
+ Direct URL
+
+
+ [B]Add a Website-Parser plugin [/B]
+ Plugin location?
+ Select the tarball (.tar.gz)
+ Parser successfully installed
+ An error has ocurred installing the parser
+ Input the plugin url
+ Not valid. tar.gz extension is required.
+ Downloading parser
+ Parser removed sucessfully
+ Syncing parsers
+ Checking...
+ Updated!
+ Already up to date.
+ Error: not a valid url for the parser repo
+ Updating...
+ Parser sucessfully updated!
+ Downloading script...
+ Script sucessfully executed
+ Any plugins you may find here are 3rd party.
+ They are not developed nor part of the core addon.
+ Do not ask for support regarding any of them.
+ All parser traces deleted
+ Remove all parser traces
+
+
+
+ *Now Live*
+ American Football
+ Football
+ Basketball
+ Ice Hockey
+ Baseball
+ Tennis
+ Motor Sports
+ Rugby
+ Golf
+ Cricket
+ Cycling
+ Other
+ Acestream or Sopcast links not found.
+ Stream list
+ Not found.
+ English
+ Sport
+ News
+ Wedding
+ Generic
+ Educational
+ CIS
+ Male Channels
+ Shopping
+ Reserved
+ Donetsk
+ Regional
+ Porn
+ Sec.21 TV
+ Ukrainian channels
+ Kids
+ Movies
+ Night related
+ Europe
+ Ukr
+ Music
+ Religion
+ Party
+ Ukraine
+ January
+ February
+ March
+ April
+ May
+ June
+ July
+ August
+ September
+ October
+ November
+ December
+ Day:
+
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/Italian/strings.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/Italian/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fb26f9bd564458d47f5f2bac064504f2d4375825
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/Italian/strings.xml
@@ -0,0 +1,351 @@
+
+
+
+P2P-Streams
+
+
+
+ Generale
+ [COLOR blue]Impostazioni generali[/COLOR]
+ Scarica moduli all'avvio
+ Forza rilevamento come Android
+ Parser
+ Fuso orario
+ Piattaforma x86_64 OpenELEC
+ Nascondi porno
+ Abilita traduzione stringhe in russo
+ [COLOR blue]Configurazione SopCast[/COLOR]
+ Tipo player
+ Percorso SopCast Client per Android
+ Ricerca indirizzo IP automatica
+ Connessione IP
+ Porta locale
+ Porta video
+ Dimensione del buffer
+ Tempo di attesa player
+ Modalità debug
+ Timeout creazione server
+ Timeout player
+ [COLOR blue]Configurazione AceStream[/COLOR]
+ Tipo player
+ Porta
+ Porta (player)
+ Modalità pausa automatica
+ Percorso/comando alternativo per AceStream Engine
+ Mantenere i file scaricati
+ Percorso download
+ Chiudi AceStream Engine se il player si ferma
+ Mostra stato AceStream Engine a video
+ Modalità debug
+ Modalità chiusura AceStream
+ Elenchi/Parser
+ Elenchi
+ Abilita elenchi ufficiali sopcast.org
+ Parser
+ Esegui script python
+ Sincronizza parser
+ Abilita sincronizzazione automatica parser
+ Intervallo di sincronizzazione parser
+ Forza l'utilizzo di DVDPlayer per la riproduzione degli stream
+ CMD alternativo
+ Storico stream
+ Abilita storico stream
+ Numero di elementi da salvare
+ Cancella storico stream
+ Accedi direttamente alla lista dei parsers
+
+
+ Elenchi xml
+ Preferiti
+ Riproduci AceStream hash / URL torrent
+ Carica file torrent locale
+ Riproduci SopCast ID
+ Riproduci SopCast URL
+ Non disponibile per il tuo sistema operativo!
+ [COLOR orange]Menu strumenti avanzati[/COLOR]
+ Si è verificato un errore
+
+
+ Si possono utilizzare player esterni solo dalla versione
+ 13.0 (Gotham) in avanti!
+ (Windows) SopCast non è stato configurato!
+ Attiva 'Scarica moduli all'avvio' nelle impostazioni generali
+ e rientra nell'addon (come Amministratore)
+ Verifica se il servizio è stato creato. Attendere prego...
+ Server creato. Tentativo di riproduzione...
+ Inizializzazione canale fallita
+ Caricamento stream. Si prega di attendere fino a 20 secondi.
+ Attesa sino al timeout...
+ Istanza di SopCast ancora in esecuzione in background
+ Vuoi riprodurre lo stream?
+
+
+ Avvio...
+ Attesa risposta...
+ Collegamento...
+ Avvio AceStream Engine...
+ Attesa iniziale:
+ secondi
+ Riproduzione
+ Link ricevuto
+ Salvataggio file...
+ Scaricamento...
+ Caricamento in corso...
+ Caricamento hash...
+ Attesa AceStream Engine...
+ Riproduzione torrent
+ Nessuna risposta
+ Verifica dati...
+ Pre-buffering...
+ Scaricamento...
+ Buffering...
+
+
+ AceStream Engine
+ Statistiche
+ Azione:
+ Download:
+ Upload:
+ Seeds:
+ Scaricato:
+ Caricato:
+
+
+ Scegli file torrent locale
+ Avvio AceStream (modalità proxy ValdikSS)
+ Se la riproduzione fallisce prova ad aumentare
+ il timeout del lettore!
+ Modulo AceStream non installato
+ Torrent non disponibile o non valido
+
+
+ Impossibile rilevare il sistema operativo
+ Selezionare dall'elenco
+ Scaricamento moduli SopCast...
+ Scaricamento moduli AceStream...
+ L'addon per Linux ARMv7 è sperimentale.
+ Selezionare il sistema operativo dall'elenco seguente.
+ Scaricamento moduli SopCast e AceStream...
+ Stai usando OpenELEC x86_x64?
+ Stai usando OpenELEC i386?
+ (Linux) Devi installare manualmente AceStream Engine.
+ Tutorial:
+ Segui il tutorial e riprova.
+ Kodi deve essere in esecuzione come Amministratore.
+ Configurare SopCast in Windows.
+ Verifica se è installato SopCast.
+ Fatto!
+ SopCast non è installato!
+ Scarica SopCast da sopcast.org ed installalo!
+ Ottengo ID utente di Windows...
+ Impossibile ottenere l'elenco degli utenti
+ Avvio scaricamento SRVany...
+ Scarico SRVany...
+ Creazione del servizio 'sopcastp2p'...
+ Impossibile creare il servizio!
+ Modifica regedit...
+ Errore: Impossibile modificare regedit.
+ Ottenimento permessi di servizio...
+ Errore: Impossibile modificare i permessi.
+ Impostazione autorizzazioni di servizio...
+ Errore: Impossibile cambiare autorizzazioni di servizio.
+ Avvio scaricamento permessi file...
+ Scaricamento permessi file (regini)...
+ Esecuzione regini (permessi regedit) ...
+ SopCast: tutto fatto!
+ Non disponibile per l'architettura Mac
+ Come impostazione predefinita, SopCast utilizzerà il player Kodi.
+ Vuoi utilizzare un'applicazione esterna?
+ Tutto fatto per SopCast!
+ Fare clic su OK per scaricare SopCast.apk
+ Selezionare la cartella in cui salvare gli apk
+ Scaricamento SopCast.apk...
+ SopCast.apk scaricato nella cartella:
+ Si prega di installarlo!
+ AppID non rilevato
+ E' necessario avere AceStreamEngine.apk
+ installato per far funzionare AceStream.
+ Verrà scaricato ora!
+ Scaricare AceStreamEngine.apk
+ AceStreamEngine.apk scaricato nella cartella:
+ Tutto fatto per AceStream!
+ Non dimenticare che l'applicazione AceStream Engine
+ deve essere in esecuzione prima di iniziare
+ qualsiasi stream!
+ Scaricamento pacchetto AceStream Engine per Android
+ Per impostazione predefinita P2P-Streams utilizzerà il proprio AceStream Engine
+ Vuoi invece scaricare ed utilizzare l'apk?
+ Vuoi scaricare Ace Player?
+ Questo abiliterà l'opzione di utilizzo di un player esterno.
+ Scaricamento Ace Player
+ Aceplayer.apk scaricato nella cartella:
+ Vuoi utilizzare il player esterno come impostazione predefinita?
+
+
+ Rimuovere il file ts.lock
+ Importa il file advancedsettings.xml raccomandato
+ Backup del file advancedsettings.xml
+ Elimina il file advancedsettings.xml
+ Recuperare backup del file advancedsettings.xml
+ Valore attuale Cachemembuffersize [
+ Porta
+ VOD buffer (on-demand) (s)
+ Live buffer (live streams) (s)
+ Limite in download (Kb/s) (0 = nessun limite)
+ Limite in upload (Kb/s) (0 = nessun limite)
+ Numero massimo di connessioni (0 = nessun limite)
+ Numero massimo di connessioni per stream (0 = nessun limite)
+ Cancella cache
+ Effettuare nuovamente la configurazione per ottenere i nuovi moduli
+ Seleziona uno degli advancedsettings.xml
+ advancedsettings.xml scaricato
+ XML importato. Riavviare Kodi!
+ Backup riuscito. Riavviare Kodi!
+ Backup recuperato con successo. Riavviare Kodi!
+ XML cancellato. Riavviare Kodi!
+ Inserire un valore intero
+ Impostazione cambiata con successo
+ Valore non valido. Solo numeri interi ammessi!
+ ts.lock rimosso con successo
+ Vuoi cambiare la cartella di cache di AceStream?
+ Scegli la nuova cartella di cache per AceStream
+ Percorso cartella di cache
+ P2P-Streams funzione di stop forzata:
+ Applica funzione di stop personalizzata
+ Vuoi sostituire il pulsante di stop della skin corrente con la funzione di stop personalizzata?
+ Skin corrente:
+ La modifica verrà applicata solo alla skin corrente
+ In caso di aggiornamento potrebbe essere necessario ripetere questa procedura
+ Se disinstalli questo addon è necessario annullare le modifiche effettuate altrimenti la funzione di stop di Kodi non funzionerà!
+ Vuoi continuare?
+ Vuoi configurare un pulsante del telecomando per eseguire la funzione di stop?
+ Allocazione cache
+
+
+ Premi ora il pulsante che vuoi configurare
+ Timeout in %.0f secondi...
+
+
+ [B][COLOR orange]Elenco sopcast.org[/COLOR][/B] (http://sopcast.org/chlist.xml)
+ [B]+ Aggiungi un altro elenco[/B]
+ Selezionare un tipo di elenco:
+ Remoto
+ Locale
+ Seleziona elenco xml:
+ Dare un nome all'elenco.
+ Elenco aggiunto con successo
+ Inserisci URL dell'elenco
+ URL non valido
+ Elenco rimosso con successo!
+
+
+Non ci sono preferiti!
+Inserito con successo nei preferiti
+Rimosso con successo dai preferiti
+Aggiungi manualmente un preferito
+Inserire un URL AceStream o SopCast
+Inserire un nome per il canale
+
+
+Aggiungi ai preferiti dell'addon
+Rimuovi dai preferiti dell'addon
+Rimuovi elenco
+Rimuovi parser
+Sincronizza codice parser
+
+
+Attesa:
+ secondi
+
+
+Estrazione contenuti del modulo. Attendere prego...
+Rimozione dei file...
+Impossibile ottenere l'XML.
+
+
+Inserire ID
+Inserire URL
+ID diretto
+URL diretto
+
+
+[B]Aggiungi un parser[/B]
+Percorso del parser
+Selezionare il file .tar.gz
+Parser installato con successo
+Errore durante l'installazione del parser
+Inserire URL del parser
+Non valido. E' richiesta l'estensione tar.gz.
+Scaricamento parser...
+Parser rimosso con successo
+Sincronizzazione parser...
+Verifica...
+Aggiornato!
+Nessun aggiornamento.
+Errore: URL non valido per la repository del parser
+Aggiornamento...
+Parser aggiornato con successo!
+Scaricamento script...
+Script eseguito con successo
+Ogni parser presente è fornito da terze parti.
+Non è stato sviluppato e non fa parte di questo addon.
+Non richiedere supporto per nessuno di essi.
+Tutti i parser sono stati eliminati
+Elimina tutti i parser
+
+
+* Ora Live *
+Football Americano
+Calcio
+Pallacanestro
+Hockey su ghiaccio
+Baseball
+Tennis
+Motori
+Rugby
+Golf
+Cricket
+Ciclismo
+Altri
+Collegamenti AceStream o SopCast non trovati.
+Elenco stream
+Non trovato.
+Inglese
+Sport
+Notizie
+Nozze
+Generico
+Formazione
+CIS
+Canali Uomini
+Shopping
+Riservati
+Donetsk
+Regionale
+Porno
+Sec.21 TV
+Canali Ucraini
+Bambini
+Film
+Notturni
+Europa
+Ukr
+Musica
+Religione
+Partito
+Ucraina
+Gennaio
+Febbraio
+Marzo
+Aprile
+Maggio
+Giugno
+Luglio
+Agosto
+Settembre
+Ottobre
+Novembre
+Dicembre
+Giorno:
+
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/Portuguese (Brazil)/strings.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/Portuguese (Brazil)/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6a5621828e2e378f456448525a8d4ea121d71877
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/Portuguese (Brazil)/strings.xml
@@ -0,0 +1,351 @@
+
+
+
+ P2P-STREAMS
+
+
+
+ Geral
+ [COLOR blue]Configurações Gerais[/COLOR]
+ Transferir modulos no arranque
+ Forçar detecção android
+ -Website-parsers do addon
+ Seleccione a sua timezone
+ Plataforma openelec x86_64
+ Esconder Porno
+ Activar traducao de categorias russas
+ [COLOR blue]Configurações de Sopcast[/COLOR]
+ Tipo de player
+ Sopclient android: localização do ficheiro
+ Encontrar IP Automaticamente
+ IP da connexão
+ Porta Local
+ Porta de Video
+ Espaco de Buffer
+ Tempo de espera antes de iniciar player
+ Modo de Debug
+ Timeout criação do servidor
+ Tempo de espera para stream
+ [COLOR blue]Configurações de Acestream[/COLOR]
+ Acestream - tipo de player
+ Porta de conexão
+ Porta de conexão (player)
+ Pausa Automática
+ Caminho alternativo para Aceengine
+ Manter ficheiro transferido no disco
+ Caminho para transferência
+ Terminar AceEngine se o player estiver parado
+ Mostrar status da Acestream Engine no videoosd
+ Modo de debug
+ Modo de stop para AceStreams
+ Listas/Parsers
+ Listas
+ Activar a lista oficial do sopcast.org
+ Parsers
+ Executar script python
+ Sincronizar parsers agora
+ Activar auto-sincronizacao de parsers
+ Intervalo na pesquisa de alterações
+ Forçar utilização do DVD Player
+ Comando alternativo
+ -Histórico do addon
+ Activar histórico do addon
+ Items a guardar
+ Apagar histórico do addon
+ Entrar na lista de parsers automaticamente
+
+
+ -Listas xml do addon
+ -Favoritos do addon
+ Ir para hash Acestream / Torrent URL
+ Carregar ficheiro .torrent local
+ Ir para ID Sopcast
+ Ir para URL Sopcast
+ Sistema Operativo incompatível!
+ [COLOR orange]Menu de opções avançadas[/COLOR]
+ Ocorreu um erro
+
+
+ Só pode usar o player externo com versões
+ superiores a XBMC 13.0 Gotham!
+ (Windows) Não fez a configuração do SopCast!
+ Active 'Transferir módulos no arranque' nas definições do addon
+ e entre novamente (como administrador!)
+ SopCast - Verificando se o servidor foi criado. Aguarde...
+ Servidor foi criado. Tentando reproduzir...
+ Falhou a inicializacao do canal
+ A carregar stream. Aguarde até 20 segundos.
+ Esperando o timeout...
+ Sopcast está ainda a correr no background
+ Deseja retomar a emissão anterior?
+
+
+ Iniciando...
+ À espera de resposta
+ Connectando
+ A iniciar módulo AceStream.
+ Espera inicial:
+ segundos
+ Reproduzindo
+ Link recebido
+ Guardando ficheiro
+ Transferindo
+ A carregar...
+ A carregar hash.
+ TS Engine à espera
+ A reproduzir torrent.
+ Sem resposta
+ Verificando dados
+ Pre-buffering
+ Downloading
+ Buffering
+
+
+ Acestream Engine
+ Estatisticas
+ Accao:
+ Download:
+ Upload:
+ Seeds:
+ Downloaded:
+ Uploaded:
+
+
+ Seleccione o ficheiro torrent local.
+ Iniciando AceStream (modo ValdikSS proxy)
+ Se a reprodução falhar aumente o timeout
+ do player!
+ O módulo acestream não está instalado.
+ Torrent não disponível ou inválido.
+
+
+ Não conseguiu detectar o seu sistema operativo
+ Seleccione-o da lista
+ A transferir módulos Sopcast.
+ A transferir módulos Acestream.
+ O addon para Linux armv7 é experimental.
+ Escolha o OS da seguinte lista.
+ A transferir módulos SopCast e Acestream.
+ Está a usar o OpenELEC x86_x64?
+ Está a usar o OpenELEC i386?
+ (Linux) Tem de instalar a acestream-engine manualmente.
+ Tutorial:
+ Siga o tutorial e tente de novo.
+ Necessita de iniciar o Kodi como administrador.
+ para configurar o sopcast no Windows.
+ Verificando se o SopCast está instalado...
+ Concluido!
+ O SopCast não está instalado no seu pc!
+ Faça o download em SopCast.org e instale!
+ Obtendo ID's dos users do Windows...
+ Não foi possível obter lista de utilizadores
+ Começando o download do SRVany...
+ A transferir SRVany...
+ Criando serviço 'sopcastp2p'...
+ Não foi possível criar o serviço!
+ Modificando o regedit...
+ Erro: Não conseguiu modificar o regedit.
+ Tentando obter as permissões do serviço...
+ Erro: Não conseguiu modificar as permissões.
+ Tentando definir permissões do serviço...
+ Erro: Não conseguiu modificar permissões do serviço.
+ A começar o download do ficheiro de permissões...
+ A transferir ficheiro de permissões (Regini)...
+ A executar Regini (permissões Regedit)...
+ Sopcast: Tudo concluído com sucesso!
+ Não está disponível para a arquitectura do seu Mac
+ Por defeito o Sopcast usa o player do Kodi.
+ Deseja usar uma aplicação externa?
+ Tudo concluído para o SopCast!
+ Clique ok para transferir a SopCast.apk
+ Seleccione uma pasta para transferir os apks
+ Transferindo SopCast.apk
+ SopCast.apk transferida para a pasta:
+ Por favor instale!
+ AppID não detectada
+ É necessário ter o acestreamengine.apk
+ instalado para reproduzir Acestreams.
+ Será transferida agora!
+ Transferindo AcestreamEngine.apk
+ Acestream.apk transferida para a pasta:
+ Acestream: Tudo concluído!
+ Não se esqueça que a AcestreamEngine app
+ deve estar em execução antes de lançar
+ qualquer acestream!
+ A transferir módulo AcestreamEngine para Android
+ Por defeito o addon irá utilizar o seu próprio módulo AcestreamEngine.
+ Deseja transferir e usar a aplicação externa oficial?
+ Deseja transferir o Ace Player?
+ Desta forma poderá utilizar a opção de player externo.
+ Transferindo Ace Player...
+ Aceplayer.apk transferido para a pasta:
+ Deseja utilizar o player externo como opção padrão?
+
+
+ Remover ficheiro ts.lock
+ Importar advancedsettings.xml recomendadas
+ Backup da configuração actual do ficheiro advancedsettings.xml
+ Eliminar o ficheiro advancedsettings.xml
+ Recuperar backup do ficheiro advancedsettings.xml
+ Valor actual do Cachemembuffersize [
+ Porta
+ VOD buffer (streams on-demand) (s)
+ Live buffer (streams em directo) (s)
+ Limite de Download (Kb/s) (0=ilimitado)
+ Limite de Upload (Kb/s) (0=ilimitado)
+ Número máximo de conexões (0=ilimitado)
+ Número máximo de conexões por stream (0=ilimitado)
+ Eliminar cache da AceStream Engine
+ Por favor repita a configuração para obter os novos módulos
+ Seleccione o advancedsettings.xml desejado
+ Transferindo advancedsettings.xml
+ Xml importado. Por favor reinicie o Kodi!
+ Backup com sucesso. Por favor reinicie o Kodi!
+ Backup recuperado com sucesso. Reinicie o Kodi!
+ O XML foi apagado. Por favor reinicie o Kodi!
+ Introduza um valor inteiro
+ Definicao alterada com sucesso
+ Valor inválido. Apenas valores inteiros!
+ ts.lock removido com sucesso
+ Deseja alterar a pasta de cache?
+ Escolha a nova pasta
+ Pasta cache da AceStream engine
+ P2P-Streams função de forçar stop:
+ Aplicar função stop costumizada
+ Deseja substituir o botão de stop do tema pela nossa função costumizada?
+ Tema actual:
+ Esta funcionalidade apenas se aplica ao tema actual
+ Se este for actualizado necessitará de repetir este procedimento
+ Se remover o addon precisará de reverter estas alterações. Caso contrário, a função de stop do xbmc não irá funcionar.
+ Tem a certeza que deseja continuar?
+ Deseja mapear um botão no seu telecomando para a função de stop?
+ Alocação de cache
+
+
+ Pressione o botão que deseja atribuir
+ Timeout em %.0f segundos...
+
+
+ [B][COLOR orange]Lista sopcast.org[/COLOR][/B] (http://sopcast.org/chlist.xml)
+ [B]+ Adicionar outra lista[/B]
+ Seleccione um tipo de lista:
+ Remota
+ Local
+ Seleccione a sua lista xml:
+ Indique um nome para a lista.
+ Lista adicionada com sucesso
+ Introduza o url da lista
+ O url não é válido
+ Lista removida com sucesso!
+
+
+ Não tem favoritos!
+ Adicionado com sucesso aos favoritos
+ Removido com sucesso dos favoritos
+ Adicionar um favorito manualmente
+ Introduza um url sop ou ace
+ Insira um nome para o canal
+
+
+ Adicionar aos favoritos do addon
+ Remover dos favoritos do addon
+ Remover lista
+ Remover parser
+ Sincronizar parser
+
+
+ Faltam:
+ segundos
+
+
+ A extrair conteudo dos módulos. Aguarde
+ A remover ficheiros.
+ Não foi possível obter o xml.
+
+
+ Introduza um ID
+ Introduza um URL
+ ID Directo
+ URL Directo
+
+
+ [B]Adicionar um Website-Parser plugin [/B]
+ Localização do plugin?
+ Escolha a tarball (.tar.gz)
+ Parser instalado com sucesso
+ Ocorreu um erro a adicionar o parser
+ Introduza o url do plugin
+ Endereco não é válido. Necessária extensão tar.gz
+ A transferir parser
+ Parser removido com sucesso
+ A sincronizar parsers
+ Verificando...
+ Actualizado!
+ Ja estava actualizado.
+ Erro: url invalido para o repositório do parser
+ Actualizando...
+ Parser actualizado com sucesso!
+ A transferir script...
+ Script executado com sucesso
+ Qualquer plugin aqui encontrado é desenvolvido por terceiros.
+ Não são parte do addon nem mantidos pelos desenvolvedores.
+ Não peça nem espere qualquer tipo de suporte.
+ Removida toda a informacao de parsers
+ Remover vestígios de parsers
+
+
+ *No Ar*
+ Futebol Americano
+ Futebol
+ Basketball
+ Hóquei no Gelo
+ Baseball
+ Ténis
+ Automobilismo
+ Rugby
+ Golfe
+ Cricket
+ Ciclismo
+ Outros
+ Acestream ou Sopcast não encontrado.
+ Lista de Streams
+ Não encontrado.
+ Ingleses
+ Desporto
+ Notícias
+ Casamento
+ Genéricos
+ Educacional
+ CIS
+ Masculino
+ Compras
+ Reserva
+ Donetsk
+ Regional
+ Porno
+ TV Sec.21
+ Canais Ucranianos
+ Infantil
+ Filmes
+ Nocturnos
+ Europa
+ Ukr
+ Música
+ Religioso
+ Diversão
+ Ucrânia
+ Janeiro
+ Fevereiro
+ Março
+ Abril
+ Maio
+ Junho
+ Julho
+ Agosto
+ Setembro
+ Outubro
+ Novembro
+ Dezembro
+ Dia:
+
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/Portuguese/strings.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/Portuguese/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fe71bd6658ccd66d664d9d21f82086ef798097bf
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/language/Portuguese/strings.xml
@@ -0,0 +1,351 @@
+
+
+
+ P2P-STREAMS
+
+
+
+ Geral
+ [COLOR blue]Configurações Gerais[/COLOR]
+ Transferir modulos no arranque
+ Forçar detecção android
+ -Website-parsers do addon
+ Seleccione a sua timezone
+ Plataforma openelec x86_64
+ Esconder Porno
+ Activar traducao de categorias russas
+ [COLOR blue]Configurações de Sopcast[/COLOR]
+ Tipo de player
+ Sopclient android: localização do ficheiro
+ Encontrar IP Automaticamente
+ IP da connexão
+ Porta Local
+ Porta de Video
+ Espaco de Buffer
+ Tempo de espera antes de iniciar player
+ Modo de Debug
+ Timeout criação do servidor
+ Tempo de espera para stream
+ [COLOR blue]Configurações de Acestream[/COLOR]
+ Acestream - tipo de player
+ Porta de conexão
+ Porta de conexão (player)
+ Pausa Automática
+ Caminho alternativo para Aceengine
+ Manter ficheiro transferido no disco
+ Caminho para transferência
+ Terminar AceEngine se o player estiver parado
+ Mostrar status da Acestream Engine no videoosd
+ Modo de debug
+ Modo de stop para AceStreams
+ Listas/Parsers
+ Listas
+ Activar a lista oficial do sopcast.org
+ Parsers
+ Executar script python
+ Sincronizar parsers agora
+ Activar auto-sincronizacao de parsers
+ Intervalo na pesquisa de alterações
+ Forçar utilização do DVD Player
+ Comando alternativo
+ -Histórico do addon
+ Activar histórico do addon
+ Items a guardar
+ Apagar histórico do addon
+ Entrar na lista de parsers automaticamente
+
+
+ -Listas xml do addon
+ -Favoritos do addon
+ Ir para hash Acestream / Torrent URL
+ Carregar ficheiro .torrent local
+ Ir para ID Sopcast
+ Ir para URL Sopcast
+ Sistema Operativo incompatível!
+ [COLOR orange]Menu de opções avançadas[/COLOR]
+ Ocorreu um erro
+
+
+ Só pode usar o player externo com versões
+ superiores a XBMC 13.0 Gotham!
+ (Windows) Não fez a configuração do SopCast!
+ Active 'Transferir módulos no arranque' nas definições do addon
+ e entre novamente (como administrador!)
+ SopCast - Verificando se o servidor foi criado. Aguarde...
+ Servidor foi criado. Tentando reproduzir...
+ Falhou a inicializacao do canal
+ A carregar stream. Aguarde até 20 segundos.
+ Esperando o timeout...
+ Sopcast está ainda a correr no background
+ Deseja retomar a emissão anterior?
+
+
+ Iniciando...
+ À espera de resposta
+ Connectando
+ A iniciar módulo AceStream.
+ Espera inicial:
+ segundos
+ Reproduzindo
+ Link recebido
+ Guardando ficheiro
+ Transferindo
+ A carregar...
+ A carregar hash.
+ TS Engine à espera
+ A reproduzir torrent.
+ Sem resposta
+ Verificando dados
+ Pre-buffering
+ Downloading
+ Buffering
+
+
+ Acestream Engine
+ Estatisticas
+ Accao:
+ Download:
+ Upload:
+ Seeds:
+ Downloaded:
+ Uploaded:
+
+
+ Seleccione o ficheiro torrent local.
+ Iniciando AceStream (modo ValdikSS proxy)
+ Se a reprodução falhar aumente o timeout
+ do player!
+ O módulo acestream não está instalado.
+ Torrent não disponível ou inválido.
+
+
+ Não conseguiu detectar o seu sistema operativo
+ Seleccione-o da lista
+ A transferir módulos Sopcast.
+ A transferir módulos Acestream.
+ O addon para Linux armv7 é experimental.
+ Escolha o OS da seguinte lista.
+ A transferir módulos SopCast e Acestream.
+ Está a usar o OpenELEC x86_x64?
+ Está a usar o OpenELEC i386?
+ (Linux) Tem de instalar a acestream-engine manualmente.
+ Tutorial:
+ Siga o tutorial e tente de novo.
+ Necessita de iniciar o Kodi como administrador.
+ para configurar o sopcast no Windows.
+ Verificando se o SopCast está instalado...
+ Concluido!
+ O SopCast não está instalado no seu pc!
+ Faça o download em SopCast.org e instale!
+ Obtendo ID's dos users do Windows...
+ Não foi possível obter lista de utilizadores
+ Começando o download do SRVany...
+ A transferir SRVany...
+ Criando serviço 'sopcastp2p'...
+ Não foi possível criar o serviço!
+ Modificando o regedit...
+ Erro: Não conseguiu modificar o regedit.
+ Tentando obter as permissões do serviço...
+ Erro: Não conseguiu modificar as permissões.
+ Tentando definir permissões do serviço...
+ Erro: Não conseguiu modificar permissões do serviço.
+ A começar o download do ficheiro de permissões...
+ A transferir ficheiro de permissões (Regini)...
+ A executar Regini (permissões Regedit)...
+ Sopcast: Tudo concluído com sucesso!
+ Não está disponível para a arquitectura do seu Mac
+ Por defeito o Sopcast usa o player do Kodi.
+ Deseja usar uma aplicação externa?
+ Tudo concluído para o SopCast!
+ Clique ok para transferir a SopCast.apk
+ Seleccione uma pasta para transferir os apks
+ Transferindo SopCast.apk
+ SopCast.apk transferida para a pasta:
+ Por favor instale!
+ AppID não detectada
+ É necessário ter o acestreamengine.apk
+ instalado para reproduzir Acestreams.
+ Será transferida agora!
+ Transferindo AcestreamEngine.apk
+ Acestream.apk transferida para a pasta:
+ Acestream: Tudo concluído!
+ Não se esqueça que a AcestreamEngine app
+ deve estar em execução antes de lançar
+ qualquer acestream!
+ A transferir módulo AcestreamEngine para Android
+ Por defeito o addon irá utilizar o seu próprio módulo AcestreamEngine.
+ Deseja transferir e usar a aplicação externa oficial?
+ Deseja transferir o Ace Player?
+ Desta forma poderá utilizar a opção de player externo.
+ Transferindo Ace Player...
+ Aceplayer.apk transferido para a pasta:
+ Deseja utilizar o player externo como opção padrão?
+
+
+ Remover ficheiro ts.lock
+ Importar advancedsettings.xml recomendadas
+ Backup da configuração actual do ficheiro advancedsettings.xml
+ Eliminar o ficheiro advancedsettings.xml
+ Recuperar backup do ficheiro advancedsettings.xml
+ Valor actual do Cachemembuffersize [
+ Porta
+ VOD buffer (streams on-demand) (s)
+ Live buffer (streams em directo) (s)
+ Limite de Download (Kb/s) (0=ilimitado)
+ Limite de Upload (Kb/s) (0=ilimitado)
+ Número máximo de conexões (0=ilimitado)
+ Número máximo de conexões por stream (0=ilimitado)
+ Eliminar cache da AceStream Engine
+ Por favor repita a configuração para obter os novos módulos
+ Seleccione o advancedsettings.xml desejado
+ Transferindo advancedsettings.xml
+ Xml importado. Por favor reinicie o Kodi!
+ Backup com sucesso. Por favor reinicie o Kodi!
+ Backup recuperado com sucesso. Reinicie o Kodi!
+ O XML foi apagado. Por favor reinicie o Kodi!
+ Introduza um valor inteiro
+ Definicao alterada com sucesso
+ Valor inválido. Apenas valores inteiros!
+ ts.lock removido com sucesso
+ Deseja alterar a pasta de cache?
+ Escolha a nova pasta
+ Pasta cache da AceStream engine
+ P2P-Streams função de forçar stop:
+ Aplicar função stop costumizada
+ Deseja substituir o botão de stop do tema pela nossa função costumizada?
+ Tema actual:
+ Esta funcionalidade apenas se aplica ao tema actual
+ Se este for actualizado necessitará de repetir este procedimento
+ Se remover o addon precisará de reverter estas alterações. Caso contrário, a função de stop do Kodi não irá funcionar.
+ Tem a certeza que deseja continuar?
+ Deseja mapear um botão no seu telecomando para a função de stop?
+ Alocação de cache
+
+
+ Pressione o botão que deseja atribuir
+ Timeout em %.0f segundos...
+
+
+ [B][COLOR orange]Lista sopcast.org[/COLOR][/B] (http://sopcast.org/chlist.xml)
+ [B]+ Adicionar outra lista[/B]
+ Seleccione um tipo de lista:
+ Remota
+ Local
+ Seleccione a sua lista xml:
+ Indique um nome para a lista.
+ Lista adicionada com sucesso
+ Introduza o url da lista
+ O url não é válido
+ Lista removida com sucesso!
+
+
+ Não tem favoritos!
+ Adicionado com sucesso aos favoritos
+ Removido com sucesso dos favoritos
+ Adicionar um favorito manualmente
+ Introduza um url sop ou ace
+ Insira um nome para o canal
+
+
+ Adicionar aos favoritos do addon
+ Remover dos favoritos do addon
+ Remover lista
+ Remover parser
+ Sincronizar parser
+
+
+ Faltam:
+ segundos
+
+
+ A extrair conteudo dos módulos. Aguarde
+ A remover ficheiros.
+ Não foi possível obter o xml.
+
+
+ Introduza um ID
+ Introduza um URL
+ ID Directo
+ URL Directo
+
+
+ [B]Adicionar um Website-Parser plugin [/B]
+ Localização do plugin?
+ Escolha a tarball (.tar.gz)
+ Parser instalado com sucesso
+ Ocorreu um erro a adicionar o parser
+ Introduza o url do plugin
+ Endereco não é válido. Necessária extensão tar.gz
+ A transferir parser
+ Parser removido com sucesso
+ A sincronizar parsers
+ Verificando...
+ Actualizado!
+ Ja estava actualizado.
+ Erro: url invalido para o repositório do parser
+ Actualizando...
+ Parser actualizado com sucesso!
+ A transferir script...
+ Script executado com sucesso
+ Qualquer plugin aqui encontrado é desenvolvido por terceiros.
+ Não são parte do addon nem mantidos pelos desenvolvedores.
+ Não peça nem espere qualquer tipo de suporte.
+ Removida toda a informacao de parsers
+ Remover vestígios de parsers
+
+
+ *No Ar*
+ Futebol Americano
+ Futebol
+ Basketball
+ Hóquei no Gelo
+ Baseball
+ Ténis
+ Automobilismo
+ Rugby
+ Golfe
+ Cricket
+ Ciclismo
+ Outros
+ Acestream ou Sopcast não encontrado.
+ Lista de Streams
+ Não encontrado.
+ Ingleses
+ Desporto
+ Notícias
+ Casamento
+ Genéricos
+ Educacional
+ CIS
+ Masculino
+ Compras
+ Reserva
+ Donetsk
+ Regional
+ Porno
+ TV Sec.21
+ Canais Ucranianos
+ Infantil
+ Filmes
+ Nocturnos
+ Europa
+ Ukr
+ Música
+ Religioso
+ Diversão
+ Ucrânia
+ Janeiro
+ Fevereiro
+ Março
+ Abril
+ Maio
+ Junho
+ Julho
+ Agosto
+ Setembro
+ Outubro
+ Novembro
+ Dezembro
+ Dia:
+
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/settings.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8346bf884c2fe5a7cd5df4f674ca7737502436f8
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/settings.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/__init__.pyo
index 3210312295fd77cf676b65d36ebf4be88bc90491..f551dc605c7de61291f67e1038f1da2e715ab619 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/__init__.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/__init__.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/config.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/config.pyo
index a7568292df9d8052f7734fb98d32c13bf3c529c0..50f40a5459147ca8c6532c0fc5c410a614c76f21 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/config.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/config.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/downloadtools.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/downloadtools.pyo
index 5e0c04f8e09bb4477c1f6d6ba1978a71eee241c8..414820570f38dd09b8a05d0bf429ccedb8b801ca 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/downloadtools.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/downloadtools.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/item.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/item.pyo
index ac885405d2b4f15f5322d2f3cf7ab82779d85ae1..e89ff50df602e04a71c34b874f113d741c62b0c5 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/item.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/item.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/logger.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/logger.pyo
index c2990e4087cf9f98dd561d0330191c776275762c..fe2b992a22c11507e81bdaf0d563ad8d70c6eb33 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/logger.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/logger.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/scrapertools.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/scrapertools.pyo
index 2af950a6b43b791761273dcd930d5b31c799b3ac..5efcea82335e392c6e371a044fc7e68cca4d5977 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/scrapertools.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/core/scrapertools.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/platformcode/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/platformcode/__init__.pyo
index f502a98443cca0e70cf1672aa80defae5b93fed5..c924b8d344ee07cceae36c23a0779ccb841ee677 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/platformcode/__init__.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/platformcode/__init__.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/platformcode/launcher.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/platformcode/launcher.pyo
index 6cc093478bcf56408f42844b6da3638695bf0f1c..170e48d4f95b2826de142ec4128fd91649e66b39 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/platformcode/launcher.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/platformcode/launcher.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/platformcode/library.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/platformcode/library.pyo
index 2acb04ee53a6c53444b33d8a726c60d53d83a02d..ab939edd25f77cb5befc959b7d04bff0888c7d8c 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/platformcode/library.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/platformcode/library.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/servers/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/servers/__init__.pyo
index ae475f61562c8170da36084dd96e9fc69fbeeb64..331d5bb91a27ba4a5ad36fa033d8ca27942801fe 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/servers/__init__.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/servers/__init__.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/servers/servertools.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/servers/servertools.pyo
index 1b5f90b8718f75f9ffbf70c716f1ada3e81eccac..6e6b664c0b1231c3769a2c2399fab14b73932e04 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/servers/servertools.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.pelisalacarta/servers/servertools.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/__init__.pyo
index bb8d075d3b76bcaabc8cc53d9e021ca083bab505..e24b12af9423adee1c51b3db4df2b4c8ea410a80 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/__init__.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/__init__.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/config.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/config.pyo
index b1385b726598f443c6204e713927932a4c983db3..7206f004263b82835ed36ca2fa6c0d902cd35203 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/config.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/config.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/downloadtools.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/downloadtools.pyo
index 6c1fc936cc1fe4e9c595d16ac8e7d41e8902e941..9c5bb6bbae6b330e925eec812339fa185b1ac821 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/downloadtools.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/downloadtools.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/item.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/item.pyo
index 735bb417656b486f7a12491aadbf72500909a13a..eb41257427eba09715a948a157e9ae7979af358a 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/item.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/item.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/logger.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/logger.pyo
index a13032de627b03f8dca62fbaa71c8e5f2dcb5765..1f4bf79389ee325754f7d7c123ade25900f58390 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/logger.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/logger.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/platform_name.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/platform_name.pyo
index c47006b7a00f27edbdc89bb1699cb2d9b563e4cb..220569e8a96d604a951b079cae2095a0603e38cb 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/platform_name.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/platform_name.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/scrapertools.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/scrapertools.pyo
index 71cf91d13345873635b05d218287f420de929206..b14cb7d1b10d17fc7e1ef41daf0197405ad9d617 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/scrapertools.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/scrapertools.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/suscription.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/suscription.pyo
index 1e7140a89b2eb3cb8db29756a637d5a51c4216af..8a60d6c5dc4e3cb0f619a34657b411b8b376c954 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/suscription.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/core/suscription.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/__init__.pyo
index 4229b34d81a0ea1bf0ecebbd12a9ce4dbb74ba27..c8924180fb2f00524c6154fdac66a3d2a71ebc41 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/__init__.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/__init__.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/xbmcgotham/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/xbmcgotham/__init__.pyo
index ef7948da9da0e8337ba14574a40032dad0acb7da..e00876e999150a386bae86a00aa33cf1f5630c7a 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/xbmcgotham/__init__.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/xbmcgotham/__init__.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/xbmcgotham/config.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/xbmcgotham/config.pyo
index 3882d762481ffe4392b491a3ac6fe7acd0010fcb..78b9795f161532012f110116fe3203535cf2b1e3 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/xbmcgotham/config.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/xbmcgotham/config.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/xbmcgotham/logger.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/xbmcgotham/logger.pyo
index e51428e3e01edf695c7203d59b6b4305c1b8b6d6..26de668c9a4484939c7b8fe88f3132ad6de657b2 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/xbmcgotham/logger.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/platformcode/xbmcgotham/logger.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/servers/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/servers/__init__.pyo
index a2369355f426d90f978896ce06d67f89d6018b6e..577073176f929bc1d642ebc6ab9960211e29e864 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/servers/__init__.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/servers/__init__.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/servers/servertools.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/servers/servertools.pyo
index 43d2db4af6aefc66f1e6683b8b60b5daf09dbf83..bb36c38c12f154f45269ea732f51b0e3592e1dc9 100644
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/servers/servertools.pyo and b/packages/mediacenter/kodi/config/base-addons/plugin.video.tvalacarta/servers/servertools.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/Logger.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/Logger.py
new file mode 100644
index 0000000000000000000000000000000000000000..afc9b690d8870afde59c254423bd015d4eff94a2
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/Logger.py
@@ -0,0 +1,33 @@
+import xbmc
+
+LOG_LEVEL = 0
+
+DEBUG = 0
+INFO = 1
+WARN = 2
+ERROR = 3
+
+class Logger():
+
+ def __init__(self, type):
+ self.type = type
+
+ def debug(self, message):
+ self.log(message, xbmc.LOGDEBUG)
+
+ def info(self, message):
+ self.log(message, xbmc.LOGINFO)
+
+ def notice(self, message):
+ self.log(message, xbmc.LOGNOTICE)
+
+ def warn(self, message):
+ self.log(message, xbmc.LOGWARNING)
+
+ def error(self, message):
+ self.log(message, xbmc.LOGERROR)
+
+ def log(self, message, level):
+ if level >= LOG_LEVEL:
+ xbmc.log("[plugins.video.veetle] %s: '%s'" % (self.type, message), level)
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/Logger.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/Logger.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..5714ea97b64ce245999a76b07f33cdc6c62b9a1a
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/Logger.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/StorageServerDummy.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/StorageServerDummy.py
new file mode 100644
index 0000000000000000000000000000000000000000..5b6a5d87bdd14ea8ef387e1241623b6d8dd685a1
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/StorageServerDummy.py
@@ -0,0 +1,29 @@
+'''
+ StorageServer override.
+ Version: 1.0
+'''
+
+class StorageServer:
+ def __init__(self, table, timeout=24):
+ return
+
+ def cacheFunction(self, funct=False, *args):
+ return funct(*args)
+
+ def set(self, name, data):
+ return ""
+
+ def get(self, name):
+ return ""
+
+ def setMulti(self, name, data):
+ return ""
+
+ def getMulti(self, name, items):
+ return ""
+
+ def lock(self, name):
+ return False
+
+ def unlock(self, name):
+ return False
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleCache.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleCache.py
new file mode 100644
index 0000000000000000000000000000000000000000..fcb5ba18949f17b1b4f1f9224535da9facd5820b
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleCache.py
@@ -0,0 +1,67 @@
+import datetime
+import time
+import Logger
+
+try:
+ import StorageServer
+except:
+ import StorageServerDummy as StorageServer
+
+VALIDITY_DATETIME_KEY = "_validity"
+VALIDITY_DATETIME_PATTERN = "%Y-%m-%dT%H:%M:%S"
+
+log = Logger.Logger("VeetleCache")
+
+# This class wraps the common plugin cache and adds a validity date to each cached object key
+# so that objects are only cached for a certain amount of time
+class VeetleCache:
+
+ def __init__(self, minutes):
+ self.cache = StorageServer.StorageServer("plugin.video.veetle", 1)
+ self.minutes = minutes
+
+ def get(self, key):
+
+ validityDateTimeString = self.cache.get(key + VALIDITY_DATETIME_KEY)
+
+ # If there is no validity date yet, then return None
+ if validityDateTimeString is None or len(str(validityDateTimeString)) == 0:
+ log.debug("Validity date is None or empty")
+ return None
+
+ # Try parse validity date
+ try:
+ try:
+ validityDateTime = datetime.datetime.strptime(validityDateTimeString, VALIDITY_DATETIME_PATTERN)
+ except TypeError:
+ validityDateTime = datetime.datetime(*(time.strptime(validityDateTimeString, VALIDITY_DATETIME_PATTERN)[0:6]))
+
+ except Exception, e:
+ log.warn("Error parsing validity date: " + repr(e))
+ return None
+
+ # If validity date is smaller than current date then return None
+ if validityDateTime < datetime.datetime.now():
+ log.debug("Validity date is smaller than now()")
+ return None
+
+ # Otherwise return cached value
+ log.debug("Using cached value")
+
+ return self.cache.get(key)
+
+
+ def set(self, key, value):
+
+ # Set validity date for this key
+ validityDateTime = datetime.datetime.now() + datetime.timedelta(minutes = self.minutes)
+
+ self.cache.set(key + VALIDITY_DATETIME_KEY, validityDateTime.strftime(VALIDITY_DATETIME_PATTERN))
+
+ log.debug("Set validity date to '%s' for key '%s'" % (repr(validityDateTime), key))
+
+ # Set value for key
+ self.cache.set(key, value)
+
+ log.debug("Set value for key '%s' to '%s'" % (key, repr(value)))
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleCache.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleCache.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..ce909bad026b4dc2a2db1eef52354d915344eb47
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleCache.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleData.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleData.py
new file mode 100644
index 0000000000000000000000000000000000000000..1c96209165098539d545b8e8fc5eecf8d634417d
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleData.py
@@ -0,0 +1,93 @@
+import xbmcaddon
+__settings__ = xbmcaddon.Addon(id='plugin.video.veetle')
+__language__ = __settings__.getLocalizedString
+
+class VeetleCategory:
+
+ def __init__(self, id, title):
+ self.id = id
+ self.title = title
+
+class VeetleChannel:
+
+ def __init__(self):
+
+ self.channelId = 0
+ self.title = ''
+ self.description = ''
+ self.categoryId = ''
+
+ self.userName = ''
+
+ self.popularityIndex = 0
+ self.bitRate = 0
+
+ self.logoUrl = ''
+
+ self.currentItem = None
+
+ def createScheduleSummary(self, scheduleItems):
+
+ scheduleItems = [scheduleItem for scheduleItem in scheduleItems if scheduleItem.channelId == self.channelId]
+ summary = ''
+
+ for scheduleItem in scheduleItems:
+ summary += scheduleItem.label()
+ summary += '[CR]'
+
+ return summary
+
+class VeetleScheduleItem:
+
+ def __init__(self):
+
+ self.title = ''
+ self.description = ''
+ self.duration = None
+ self.startTime = None
+
+ def label(self):
+ return '[B]%s[/B] - %s ([COLOR=blue]%s mins[/COLOR])' % (self.startTime.strftime('%H:%M'), self.title, self.duration.seconds / 60)
+
+CategoryAll = VeetleCategory('0', __language__(40003))
+CategoryEntertainment = VeetleCategory('10', __language__(40004))
+CategoryShows = VeetleCategory('20', __language__(40005))
+CategoryAnimation = VeetleCategory('60', __language__(40006))
+CategorySports = VeetleCategory('80', __language__(40007))
+CategoryComedy = VeetleCategory('50', __language__(40008))
+CategoryMusic = VeetleCategory('70', __language__(40009))
+CategoryEducation = VeetleCategory('90', __language__(40010))
+CategoryGaming = VeetleCategory('40', __language__(40011))
+CategoryNews = VeetleCategory('30', __language__(40012))
+CategoryReligion = VeetleCategory('100', __language__(40013))
+CategoryMobile = VeetleCategory('110', __language__(40014))
+
+Categories = [
+ CategoryAll,
+ CategoryEntertainment,
+ CategoryShows,
+ CategoryAnimation,
+ CategorySports,
+ CategoryComedy,
+ CategoryMusic,
+ CategoryEducation,
+ CategoryGaming,
+ CategoryNews,
+ CategoryReligion,
+ CategoryMobile
+ ]
+
+CategoryMap = {
+ CategoryAll.id: CategoryAll,
+ CategoryAnimation.id: CategoryAnimation,
+ CategoryComedy.id: CategoryComedy,
+ CategoryEducation.id: CategoryEducation,
+ CategoryGaming.id: CategoryGaming,
+ CategoryMobile.id: CategoryMobile,
+ CategoryEntertainment.id: CategoryEntertainment,
+ CategoryShows.id: CategoryShows,
+ CategorySports.id: CategorySports,
+ CategoryMusic.id: CategoryMusic,
+ CategoryNews.id: CategoryNews,
+ CategoryReligion.id: CategoryReligion
+}
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleData.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleData.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..247290d1aff896a04c4036f5b942f87fda10e053
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleData.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleGuideDataSource.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleGuideDataSource.py
new file mode 100644
index 0000000000000000000000000000000000000000..a51d90da94350fcbc611065d4b35c0f235816699
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleGuideDataSource.py
@@ -0,0 +1,125 @@
+from datetime import date
+import urllib2
+import simplejson as json
+import datetime
+import Logger
+import VeetleCache
+import VeetleData
+import xbmcaddon
+
+__settings__ = xbmcaddon.Addon(id='plugin.video.veetle')
+__language__ = __settings__.getLocalizedString
+getSetting = xbmcaddon.Addon().getSetting
+
+URL_VEETLE = 'http://www.veetle.com'
+URL_VEETLE_STREAM_URL = URL_VEETLE + '/index.php/channel/ajaxStreamLocation/%s/flash'
+
+if getSetting("chlist_official") == 'true':URL_VEETLE_GUIDE_LOAD_CHANNELS = URL_VEETLE + "/channel-listing-cross-site.js"
+else: URL_VEETLE_GUIDE_LOAD_CHANNELS = "http://veetleguide.appspot.com/load-channels"
+URL_VEETLE_GUIDE_LOAD_SCHEDULE = "http://veetleguide.appspot.com/load-schedule"
+
+CACHE_DURATION_IN_MINUTES = 10
+
+log = Logger.Logger("VeetleGuideDataSource")
+
+class VeetleGuideDataSource:
+
+ def __init__(self):
+ self.cache = VeetleCache.VeetleCache(CACHE_DURATION_IN_MINUTES)
+
+ def loadChannels(self):
+
+ channels = []
+
+ try:
+
+ jsonChannels = self.cache.get("channels")
+ if jsonChannels is None or len(jsonChannels) == 0:
+ log.notice("Refreshing channel data from: %s" % (URL_VEETLE_GUIDE_LOAD_CHANNELS))
+ response = urllib2.urlopen(URL_VEETLE_GUIDE_LOAD_CHANNELS)
+ jsonChannels = response.read().decode("utf-8")
+ self.cache.set("channels", jsonChannels)
+ else:
+ log.debug("Using cached channel data")
+
+ jsonChannels = json.loads(jsonChannels)
+ for jsonChannel in jsonChannels:
+ channels.append(parseChannel(jsonChannel))
+
+ except Exception, e:
+ log.error('Error loading channel list: ' + repr(e))
+
+ return channels
+
+ def loadSchedule(self):
+
+ schedule = []
+
+ try:
+
+ jsonSchedule = self.cache.get("schedule")
+ if jsonSchedule is None or len(jsonSchedule) == 0:
+ log.notice("Refreshing schedule data from: %s" %(URL_VEETLE_GUIDE_LOAD_SCHEDULE))
+ response = urllib2.urlopen(URL_VEETLE_GUIDE_LOAD_SCHEDULE)
+ jsonSchedule = response.read().decode("utf-8")
+ self.cache.set("schedule", jsonSchedule)
+ else:
+ log.debug("Using cached schedule data")
+
+ jsonSchedule = json.loads(jsonSchedule)
+
+ for jsonScheduleItem in jsonSchedule:
+ schedule.append(parseScheduleItem(jsonScheduleItem))
+
+ except Exception, e:
+ log.error('Error loading schedule: ' + repr(e))
+
+ return schedule
+
+ def loadChannelStreamUrl(self, channelId):
+
+ url = URL_VEETLE_STREAM_URL % channelId
+
+ response = urllib2.urlopen(url)
+ jsonContent = json.loads(response.read())
+ if jsonContent['success']==False: return False
+ else: return jsonContent['payload']
+
+
+def parseChannel(jsonChannel):
+ channel = VeetleData.VeetleChannel()
+ channel.channelId = jsonChannel['channelId']
+ channel.title = jsonChannel['title']
+ try:channel.description = jsonChannel['description']
+ except:channel.description = __language__(40015)
+ channel.categoryId = str(jsonChannel['categoryId'])
+ try:channel.userName = str(jsonChannel['userName'])
+ except:channel.userName = __language__(40015)
+ channel.popularityIndex = jsonChannel['popularityIndex']
+ try:channel.bitRate = jsonChannel['bitRate']
+ except:channel.bitRate = jsonChannel['bitrate']
+ try:channel.logoUrl = jsonChannel['logoUrl']
+ except:channel.logoUrl = jsonChannel['logo']['lg']
+ try:channel.viewers=str(jsonChannel['currentNumViewers'])
+ except: channel.viewers = None
+
+ if 'currentItem' in jsonChannel:
+
+ jsonScheduleItem = jsonChannel['currentItem']
+
+ channel.currentItem = parseScheduleItem(jsonScheduleItem)
+
+ return channel
+
+def parseScheduleItem(jsonScheduleItem):
+
+ scheduleItem = VeetleData.VeetleScheduleItem()
+ scheduleItem.title = jsonScheduleItem['title']
+ scheduleItem.description = jsonScheduleItem['description']
+ scheduleItem.duration = datetime.timedelta(milliseconds=jsonScheduleItem['duration'])
+ scheduleItem.startTime = datetime.datetime.fromtimestamp(jsonScheduleItem['startTime'] / 1000.0)
+ scheduleItem.channelId = jsonScheduleItem['channelId']
+
+ return scheduleItem
+
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleGuideDataSource.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleGuideDataSource.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..1bbf05df2d1241eb01c52a8ff03223f260835a0b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleGuideDataSource.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleProxyServer.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleProxyServer.py
new file mode 100644
index 0000000000000000000000000000000000000000..c9cec56abbcb8d6992cf7d37d24bec2375e87313
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleProxyServer.py
@@ -0,0 +1,30 @@
+import urllib2
+import xbmc, xbmcaddon, xbmcplugin, xbmcgui
+import Logger
+
+addon = xbmcaddon.Addon()
+akamaiProxyServer = xbmc.translatePath(addon.getAddonInfo('path') + "/akamaiSecureHD.py")
+
+log = Logger.Logger('VeetleProxyServer')
+
+def getUrl(url):
+ req = urllib2.Request(url)
+ req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/13.0')
+ response = urllib2.urlopen(req, timeout=30)
+ link = response.read()
+ response.close()
+ return link
+
+def run():
+ try:
+ log.debug('Checking proxy server...')
+ getUrl("http://127.0.0.1:9000/version")
+ proxyIsRunning = True
+ log.debug('Proxy server is running')
+ except:
+ proxyIsRunning = False
+ log.debug('Proxy server is not running')
+ if not proxyIsRunning:
+ log.notice('Starting proxy server...')
+ xbmc.executebuiltin('RunScript(' + akamaiProxyServer + ')')
+ log.notice('Proxy server started')
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleProxyServer.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleProxyServer.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..979ac475bed1052b82583aadd9492db908b21bba
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleProxyServer.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleViews.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleViews.py
new file mode 100644
index 0000000000000000000000000000000000000000..b3d36edbbbc804286e49f84393f2a57956606bba
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleViews.py
@@ -0,0 +1,239 @@
+import Logger
+import VeetleData
+import xbmc, xbmcaddon, xbmcplugin, xbmcgui
+import base64,urllib2
+
+__settings__ = xbmcaddon.Addon(id='plugin.video.veetle')
+__language__ = __settings__.getLocalizedString
+
+URL_VIEW_CHANNEL = '?channel='
+URL_VIEW_CATEGORY = '?category='
+URL_VIEW_CATEGORIES = '?categories'
+URL_VIEW_SCHEDULE = '?schedule'
+URL_VIEW_SEARCH = '?search'
+
+URL_AKAMAI_PROXY = 'http://127.0.0.1:9000/veetle/%s'
+
+dialog = xbmcgui.Dialog()
+
+log = Logger.Logger("VeetleViews")
+
+class VeetleViews:
+
+ def __init__(self, pluginUrl, pluginHandle, dataSource):
+ self.baseUrl = pluginUrl
+ self.pluginHandle = pluginHandle
+ self.dataSource = dataSource
+
+ def buildChannelUrl(self, channelId):
+ return self.baseUrl + URL_VIEW_CHANNEL + channelId
+
+ def buildCategoryUrl(self, categoryId):
+ return self.baseUrl + URL_VIEW_CATEGORY + str(categoryId)
+
+ def createChannelListItem(self, channel, scheduleItems):
+
+ if channel.viewers == None: extra=''
+ else: extra=' / %s %s' % (channel.viewers,str(__language__(40016)))
+ channelDisplayTitle = '[B]%s[/B] (%s kbps%s)' % (channel.title,channel.bitRate/1000,extra)
+
+ if channel.currentItem:
+ channelDisplayTitle += ' ([COLOR=blue]%s[/COLOR])' %channel.currentItem.title
+
+ listItem = xbmcgui.ListItem(
+ channelDisplayTitle,
+ iconImage=channel.logoUrl,
+ thumbnailImage=channel.logoUrl)
+
+ infoLabels = {
+ 'title': channel.title,
+ 'director': channel.userName,
+ 'genre': VeetleData.CategoryMap[channel.categoryId].title,
+ 'tagline': channel.description,
+ 'plot': channel.createScheduleSummary(scheduleItems),
+ }
+
+ listItem.setInfo('video', infoLabels)
+ listItem.setProperty('IsPlayable', 'true')
+
+ return listItem
+
+ def createScheduleListItem(self, scheduleItem):
+
+ displayTitle = scheduleItem.label()
+
+ listItem = xbmcgui.ListItem(
+ displayTitle)
+
+ infoLabels = {'title': scheduleItem.title}
+ listItem.setInfo('video', infoLabels)
+ listItem.setProperty('IsPlayable', 'true')
+
+ return listItem
+
+ def renderHome(self, queryUrl):
+
+ categoriesListItem = xbmcgui.ListItem(
+ __language__(40001),
+ iconImage='',
+ thumbnailImage='')
+
+ xbmcplugin.addDirectoryItem(
+ self.pluginHandle,
+ self.baseUrl + URL_VIEW_CATEGORIES,
+ categoriesListItem,
+ isFolder=True)
+
+ categoriesListItem = xbmcgui.ListItem(
+ __language__(40002),
+ iconImage='',
+ thumbnailImage='')
+
+ xbmcplugin.addDirectoryItem(
+ self.pluginHandle,
+ self.baseUrl + URL_VIEW_SCHEDULE,
+ categoriesListItem,
+ isFolder=True)
+
+ xbmcplugin.endOfDirectory(self.pluginHandle)
+
+ def renderCategories(self, queryUrl):
+
+ # Load the channel list
+ channels = self.dataSource.loadChannels()
+
+ for category in VeetleData.Categories:
+
+ # Get channel count for category
+ channelCount = len(channels) if category.id == VeetleData.CategoryAll.id else len([channel for channel in channels if channel.categoryId == category.id])
+
+ listItem = xbmcgui.ListItem(
+ category.title + (' ([COLOR=blue]%s[/COLOR])' % str(channelCount)),
+ iconImage='',
+ thumbnailImage='')
+
+ xbmcplugin.addDirectoryItem(
+ self.pluginHandle,
+ self.buildCategoryUrl(category.id),
+ listItem,
+ isFolder=True)
+
+ xbmcplugin.endOfDirectory(self.pluginHandle)
+
+ def renderCategory(self, queryUrl):
+
+ # Set content type for a category view to movies - this will enable more view types like media info
+ xbmcplugin.setContent(self.pluginHandle, 'movies')
+
+ categoryId = queryUrl[len(URL_VIEW_CATEGORY):].strip()
+
+ # Load the channel list
+ channels = self.dataSource.loadChannels()
+ scheduleItems = self.dataSource.loadSchedule()
+
+ # Filter channel for specified category
+ channels = channels if categoryId == VeetleData.CategoryAll.id else [channel for channel in channels if channel.categoryId == categoryId]
+
+ # Sort channels by popularity
+ channels = sorted(channels, key=lambda channel: channel.popularityIndex, reverse=True)
+
+ for channel in channels:
+
+ url = self.buildChannelUrl(channel.channelId)
+ listItem = self.createChannelListItem(channel, scheduleItems)
+
+ xbmcplugin.addDirectoryItem(
+ self.pluginHandle,
+ url,
+ listItem,
+ isFolder=False,
+ totalItems=len(channels))
+
+ xbmcplugin.endOfDirectory(self.pluginHandle)
+
+ def renderChannel(self, queryUrl):
+
+ #Play a stream with the given channel id
+ channelId = queryUrl[len(URL_VIEW_CHANNEL):].strip()
+ if len(channelId)==32: #embed id
+ try: channelId=self.abrir_url('http://fightnightaddons.esy.es/tools/veet.php?id=%s' % (channelId)).replace(' ','')
+ except: pass
+
+ channelStreamUrl = self.dataSource.loadChannelStreamUrl(channelId)
+ try:
+ VIDb64 = base64.encodestring(channelStreamUrl).replace('\n', '')
+ fullUrl = URL_AKAMAI_PROXY % VIDb64
+ except: pass
+
+ if channelStreamUrl:
+ xbmcplugin.setResolvedUrl(
+ self.pluginHandle,
+ True,
+ xbmcgui.ListItem(path=fullUrl))
+ else:
+ xbmcplugin.setResolvedUrl(
+ self.pluginHandle,
+ False,
+ xbmcgui.ListItem())
+
+
+ ok = dialog.ok(__language__(30000), __language__(30001))
+
+ def renderSchedule(self, queryUrl):
+
+ # Load the schedule list
+ schedule = self.dataSource.loadSchedule()
+
+ for scheduleItem in schedule:
+
+ url = self.buildChannelUrl(scheduleItem.channelId)
+ listItem = self.createScheduleListItem(scheduleItem)
+
+ xbmcplugin.addDirectoryItem(
+ self.pluginHandle,
+ url,
+ listItem,
+ isFolder=False)
+
+ xbmcplugin.endOfDirectory(self.pluginHandle)
+
+ def renderUrl(self, queryUrl):
+
+ log.debug("Rendering URL: %s%s" % (self.baseUrl, queryUrl))
+
+ if queryUrl.startswith(URL_VIEW_CHANNEL):
+ self.renderChannel(queryUrl)
+ return
+
+ if queryUrl.startswith(URL_VIEW_CATEGORIES):
+ self.renderCategories(queryUrl)
+ return
+
+ if queryUrl.startswith(URL_VIEW_CATEGORY):
+ self.renderCategory(queryUrl)
+ return
+
+ if queryUrl.startswith(URL_VIEW_SCHEDULE):
+ self.renderSchedule(queryUrl)
+ return
+
+ self.renderHome(queryUrl)
+
+ def abrir_url(self,url,erro=True):
+ print "A fazer request normal de: " + url
+ try:
+ req = urllib2.Request(url)
+ req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36')
+ response = urllib2.urlopen(req)
+ link=response.read()
+ response.close()
+ return link
+ except urllib2.HTTPError, e:
+ if erro==True:
+ dialog.ok('Veetle',str(urllib2.HTTPError(e.url, e.code, __language__(30000), e.hdrs, e.fp)))
+ sys.exit(0)
+ except urllib2.URLError, e:
+ if erro==True:
+ dialog.ok('Veetle',__language__(30000))
+ sys.exit(0)
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleViews.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleViews.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..2eba5428c29eff310d8e6737c05c58a10ba51bcf
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/VeetleViews.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/addon.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/addon.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c94a5c246266466cc9b6fde5cd3110b950101896
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/addon.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+ video
+
+
+ Αναζήτηση και ρεύμα από veetle.com
+ Browse and stream from veetle.com
+ Veja canais de veetle.com
+ Veja canais de veetle.com
+ Επιτρέπει βλέποντας ρέματα veetle.com που flash ενεργοποιηθεί.
+ Enables watching streams on veetle.com that are flash enabled.
+ Permite visualizar streams de veetle.com que necessitam de flash.
+ Permite visualizar streams de veetle.com que necessitam de flash.
+ Δεν λειτουργεί για τις ροές 'HD' που απαιτούν λήψη λογισμικού.
+ Does not work for 'HD' streams which require a software download.
+ Não funciona para streams 'HD' que necessitam do download de software.
+ Não funciona para streams 'HD' que necessitam do download de software.
+ all
+
+
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/akamaiSecureHD.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/akamaiSecureHD.py
new file mode 100644
index 0000000000000000000000000000000000000000..6010f7b175d2c3475765a31d62c8d0b9e7b1f43a
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/akamaiSecureHD.py
@@ -0,0 +1,276 @@
+"""
+XBMCLocalProxy 0.1
+Copyright 2011 Torben Gerkensmeyer
+
+Modified for Akamai SecureHD by BlueCop
+
+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 2 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, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+MA 02110-1301, USA.
+"""
+
+import base64
+import re
+import time
+import urllib
+import urllib2
+import sys
+import traceback
+import socket
+from SocketServer import ThreadingMixIn
+from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+from urllib import *
+
+from flvlib import tags
+from flvlib import helpers
+from flvlib.astypes import MalformedFLV
+
+import zlib
+from StringIO import StringIO
+import hmac
+import hashlib
+import base64
+
+
+class MyHandler(BaseHTTPRequestHandler):
+ """
+ Serves a HEAD request
+ """
+ def do_HEAD(self):
+ print "XBMCLocalProxy: Serving HEAD request..."
+ self.answer_request(0)
+
+ """
+ Serves a GET request.
+ """
+ def do_GET(self):
+ print "XBMCLocalProxy: Serving GET request..."
+ self.answer_request(1)
+
+ def answer_request(self, sendData):
+ try:
+ request_path = self.path[1:]
+ print 'request_path: ' + request_path
+ extensions = ['.Vprj', '.edl', '.txt', '.chapters.xml']
+ for extension in extensions:
+ if request_path.endswith(extension):
+ self.send_response(404)
+ request_path = ''
+ request_path = re.sub(r"\?.*", "", request_path)
+ if request_path == "stop":
+ sys.exit()
+ elif request_path == "version":
+ self.send_response(200)
+ self.end_headers()
+ self.wfile.write("Proxy: Running\r\n")
+ self.wfile.write("Version: 0.1")
+ elif request_path[0:7] == "veetle/":
+ realpath = request_path[7:]
+ print 'realpath: ' + realpath
+ fURL = base64.b64decode(realpath)
+ print 'fURL: ' + fURL
+ self.serveFile(fURL, sendData)
+ else:
+ self.send_response(403)
+ except:
+ traceback.print_exc()
+ self.wfile.close()
+ return
+ try:
+ self.wfile.close()
+ except:
+ pass
+
+
+ """
+ Sends the requested file and add additional headers.
+ """
+ def serveFile(self, fURL, sendData):
+ opener = FancyURLopener()
+ opener.addheaders = []
+ response = opener.open(fURL)
+ #print response
+ self.send_response(response.code)
+ print "XBMCLocalProxy: Sending headers..."
+ headers = response.info()
+ #print headers
+ for key in headers:
+ try:
+ val = headers[key]
+ #print val
+ if 'content-length' == key.lower():
+ pass
+ else:
+ self.send_header(key, val)
+ except Exception, e:
+ print e
+ pass
+ self.end_headers()
+
+ if (sendData):
+ print "XBMCLocalProxy: Sending data..."
+ fileout = self.wfile
+ try:
+ buf = "INIT"
+ firstBlock = True
+ try:
+ while (buf != None and len(buf) > 0):
+ buf = response.read(200 * 1024)
+ #print str(buf[0:3])
+ if firstBlock:
+ #EdgeClass(buf, fURL, swfUrl)
+ buf = buf.replace(b'GGG', bytes('FLV'))
+ firstBlock = False
+ fileout.write(buf)
+ fileout.flush()
+ response.close()
+ fileout.close()
+ print time.asctime(), "Closing connection"
+ except socket.error, e:
+ print time.asctime(), "Client Closed the connection."
+ try:
+ response.close()
+ fileout.close()
+ except Exception, e:
+ return
+ except Exception, e:
+ traceback.print_exc(file=sys.stdout)
+ response.close()
+ fileout.close()
+ except:
+ traceback.print_exc()
+ self.wfile.close()
+ return
+ try:
+ self.wfile.close()
+ except:
+ pass
+
+
+class EdgeClass():
+ def __init__(self, data, url, swfUrl):
+ self.url = url
+ self.swfUrl = swfUrl
+ self.domain = self.url.split('://')[1].split('/')[0]
+ self.control = 'http://%s/control/' % self.domain
+ self.onEdge = self.extractTags(data, onEdge=True)
+ #self.MetaData = self.extractTags(data,onMetaData=True)
+ self.sendNewToken(self.onEdge['session'], self.onEdge['streamName'], self.swfUrl, self.control)
+
+ def getURL(self, url, post=False, sessionID=False, sessionToken=False):
+ try:
+ print 'GetURL --> url = ' + url
+ opener = urllib2.build_opener()
+ if sessionID and sessionToken:
+ opener.addheaders = [('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:14.0) Gecko/20100101 Firefox/14.0.1'),
+ ('x-Akamai-Streaming-SessionToken', sessionToken),
+ ('x-Akamai-Streaming-SessionID', sessionID),
+ ('Content-Type', 'text/xml')]
+ else:
+ opener.addheaders = [('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:14.0) Gecko/20100101 Firefox/14.0.1')]
+ if not post:
+ usock = opener.open(url)
+ else:
+ usock = opener.open(url, ':)')
+ response = usock.read()
+ usock.close()
+ except urllib2.URLError, e:
+ print 'Error reason: ', e
+ return False
+ else:
+ return response
+
+ def extractTags(self, filedata, onEdge=True, onMetaData=False):
+ f = StringIO(filedata)
+ flv = tags.FLV(f)
+ try:
+ tag_generator = flv.iter_tags()
+ for i, tag in enumerate(tag_generator):
+ if isinstance(tag, tags.ScriptTag):
+ if tag.name == "onEdge" and onEdge:
+ return tag.variable
+ elif tag.name == "onMetaData" and onMetaData:
+ return tag.variable
+ except MalformedFLV, e:
+ return False
+ except tags.EndOfFile:
+ return False
+ f.close()
+ return False
+
+ def decompressSWF(self, f):
+ if type(f) is str:
+ f = StringIO(f)
+ f.seek(0, 0)
+ magic = f.read(3)
+ if magic == "CWS":
+ return "FWS" + f.read(5) + zlib.decompress(f.read())
+ elif magic == "FWS":
+ #SWF Not Compressed
+ f.seek(0, 0)
+ return f.read()
+ else:
+ #Not SWF
+ return None
+
+ def MD5(self, data):
+ m = hashlib.md5()
+ m.update(data)
+ return m.digest()
+
+ def makeToken(self, sessionID, swfUrl):
+ swfData = self.getURL(swfUrl)
+ decData = self.decompressSWF(swfData)
+ swfMD5 = self.MD5(decData)
+ data = sessionID + swfMD5
+ sig = hmac.new('foo', data, hashlib.sha1)
+ return base64.encodestring(sig.digest()).replace('\n', '')
+
+ def sendNewToken(self, sessionID, path, swf, domain):
+ sessionToken = self.makeToken(sessionID, swf)
+ commandUrl = domain + path + '?cmd=sendingNewToken&v=2.7.6&swf=' + swf.replace('http://', 'http%3A//')
+ self.getURL(commandUrl, True, sessionID, sessionToken)
+
+
+class Server(HTTPServer):
+ """HTTPServer class with timeout."""
+
+ def get_request(self):
+ """Get the request and client address from the socket."""
+ self.socket.settimeout(5.0)
+ result = None
+ while result is None:
+ try:
+ result = self.socket.accept()
+ except socket.timeout:
+ pass
+ result[0].settimeout(1000)
+ return result
+
+class ThreadedHTTPServer(ThreadingMixIn, Server):
+ """Handle requests in a separate thread."""
+
+HOST_NAME = '127.0.0.1'
+#PORT_NUMBER = 64653
+PORT_NUMBER = 9000
+
+if __name__ == '__main__':
+ socket.setdefaulttimeout(10)
+ server_class = ThreadedHTTPServer
+ httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)
+ print "XBMCLocalProxy Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
+ while(True):
+ httpd.handle_request()
+ httpd.server_close()
+ print "XBMCLocalProxy Stops %s:%s" % (HOST_NAME, PORT_NUMBER)
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/changelog.txt b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/changelog.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ed9d9dec13eaa755ed00edfbc33445f223e47e35
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/changelog.txt
@@ -0,0 +1,65 @@
+[B]Version 0.3.2 - fightnight/Leinad4Mind[/B]
+- Fixed some translations.
+- Fixed embed channel id support.
+
+[B]Version 0.3.1 - fightnight[/B]
+- Fixed empty folder on alternative list.
+
+[B]Version 0.3.0 - fightnight[/B]
+- Added support for embed channel IDs (plugin://plugin.video.veetle/?channel=example1234)
+- Added bitrate, thumbnail and watchers info.
+
+[B]Version 0.2.5 - lambda[/B]
+- Added greek translation.
+
+[B]Version 0.2.4 - fightnight[/B]
+- Fixed empty channel folder list (now using official veetle list). More complete list switch on addon settings.
+- Fixed xbmc freeze if plays an offline id.
+- Added strings for translation.
+- Added portuguese translation.
+
+[B]Version 0.2.3 - fightnight[/B]
+- Fixed akamaisecurehd script error.
+- Bumped xbmc.python to 2.1.0.
+
+[B]Version 0.2.2 - sissbruecker[/B]
+- Added more info labels in category view:
+ - Director: Veetle username
+ - Genre: Veetle category
+ - Tagline: Channel description
+ - Plot: Schedule
+
+[B]Version 0.2.1 - sissbruecker[/B]
+- Fixed caching problem - channels/schedule data is now only cached for 10 minutes
+- Added some basic logging
+
+[B]Version 0.2.0 - sissbruecker[/B]
+- Refactoring to several modules/objects
+- Loads channel/schedule data from veetleguide.appspot.com
+- Caches channel/schedule data to prevent reloading of data for each view
+- Sort channels by popularity / current viewers
+- Show channel count next to category
+- Show current schedule item next to channel in category view
+- Added schedule view
+- Improved label formatting
+
+[B]Version 0.1.6 - t0mm0[/B]
+- fix breakage due to site changes
+
+[B]Version 0.1.5 - t0mm0[/B]
+- temporarily(?) remove schedule code due to site changes
+
+[B]Version 0.1.4 - t0mm0[/B]
+- more error handling
+
+[B]Version 0.1.3 - t0mm0[/B]
+- quick small fix for older python versions
+
+[B]Version 0.1.2 - t0mm0[/B]
+- Schedule grabbing (turn off in plugin settings)
+
+[B]Version 0.1.1 - t0mm0[/B]
+- Quick fix for missing large thumbnail on a channel
+
+[B]Version 0.1.0 - t0mm0[/B]
+- Initial version
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/default.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/default.py
new file mode 100644
index 0000000000000000000000000000000000000000..d68ca83d666fec58645078e498eefdca40b63300
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/default.py
@@ -0,0 +1,40 @@
+'''
+ veetle.com XBMC Plugin
+ Copyright (C) 2011 t0mm0
+
+ 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 .
+'''
+
+import xbmc, xbmcaddon, xbmcplugin, xbmcgui
+import Logger
+import VeetleGuideDataSource
+import VeetleProxyServer
+import VeetleViews
+
+pluginUrl = sys.argv[0]
+pluginHandle = int(sys.argv[1])
+pluginQuery = sys.argv[2]
+__settings__ = xbmcaddon.Addon(id='plugin.video.veetle')
+__language__ = __settings__.getLocalizedString
+
+log = Logger.Logger("Main")
+
+dataSource = VeetleGuideDataSource.VeetleGuideDataSource()
+views = VeetleViews.VeetleViews(pluginUrl, pluginHandle, dataSource)
+
+# Start proxy server
+VeetleProxyServer.run()
+
+# Render view according to query URL
+views.renderUrl(pluginQuery)
\ No newline at end of file
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/fanart.jpg b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/fanart.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..32a41ea82d0672ddc8ba6c192e234e607d0a3309
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/fanart.jpg differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/__init__.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..2070df1c7cad57339ed0b2d6e05c2677c3aa4292
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/__init__.py
@@ -0,0 +1,24 @@
+import os
+
+# python 2.4 does not have os.SEEK_*
+try:
+ os.SEEK_SET
+except AttributeError:
+ os.SEEK_SET, os.SEEK_CUR, os.SEEK_END = range(3)
+
+import logging
+
+log = logging.getLogger('flvlib')
+log.setLevel(logging.NOTSET)
+
+handler = logging.StreamHandler()
+handler.setLevel(logging.NOTSET)
+
+formatter = logging.Formatter("%(levelname)-7s %(name)-20s "
+ "%(message)s (%(pathname)s:%(lineno)d)")
+handler.setFormatter(formatter)
+
+log.addHandler(handler)
+
+__version__ = (0, 1, 12)
+__versionstr__ = '.'.join([str(n) for n in __version__])
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/__init__.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..360d1c2aa081acbf52047d07418d7b6690327b28
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/__init__.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/astypes.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/astypes.py
new file mode 100644
index 0000000000000000000000000000000000000000..a1113a7fcee6fc1825eab0de17ab361c69a07864
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/astypes.py
@@ -0,0 +1,310 @@
+import os
+import calendar
+import datetime
+import logging
+
+from primitives import *
+from constants import *
+from helpers import OrderedAttrDict, utc
+
+
+"""
+The AS types and their FLV representations.
+"""
+
+log = logging.getLogger('flvlib.astypes')
+
+
+class MalformedFLV(Exception):
+ pass
+
+
+# Number
+def get_number(f, max_offset=None):
+ return get_double(f)
+
+def make_number(num):
+ return make_double(num)
+
+
+# Boolean
+def get_boolean(f, max_offset=None):
+ value = get_ui8(f)
+ return bool(value)
+
+def make_boolean(value):
+ return make_ui8((value and 1) or 0)
+
+
+# String
+def get_string(f, max_offset=None):
+ # First 16 bits are the string's length
+ length = get_ui16(f)
+ # Then comes the string itself
+ ret = f.read(length)
+ return ret
+
+def make_string(string):
+ if isinstance(string, unicode):
+ # We need a blob, not unicode. Arbitrarily choose UTF-8
+ string = string.encode('UTF-8')
+ length = make_ui16(len(string))
+ return length + string
+
+
+# Longstring
+def get_longstring(f, max_offset=None):
+ # First 32 bits are the string's length
+ length = get_ui32(f)
+ # Then comes the string itself
+ ret = f.read(length)
+ return ret
+
+def make_longstring(string):
+ if isinstance(string, unicode):
+ # We need a blob, not unicode. Arbitrarily choose UTF-8
+ string = string.encode('UTF-8')
+ length = make_ui32(len(string))
+ return length + string
+
+
+# ECMA Array
+class ECMAArray(OrderedAttrDict):
+ pass
+
+
+def get_ecma_array(f, max_offset=None):
+ length = get_ui32(f)
+ log.debug("The ECMA array has approximately %d elements", length)
+ array = ECMAArray()
+ while True:
+ if max_offset and (f.tell() == max_offset):
+ log.debug("Prematurely terminating reading an ECMA array")
+ break
+ marker = get_ui24(f)
+ if marker == 9:
+ log.debug("Marker!")
+ break
+ else:
+ f.seek(-3, os.SEEK_CUR)
+ name, value = get_script_data_variable(f, max_offset=max_offset)
+ array[name] = value
+ return array
+
+def make_ecma_array(d):
+ length = make_ui32(len(d))
+ rest = ''.join([make_script_data_variable(name, value)
+ for name, value in d.iteritems()])
+ marker = make_ui24(9)
+ return length + rest + marker
+
+
+# Strict Array
+def get_strict_array(f, max_offset=None):
+ length = get_ui32(f)
+ log.debug("The length is %d", length)
+ elements = [get_script_data_value(f, max_offset=max_offset)
+ for _ in xrange(length)]
+ return elements
+
+def make_strict_array(l):
+ ret = make_ui32(len(l))
+ rest = ''.join([make_script_data_value(value) for value in l])
+ return ret + rest
+
+
+# Date
+def get_date(f, max_offset=None):
+ timestamp = get_number(f) / 1000.0
+ # From the following document:
+ # http://opensource.adobe.com/wiki/download/
+ # attachments/1114283/amf0_spec_121207.pdf
+ #
+ # Section 2.13 Date Type
+ #
+ # (...) While the design of this type reserves room for time zone offset
+ # information, it should not be filled in, nor used (...)
+ _ignored = get_si16(f)
+ return datetime.datetime.fromtimestamp(timestamp, utc)
+
+def make_date(date):
+ if date.tzinfo:
+ utc_date = date.astimezone(utc)
+ else:
+ # assume it's UTC
+ utc_date = date.replace(tzinfo=utc)
+ ret = make_number(calendar.timegm(utc_date.timetuple()) * 1000)
+ offset = 0
+ return ret + make_si16(offset)
+
+
+# Null
+def get_null(f, max_offset=None):
+ return None
+
+def make_null(none):
+ return ''
+
+
+# Object
+class FLVObject(OrderedAttrDict):
+ pass
+
+
+def get_object(f, max_offset=None):
+ ret = FLVObject()
+ while True:
+ if max_offset and (f.tell() == max_offset):
+ log.debug("Prematurely terminating reading an object")
+ break
+ marker = get_ui24(f)
+ if marker == 9:
+ log.debug("Marker!")
+ break
+ else:
+ f.seek(-3, os.SEEK_CUR)
+ name, value = get_script_data_variable(f)
+ setattr(ret, name, value)
+ return ret
+
+def make_object(obj):
+ # If the object is iterable, serialize keys/values. If not, fall
+ # back on iterating over __dict__.
+ # This makes sure that make_object(get_object(StringIO(blob))) == blob
+ try:
+ iterator = obj.iteritems()
+ except AttributeError:
+ iterator = obj.__dict__.iteritems()
+ ret = ''.join([make_script_data_variable(name, value)
+ for name, value in iterator])
+ marker = make_ui24(9)
+ return ret + marker
+
+
+# MovieClip
+class MovieClip(object):
+
+ def __init__(self, path):
+ self.path = path
+
+ def __eq__(self, other):
+ return isinstance(other, MovieClip) and self.path == other.path
+
+ def __repr__(self):
+ return "" % self.path
+
+def get_movieclip(f, max_offset=None):
+ ret = get_string(f)
+ return MovieClip(ret)
+
+def make_movieclip(clip):
+ return make_string(clip.path)
+
+
+# Undefined
+class Undefined(object):
+
+ def __eq__(self, other):
+ return isinstance(other, Undefined)
+
+ def __repr__(self):
+ return ''
+
+def get_undefined(f, max_offset=None):
+ return Undefined()
+
+def make_undefined(undefined):
+ return ''
+
+
+# Reference
+class Reference(object):
+
+ def __init__(self, ref):
+ self.ref = ref
+
+ def __eq__(self, other):
+ return isinstance(other, Reference) and self.ref == other.ref
+
+ def __repr__(self):
+ return "" % self.ref
+
+def get_reference(f, max_offset=None):
+ ret = get_ui16(f)
+ return Reference(ret)
+
+def make_reference(reference):
+ return make_ui16(reference.ref)
+
+
+as_type_to_getter_and_maker = {
+ VALUE_TYPE_NUMBER: (get_number, make_number),
+ VALUE_TYPE_BOOLEAN: (get_boolean, make_boolean),
+ VALUE_TYPE_STRING: (get_string, make_string),
+ VALUE_TYPE_OBJECT: (get_object, make_object),
+ VALUE_TYPE_MOVIECLIP: (get_movieclip, make_movieclip),
+ VALUE_TYPE_NULL: (get_null, make_null),
+ VALUE_TYPE_UNDEFINED: (get_undefined, make_undefined),
+ VALUE_TYPE_REFERENCE: (get_reference, make_reference),
+ VALUE_TYPE_ECMA_ARRAY: (get_ecma_array, make_ecma_array),
+ VALUE_TYPE_STRICT_ARRAY: (get_strict_array, make_strict_array),
+ VALUE_TYPE_DATE: (get_date, make_date),
+ VALUE_TYPE_LONGSTRING: (get_longstring, make_longstring)
+}
+
+type_to_as_type = {
+ bool: VALUE_TYPE_BOOLEAN,
+ int: VALUE_TYPE_NUMBER,
+ long: VALUE_TYPE_NUMBER,
+ float: VALUE_TYPE_NUMBER,
+ # WARNING: not supporting Longstrings here.
+ # With a max length of 65535 chars, noone will notice.
+ str: VALUE_TYPE_STRING,
+ unicode: VALUE_TYPE_STRING,
+ list: VALUE_TYPE_STRICT_ARRAY,
+ dict: VALUE_TYPE_ECMA_ARRAY,
+ ECMAArray: VALUE_TYPE_ECMA_ARRAY,
+ datetime.datetime: VALUE_TYPE_DATE,
+ Undefined: VALUE_TYPE_UNDEFINED,
+ MovieClip: VALUE_TYPE_MOVIECLIP,
+ Reference: VALUE_TYPE_REFERENCE,
+ type(None): VALUE_TYPE_NULL
+}
+
+# SCRIPTDATAVARIABLE
+def get_script_data_variable(f, max_offset=None):
+ name = get_string(f)
+ log.debug("The name is %s", name)
+ value = get_script_data_value(f, max_offset=max_offset)
+ log.debug("The value is %r", value)
+ return (name, value)
+
+def make_script_data_variable(name, value):
+ log.debug("The name is %s", name)
+ log.debug("The value is %r", value)
+ ret = make_string(name) + make_script_data_value(value)
+ return ret
+
+
+# SCRIPTDATAVALUE
+def get_script_data_value(f, max_offset=None):
+ value_type = get_ui8(f)
+ log.debug("The value type is %r", value_type)
+ try:
+ get_value = as_type_to_getter_and_maker[value_type][0]
+ except KeyError:
+ raise MalformedFLV("Invalid script data value type: %d", value_type)
+ log.debug("The getter function is %r", get_value)
+ value = get_value(f, max_offset=max_offset)
+ return value
+
+def make_script_data_value(value):
+ value_type = type_to_as_type.get(value.__class__, VALUE_TYPE_OBJECT)
+ log.debug("The value type is %r", value_type)
+ # KeyError can't happen here, because we always fall back on
+ # VALUE_TYPE_OBJECT when determining value_type
+ make_value = as_type_to_getter_and_maker[value_type][1]
+ log.debug("The maker function is %r", make_value)
+ type_tag = make_ui8(value_type)
+ ret = make_value(value)
+ return type_tag + ret
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/astypes.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/astypes.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..78b3978170028e39fca12561f5222052779cfb77
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/astypes.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/constants.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/constants.py
new file mode 100644
index 0000000000000000000000000000000000000000..cee8dce105117795f32b3b2cd1e9f321e258c02d
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/constants.py
@@ -0,0 +1,161 @@
+"""
+The constants used in FLV files and their meanings.
+"""
+
+# Tag type
+(TAG_TYPE_AUDIO, TAG_TYPE_VIDEO, TAG_TYPE_SCRIPT) = (8, 9, 18)
+
+
+# Sound format
+(SOUND_FORMAT_PCM_PLATFORM_ENDIAN,
+ SOUND_FORMAT_ADPCM,
+ SOUND_FORMAT_MP3,
+ SOUND_FORMAT_PCM_LITTLE_ENDIAN,
+ SOUND_FORMAT_NELLYMOSER_16KHZ,
+ SOUND_FORMAT_NELLYMOSER_8KHZ,
+ SOUND_FORMAT_NELLYMOSER,
+ SOUND_FORMAT_G711_A_LAW,
+ SOUND_FORMAT_G711_MU_LAW) = range(9)
+
+(SOUND_FORMAT_AAC,
+ SOUND_FORMAT_SPEEX) = range(10, 12)
+
+(SOUND_FORMAT_MP3_8KHZ,
+ SOUND_FORMAT_DEVICE_SPECIFIC) = range(14, 16)
+
+sound_format_to_string = {
+ SOUND_FORMAT_PCM_PLATFORM_ENDIAN: "Linear PCM, platform endian",
+ SOUND_FORMAT_ADPCM: "ADPCM",
+ SOUND_FORMAT_MP3: "MP3",
+ SOUND_FORMAT_PCM_LITTLE_ENDIAN: "Linear PCM, little endian",
+ SOUND_FORMAT_NELLYMOSER_16KHZ: "Nellymoser 16-kHz mono",
+ SOUND_FORMAT_NELLYMOSER_8KHZ: "Nellymoser 8-kHz mono",
+ SOUND_FORMAT_NELLYMOSER: "Nellymoser",
+ SOUND_FORMAT_G711_A_LAW: "G.711 A-law logarithmic PCM",
+ SOUND_FORMAT_G711_MU_LAW: "G.711 mu-law logarithmic PCM",
+ SOUND_FORMAT_AAC: "AAC",
+ SOUND_FORMAT_SPEEX: "Speex",
+ SOUND_FORMAT_MP3_8KHZ: "MP3 8-kHz",
+ SOUND_FORMAT_DEVICE_SPECIFIC: "Device-specific sound"
+}
+
+
+# Sound rate
+(SOUND_RATE_5_5_KHZ,
+ SOUND_RATE_11_KHZ,
+ SOUND_RATE_22_KHZ,
+ SOUND_RATE_44_KHZ) = range(4)
+
+sound_rate_to_string = {
+ SOUND_RATE_5_5_KHZ: "5.5-kHz",
+ SOUND_RATE_11_KHZ: "11-kHz",
+ SOUND_RATE_22_KHZ: "22-kHz",
+ SOUND_RATE_44_KHZ: "44-kHz"
+}
+
+
+# Sound size
+(SOUND_SIZE_8_BIT, SOUND_SIZE_16_BIT) = range(2)
+
+sound_size_to_string = {
+ SOUND_SIZE_8_BIT: "snd8Bit",
+ SOUND_SIZE_16_BIT: "snd16Bit"
+}
+
+
+# Sound type
+(SOUND_TYPE_MONO, SOUND_TYPE_STEREO) = range(2)
+
+sound_type_to_string = {
+ SOUND_TYPE_MONO: "sndMono",
+ SOUND_TYPE_STEREO: "sndStereo"
+}
+
+
+# AAC packet type
+(AAC_PACKET_TYPE_SEQUENCE_HEADER,
+ AAC_PACKET_TYPE_RAW) = range(2)
+
+aac_packet_type_to_string = {
+ AAC_PACKET_TYPE_SEQUENCE_HEADER: "sequence header",
+ AAC_PACKET_TYPE_RAW: "raw"
+}
+
+
+# Codec ID
+(CODEC_ID_JPEG,
+ CODEC_ID_H263,
+ CODEC_ID_SCREEN_VIDEO,
+ CODEC_ID_VP6,
+ CODEC_ID_VP6_WITH_ALPHA,
+ CODEC_ID_SCREEN_VIDEO_V2,
+ CODEC_ID_H264) = range(1, 8)
+
+codec_id_to_string = {
+ CODEC_ID_JPEG: "JPEG",
+ CODEC_ID_H263: "Sorenson H.263",
+ CODEC_ID_SCREEN_VIDEO: "Screen video",
+ CODEC_ID_VP6: "On2 VP6",
+ CODEC_ID_VP6_WITH_ALPHA: "On2 VP6 with alpha channel",
+ CODEC_ID_SCREEN_VIDEO_V2: "Screen video version 2",
+ CODEC_ID_H264: "H.264"
+}
+
+
+# Frame type
+(FRAME_TYPE_KEYFRAME,
+ FRAME_TYPE_INTERFRAME,
+ FRAME_TYPE_DISPOSABLE_INTERFRAME,
+ FRAME_TYPE_GENERATED_KEYFRAME,
+ FRAME_TYPE_INFO_FRAME) = range(1, 6)
+
+frame_type_to_string = {
+ FRAME_TYPE_KEYFRAME: "keyframe",
+ FRAME_TYPE_INTERFRAME: "interframe",
+ FRAME_TYPE_DISPOSABLE_INTERFRAME: "disposable interframe",
+ FRAME_TYPE_GENERATED_KEYFRAME: "generated keyframe",
+ FRAME_TYPE_INFO_FRAME: "video info/command frame"
+}
+
+
+# H.264 packet type
+(H264_PACKET_TYPE_SEQUENCE_HEADER,
+ H264_PACKET_TYPE_NALU,
+ H264_PACKET_TYPE_END_OF_SEQUENCE) = range(3)
+
+h264_packet_type_to_string = {
+ H264_PACKET_TYPE_SEQUENCE_HEADER: "sequence header",
+ H264_PACKET_TYPE_NALU: "NAL unit",
+ H264_PACKET_TYPE_END_OF_SEQUENCE: "sequence end"
+}
+
+
+# Value type
+(VALUE_TYPE_NUMBER,
+ VALUE_TYPE_BOOLEAN,
+ VALUE_TYPE_STRING,
+ VALUE_TYPE_OBJECT,
+ VALUE_TYPE_MOVIECLIP,
+ VALUE_TYPE_NULL,
+ VALUE_TYPE_UNDEFINED,
+ VALUE_TYPE_REFERENCE,
+ VALUE_TYPE_ECMA_ARRAY) = range(9)
+
+(VALUE_TYPE_STRICT_ARRAY,
+ VALUE_TYPE_DATE,
+ VALUE_TYPE_LONGSTRING) = range(10, 13)
+
+value_type_to_string = {
+ VALUE_TYPE_NUMBER: 'Number',
+ VALUE_TYPE_BOOLEAN: 'Boolean',
+ VALUE_TYPE_STRING: 'String',
+ VALUE_TYPE_OBJECT: 'Object',
+ VALUE_TYPE_MOVIECLIP: 'MovieClip',
+ VALUE_TYPE_NULL: 'Null',
+ VALUE_TYPE_UNDEFINED: 'Undefined',
+ VALUE_TYPE_REFERENCE: 'Reference',
+ VALUE_TYPE_ECMA_ARRAY: 'ECMA Array',
+ VALUE_TYPE_STRICT_ARRAY: 'Strict Array',
+ VALUE_TYPE_DATE: 'Date',
+ VALUE_TYPE_LONGSTRING: 'Longstring'
+}
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/constants.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/constants.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..1ab5f007ee293335c0d546b577d71c3e5775188b
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/constants.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/helpers.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/helpers.py
new file mode 100644
index 0000000000000000000000000000000000000000..835747867c4bd1a9bf761077a8c936899b3852ba
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/helpers.py
@@ -0,0 +1,205 @@
+import os
+import time
+import datetime
+
+from StringIO import StringIO
+from UserDict import DictMixin
+
+
+class UTC(datetime.tzinfo):
+ """
+ A UTC tzinfo class, based on
+ http://docs.python.org/library/datetime.html#datetime.tzinfo
+ """
+
+ ZERO = datetime.timedelta(0)
+
+ def utcoffset(self, dt):
+ return self.ZERO
+
+ def tzname(self, dt):
+ return "UTC"
+
+ def dst(self, dt):
+ return self.ZERO
+
+utc = UTC()
+
+class OrderedAttrDict(DictMixin):
+ """
+ A dictionary that preserves insert order and also has an attribute
+ interface.
+
+ Values can be transparently accessed and set as keys or as attributes.
+ """
+
+ def __init__(self, dict=None, **kwargs):
+ self.__dict__["_order_priv_"] = []
+ self.__dict__["_data_priv_"] = {}
+ if dict is not None:
+ self.update(dict)
+ if len(kwargs):
+ self.update(kwargs)
+
+ # Mapping interface
+
+ def __setitem__(self, key, value):
+ if key not in self:
+ self._order_priv_.append(key)
+ self._data_priv_[key] = value
+
+ def __getitem__(self, key):
+ return self._data_priv_[key]
+
+ def __delitem__(self, key):
+ del self._data_priv_[key]
+ self._order_priv_.remove(key)
+
+ def keys(self):
+ return list(self._order_priv_)
+
+ # Attribute interface
+
+ def __getattr__(self, name):
+ try:
+ return self[name]
+ except KeyError:
+ raise AttributeError(name)
+
+ def __setattr__(self, name, value):
+ self[name] = value
+
+ def __delattr__(self, name):
+ try:
+ del self[name]
+ except KeyError:
+ raise AttributeError(name)
+
+ # Equality
+ def __eq__(self, other):
+ try:
+ my_iter = self.iteritems()
+ his_iter = other.iteritems()
+ except AttributeError:
+ return False
+ my_empty = False
+ his_empty = False
+ while True:
+ try:
+ my_key, my_val = my_iter.next()
+ except StopIteration:
+ my_empty = True
+ try:
+ his_key, his_val = his_iter.next()
+ except StopIteration:
+ his_empty = True
+ if my_empty and his_empty:
+ return True
+ if my_empty or his_empty:
+ return False
+ if (my_key, my_val) != (his_key, his_val):
+ return False
+
+ # String representation
+ def __repr__(self):
+ return '<%s %s>' % (self.__class__.__name__, self)
+
+ def __str__(self):
+ return '{' + ', '.join([('%r: %r' % (key, self[key]))
+ for key in self._order_priv_]) + '}'
+
+
+class ASPrettyPrinter(object):
+ """Pretty printing of AS objects"""
+
+ def pformat(cls, val, indent=0):
+ cls.io = StringIO()
+ cls.pprint_lookup(val, indent)
+ return cls.io.getvalue()
+ pformat = classmethod(pformat)
+
+ def pprint(cls, val):
+ print cls.pformat(val)
+ pprint = classmethod(pprint)
+
+ def pprint_lookup(cls, val, ident):
+ if isinstance(val, basestring):
+ return cls.pprint_string(val)
+ if isinstance(val, (int, long, float)):
+ return cls.pprint_number(val)
+ if isinstance(val, datetime.datetime):
+ return cls.pprint_datetime(val)
+ if hasattr(val, 'iterkeys'):
+ # dict interface
+ return cls.pprint_dict(val, ident)
+ if hasattr(val, 'append'):
+ # list interface
+ return cls.pprint_list(val, ident)
+ # Unknown type ?
+ cls.io.write("%r" % (val, ))
+ return False
+ pprint_lookup = classmethod(pprint_lookup)
+
+ def pprint_string(cls, val):
+ if isinstance(val, unicode):
+ cls.io.write("u'%s'" % val.encode("UTF8"))
+ else:
+ cls.io.write("'%s'" % val)
+ return False
+ pprint_string = classmethod(pprint_string)
+
+ def pprint_number(cls, val):
+ cls.io.write(str(val))
+ return False
+ pprint_number = classmethod(pprint_number)
+
+ def pprint_datetime(cls, val):
+ cls.io.write(val.replace(microsecond=0).isoformat(' '))
+ return False
+ pprint_datetime = classmethod(pprint_datetime)
+
+ def pprint_dict(cls, val, indent):
+
+ def pprint_item(k):
+ last_pos = cls.io.tell()
+ cls.io.write(repr(k))
+ cls.io.write(": ")
+ new_indent = indent + cls.io.tell() - last_pos + 1
+ return cls.pprint_lookup(val[k], new_indent)
+
+ cls.io.write('{')
+ indented = False
+ keys = list(val.iterkeys())
+ if keys:
+ for k in keys[:-1]:
+ indented |= pprint_item(k)
+ cls.io.write(",\n%s " % (" "*indent))
+ indented |= pprint_item(keys[-1])
+ cls.io.write('}')
+ return (len(keys) > 1) | indented
+ pprint_dict = classmethod(pprint_dict)
+
+ def pprint_list(cls, val, indent):
+ last_pos = cls.io.tell()
+ cls.io.write('[')
+ new_indent = indent + cls.io.tell() - last_pos
+ indented = False
+ values = list(iter(val))
+ if values:
+ for v in values[:-1]:
+ indented |= cls.pprint_lookup(v, new_indent)
+ cls.io.write(",\n%s" % (" "*new_indent))
+ indented |= cls.pprint_lookup(values[-1], new_indent)
+ cls.io.write(']')
+ return (len(values) > 1) | indented
+ pprint_list = classmethod(pprint_list)
+
+pformat = ASPrettyPrinter.pformat
+pprint = ASPrettyPrinter.pprint
+
+
+def force_remove(path):
+ try:
+ os.remove(path)
+ except OSError:
+ pass
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/helpers.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/helpers.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..bfa83e96f74dfae085c8d5939d24ef8256b8b1fa
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/helpers.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/primitives.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/primitives.py
new file mode 100644
index 0000000000000000000000000000000000000000..38b823c623eecd66fafa4f37276cc426dce172b5
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/primitives.py
@@ -0,0 +1,106 @@
+import struct
+
+"""
+The internal FLV representations of numbers.
+"""
+
+
+__all__ = ['get_ui32', 'make_ui32', 'get_si32_extended', 'make_si32_extended',
+ 'get_ui24', 'make_ui24', 'get_ui16', 'make_ui16',
+ 'get_si16', 'make_si16', 'get_ui8', 'make_ui8',
+ 'get_double', 'make_double', 'EndOfFile']
+
+
+class EndOfFile(Exception):
+ pass
+
+
+# UI32
+def get_ui32(f):
+ try:
+ ret = struct.unpack(">I", f.read(4))[0]
+ except struct.error:
+ raise EndOfFile
+ return ret
+
+def make_ui32(num):
+ return struct.pack(">I", num)
+
+
+# SI32 extended
+def get_si32_extended(f):
+ # The last 8 bits are the high 8 bits of the whole number
+ # That's how Adobe likes it. Go figure...
+ low_high = f.read(4)
+ if len(low_high) < 4:
+ raise EndOfFile
+ combined = low_high[3] + low_high[:3]
+ return struct.unpack(">i", combined)[0]
+
+def make_si32_extended(num):
+ ret = struct.pack(">i", num)
+ return ret[1:] + ret[0]
+
+
+# UI24
+def get_ui24(f):
+ try:
+ high, low = struct.unpack(">BH", f.read(3))
+ except struct.error:
+ raise EndOfFile
+ ret = (high << 16) + low
+ return ret
+
+def make_ui24(num):
+ ret = struct.pack(">I", num)
+ return ret[1:]
+
+
+# UI16
+def get_ui16(f):
+ try:
+ ret = struct.unpack(">H", f.read(2))[0]
+ except struct.error:
+ raise EndOfFile
+ return ret
+
+def make_ui16(num):
+ return struct.pack(">H", num)
+
+
+# SI16
+def get_si16(f):
+ try:
+ ret = struct.unpack(">h", f.read(2))[0]
+ except struct.error:
+ raise EndOfFile
+ return ret
+
+def make_si16(num):
+ return struct.pack(">h", num)
+
+
+# UI8
+def get_ui8(f):
+ try:
+ ret = struct.unpack("B", f.read(1))[0]
+ except struct.error:
+ raise EndOfFile
+ return ret
+
+def make_ui8(num):
+ return struct.pack("B", num)
+
+
+
+# DOUBLE
+def get_double(f):
+ data = f.read(8)
+ try:
+ ret = struct.unpack(">d", data)[0]
+ except struct.error:
+ raise EndOfFile
+ return ret
+
+def make_double(num):
+ return struct.pack(">d", num)
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/primitives.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/primitives.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..92fd837ce08b876124789afbdd56bfb6f0b5d626
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/primitives.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/scripts/__init__.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/scripts/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/scripts/debug_flv.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/scripts/debug_flv.py
new file mode 100644
index 0000000000000000000000000000000000000000..97550fa83a2d2b6f425b92f3ea23ea05f06b269c
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/scripts/debug_flv.py
@@ -0,0 +1,119 @@
+import sys
+import logging
+
+from optparse import OptionParser
+
+from flvlib import __versionstr__
+from flvlib import tags
+from flvlib import helpers
+from flvlib.astypes import MalformedFLV
+
+log = logging.getLogger('flvlib.debug-flv')
+log.setLevel(logging.ERROR)
+
+
+def debug_file(filename, quiet=False, metadata=False):
+ try:
+ f = open(filename, 'rb')
+ except IOError, (errno, strerror):
+ log.error("Failed to open `%s': %s", filename, strerror)
+ return False
+
+ flv = tags.FLV(f)
+
+ if not quiet:
+ print "=== `%s' ===" % filename
+
+ try:
+ tag_generator = flv.iter_tags()
+ for i, tag in enumerate(tag_generator):
+ if quiet:
+ # If we're quiet, we just want to catch errors
+ continue
+ # Print the tag information
+ print "#%05d %s" % (i + 1, tag)
+ # Print the content of onMetaData tags
+ if (isinstance(tag, tags.ScriptTag)
+ and tag.name == "onMetaData"):
+ helpers.pprint(tag.variable)
+ if metadata:
+ return True
+ except MalformedFLV, e:
+ message = e[0] % e[1:]
+ log.error("The file `%s' is not a valid FLV file: %s",
+ filename, message)
+ return False
+ except tags.EndOfFile:
+ log.error("Unexpected end of file on file `%s'", filename)
+ return False
+
+ f.close()
+
+ return True
+
+
+def process_options():
+ usage = "%prog [options] files ..."
+ description = ("Checks FLV files for comformance with the FLV "
+ "specification. Outputs a list of tags and, "
+ "if present, the content of the onMetaData script tag.")
+ version = "%%prog flvlib %s" % __versionstr__
+ parser = OptionParser(usage=usage, description=description,
+ version=version)
+ parser.add_option("-s", "--strict", action="store_true",
+ help="be strict while parsing the FLV file")
+ parser.add_option("-q", "--quiet", action="store_true",
+ help="do not output anything unless there are errors")
+ parser.add_option("-m", "--metadata", action="store_true",
+ help="exit immediately after printing an onMetaData tag")
+ parser.add_option("-v", "--verbose", action="count",
+ default=0, dest="verbosity",
+ help="be more verbose, each -v increases verbosity")
+ options, args = parser.parse_args(sys.argv)
+
+ if len(args) < 2:
+ parser.error("You have to provide at least one file path")
+
+ if options.strict:
+ tags.STRICT_PARSING = True
+
+ if options.verbosity > 3:
+ options.verbosity = 3
+
+ level = ({0: logging.ERROR, 1: logging.WARNING,
+ 2: logging.INFO, 3: logging.DEBUG}[options.verbosity])
+ logging.getLogger('flvlib').setLevel(level)
+
+ return options, args
+
+
+def debug_files():
+ options, args = process_options()
+
+ clean_run = True
+
+ for filename in args[1:]:
+ if not debug_file(filename, options.quiet, options.metadata):
+ clean_run = False
+
+ return clean_run
+
+
+def main():
+ try:
+ outcome = debug_files()
+ except KeyboardInterrupt:
+ # give the right exit status, 128 + signal number
+ # signal.SIGINT = 2
+ sys.exit(128 + 2)
+ except EnvironmentError, (errno, strerror):
+ try:
+ print >>sys.stderr, strerror
+ except StandardError:
+ pass
+ sys.exit(2)
+
+ if outcome:
+ sys.exit(0)
+ else:
+ sys.exit(1)
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/scripts/index_flv.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/scripts/index_flv.py
new file mode 100644
index 0000000000000000000000000000000000000000..cb0c437651d8456724d2c1322df64ce83fe2295e
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/scripts/index_flv.py
@@ -0,0 +1,400 @@
+import os
+import sys
+import shutil
+import logging
+import tempfile
+
+from optparse import OptionParser
+
+from flvlib import __versionstr__
+from flvlib.constants import TAG_TYPE_AUDIO, TAG_TYPE_VIDEO, TAG_TYPE_SCRIPT
+from flvlib.constants import FRAME_TYPE_KEYFRAME
+from flvlib.astypes import MalformedFLV, FLVObject
+from flvlib.tags import FLV, EndOfFile, AudioTag, VideoTag, ScriptTag
+from flvlib.tags import create_script_tag, create_flv_header
+from flvlib.helpers import force_remove
+
+log = logging.getLogger('flvlib.index-flv')
+
+
+class IndexingAudioTag(AudioTag):
+
+ SEEKPOINT_DENSITY = 10
+
+ def __init__(self, parent_flv, f):
+ AudioTag.__init__(self, parent_flv, f)
+
+ def parse(self):
+ parent = self.parent_flv
+ AudioTag.parse(self)
+
+ if not parent.first_media_tag_offset:
+ parent.first_media_tag_offset = self.offset
+
+
+ # If the FLV has video, we're done. No need to store audio seekpoint
+ # information anymore.
+ if not parent.no_video:
+ return
+
+ # We haven't seen any video tag yet. Store every SEEKPOINT_DENSITY tag
+ # offset and timestamp.
+ parent.audio_tag_number += 1
+ if (parent.audio_tag_number % self.SEEKPOINT_DENSITY == 0):
+ parent.audio_seekpoints.filepositions.append(self.offset)
+ parent.audio_seekpoints.times.append(self.timestamp / 1000.0)
+
+
+class IndexingVideoTag(VideoTag):
+
+ def parse(self):
+ parent = self.parent_flv
+ VideoTag.parse(self)
+
+ parent.no_video = False
+
+ if not parent.first_media_tag_offset:
+ parent.first_media_tag_offset = self.offset
+
+ if self.frame_type == FRAME_TYPE_KEYFRAME:
+ parent.keyframes.filepositions.append(self.offset)
+ parent.keyframes.times.append(self.timestamp / 1000.0)
+
+
+class IndexingScriptTag(ScriptTag):
+
+ def parse(self):
+ parent = self.parent_flv
+ ScriptTag.parse(self)
+
+ if self.name == 'onMetaData':
+ parent.metadata = self.variable
+ parent.metadata_tag_start = self.offset
+ parent.metadata_tag_end = self.f.tell()
+
+
+tag_to_class = {
+ TAG_TYPE_AUDIO: IndexingAudioTag,
+ TAG_TYPE_VIDEO: IndexingVideoTag,
+ TAG_TYPE_SCRIPT: IndexingScriptTag
+}
+
+
+class IndexingFLV(FLV):
+
+ def __init__(self, f):
+ FLV.__init__(self, f)
+ self.metadata = None
+ self.keyframes = FLVObject()
+ self.keyframes.filepositions = []
+ self.keyframes.times = []
+ self.no_video = True
+
+ # If the FLV file has no video, there are no keyframes. We want to put
+ # some info in the metadata anyway -- Flash players use keyframe
+ # information as a seek table. In audio-only FLV files you can usually
+ # seek to the beginning of any tag (this is not entirely true for AAC).
+ # Most players still work if you just provide "keyframe" info that's
+ # really a table of every Nth audio tag, even with AAC.
+ # Because of that, until we see a video tag we make every Nth
+ # IndexingAudioTag store its offset and timestamp.
+ self.audio_tag_number = 0
+ self.audio_seekpoints = FLVObject()
+ self.audio_seekpoints.filepositions = []
+ self.audio_seekpoints.times = []
+
+ self.metadata_tag_start = None
+ self.metadata_tag_end = None
+ self.first_media_tag_offset = None
+
+ def tag_type_to_class(self, tag_type):
+ try:
+ return tag_to_class[tag_type]
+ except KeyError:
+ raise MalformedFLV("Invalid tag type: %d", tag_type)
+
+
+def filepositions_difference(metadata, original_metadata_size):
+ test_payload = create_script_tag('onMetaData', metadata)
+ payload_size = len(test_payload)
+ difference = payload_size - original_metadata_size
+ return test_payload, difference
+
+
+def retimestamp_and_index_file(inpath, outpath=None, retimestamp=None):
+
+ # no retimestamping needed
+ if retimestamp is None:
+
+ return index_file(inpath, outpath)
+
+ # retimestamp the input in place and index
+ elif retimestamp == 'inplace':
+ from flvlib.scripts.retimestamp_flv import retimestamp_file_inplace
+
+ log.debug("Retimestamping file `%s' in place", inpath)
+
+ # retimestamp the file inplace
+ if not retimestamp_file_inplace(inpath):
+ log.error("Failed to retimestamp `%s' in place", inpath)
+ return False
+
+ return index_file(inpath, outpath)
+
+ # retimestamp the input into a temporary file
+ elif retimestamp == 'atomic':
+ from flvlib.scripts.retimestamp_flv import retimestamp_file_atomically
+
+ log.debug("Retimestamping file `%s' atomically", inpath)
+
+ try:
+ fd, temppath = tempfile.mkstemp()
+ os.close(fd)
+ # preserve the permission bits
+ shutil.copymode(inpath, temppath)
+ except EnvironmentError, (errno, strerror):
+ log.error("Failed to create temporary file: %s", strerror)
+ return False
+
+ if not retimestamp_file_atomically(inpath, temppath):
+ log.error("Failed to retimestamp `%s' atomically", inpath)
+ # remove the temporary files
+ force_remove(temppath)
+ return False
+
+ # index the temporary file
+ if not index_file(temppath, outpath):
+ force_remove(temppath)
+ return False
+
+ if not outpath:
+ # If we were not writing directly to the output file
+ # we need to overwrite the original
+ try:
+ shutil.move(temppath, inpath)
+ except EnvironmentError, (errno, strerror):
+ log.error("Failed to overwrite the original file with the "
+ "retimestamped and indexed version: %s", strerror)
+ return False
+ else:
+ # if we were writing directly to the output file we need to remove
+ # the retimestamped temporary file
+ force_remove(temppath)
+
+ return True
+
+
+def index_file(inpath, outpath=None):
+ out_text = (outpath and ("into file `%s'" % outpath)) or "and overwriting"
+ log.debug("Indexing file `%s' %s", inpath, out_text)
+
+ try:
+ f = open(inpath, 'rb')
+ except IOError, (errno, strerror):
+ log.error("Failed to open `%s': %s", inpath, strerror)
+ return False
+
+ flv = IndexingFLV(f)
+ tag_iterator = flv.iter_tags()
+ last_tag = None
+
+ try:
+ while True:
+ tag = tag_iterator.next()
+ # some buggy software, like gstreamer's flvmux, puts a metadata tag
+ # at the end of the file with timestamp 0, and we don't want to
+ # base our duration computation on that
+ if tag.timestamp != 0:
+ last_tag = tag
+ except MalformedFLV, e:
+ message = e[0] % e[1:]
+ log.error("The file `%s' is not a valid FLV file: %s", inpath, message)
+ return False
+ except EndOfFile:
+ log.error("Unexpected end of file on file `%s'", inpath)
+ return False
+ except StopIteration:
+ pass
+
+ if not flv.first_media_tag_offset:
+ log.error("The file `%s' does not have any media content", inpath)
+ return False
+
+ if not last_tag:
+ log.error("The file `%s' does not have any content with a "
+ "non-zero timestamp", inpath)
+ return False
+
+ metadata = flv.metadata or {}
+
+ if flv.metadata_tag_start:
+ original_metadata_size = flv.metadata_tag_end - flv.metadata_tag_start
+ else:
+ log.debug("The file `%s' has no metadata", inpath)
+ original_metadata_size = 0
+
+ keyframes = flv.keyframes
+
+ if flv.no_video:
+ log.info("The file `%s' has no video, using audio seekpoints info",
+ inpath)
+ keyframes = flv.audio_seekpoints
+
+ duration = metadata.get('duration')
+ if not duration:
+ # A duration of 0 is nonsensical, yet some tools put it like that. In
+ # that case (or when there is no such field) update the duration value.
+ duration = last_tag.timestamp / 1000.0
+
+ metadata['duration'] = duration
+ metadata['keyframes'] = keyframes
+ metadata['metadatacreator'] = 'flvlib %s' % __versionstr__
+
+ # we're going to write new metadata, so we need to shift the
+ # filepositions by the amount of bytes that we're going to add to
+ # the metadata tag
+ test_payload, difference = filepositions_difference(metadata,
+ original_metadata_size)
+
+ if difference:
+ new_filepositions = [pos + difference
+ for pos in keyframes.filepositions]
+ metadata['keyframes'].filepositions = new_filepositions
+ payload = create_script_tag('onMetaData', metadata)
+ else:
+ log.debug("The file `%s' metadata size did not change.", inpath)
+ payload = test_payload
+
+ if outpath:
+ try:
+ fo = open(outpath, 'wb')
+ except IOError, (errno, strerror):
+ log.error("Failed to open `%s': %s", outpath, strerror)
+ return False
+ else:
+ try:
+ fd, temppath = tempfile.mkstemp()
+ # preserve the permission bits
+ shutil.copymode(inpath, temppath)
+ fo = os.fdopen(fd, 'wb')
+ except EnvironmentError, (errno, strerror):
+ log.error("Failed to create temporary file: %s", strerror)
+ return False
+
+ log.debug("Creating the output file")
+
+ try:
+ fo.write(create_flv_header(has_audio=flv.has_audio,
+ has_video=flv.has_video))
+ fo.write(payload)
+ f.seek(flv.first_media_tag_offset)
+ shutil.copyfileobj(f, fo)
+ except IOError, (errno, strerror):
+ log.error("Failed to create the indexed file: %s", strerror)
+ if not outpath:
+ # remove the temporary file
+ force_remove(temppath)
+ return False
+
+ f.close()
+ fo.close()
+
+ if not outpath:
+ # If we were not writing directly to the output file
+ # we need to overwrite the original
+ try:
+ shutil.move(temppath, inpath)
+ except EnvironmentError, (errno, strerror):
+ log.error("Failed to overwrite the original file "
+ "with the indexed version: %s", strerror)
+ return False
+
+ return True
+
+
+def process_options():
+ usage = "%prog [-U] file [outfile|file2 file3 ...]"
+ description = ("Finds keyframe timestamps and file offsets "
+ "in FLV files and updates the onMetaData "
+ "script tag with that information. "
+ "With the -U (update) option operates on all parameters, "
+ "overwriting the original file. Without the -U "
+ "option accepts one input and one output file path.")
+ version = "%%prog flvlib %s" % __versionstr__
+ parser = OptionParser(usage=usage, description=description,
+ version=version)
+ parser.add_option("-U", "--update", action="store_true",
+ help=("update mode, overwrites the given files "
+ "instead of writing to outfile"))
+ parser.add_option("-r", "--retimestamp", action="store_true",
+ help=("rewrite timestamps in the files before indexing, "
+ "identical to running retimestamp-flv first"))
+ parser.add_option("-R", "--retimestamp-inplace", action="store_true",
+ help=("same as -r but avoid creating temporary files at "
+ "the risk of corrupting the input files in case "
+ "of errors"))
+ parser.add_option("-v", "--verbose", action="count",
+ default=0, dest="verbosity",
+ help="be more verbose, each -v increases verbosity")
+ options, args = parser.parse_args(sys.argv)
+
+ if len(args) < 2:
+ parser.error("You have to provide at least one file path")
+
+ if not options.update and len(args) != 3:
+ parser.error("You need to provide one infile and one outfile "
+ "when not using the update mode")
+
+ if options.retimestamp and options.retimestamp_inplace:
+ parser.error("You cannot provide both -r and -R")
+
+ if options.verbosity > 3:
+ options.verbosity = 3
+
+ log.setLevel({0: logging.ERROR, 1: logging.WARNING,
+ 2: logging.INFO, 3: logging.DEBUG}[options.verbosity])
+
+ return options, args
+
+
+def index_files():
+ options, args = process_options()
+
+ clean_run = True
+
+ retimestamp_mode = None
+ if options.retimestamp:
+ retimestamp_mode = 'atomic'
+ elif options.retimestamp_inplace:
+ retimestamp_mode = 'inplace'
+
+ if not options.update:
+ clean_run = retimestamp_and_index_file(args[1], args[2],
+ retimestamp=retimestamp_mode)
+ else:
+ for filename in args[1:]:
+ if not retimestamp_and_index_file(filename,
+ retimestamp=retimestamp_mode):
+ clean_run = False
+
+ return clean_run
+
+
+def main():
+ try:
+ outcome = index_files()
+ except KeyboardInterrupt:
+ # give the right exit status, 128 + signal number
+ # signal.SIGINT = 2
+ sys.exit(128 + 2)
+ except EnvironmentError, (errno, strerror):
+ try:
+ print >>sys.stderr, strerror
+ except StandardError:
+ pass
+ sys.exit(2)
+
+ if outcome:
+ sys.exit(0)
+ else:
+ sys.exit(1)
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/scripts/retimestamp_flv.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/scripts/retimestamp_flv.py
new file mode 100644
index 0000000000000000000000000000000000000000..6fe2fffa486906b350cf22614f3b788faa4f98f8
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/scripts/retimestamp_flv.py
@@ -0,0 +1,254 @@
+import os
+import sys
+import shutil
+import logging
+import tempfile
+
+from optparse import OptionParser
+
+from flvlib import __versionstr__
+from flvlib.constants import TAG_TYPE_AUDIO, TAG_TYPE_VIDEO, TAG_TYPE_SCRIPT
+from flvlib.constants import AAC_PACKET_TYPE_SEQUENCE_HEADER
+from flvlib.constants import H264_PACKET_TYPE_SEQUENCE_HEADER
+from flvlib.primitives import make_ui8, make_ui24, make_si32_extended
+from flvlib.astypes import MalformedFLV
+from flvlib.tags import FLV, EndOfFile, AudioTag, VideoTag, ScriptTag
+from flvlib.helpers import force_remove
+
+log = logging.getLogger('flvlib.retimestamp-flv')
+
+
+class_to_tag = {
+ AudioTag: TAG_TYPE_AUDIO,
+ VideoTag: TAG_TYPE_VIDEO,
+ ScriptTag: TAG_TYPE_SCRIPT
+}
+
+
+def is_nonheader_media(tag):
+ if isinstance(tag, ScriptTag):
+ return False
+ if isinstance(tag, AudioTag):
+ return tag.aac_packet_type != AAC_PACKET_TYPE_SEQUENCE_HEADER
+ if isinstance(tag, VideoTag):
+ return tag.h264_packet_type != H264_PACKET_TYPE_SEQUENCE_HEADER
+
+
+def output_offset_tag(fi, fo, tag, offset):
+ new_timestamp = tag.timestamp - offset
+ # do not offset non-media and media header
+ if not is_nonheader_media(tag):
+ new_timestamp = tag.timestamp
+
+ # write the FLV tag value
+ fo.write(make_ui8(class_to_tag[tag.__class__]))
+ # the tag size remains unchanged
+ fo.write(make_ui24(tag.size))
+ # wirte the new timestamp
+ fo.write(make_si32_extended(new_timestamp))
+ # seek inside the input file
+ # seek position: tag offset + tag (1) + size (3) + timestamp (4)
+ fi.seek(tag.offset + 8, os.SEEK_SET)
+ # copy the tag content to the output file
+ # content size: tag size + stream ID (3) + previous tag size (4)
+ fo.write(fi.read(tag.size + 7))
+
+
+def retimestamp_tags_inplace(f, fu):
+ flv = FLV(f)
+ offset = None
+
+ for tag in flv.iter_tags():
+ if offset is None and is_nonheader_media(tag):
+ offset = tag.timestamp
+ log.debug("Determined the offset to be %d", offset)
+
+ # optimise for offset == 0, which in case of inplace updating is a noop
+ if offset is not None and offset != 0:
+ fu.seek(tag.offset + 4, os.SEEK_SET)
+ fu.write(make_si32_extended(tag.timestamp - offset))
+
+
+def retimestamp_file_inplace(inpath):
+ try:
+ f = open(inpath, 'rb')
+ fu = open(inpath, 'rb+')
+ except IOError, (errno, strerror):
+ log.error("Failed to open `%s': %s", inpath, strerror)
+ return False
+
+ try:
+ retimestamp_tags_inplace(f, fu)
+ except IOError, (errno, strerror):
+ log.error("Failed to create the retimestamped file: %s", strerror)
+ return False
+ except MalformedFLV, e:
+ message = e[0] % e[1:]
+ log.error("The file `%s' is not a valid FLV file: %s", inpath, message)
+ return False
+ except EndOfFile:
+ log.error("Unexpected end of file on file `%s'", inpath)
+ return False
+
+ f.close()
+ fu.close()
+
+ return True
+
+
+def retimestamp_file_atomically(inpath, outpath):
+ try:
+ f = open(inpath, 'rb')
+ except IOError, (errno, strerror):
+ log.error("Failed to open `%s': %s", inpath, strerror)
+ return False
+
+ if outpath:
+ try:
+ fo = open(outpath, 'w+b')
+ except IOError, (errno, strerror):
+ log.error("Failed to open `%s': %s", outpath, strerror)
+ return False
+ else:
+ try:
+ fd, temppath = tempfile.mkstemp()
+ # preserve the permission bits
+ shutil.copymode(inpath, temppath)
+ fo = os.fdopen(fd, 'wb')
+ except EnvironmentError, (errno, strerror):
+ log.error("Failed to create temporary file: %s", strerror)
+ return False
+
+ try:
+ shutil.copyfileobj(f, fo)
+ except EnvironmentError, (errno, strerror):
+ log.error("Failed to create temporary copy: %s", strerror)
+ force_remove(temppath)
+ return False
+
+ f.seek(0)
+ fo.seek(0)
+
+ try:
+ retimestamp_tags_inplace(f, fo)
+ except IOError, (errno, strerror):
+ log.error("Failed to create the retimestamped file: %s", strerror)
+ if not outpath:
+ force_remove(temppath)
+ return False
+ except MalformedFLV, e:
+ message = e[0] % e[1:]
+ log.error("The file `%s' is not a valid FLV file: %s", inpath, message)
+ if not outpath:
+ force_remove(temppath)
+ return False
+ except EndOfFile:
+ log.error("Unexpected end of file on file `%s'", inpath)
+ if not outpath:
+ force_remove(temppath)
+ return False
+
+ f.close()
+ fo.close()
+
+ if not outpath:
+ # If we were not writing directly to the output file
+ # we need to overwrite the original
+ try:
+ shutil.move(temppath, inpath)
+ except EnvironmentError, (errno, strerror):
+ log.error("Failed to overwrite the original file "
+ "with the indexed version: %s", strerror)
+ return False
+
+ return True
+
+
+def retimestamp_file(inpath, outpath=None, inplace=False):
+ out_text = (outpath and ("into file `%s'" % outpath)) or "and overwriting"
+ log.debug("Retimestamping file `%s' %s", inpath, out_text)
+
+ if inplace:
+ log.debug("Operating in inplace mode")
+ return retimestamp_file_inplace(inpath)
+ else:
+ log.debug("Not operating in inplace mode, using temporary files")
+ return retimestamp_file_atomically(inpath, outpath)
+
+
+def process_options():
+ usage = "%prog [-i] [-U] file [outfile|file2 file3 ...]"
+ description = (
+"""Rewrites timestamps in FLV files making by the first media tag timestamped
+ with 0. The rest of the tags is retimestamped relatively. With the -i
+ (inplace) option modifies the files without creating temporary copies. With
+ the -U (update) option operates on all parameters, updating the files in
+ place. Without the -U option accepts one input and one output file path.
+""")
+ version = "%%prog flvlib %s" % __versionstr__
+ parser = OptionParser(usage=usage, description=description,
+ version=version)
+ parser.add_option("-i", "--inplace", action="store_true",
+ help=("inplace mode, does not create temporary files, but "
+ "risks corruption in case of errors"))
+ parser.add_option("-U", "--update", action="store_true",
+ help=("update mode, overwrites the given files "
+ "instead of writing to outfile"))
+ parser.add_option("-v", "--verbose", action="count",
+ default=0, dest="verbosity",
+ help="be more verbose, each -v increases verbosity")
+ options, args = parser.parse_args(sys.argv)
+
+ if len(args) < 2:
+ parser.error("You have to provide at least one file path")
+
+ if not options.update and options.inplace:
+ parser.error("You need to use the update mode if you are updating "
+ "files in place")
+
+ if not options.update and len(args) != 3:
+ parser.error("You need to provide one infile and one outfile "
+ "when not using the update mode")
+
+ if options.verbosity > 3:
+ options.verbosity = 3
+
+ log.setLevel({0: logging.ERROR, 1: logging.WARNING,
+ 2: logging.INFO, 3: logging.DEBUG}[options.verbosity])
+
+ return options, args
+
+
+def retimestamp_files():
+ options, args = process_options()
+
+ clean_run = True
+
+ if not options.update:
+ clean_run = retimestamp_file(args[1], args[2])
+ else:
+ for filename in args[1:]:
+ if not retimestamp_file(filename, inplace=options.inplace):
+ clean_run = False
+
+ return clean_run
+
+
+def main():
+ try:
+ outcome = retimestamp_files()
+ except KeyboardInterrupt:
+ # give the right exit status, 128 + signal number
+ # signal.SIGINT = 2
+ sys.exit(128 + 2)
+ except EnvironmentError, (errno, strerror):
+ try:
+ print >>sys.stderr, strerror
+ except StandardError:
+ pass
+ sys.exit(2)
+
+ if outcome:
+ sys.exit(0)
+ else:
+ sys.exit(1)
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/tags.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/tags.py
new file mode 100644
index 0000000000000000000000000000000000000000..ef76946514b6f9f35c33221423df862b7b5bfe72
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/tags.py
@@ -0,0 +1,360 @@
+import os
+import struct
+import logging
+
+from primitives import *
+from constants import *
+from astypes import MalformedFLV
+from astypes import get_script_data_variable, make_script_data_variable
+
+log = logging.getLogger('flvlib.tags')
+
+STRICT_PARSING = False
+def strict_parser():
+ return globals()['STRICT_PARSING']
+
+
+class EndOfTags(Exception):
+ pass
+
+
+def ensure(value, expected, error_msg):
+ if value == expected:
+ return
+
+ if strict_parser():
+ raise MalformedFLV(error_msg)
+ else:
+ log.warning('Skipping non-conformant value in FLV file')
+
+
+class Tag(object):
+
+ def __init__(self, parent_flv, f):
+ self.f = f
+ self.parent_flv = parent_flv
+ self.offset = None
+ self.size = None
+ self.timestamp = None
+
+ def parse(self):
+ f = self.f
+
+ self.offset = f.tell() - 1
+
+ # DataSize
+ self.size = get_ui24(f)
+
+ # Timestamp + TimestampExtended
+ self.timestamp = get_si32_extended(f)
+
+ if self.timestamp < 0:
+ log.warning("The tag at offset 0x%08X has negative timestamp: %d",
+ self.offset, self.timestamp)
+
+ # StreamID
+ stream_id = get_ui24(f)
+ ensure(stream_id, 0, "StreamID non zero: 0x%06X" % stream_id)
+
+ # The rest gets parsed in the subclass, it should move f to the
+ # correct position to read PreviousTagSize
+ self.parse_tag_content()
+
+ previous_tag_size = get_ui32(f)
+ ensure(previous_tag_size, self.size + 11,
+ "PreviousTagSize of %d (0x%08X) "
+ "not equal to actual tag size of %d (0x%08X)" %
+ (previous_tag_size, previous_tag_size,
+ self.size + 11, self.size + 11))
+
+ def parse_tag_content(self):
+ # By default just seek past the tag content
+ self.f.seek(self.size, os.SEEK_CUR)
+
+
+class AudioTag(Tag):
+
+ def __init__(self, parent_flv, f):
+ Tag.__init__(self, parent_flv, f)
+ self.sound_format = None
+ self.sound_rate = None
+ self.sound_size = None
+ self.sound_type = None
+ self.aac_packet_type = None # always None for non-AAC tags
+
+ def parse_tag_content(self):
+ f = self.f
+
+ sound_flags = get_ui8(f)
+ read_bytes = 1
+
+ self.sound_format = (sound_flags & 0xF0) >> 4
+ self.sound_rate = (sound_flags & 0xC) >> 2
+ self.sound_size = (sound_flags & 0x2) >> 1
+ self.sound_type = sound_flags & 0x1
+
+ if self.sound_format == SOUND_FORMAT_AAC:
+ # AAC packets can be sequence headers or raw data.
+ # The former contain codec information needed by the decoder to be
+ # able to interpret the rest of the data.
+ self.aac_packet_type = get_ui8(f)
+ read_bytes += 1
+ # AAC always has sampling rate of 44 kHz
+ ensure(self.sound_rate, SOUND_RATE_44_KHZ,
+ "AAC sound format with incorrect sound rate: %d" %
+ self.sound_rate)
+ # AAC is always stereo
+ ensure(self.sound_type, SOUND_TYPE_STEREO,
+ "AAC sound format with incorrect sound type: %d" %
+ self.sound_type)
+
+ if strict_parser():
+ try:
+ sound_format_to_string[self.sound_format]
+ except KeyError:
+ raise MalformedFLV("Invalid sound format: %d",
+ self.sound_format)
+ try:
+ (self.aac_packet_type and
+ aac_packet_type_to_string[self.aac_packet_type])
+ except KeyError:
+ raise MalformedFLV("Invalid AAC packet type: %d",
+ self.aac_packet_type)
+
+ f.seek(self.size - read_bytes, os.SEEK_CUR)
+
+ def __repr__(self):
+ if self.offset is None:
+ return ""
+ elif self.aac_packet_type is None:
+ return ("" %
+ (self.offset, self.timestamp, self.size,
+ sound_format_to_string.get(self.sound_format, '?')))
+ else:
+ return ("" %
+ (self.offset, self.timestamp, self.size,
+ sound_format_to_string.get(self.sound_format, '?'),
+ aac_packet_type_to_string.get(self.aac_packet_type, '?')))
+
+
+class VideoTag(Tag):
+
+ def __init__(self, parent_flv, f):
+ Tag.__init__(self, parent_flv, f)
+ self.frame_type = None
+ self.codec_id = None
+ self.h264_packet_type = None # Always None for non-H.264 tags
+
+ def parse_tag_content(self):
+ f = self.f
+
+ video_flags = get_ui8(f)
+ read_bytes = 1
+
+ self.frame_type = (video_flags & 0xF0) >> 4
+ self.codec_id = video_flags & 0xF
+
+ if self.codec_id == CODEC_ID_H264:
+ # H.264 packets can be sequence headers, NAL units or sequence
+ # ends.
+ self.h264_packet_type = get_ui8(f)
+ read_bytes += 1
+
+ if strict_parser():
+ try:
+ frame_type_to_string[self.frame_type]
+ except KeyError:
+ raise MalformedFLV("Invalid frame type: %d", self.frame_type)
+ try:
+ codec_id_to_string[self.codec_id]
+ except KeyError:
+ raise MalformedFLV("Invalid codec ID: %d", self.codec_id)
+ try:
+ (self.h264_packet_type and
+ h264_packet_type_to_string[self.h264_packet_type])
+ except KeyError:
+ raise MalformedFLV("Invalid H.264 packet type: %d",
+ self.h264_packet_type)
+
+ f.seek(self.size - read_bytes, os.SEEK_CUR)
+
+ def __repr__(self):
+ if self.offset is None:
+ return ""
+ elif self.h264_packet_type is None:
+ return ("" %
+ (self.offset, self.timestamp, self.size,
+ codec_id_to_string.get(self.codec_id, '?'),
+ frame_type_to_string.get(self.frame_type, '?')))
+ else:
+ return ("" %
+ (self.offset, self.timestamp, self.size,
+ codec_id_to_string.get(self.codec_id, '?'),
+ frame_type_to_string.get(self.frame_type, '?'),
+ h264_packet_type_to_string.get(
+ self.h264_packet_type, '?')))
+
+
+class ScriptTag(Tag):
+
+ def __init__(self, parent_flv, f):
+ Tag.__init__(self, parent_flv, f)
+ self.name = None
+ self.variable = None
+
+ def parse_tag_content(self):
+ f = self.f
+
+ # Here there's always a byte with the value of 0x02,
+ # which means "string", although the spec says NOTHING
+ # about it..
+ value_type = get_ui8(f)
+ ensure(value_type, 2, "The name of a script tag is not a string")
+
+ # Need to pass the tag end offset, because apparently YouTube
+ # doesn't give a *shit* about the FLV spec and just happily
+ # ends the onMetaData tag after self.size bytes, instead of
+ # ending it with the *required* 0x09 marker. Bastards!
+
+ if strict_parser():
+ # If we're strict, just don't pass this info
+ tag_end = None
+ else:
+ # 11 = tag type (1) + data size (3) + timestamp (4) + stream id (3)
+ tag_end = self.offset + 11 + self.size
+ log.debug("max offset is 0x%08X", tag_end)
+
+ self.name, self.variable = \
+ get_script_data_variable(f, max_offset=tag_end)
+ log.debug("A script tag with a name of %s and value of %r",
+ self.name, self.variable)
+
+ def __repr__(self):
+ if self.offset is None:
+ return ""
+ else:
+ return ("" %
+ (self.name, self.offset, self.timestamp, self.size))
+
+
+tag_to_class = {
+ TAG_TYPE_AUDIO: AudioTag,
+ TAG_TYPE_VIDEO: VideoTag,
+ TAG_TYPE_SCRIPT: ScriptTag
+}
+
+
+class FLV(object):
+
+ def __init__(self, f):
+ self.f = f
+ self.version = None
+ self.has_audio = None
+ self.has_video = None
+ self.tags = []
+
+ def parse_header(self):
+ f = self.f
+ f.seek(0)
+
+ # FLV header
+ header = f.read(3)
+ if len(header) < 3:
+ raise MalformedFLV("The file is shorter than 3 bytes")
+
+ # Do this irrelevant of STRICT_PARSING, to catch bogus files
+ if header != "FLV":
+ raise MalformedFLV("File signature is incorrect: 0x%X 0x%X 0x%X" %
+ struct.unpack("3B", header))
+
+ # File version
+ self.version = get_ui8(f)
+ log.debug("File version is %d", self.version)
+
+ # TypeFlags
+ flags = get_ui8(f)
+
+ ensure(flags & 0xF8, 0,
+ "First TypeFlagsReserved field non zero: 0x%X" % (flags & 0xF8))
+ ensure(flags & 0x2, 0,
+ "Second TypeFlagsReserved field non zero: 0x%X" % (flags & 0x2))
+
+ self.has_audio = False
+ self.has_video = False
+ if flags & 0x4:
+ self.has_audio = True
+ if flags & 0x1:
+ self.has_video = True
+ log.debug("File %s audio",
+ (self.has_audio and "has") or "does not have")
+ log.debug("File %s video",
+ (self.has_video and "has") or "does not have")
+
+ header_size = get_ui32(f)
+ log.debug("Header size is %d bytes", header_size)
+
+ f.seek(header_size)
+
+ tag_0_size = get_ui32(f)
+ ensure(tag_0_size, 0, "PreviousTagSize0 non zero: 0x%08X" % tag_0_size)
+
+ def iter_tags(self):
+ self.parse_header()
+ try:
+ while True:
+ tag = self.get_next_tag()
+ yield tag
+ except EndOfTags:
+ pass
+
+ def read_tags(self):
+ self.tags = list(self.iter_tags())
+
+ def get_next_tag(self):
+ f = self.f
+
+ try:
+ tag_type = get_ui8(f)
+ except EndOfFile:
+ raise EndOfTags
+
+ tag_klass = self.tag_type_to_class(tag_type)
+ tag = tag_klass(self, f)
+
+ tag.parse()
+
+ return tag
+
+ def tag_type_to_class(self, tag_type):
+ try:
+ return tag_to_class[tag_type]
+ except KeyError:
+ raise MalformedFLV("Invalid tag type: %d", tag_type)
+
+
+def create_flv_tag(type, data, timestamp=0):
+ tag_type = struct.pack("B", type)
+ timestamp = make_si32_extended(timestamp)
+ stream_id = make_ui24(0)
+
+ data_size = len(data)
+ tag_size = data_size + 11
+
+ return ''.join([tag_type, make_ui24(data_size), timestamp, stream_id,
+ data, make_ui32(tag_size)])
+
+
+def create_script_tag(name, data, timestamp=0):
+ payload = make_ui8(2) + make_script_data_variable(name, data)
+ return create_flv_tag(TAG_TYPE_SCRIPT, payload, timestamp)
+
+
+def create_flv_header(has_audio=True, has_video=True):
+ type_flags = 0
+ if has_video:
+ type_flags = type_flags | 0x1
+ if has_audio:
+ type_flags = type_flags | 0x4
+ return ''.join(['FLV', make_ui8(1), make_ui8(type_flags), make_ui32(9),
+ make_ui32(0)])
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/tags.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/tags.pyo
new file mode 100644
index 0000000000000000000000000000000000000000..47577d8dbc7b3bcd32d74d8b655d2ef9e25e8716
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/flvlib/tags.pyo differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/icon.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..8db250c679af1a9dc976d00b1c2bd83028a4dc5e
Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/icon.png differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/language/English/strings.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/language/English/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..354d67b840d4d702ec52fc0da9f556bde87f2aaf
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/language/English/strings.xml
@@ -0,0 +1,23 @@
+
+
+ Veetle Error
+ Stream URL not available or offline.
+ Grab Schedules
+ Use Official Channel List
+ Categories
+ Schedules
+ All
+ Entertainment
+ Shows
+ Animation
+ Sports
+ Comedy
+ Music
+ Education
+ Gaming
+ News
+ Religion
+ Mobile
+ Not Available
+ watching
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/language/Greek/strings.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/language/Greek/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f1d16e3c7b7a10f982025c83e4eddd8474bce1ac
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/language/Greek/strings.xml
@@ -0,0 +1,23 @@
+
+
+ Σφάλμα του Veetle
+ Η ροή δεν είναι διαθέσιμη.
+ Λήψη προγραμμάτων
+ Χρήση επίσημης λίστας καναλιών
+ Κατηγορίες
+ Πρόγραμμα
+ Όλα
+ Ψυχαγωγία
+ Σειρές
+ Κινουμένα σχέδια
+ Αθλητικά
+ Κωμωδίες
+ Μουσική
+ Εκπαίδευση
+ Παιχνίδια
+ Ειδήσεις
+ Θρησκεία
+ Κινητά
+ Μη διαθέσιμο
+ βλέποντας
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/language/Portuguese (Brazil)/strings.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/language/Portuguese (Brazil)/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c79d0d163366bb922d2ce502dfa4cac0f29daec9
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/language/Portuguese (Brazil)/strings.xml
@@ -0,0 +1,23 @@
+
+
+ Erro de Veetle
+ Stream não disponível ou offline.
+ Apanhar Horário
+ Usar listagem de canais oficial
+ Categorias
+ Horários
+ Todos
+ Entretinimento
+ Séries
+ Animação
+ Desporto
+ Comédia
+ Música
+ Educação
+ Jogos
+ Notícias
+ Religião
+ Mobile
+ Não disponível
+ a ver
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/language/Portuguese/strings.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/language/Portuguese/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2b51128cc7b3d1c75c825a2905ac34de793d7482
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/language/Portuguese/strings.xml
@@ -0,0 +1,23 @@
+
+
+ Erro de Veetle
+ Stream não disponível ou offline.
+ Apanhar Horário
+ Usar listagem de canais oficial
+ Categorias
+ Horários
+ Todos
+ Entretenimento
+ Séries
+ Animação
+ Desporto
+ Comédia
+ Música
+ Educação
+ Jogos
+ Notícias
+ Religião
+ Mobile
+ Não disponível
+ a ver
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/settings.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..706a4cc1cf4b84bc9e2a8bd053a8956cdc63e4c7
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.veetle/resources/settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/README.md b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/README.md
deleted file mode 100644
index 6ca97e32ef35c152b48a7051c67e4731a6d26513..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/README.md
+++ /dev/null
@@ -1,43 +0,0 @@
-VEVO add-on for XBMC
-==========================================
-
-This plugin provides to watch your favorite artist's music videos, see premiere performances
-and search for new music on VEVO and allows you to watch them in XBMC.
-
-The content is only available in some countries. You can use a proxy, VPN or smartDNS to bypass.
-
-Installation
-------------
-This latest stable release of this add-on is available as part of the
-[xbmcplus repository] [repository].
-
-For the latest development version,
-you can grab the [GitHub generated ZIP file] [githubzip].
-
-Simply download the ZIP file to your XBMC device and install through the menu
-via System -> Settings -> Add-ons -> Install from zip file
-
-Issues
-------
-For any issues or bug reports, please file them on the [issues page] [issues].
-
-Please include log output if possible, using [Github Gist] [gist].
-
-The location of your XBMC log file will depend on your platform,
-see the [XBMC Wiki page] [xbmc-wiki-log-file] for information.
-
-Credits
--------
- - BlueCop
- Initial addon development.
-
-Contact Me
-----------
-For anything else, you can contact me at [forum.xbmc.org] [moneymaker].
-
-[repository]: https://github.com/moneymaker365/repository.xbmcplus.xbmc-plugins/releases
-[githubzip]: https://github.com/moneymaker365/plugin.video.vevo/archive/master.zip
-[issues]: https://github.com/moneymaker365/plugin.video.vevo/issues
-[gist]: https://gist.github.com
-[moneymaker]: http://forum.xbmc.org/member.php?action=profile&uid=116826
-[xbmc-wiki-log-file]: http://wiki.xbmc.org/index.php?title=Log_file/Advanced#Log_files
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/addon.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/addon.xml
deleted file mode 100644
index 23aa722af26b9f218125d17e92470ae75c8c49fc..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/addon.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
- video audio
-
-
- all
- Music Videos from VEVO
- Musik Videos von VEVO
- Watch your favorite artist's music videos, see premiere performances and search for new music on VEVO.com
- Schaue Top Videos und Performances Deiner Lieblingskünstler und entdecke neue Musik auf VEVO.com
- Some parts of this addon may not be legal in your country of residence - please check with your local laws before installing.
- Einige Teile dieses Addons sind möglicherweise in Ihrem Land nicht legal - bitte prüfen Sie Ihre lokal gültigen Gesetze vor der Installation.
-
-
-
\ No newline at end of file
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/changelog.txt b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/changelog.txt
deleted file mode 100644
index 01f1c47c75c8a279985eac3740a7b1f3b6e8f171..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/changelog.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-version 0.8.2
-
- * revert back to v0.7.8a
-
-version 0.7.8a
-
- * fix for addon.xml to add dependency for script.facebook.media
-
-version 0.7.7d
-
- * Facebook login fix
-
-version 0.7.7c
-
- * fixed add-on description caused installation failed
-
-version 0.7.7
-
- * make the artist variable passed to infoLabels as list
-
-version 0.7.6
-
- * update fanart and logo
-
-version 0.7.5
-
- * fixed german language, clean-up
-
-version 0.7.4
-
- * fixed Facebook token size, added german language
-
-version 0.7.3
-
- * last initial version () Github fork from BlueCop
-
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/default.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/default.py
deleted file mode 100644
index da59a7e608a91097d50c986c9c7dbea473143d65..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/default.py
+++ /dev/null
@@ -1,1562 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import urllib, urllib2, cookielib
-import string, os, re, time, datetime, math, time, unicodedata, types
-import threading
-
-import xbmc, xbmcgui, xbmcplugin, xbmcaddon
-
-from BeautifulSoup import BeautifulSoup
-from BeautifulSoup import BeautifulStoneSoup
-import demjson
-
-import facebook
-from facebook import GraphAPIError, GraphWrapAuthError
-
-import mechanize
-
-try:
- from sqlite3 import dbapi2 as sqlite
-except:
- from pysqlite2 import dbapi2 as sqlite
-
-pluginhandle = int(sys.argv[1])
-#xbmcplugin.setContent(pluginhandle, 'musicvideos')
-
-__plugin__ = 'VEVO'
-__authors__ = 'BlueCop'
-__credits__ = 'moneymaker'
-
-addon = xbmcaddon.Addon('plugin.video.vevo')
-pluginpath = addon.getAddonInfo('path')
-datapath = xbmc.translatePath('special://profile/addon_data/plugin.video.vevo/')
-cachepath = xbmc.translatePath(addon.getSetting('cache-folder'))
-
-BASE = 'http://www.vevo.com'
-COOKIEFILE = os.path.join(pluginpath,'resources','vevo-cookies.lwp')
-#USERFILE = os.path.join(pluginpath,'resources','userfile.js')
-FAVFILE = os.path.join(datapath,'favs.json')
-FAVFILESQL = os.path.join(datapath,'favs.sqlite')
-CACHEDB = os.path.join(datapath,'cache.sqlite')
-
-fanart = os.path.join(pluginpath,'fanart.jpg')
-vicon = os.path.join(pluginpath,'icon.png')
-maxperpage=(int(addon.getSetting('perpage'))+1)*25
-
-# Root listing
-
-def listCategories():
- addDir('Featured', 'http://api.vevo.com/mobile/v2/featured/carousel.json?', 'listFeatured')
- addDir('Premieres', 'http://api.vevo.com/mobile/v1/video/list.json?ispremiere=true', 'listVideos')
- addDir('Staff Picks', '', 'listStaffPicks')
- if (addon.getSetting('latitude') == 'Lookup by IP') and (addon.getSetting('latitude') == 'Lookup by IP'):
- setLocation()
- if (addon.getSetting('latitude') <> '') or (addon.getSetting('latitude') <> ''):
- cm = []
- u=sys.argv[0]+"?url="+urllib.quote_plus('')+"&mode="+urllib.quote_plus('setLocation')+'&page='+str(1)
- cm.append( ('Set Location by IP', "XBMC.RunPlugin(%s)" % u) )
- addDir('Trending', '', 'Trending', cm=cm)
- addDir('Touring', '', 'toursRightNow', cm=cm)
- addDir('Videos', 'http://api.vevo.com/mobile/v1/video/list.json', 'rootVideos')
- addDir('Artists', 'http://api.vevo.com/mobile/v1/artist/list.json', 'rootArtists')
- addDir('Shows', 'http://api.vevo.com/mobile/v1/show/list.json?', 'rootShows')
- cm = []
- u=sys.argv[0]+"?url="+urllib.quote_plus('')+"&mode="+urllib.quote_plus('rematchArtists')+'&page='+str(1)
- cm.append( ('Rematch Library Artists', "XBMC.RunPlugin(%s)" % u) )
- u=sys.argv[0]+"?url="+urllib.quote_plus('')+"&mode="+urllib.quote_plus('deletefavArtists')+'&page='+str(1)
- cm.append( ('Delete All Artists', "XBMC.RunPlugin(%s)" % u) )
- addDir('Favorite Artists', '', 'favArtists' , cm=cm)
- addDir('Playlists', 'http://api.vevo.com/mobile/v1/featured/staffpicks.json', 'rootPlaylists')
- addDir('Search', '', 'searchArtists')
- #addDir('Search Videos', '', 'searchVideos')
- #addDir('Search Artists', '', 'searchArtists')
- xbmcplugin.endOfDirectory(pluginhandle)
-
-def listStaffPicks():
- addDir('Video Picks', 'http://api.vevo.com/mobile/v1/featured/TopVideos.json?', 'listVideos')
- addDir('Playlist Picks', 'http://api.vevo.com/mobile/v3/featured/TopPlaylists.json?', 'listPlaylists')
- xbmcplugin.endOfDirectory(pluginhandle)
-
-def Trending():
- addDir('Being Watched', '', 'watchingRightNowIn')
- addDir('Trending Now', '', 'TrendingRightNowIn')
- xbmcplugin.endOfDirectory(pluginhandle)
-
-def listFeatured(url=False):
- xbmcplugin.setContent(pluginhandle, 'musicvideos')
- if not url:
- url = params['url']
- max = maxperpage
- page = int(params['page'])
- offset = (page-1)*max
- fetch_url=url+'&offset='+str(offset)+'&max='+str(max)+'&extended=true'
- data = getURL(fetch_url)
- if data:
- items = demjson.decode(data)['result']
- for item in items:
- image_url = item['image_url']
- primary_text = item['primary_text'].encode('utf-8')
- secondary_text = item['secondary_text'].encode('utf-8')
-
- action_url = item['action_url']
- is_live_stream = item['is_live_stream']
- image_wide_url = item['image_wide_url']
- cm=[]
- if 'vevo://playlist/' in action_url:
- mode = 'playlistRoot'
- videoid = action_url.replace('vevo://playlist/','')
- elif 'vevo://video/' in action_url:
- mode = 'playVideo'
- videoid = action_url.replace('vevo://video/','')
- if addon.getSetting('session_token'):
- u=sys.argv[0]+"?url="+urllib.quote_plus(videoid)+"&mode="+urllib.quote_plus('addVideo2Playlist')+'&page='+str(1)
- cm.append( ('Add to Playlist', "XBMC.RunPlugin(%s)" % u) )
- u=sys.argv[0]+"?url="+urllib.quote_plus(videoid)+"&mode="+urllib.quote_plus('newVideoPlaylist')+'&page='+str(1)
- cm.append( ('Start New Playlist', "XBMC.RunPlugin(%s)" % u) )
-
- if ':' in primary_text:
- primary_split = primary_text.split(':')
- primary_text = primary_split[1].strip()
- text = primary_split[0].strip().title()
- else:
- text = ''
-
- u='plugin://plugin.video.youtube/?path=/root/search&feed=search&search='+urllib.quote_plus(primary_text)+'&'
- cm.append( ('YouTube %s' % primary_text, "Container.Update(%s)" % u) )
-
- displayname = primary_text+' - '+secondary_text
- if text <> '':
- displayname +=' ('+text+')'
- if mode == 'playVideo':
- overlay = checkIDdb(videoid)
- if overlay:
- dcu=sys.argv[0]+"?url="+urllib.quote_plus(videoid)+"&mode="+urllib.quote_plus('deleteCachedFile')+'&page='+urllib.quote_plus('1')
- cm.append( ('Delete Cached File', "XBMC.RunPlugin(%s)" % dcu) )
- else:
- overlay=0
- else:
- overlay=0
- u = sys.argv[0]
- u += '?url='+urllib.quote_plus(videoid)
- u += '&mode='+urllib.quote_plus(mode)
- u += '&duration='+urllib.quote_plus('210')
- item=xbmcgui.ListItem(displayname, iconImage=image_url, thumbnailImage=image_url)
- item.setInfo( type="Video", infoLabels={ "Title" : secondary_text,
- "Artist" : [primary_text],
- "Album" : primary_text,
- "Studio" : text,
- "overlay" : overlay
- })
- item.setProperty('fanart_image',image_wide_url)
- item.addContextMenuItems( cm )
- if mode == 'playVideo':
- item.setProperty('IsPlayable', 'true')
- xbmcplugin.addDirectoryItem(pluginhandle,url=u,listitem=item,isFolder=False)
- else:
- u += '&page=1'
- xbmcplugin.addDirectoryItem(pluginhandle,url=u,listitem=item,isFolder=True)
- xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=True)
- setView()
-
-# Video listings
-def rootVideos():
- videos_url = params['url']
- addGenres(videos_url, 'sortByVideo')
- xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=True)
-
-def sortByVideo():
- url = params['url']
- addDir('Most Viewed', url+'&order=MostViewed', 'sortWhenVideo')
- addDir('Most Liked', url+'&order=MostFavorited', 'sortWhenVideo')
- addDir('Most Recent', url+'&order=MostRecent', 'listVideos')
- addDir('Surprise Me', url+'&order=Random', 'listVideos')
- xbmcplugin.endOfDirectory(pluginhandle)
-
-def sortWhenVideo():
- url = params['url']
- if 'MostFavorited' in url:
- name = 'Most Liked'
- elif 'MostViewed' in url:
- name = 'Most Viewed'
- addDir(name+' Today', url+'Today', 'listVideos')
- addDir(name+' This Week' , url+'ThisWeek', 'listVideos')
- addDir(name+' This Month', url+'ThisMonth', 'listVideos')
- addDir(name+' All-Time', url+'AllTime', 'listVideos')
- xbmcplugin.endOfDirectory(pluginhandle)
-
-def listArtistVideos():
- listVideos(artistlist=True)
-
-def listVideosNoPage(url=False):
- listVideos(url=url,paginate=False)
-
-def listVideos(url = False,playlist=False,playall=False,queue=False,VEVOToken=False,artistlist=False,paginate=True):
- xbmcplugin.setContent(pluginhandle, 'musicvideos')
- if artistlist:
- xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_PLAYLIST_ORDER)
- xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_VIDEO_YEAR)
- xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_STUDIO)
- xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_GENRE)
- #xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_LABEL)
- if not url:
- url = params['url']
- if paginate:
- max = maxperpage
- page = int(params['page'])
- offset = (page-1)*max
- fetch_url=url+'&offset='+str(offset)+'&max='+str(max)+'&extended=true'
- else:
- fetch_url=url+'&extended=true'
- data = getURL(fetch_url,VEVOToken=VEVOToken)
- if data:
- if playlist:
- videos = demjson.decode(data)['result']['videos']
- else:
- videos = demjson.decode(data)['result']
- total = len(videos)
- if playall or queue:
- playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
- if playall:
- playlist.clear()
- elif playlist is False:
- total = len(videos)
- if paginate:
- if total >= max:
- addDir('*Next Page*', url, 'listVideos', page=str(page+1))
- cm=[]
- u=sys.argv[0]+"?url="+urllib.quote_plus(fetch_url)+"&mode="+urllib.quote_plus('queueAll')+'&page='+urllib.quote_plus('1')
- cm.append( ('Queue All', "XBMC.RunPlugin(%s)" % u) )
- if addon.getSetting('session_token'):
- #if VEVOToken:
- u=sys.argv[0]+"?url="+urllib.quote_plus(fetch_url)+"&mode="+urllib.quote_plus('addVideoPlaylistURL')+'&page='+urllib.quote_plus('1')
- #cm.append( ('Save to Playlist', "XBMC.RunPlugin(%s)" % u) )
- u=sys.argv[0]+"?url="+urllib.quote_plus(fetch_url)+"&mode="+urllib.quote_plus('newVideoPlaylistURL')+'&page='+urllib.quote_plus('1')
- cm.append( ('New Playlist', "XBMC.RunPlugin(%s)" % u) )
- addDir('*Play All*', url, 'playAll',folder=False,cm=cm)
- count = 0
- for video in videos:
- video_id = video['isrc']
- try:title = video['title'].encode('utf-8')
- except: title = ''
- video_image = video['image_url']
- duration = video['duration_in_seconds']
- try:year = int(video['video_year'])
- except:year = 0
-
- genre = ''
- recordlabel = ''
- director = ''
- producer = ''
- composer = ''
- plot = ''
- if video.has_key('credit'):
- credits = video['credit']
- if isinstance(credits, list):
- metadict={}
- for credit in credits:
- if credit['Key'] == 'Credit':
- value = credit['Value']
- if '=>' in value:
- valuesplit = value.split('=>')
- metadict[valuesplit[0].strip()]=valuesplit[1].strip()
- else:
- metadict[credit['Key']]=credit['Value']
- else:
- metadict[credit['Key']]=credit['Value']
- else:
- metadict=credits
- for item in metadict:
- plot+=item+' : '+metadict[item]+'\n'
- if metadict.has_key('Director'):
- director = metadict['Director']
- if metadict.has_key('Record Label'):
- recordlabel = metadict['Record Label']
- if metadict.has_key('Genre'):
- genre = metadict['Genre']
- if metadict.has_key('Composer'):
- composer = metadict['Composer']
- if metadict.has_key('Producer'):
- producer = metadict['Producer']
-
- if len(video['artists_main']) > 0:
- artistdata = video['artists_main'][0]
- artist_id = artistdata['id']
- artist_name = artistdata['name'].encode('utf-8')
- artist_image = artistdata['image_url']
- else:
- artist_name = ''
- artist_id = ''
- artist_image = ''
- artists = {artist_id:artist_name}
- if len(video['artists_featured']) > 0:
- feats=''
- for featuredartist in video['artists_featured']:
- featuredartist_id = featuredartist['id']
- #featuredartist_image = featuredartist['image_url']
- featuredartist_name = featuredartist['name'].encode('utf-8')
- feats+=featuredartist_name+', '
- artists[featuredartist_id]=featuredartist_name
- feats=feats[:-2]
- title += ' (ft. '+feats+')'
-
- cm=[]
- if addon.getSetting('session_token'):
- if VEVOToken:
- playlist_id = fetch_url.split('userplaylist/')[1].split('.')[0]
- index=str(videos.index(video))
- u=sys.argv[0]+"?url="+urllib.quote_plus(index)+"&mode="+urllib.quote_plus('removeVideo2Playlist')+'&page='+urllib.quote_plus(playlist_id)
- cm.append( ('Remove from Playlist', "XBMC.RunPlugin(%s)" % u) )
- u=sys.argv[0]+"?url="+urllib.quote_plus(video_id)+"&mode="+urllib.quote_plus('addVideo2Playlist')+'&page='+str(1)
- cm.append( ('Add to Playlist', "XBMC.RunPlugin(%s)" % u) )
- u=sys.argv[0]+"?url="+urllib.quote_plus(video_id)+"&mode="+urllib.quote_plus('newVideoPlaylist')+'&page='+str(1)
- cm.append( ('Start New Playlist', "XBMC.RunPlugin(%s)" % u) )
- artist = artist_name
- for _artist in artists:
- if _artist <> '':
- artist_name = artists[_artist]
- artist_id = _artist
- artist_url = 'http://api.vevo.com/mobile/v1/artist/%s/videos.json?order=MostRecent' % artist_id
- u=sys.argv[0]+"?url="+urllib.quote_plus(artist_url)+"&mode="+urllib.quote_plus('listVideos')+'&page='+str(1)
- cm.append( ('More %s' % artist_name, "Container.Update(%s)" % u) )
- artist_url = 'http://api.vevo.com/mobile/v1/artist/%s.json' % artist_id
- u='plugin://plugin.video.youtube/?path=/root/search&feed=search&search='+urllib.quote_plus(artist_name)+'&'
- cm.append( ('YouTube %s' % artist_name, "Container.Update(%s)" % u) )
- u=sys.argv[0]+"?url="+urllib.quote_plus(artist_url)+"&mode="+urllib.quote_plus('addfavArtists')+'&page='+str(1)
- cm.append( ('Favorite %s' % artist_name, "XBMC.RunPlugin(%s)" % u) )
- u = sys.argv[0]
- u += '?url='+urllib.quote_plus(video_id)
- u += '&mode='+urllib.quote_plus('playVideo')
- u += '&duration='+urllib.quote_plus(str(duration))
- displayname = artist+' - '+title
- item=xbmcgui.ListItem(displayname, iconImage=video_image, thumbnailImage=video_image)
- infoLabels={ "Title":title,
- "Artist": [ artist ],
- #Set album to artist because xbmc bug doesn't display artist value for video type
- "Album":artist,
- "Duration":str(duration/60)+':'+str(duration-(duration/60)*60),
- "Studio":recordlabel,
- "Director":director,
- "Writer":composer,
- "Producer":producer,
- "Genre":genre,
- "Plot":plot,
- "Year":year,
- "Count":count
- }
- overlay = checkIDdb(video_id)
- if overlay:
- infoLabels['overlay']=overlay
- dcu=sys.argv[0]+"?url="+urllib.quote_plus(video_id)+"&mode="+urllib.quote_plus('deleteCachedFile')+'&page='+urllib.quote_plus('1')
- cm.append( ('Delete Cached File', "XBMC.RunPlugin(%s)" % dcu) )
- item.setInfo( type="Video",infoLabels=infoLabels)
- item.setProperty('Artist',artist)
- count +=1
- item.setProperty('fanart_image',artist_image)
- item.setProperty('IsPlayable', 'true')
- item.addContextMenuItems( cm )
- if playall or queue:
- playlist.add(url=u, listitem=item)
- else:
- xbmcplugin.addDirectoryItem(pluginhandle,url=u,listitem=item,isFolder=False,totalItems=total)
- if playall:
- xbmc.Player().play(playlist)
- elif queue:
- pass
- else:
- xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=True)
- setView()
-
-def playAll():
- listVideos(params['url'],playall=True)
-
-def queueAll():
- listVideos(params['url'],queue=True)
-
-# common genre listing for artists and videos
-def addGenres(url,mode):
- data = getURL('http://api.vevo.com/mobile/v1/genre/list.json?culture=en_US')
- genres = demjson.decode(data)['result']
- addDir('All Genres', url+'?', mode)
- for genre in genres:
- name = genre['Value']
- furl = url+'?genres='+genre['Key']
- addDir(name, furl, mode)
-
-# Artist listings
-def rootArtists():
- artist_url = params['url']
- addGenres(artist_url, 'sortByArtists')
- xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=True)
-
-def sortByArtists():
- url = params['url']
- #addDir('Alphabetical', url+'&order=Alphabetic', 'listAZ')
- addDir('Most Viewed', url+'&order=MostViewed', 'sortWhenArtists')
- addDir('Most Liked', url+'&order=MostFavorited', 'sortWhenArtists')
- addDir('Most Recent', url+'&order=MostRecent', 'listArtists')
- addDir('Surprise Me', url+'&order=Random', 'listArtists')
- xbmcplugin.endOfDirectory(pluginhandle)
-
-def sortWhenArtists():
- url = params['url']
- if 'MostFavorited' in url:
- name = 'Most Liked'
- elif 'MostViewed' in url:
- name = 'Most Viewed'
- addDir(name+' Today', url+'Today', 'listArtists')
- addDir(name+' This Week' , url+'ThisWeek', 'listArtists')
- addDir(name+' This Month', url+'ThisMonth', 'listArtists')
- addDir(name+' All-Time', url+'AllTime', 'listArtists')
- xbmcplugin.endOfDirectory(pluginhandle)
-
-def listAZ():
- url = params['url']
- addDir('#', url+'&alpha='+urllib.quote_plus('#'), 'listVideos')
- alphabet=set(string.ascii_uppercase)
- for letter in alphabet:
- addDir(letter, url+'&alpha='+str(letter), 'listArtists')
- xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_LABEL)
- xbmcplugin.endOfDirectory(pluginhandle)
-
-def listArtists(url = False):
- xbmcplugin.setContent(pluginhandle, 'artists')
- if not url:
- url = params['url']
- max = maxperpage
- page = int(params['page'])
- offset = (page-1)*max
- fetch_url=url+'&offset='+str(offset)+'&max='+str(max)
- data = getURL(fetch_url)
- artists = demjson.decode(data)['result']
- total = len(artists)
- if total >= max:
- addDir('*Next Page*', url, 'listArtists', page=str(page+1))
- for artist in artists:
- artist_id = artist['id']
- artist_name = artist['name'].encode('utf-8')
- artist_image = artist['image_url']
- video_count = artist['video_count']
- url = 'http://api.vevo.com/mobile/v1/artist/'+artist_id+'/videos.json?order=MostRecent'
- display_name=artist_name+' ('+str(video_count)+')'
- cm = []
- artist_url = 'http://api.vevo.com/mobile/v1/artist/%s.json' % artist_id
- u=sys.argv[0]+"?url="+urllib.quote_plus(artist_url)+"&mode="+urllib.quote_plus('addfavArtists')+'&page='+str(1)
- cm.append( ('Favorite %s' % artist_name, "XBMC.RunPlugin(%s)" % u) )
- u='plugin://plugin.video.youtube/?path=/root/search&feed=search&search='+urllib.quote_plus(artist_name)+'&'
- cm.append( ('YouTube %s' % artist_name, "Container.Update(%s)" % u) )
- tours_url = 'http://api.vevo.com/mobile/v1/artist/%s/tours.json?toDate=2020-12-31&extended=true' % artist_id
- u=sys.argv[0]+"?url="+urllib.quote_plus(tours_url)+"&mode="+urllib.quote_plus('listTours')+'&page='+str(1)
- cm.append( ('List Tours', "Container.Update(%s)" % u) )
- addDir(display_name, url, 'listArtistVideos', iconimage=artist_image, total=total, cm=cm)
- xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=True)
- setView()
-
-# Playlist listings
-def rootPlaylists():
- addDir('Top Playlists', 'http://api.vevo.com/mobile/v1/featured/staffpicks.json', 'listPlaylists')
- if addon.getSetting('login_name') <> '' and addon.getSetting('login_pass') <> '':
- if addon.getSetting('getnewtoken') == 'true':
- if getFBAuth():
- getVEVOAccount()
- addon.setSetting(id='getnewtoken',value='false')
- else:
- xbmcgui.Dialog().ok('Error','Facebook Login Failed')
- if addon.getSetting('session_token'):
- addDir('My Playlists', 'http://api.vevo.com/mobile/v1/userplaylists.json?', 'listPlaylistsToken')
- #friendPlaylists('http://api.vevo.com/mobile/v1/user/getfacebookfriends.json?')
- addDir('My Friends', 'http://api.vevo.com/mobile/v1/user/getfacebookfriends.json?', 'friendPlaylists')
- xbmcplugin.endOfDirectory(pluginhandle)
-
-def removeVideo2Playlist(playlist_id=False,isrc=False):
- if not isrc:
- isrc = params['url']
- if not playlist_id:
- playlist_id = params['page']
- url = 'http://api.vevo.com/mobile/v1/userplaylist/%s.json'%(playlist_id)
- data = getURL(url,VEVOToken=True)
- playlist = demjson.decode(data)['result']
- title=playlist['title'].replace(' ','%20')
- videos = playlist['videos']
- ids=''
- videos.pop(int(isrc))
- for video in videos:
- id = video['isrc']
- #if isrc <> id:
- ids += id+','
- addurl = 'http://api.vevo.com/mobile/v1/userplaylist/%s.json?title=%s&description=&isrcs=%s&append=false'%(playlist_id,title,ids)
- getURL(addurl,postdata=':)',method='POST',VEVOToken=True)
- xbmc.executebuiltin("Container.Refresh()")
- xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( 'Success', 'Removed from Playlist', 5000) )
-
-def addVideo2Playlist(isrc=False):
- if not isrc:
- isrc = params['url']
- url = 'http://api.vevo.com/mobile/v1/userplaylists.json?'
- data = getURL(url,VEVOToken=True)
- playlists = demjson.decode(data)['result']
- selected=xbmcgui.Dialog().select('Add Video to Playlist',
- [playlist['title']+' ('+str(playlist['videocount'])+')' for playlist in playlists])
- playlist=playlists[selected]
- title=playlist['title'].replace(' ','%20')
- playlist_id=playlist['playlist_id']
- if ',' in isrc:
- isrcs=isrc
- isrcs=isrcs.strip(',').split(',')
- for isrc in isrcs:
- addurl = 'http://api.vevo.com/mobile/v1/userplaylist/%s.json?title=%s&description=&isrcs=%s&append=true'%(playlist_id,title,isrc)
- getURL(addurl,postdata=':)',method='POST',VEVOToken=True)
- else:
- addurl = 'http://api.vevo.com/mobile/v1/userplaylist/%s.json?title=%s&description=&isrcs=%s&append=true'%(playlist_id,title,isrc)
- getURL(addurl,postdata=':)',method='POST',VEVOToken=True)
- xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( 'Success', 'Added to Playlist', 5000) )
-
-def newVideoPlaylistURLPLToken():
- newVideoPlaylistURL(playlist=True,VEVOToken=True)
-
-def addVideoPlaylistURLPLToken():
- newVideoPlaylistURL(playlist=True,VEVOToken=True,Add=True)
-
-def newVideoPlaylistURLPL():
- newVideoPlaylistURL(playlist=True)
-
-def addVideoPlaylistURLPL():
- newVideoPlaylistURL(playlist=True,Add=True)
-
-def addVideoPlaylistURL():
- newVideoPlaylistURL(Add=True)
-
-def newVideoPlaylistURL(url=False,playlist=False,VEVOToken=False,Add=False):
- if not url:
- url = params['url']
- data = getURL(url,VEVOToken=VEVOToken)
- if data:
- if playlist:
- videos = demjson.decode(data)['result']['videos']
- else:
- videos = demjson.decode(data)['result']
- isrcs=''
- for video in videos:
- isrcs+=video['isrc']+','
- if Add:
- addVideo2Playlist(isrc=isrcs)
- else:
- newVideoPlaylist(isrc=isrcs)
-
-
-def newVideoPlaylist(name='',isrc=False):
- if not isrc:
- isrc = params['url']
- keyb = xbmc.Keyboard(name, 'Playlist Name')
- keyb.doModal()
- if keyb.isConfirmed():
- name = urllib.quote_plus(keyb.getText())
- addurl = 'http://api.vevo.com/mobile/v1/userplaylist.json?title=%s&description=&isrcs=%s' % (name,isrc)
- #require PUT
- getURL(addurl,postdata=':)',method='PUT',VEVOToken=True)
- xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( 'Success', 'New Playlist', 5000) )
-
-def deleteVideoPlaylist(id=False):
- if not id:
- id = params['url']
- url = 'http://api.vevo.com/mobile/v1/userplaylist/%s.json?' % id
- getURL(url,postdata=':)',method='DELETE',VEVOToken=True)
- xbmc.executebuiltin("Container.Refresh()")
- xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( 'Success', 'Deleted Playlist', 5000) )
-
-def friendPlaylists(url = False):
- if not url:
- url = params['url']
- #if getFBAuth():
- sendtoken = 'accessToken='+addon.getSetting(id='fbtoken')
- data = getURL(url, postdata=sendtoken, VEVOToken=True)
- friends = demjson.decode(data)['result']['friends_on_vevo']
- total = len(friends)
- for friend in friends:
- url = 'http://api.vevo.com/mobile/v1/userplaylists/%s/list.json' % friend['vevo_id']
- name = friend['name']
- addDir(name, url, 'listPlaylistsToken', total=total)
- xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=True)
-
-def listPlaylistsToken():
- listPlaylists(VEVOToken=True)
-
-def listPlaylists(url = False, VEVOToken=False):
- if not url:
- url = params['url']
- #max = maxperpage
- #page = int(params['page'])
- #offset = (page-1)*max1
- #fetch_url=url+'&offset='+str(offset)+'&max='+str(max)#+'&extended=true'
- #data = getURL(fetch_url)
- data = getURL(url,VEVOToken=VEVOToken)
- playlists = demjson.decode(data)['result']
- total = len(playlists)
- #if total >= max:
- # addDir('*Next Page*', url, 'listPlaylists', page=str(page+1))
- for playlist in playlists:
- try:playlist_id = playlist['playlist_id']
- except:playlist_id = str(playlist['id'])
- cm=[]
- if addon.getSetting('session_token') and VEVOToken:
- u=sys.argv[0]+"?url="+urllib.quote_plus(playlist_id)+"&mode="+urllib.quote_plus('deleteVideoPlaylist')+'&page='+str(1)
- cm.append( ('Delete Playlist', "XBMC.RunPlugin(%s)" % u) )
- playlist_name = playlist['title']
- playlist_image = playlist['image_url']
- video_count = playlist['videocount']
- display_name=playlist_name+' ('+str(video_count)+')'
- if VEVOToken:
- mode = 'playlistUserRoot'
- else:
- mode = 'playlistRoot'
- addDir(display_name, playlist_id, mode, iconimage=playlist_image, total=total,cm=cm)
- xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=True)
-
-def playlistUserRoot():
- playlistRoot(VEVOToken=True)
-
-def playlistRoot(VEVOToken=False):
- playlist_id = params['url']
- mode = 'playPlaylist'
- smode = 'newVideoPlaylistURLPL'
- amode = 'addVideoPlaylistURLPL'
- qmode = 'queuePlaylist'
- if VEVOToken:
- url = 'http://api.vevo.com/mobile/v1/userplaylist/%s.json?' % playlist_id
- mode = 'playUserPlaylist'
- smode = 'newVideoPlaylistURLPLToken'
- amode = 'addVideoPlaylistURLPLToken'
- qmode = 'queueUserPlaylist'
- elif playlist_id.isdigit():
- url = 'http://api.vevo.com/mobile/v1/playlist/%s.json?' % playlist_id
- else:
- url = 'http://api.vevo.com/mobile/v2/playlist/%s.json?' % playlist_id
- cm=[]
- u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+urllib.quote_plus(qmode)+'&page='+urllib.quote_plus('1')
- cm.append( ('Queue', "XBMC.RunPlugin(%s)" % u) )
- if addon.getSetting('session_token'):
- #if VEVOToken:
- u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+urllib.quote_plus(amode)+'&page='+urllib.quote_plus('1')
- #cm.append( ('Save to Playlist', "XBMC.RunPlugin(%s)" % u) )
- u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+urllib.quote_plus(smode)+'&page='+urllib.quote_plus('1')
- cm.append( ('New Playlist', "XBMC.RunPlugin(%s)" % u) )
- addDir('*Play*', url, mode,folder=False,cm=cm)
- listVideos(url,playlist=True,VEVOToken=VEVOToken)
- xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=True)
-
-def playUserPlaylist():
- listVideos(params['url'],playlist=True,playall=True,VEVOToken=True)
-
-def playPlaylist():
- listVideos(params['url'],playlist=True,playall=True)
-
-def queueUserPlaylist():
- listVideos(params['url'],playlist=True,queue=True,VEVOToken=True)
-
-def queuePlaylist():
- listVideos(params['url'],playlist=True,queue=True)
-
-# Show listings
-def rootShows(url = False):
- xbmcplugin.setContent(pluginhandle, 'tvshows')
- if not url:
- url = params['url']
- data = getURL(url)
- shows = demjson.decode(data)['result']
- total = len(shows)
- if total >= max:
- addDir('*Next Page*', url, 'listArtists', page=str(page+1))
- for show in shows:
- show_id = show['id']
- show_name = show['name']
- show_image = show['image_url']
- video_count = show['total_videos_count']
- description = show['description']
- url = 'http://api.vevo.com/mobile/v1/show/'+str(show_id)+'.json'
- display_name=show_name+' ('+str(video_count)+')'
- addDir(display_name, url, 'rootEpisodes', plot=description, iconimage=show_image, total=total)
- xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_LABEL)
- xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=True)
- setView(override=504)
-
-def rootEpisodes(url = False):
- if not url:
- url = params['url']
- data = getURL(url)
- result = demjson.decode(data)['result']
- show_id = result['id']
- show_name = result['name']
- show_image = result['image_url']
- description = result['description']
- if len(result['videos']) > 0:
- url = 'http://api.vevo.com/mobile/v1/show/'+str(show_id)+'/videos.json?order=MostRecent'
- listVideosNoPage(url)
- else:
- xbmcplugin.setContent(pluginhandle, 'episodes')
- episodes = result['episodes']
- total = len(episodes)
- for episode in episodes:
- episode_id = episode['episode_id']
- episode_title = episode['title']
- episode_image = episode['image_url']
- video_count = episode['video_count']
- url = 'http://api.vevo.com/mobile/v1/show/'+str(show_id)+'/videos.json?episode='+episode_id.replace(" ", "%20")
- display_name=episode_title +' ('+str(video_count)+')'
- u = sys.argv[0]
- u += '?url='+urllib.quote_plus(url)
- u += '&mode='+urllib.quote_plus('listVideosNoPage')
- u += '&page=1'
- item=xbmcgui.ListItem(display_name, iconImage=episode_image, thumbnailImage=episode_image)
- item.setInfo( type="Video", infoLabels={ "Title":episode_title,
- "TVShowTitle":show_name,
- "plot":description,
- #"episode":video_count,
- })
- item.setProperty('fanart_image',show_image)
- xbmcplugin.addDirectoryItem(pluginhandle,url=u,listitem=item,isFolder=True,totalItems=total)
- xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_LABEL)
- xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=True)
- setView(override=503)
-
-# Search
-def searchVideos():
- Search('Videos')
-
-def searchArtists():
- Search('Artists')
-
-def researchArtists():
- listArtists(params['url'])
-
-def researchVideos():
- listVideos(params['url'])
-
-def Search(mode):
- keyb = xbmc.Keyboard('', 'Search '+mode)
- keyb.doModal()
- if keyb.isConfirmed():
- search = urllib.quote_plus(keyb.getText())
- vurl = 'http://api.vevo.com/mobile/v1/search/videos.json?q='+search
- aurl = 'http://api.vevo.com/mobile/v1/search/artists.json?q='+search
- if mode == 'Videos':
- addDir('*Artist Results*',aurl,'researchArtists')
- listVideos(vurl)
- elif mode == 'Artists':
- addDir('*Video Results*',vurl,'researchVideos')
- listArtists(aurl)
-
-def searchBox():
- latitude = float(addon.getSetting('latitude'))
- longitude = float(addon.getSetting('longitude'))
- radius = (int(addon.getSetting('radius'))+1)*100
- lon_min = longitude - radius / abs(math.cos(math.radians(latitude)) * 69)
- lon_max = longitude + radius / abs(math.cos(math.radians(latitude)) * 69)
- lat_min = latitude - (radius / 69)
- lat_max = latitude + (radius / 69)
- parameters = '?s='+str(lat_min)
- parameters += '&w='+str(lon_min)
- parameters += '&n='+str(lat_max)
- parameters += '&e='+str(lon_max)
- return parameters
-
-def TrendingRightNowIn():
- url = 'http://api.vevo.com/mobile/v1/video/TrendingRightNowIn.json'+searchBox()
- listVideos(url)
-
-def watchingRightNowIn():
- url = 'http://api.vevo.com/mobile/v1/video/watchingRightNowIn.json'+searchBox()
- listVideos(url)
-
-def toursRightNow():
- url = 'http://api.vevo.com/mobile/v1/geo/toursrightnow.json'+searchBox()
- max = maxperpage
- page = int(params['page'])
- offset = (page-1)*max
- fetch_url=url+'&offset='+str(offset)+'&max='+str(max)+'&extended=true'
- #if total >= max:
- # addDir('*Next Page*', url, 'toursRightNow', page=str(page+1))
- listTours(fetch_url)
-
-def listTours(url=False):
- if not url:
- url = params['url']
- data = getURL(url)
- artists = demjson.decode(data)['result']
- total = len(artists)
- for artist in artists:
- artist_id = artist['artistid']
- url = 'http://api.vevo.com/mobile/v1/artist/'+artist_id+'/videos.json?order=MostRecent'
- event_name = artist['eventname'].encode('utf-8')
- city = artist['city'].encode('utf-8')
- venuename = artist['venuename'].encode('utf-8')
- startdate = artist['startdate']
- type = artist['type']
- date = time.strftime("%B %d, %Y %I:%M%p", time.strptime(startdate[:-5], "%Y-%m-%dT%H:%M:%S") )
- if artist.has_key('artist'):
- artist_name = artist['artist']['name'].encode('utf-8')
- artist_image = artist['artist']['image_url']
- else:
- artist_name = event_name.split(' at ')[0].strip()
- artist_image = ''
- if type == 'Festival':
- if '@' in event_name:
- event_name = event_name.split('@')[1]
- if artist_name == event_name:
- final_name = date +' : '+city+' - '+event_name+' @ '+venuename
- else:
- final_name = date +' : '+city+' - '+artist_name+' @ '+event_name
- elif type == 'Concert':
- final_name = date+' : '+city+' - '+artist_name+' @ '+venuename
- addDir(final_name, url, 'listArtistVideos', iconimage=artist_image, total=total)
- xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=True)
- setView(override=51)
-
-def createArtistdb():
- if not os.path.isfile(FAVFILESQL):
- db = sqlite.connect(FAVFILESQL)
- db.text_factory = str
- c = db.cursor()
- c.execute('''CREATE TABLE artists(
- id TEXT,
- name TEXT,
- image TEXT,
- count INTEGER,
- PRIMARY KEY(id)
- );''')
- db.commit()
- c.close()
- rematchArtists()
- try:convertJSONfavs()
- except:pass
-
-def addArtistdb(artist):
- createArtistdb()
- db = sqlite.connect(FAVFILESQL)
- db.text_factory = str
- c = db.cursor()
- c.execute('insert or ignore into artists values (?,?,?,?)', [artist['id'],artist['name'],artist['image_url'],artist['video_count']])
- db.commit()
- c.close()
-
-def addfavArtists():
- artist = demjson.decode(getURL(params['url']))['result']
- addArtistdb(artist)
- xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( 'Success', 'Added Artist', 5000) )
-
-def removefavArtists():
- db = sqlite.connect(FAVFILESQL)
- db.text_factory = str
- c = db.cursor()
- c.execute('delete from artists where id = (?)', (params['url'],) )
- db.commit()
- c.close()
- xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( 'Success', 'Deleted Artist', 5000) )
- #xbmc.executebuiltin("Container.Refresh()")
-
-def deletefavArtists():
- db = sqlite.connect(FAVFILESQL)
- db.text_factory = str
- c = db.cursor()
- c.execute('delete from artists')
- db.commit()
- c.close()
- xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( 'Success', 'Deleted Favorite Artists', 10000) )
-
-def rematchArtists():
- for artist in matchedArtists():
- addArtistdb(artist)
- xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( 'Success', 'Library Artists Added', 10000) )
-
-def convertJSONfavs():
- if os.path.isfile(FAVFILE):
- for artist in demjson.decode(OpenFile(FAVFILE)):
- addArtistdb(artist)
- os.remove(FAVFILE)
-
-def favArtists():
- xbmcplugin.setContent(pluginhandle, 'artists')
- createArtistdb()
- db = sqlite.connect(FAVFILESQL)
- db.text_factory = str
- c = db.cursor()
- for artist in c.execute('select distinct * from artists'):
- artist_id = artist[0]
- artist_name = artist[1]
- artist_image = artist[2]
- video_count = artist[3]
- url = 'http://api.vevo.com/mobile/v1/artist/'+artist_id+'/videos.json?order=MostRecent'
- display_name=artist_name+' ('+str(video_count)+')'
- cm = []
- tours_url = 'http://api.vevo.com/mobile/v1/artist/%s/tours.json?toDate=2020-12-31&extended=true' % artist_id
- u=sys.argv[0]+"?url="+urllib.quote_plus(tours_url)+"&mode="+urllib.quote_plus('listTours')+'&page='+str(1)
- cm.append( ('List Tours', "Container.Update(%s)" % u) )
- u='plugin://plugin.video.youtube/?path=/root/search&feed=search&search='+urllib.quote_plus(artist_name)+'&'
- cm.append( ('YouTube %s' % artist_name, "Container.Update(%s)" % u) )
- u=sys.argv[0]+"?url="+urllib.quote_plus(artist_id)+"&mode="+urllib.quote_plus('removefavArtists')+'&page='+str(1)
- cm.append( ('Remove %s' % artist_name, "XBMC.RunPlugin(%s)" % u) )
- addDir(display_name, url, 'listArtistVideos', iconimage=artist_image, cm=cm)
- xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_LABEL)
- xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=True)
- setView()
- c.close()
-
-def matchedArtists():
- url = 'http://api.vevo.com/mobile/v1/search/artistmatch.json'
- json_query = {}
- json_list = []
- for artist in getLibraryArtists():
- artistjson = {'songCount':1,
- 'query':artist}
- json_list.append(artistjson)
- json_query['query']=json_list
- json_query['last_batch']='true'
- json_query = demjson.encode(json_query)
- data = getURL( url , postdata=json_query, extendTimeout=60)
- artists = demjson.decode(data)['result']
- #total = len(artists)
- returns = []
- for artist in artists:
- returns.append(artist['artist'])
- return returns
-
-def getLibraryArtists():
- json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "AudioLibrary.GetArtists", "id": 1}')
- json_response = demjson.decode(json_query)
- artistlist = []
- if json_response['result']:
- for item in json_response['result']['artists']:
- artistname = cleanartists(item['label'])
- artistlist.append(artistname)
- return artistlist
-
-# Play Video
-def playVideo():
- playlistVideo()
-
-def playlistVideo():
- if addon.getSetting('rickroll') == 'true':
- params['url']='GB1108700010'
- subtitles = os.path.join(datapath,params['url']+'.srt')
- if addon.getSetting('lyricsubs') == 'true':
- if params['duration']:
- try:getLyrics(params['url'],params['duration'],subtitles)
- except: print "Subtitles Failed"
-
- if addon.getSetting('defaultyoutube') == 'true':
- try:YouTube()
- except:
- try:HLS()
- except:
- try:RTMP()
- except:HTTPDynamic()
- elif addon.getSetting('defaultrtmp') == 'true':
- try:RTMP()
- except:YouTube()
- elif addon.getSetting('defaulthls') == 'true':
- try:HLS()
- except:YouTube()
- elif addon.getSetting('enabled-cache') == 'true':
- HTTPDynamicCache()
- else:
- try:HTTPDynamic()
- except:YouTube()
- xbmc.sleep(5000)
- if addon.getSetting('lyricsubs') == 'true':
- if os.path.isfile(subtitles) and xbmc.Player().isPlaying():
- xbmc.Player().setSubtitles(subtitles)
-
-class DownloadThread (threading.Thread):
- def __init__(self, url, dest, artist, title, id):
- self.url = url
- self.dest = dest
- self.artist = artist
- self.title = title
- self.id = id
- threading.Thread.__init__(self)
-
- def run(self):
- start_time = time.time()
- try:
- addCachedb(self.id,self.artist,self.title)
- urllib.urlretrieve(self.url, self.dest)
- statusUpdatedb(self.id,'completed')
- except:
- statusUpdatedb(self.id,'failed')
-
-def createCachedb():
- if not os.path.isfile(CACHEDB):
- db = sqlite.connect(CACHEDB)
- db.text_factory = str
- c = db.cursor()
- c.execute('''CREATE TABLE videos(
- id TEXT,
- artist TEXT,
- title TEXT,
- status TEXT,
- PRIMARY KEY(id)
- );''')
- db.commit()
- c.close()
-
-def checkIDdb(id):
- if addon.getSetting('enabled-cache') == 'true':
- createCachedb()
- db = sqlite.connect(CACHEDB)
- db.text_factory = str
- c = db.cursor()
- video = c.execute('select distinct * from videos where id = (?)', (id,)).fetchone()
- c.close()
- if video:
- id,artist,title,status = video
- if status == 'failed':
- return False
- elif status == 'started':
- return 1
- elif status == 'completed':
- return 7
- else:
- return 3
- else:
- return False
- return False
-
-def deleteCachedFile(id=False):
- if not id:
- id = params['url']
- db = sqlite.connect(CACHEDB)
- db.text_factory = str
- c = db.cursor()
- video = c.execute('select distinct * from videos where id = (?)', (id,)).fetchone()
- if video:
- id,artist,title,status = video
- filename=cleanfilename(artist+' - '+title)
- videofile = os.path.join(cachepath,filename+'.flv')
- jpgfile = os.path.join(cachepath,filename+'.jpg')
- nfofile = os.path.join(cachepath,filename+'.nfo')
- subfile = os.path.join(cachepath,filename+'.srt')
- for file in (videofile,jpgfile,nfofile,subfile):
- if os.path.exists(file):
- os.remove(file)
- deleteCachedb(id)
- #xbmc.executebuiltin("Container.Refresh()")
-
-def statusUpdatedb(id,status):
- db = sqlite.connect(CACHEDB)
- db.text_factory = str
- c = db.cursor()
- c.execute("update videos set status=? where id=?", (status,id))
- db.commit()
- c.close()
-
-def deleteCachedb(id):
- db = sqlite.connect(CACHEDB)
- db.text_factory = str
- c = db.cursor()
- c.execute("delete from videos where id=?", (id,))
- db.commit()
- c.close()
-
-def addCachedb(id,artist,title,status='started'):
- db = sqlite.connect(CACHEDB)
- db.text_factory = str
- c = db.cursor()
- c.execute('insert or ignore into videos values (?,?,?,?)', [id,artist,title,status])
- db.commit()
- c.close()
-
-def cleanfilename(name):
- valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)
- return ''.join(c for c in name if c in valid_chars)
-
-def HTTPDynamicCache():
- vevoID = params['url'].split('/')[-1]
- createCachedb()
- db = sqlite.connect(CACHEDB)
- db.text_factory = str
- c = db.cursor()
- video = c.execute('select distinct * from videos where id = (?)', (vevoID,)).fetchone()
- if video:
- id,artist,title,status = video
- filename=cleanfilename(artist+' - '+title)
- videofile = os.path.join(cachepath,filename+'.flv')
- #jpgfile = os.path.join(cachepath,filename+'.jpg')
- #nfofile = os.path.join(cachepath,filename+'.nfo')
- #subfile = os.path.join(cachepath,filename+'.srt')
- if os.path.exists(videofile):
- if status == 'failed':
- os.remove(videofile)
- deleteCachedb(vevoID)
- HTTPDynamicCacheDownload(vevoID)
- else:
- print "Playing %s from Cache" % filename
- item = xbmcgui.ListItem(path=videofile)
- xbmcplugin.setResolvedUrl(pluginhandle, True, item)
- #if not os.path.exists(jpgfile):
- # SaveFile(jpgfile, getURL(image_url))
- #if not os.path.exists(nfofile):
- # url = 'http://videoplayer.vevo.com/VideoService/AuthenticateVideo?isrc=%s' % vevoID
- # data = getURL(url)
- # video = demjson.decode(data)['video']
- # HTTPDynamicCacheNFO(video,nfofile)
- #if not os.path.exists(subfile):
- # HTTPDynamicCacheSubtitles(subfile)
- else:
- deleteCachedb(vevoID)
- HTTPDynamicCacheDownload(vevoID)
- else:
- HTTPDynamicCacheDownload(vevoID)
-
-def HTTPDynamicCacheSubtitles(filename):
- try:getLyrics(params['url'],params['duration'],filename)
- except:print 'subtitles failed'
-
-def HTTPDynamicCacheNFO(video,nfofile):
- try:
- title = video['title'].encode('utf-8')
- image_url = video['imageUrl']
- artist = video['mainArtists'][0]['artistName'].encode('utf-8')
- duration = str(video['duration'])
- genre=''
- for item in video['genres']:
- genre+=item+','
- genre=genre[:-1]
- releaseDate=int(video['releaseDate'].replace('/Date(','').replace(')/','')[:-3])
- year = time.strftime("%Y",time.localtime(releaseDate))
- metadict={}
- plot=''
- for meta in video['metadata']:
- metadict[meta['keyType']]=meta['keyValue']
- if meta['keyType'] == 'Credit':
- plot+=meta['keyValue'].replace('=>',':')+'\n'
- else:
- plot+=meta['keyType']+' : '+meta['keyValue']+'\n'
- nfo =''+'\n'
- nfo+=''+title+''+'\n'
- nfo+=''+artist+''+'\n'
- nfo+=''+'Music Video'+''
- nfo+=''+genre+''+'\n'
- nfo+=''+duration+''+'\n'
- nfo+=''+image_url+''+'\n'
- nfo+=''+plot+''+'\n'
- nfo+=''+year+''+'\n'
- try:director = metadict['Director'].encode('utf-8')
- except:director = ''
- nfo+=''+director+''+'\n'
- try:studio = metadict['Label'].encode('utf-8')
- except:studio = ''
- nfo+=''+studio+''+'\n'
- nfo+=''
- SaveFile(nfofile, nfo)
- except: print 'nfo failed'
-
-def HTTPDynamicCacheDownload(vevoID):
- print "Cacheing %s" % vevoID
- url = 'http://videoplayer.vevo.com/VideoService/AuthenticateVideo?isrc=%s' % vevoID
- data = getURL(url)
- video = demjson.decode(data)['video']
- title = video['title'].encode('utf-8')
- image_url = video['imageUrl']
- artist = video['mainArtists'][0]['artistName'].encode('utf-8')
-
-
- filename=cleanfilename(artist+' - '+title)
- videofile = os.path.join(cachepath,filename+'.flv')
- jpgfile = os.path.join(cachepath,filename+'.jpg')
- nfofile = os.path.join(cachepath,filename+'.nfo')
- subfile = os.path.join(cachepath,filename+'.srt')
- if os.path.exists(videofile):
- print "Found %s in cache, Adding to savedDB and resolving" % filename
- item = xbmcgui.ListItem(path=videofile)
- xbmcplugin.setResolvedUrl(pluginhandle, True, item)
- addCachedb(vevoID,artist,title,'completed')
- if not os.path.exists(jpgfile):
- SaveFile(jpgfile, getURL(image_url))
- if not os.path.exists(nfofile):
- HTTPDynamicCacheNFO(video,nfofile)
- if not os.path.exists(subfile):
- HTTPDynamicCacheSubtitles(subfile)
- else:
- type5=False
- youtube=False
- for version in video['videoVersions']:
- if version['sourceType'] == 5:
- type5=True
- elif version['sourceType'] == 0:
- youtubeID = version['id']
- youtube=True
-
-
- video_url=False
- if type5:
- print "VEVO - Saving from VEVO"
- video_url = getVideo(params['url'])
- elif youtube:
- print "VEVO - Saving from Youtube"
- video_url = getYouTubeLink(youtubeID)
- else:
- try:video_url = getVideo(params['url'])
- except: pass
- if video_url:
- print "VEVO Downloading : %s" % video_url
- dlThread = DownloadThread(video_url, videofile, artist, title, vevoID)
- dlThread.start()
- HTTPDynamicCacheSubtitles(subfile)
- HTTPDynamicCacheNFO(video,nfofile)
- try:SaveFile(jpgfile, getURL(image_url))
- except: print 'Saving screenshot failed'
- count=0
- while not os.path.exists(videofile):
- count+=1
- if count > 6:
- break
- xbmc.sleep(2500)
- if os.path.exists(videofile):
- if dlThread.isAlive():
- sleeptime = (int(addon.getSetting('unpausetime'))+1)*1000
- xbmc.sleep(sleeptime+5000)
- print "Playing %s while downloading" % filename
- item = xbmcgui.ListItem(path=videofile)
- xbmcplugin.setResolvedUrl(pluginhandle, True, item)
- else:
- print "No Link Found"
-
-def getYouTubeLink(youtubeID):
- data = getURL('http://www.youtube.com/watch?v=%s&safeSearch=none' % youtubeID, browser=True)
- data = re.compile('yt.playerConfig = (.*?)};',re.DOTALL).findall(data)[0].replace("\\/", "/")
- json = demjson.decode('{ "PLAYER_CONFIG" : ' + data + "}}" )
- fmt_stream_map = json['PLAYER_CONFIG']['args']['url_encoded_fmt_stream_map']
- links = urllib.unquote(fmt_stream_map[4:]).split(',url=')
- qualities = (5,33,18,26,43,34,78,44,59,35,22,45,38,37)
- index= -1
- for link in links:
- for quality in qualities:
- tag = '&itag='+str(quality)
- if tag in link:
- vindex = qualities.index(quality)
- if vindex > index:
- index=vindex
- video_url=link
- return video_url.replace(" ", "%20").split('&type')[0]
-
-def HTTPDynamic():
- item = xbmcgui.ListItem(path=getVideo(params['url']))
- xbmcplugin.setResolvedUrl(pluginhandle, True, item)
- if addon.getSetting('unpause') == 'true':
- sleeptime = (int(addon.getSetting('unpausetime'))+1)*1000
- xbmc.sleep(sleeptime)
- xbmc.Player().pause()
-
-def convert_time(milliseconds):
- seconds = int(float(milliseconds)/1000)
- milliseconds -= (seconds*1000)
- hours = seconds / 3600
- seconds -= 3600*hours
- minutes = seconds / 60
- seconds -= 60*minutes
- return "%02d:%02d:%02d,%03d" % (hours, minutes, seconds, milliseconds)
-
-def getLyrics(vevoID,duration,subtitles):
- if not os.path.isfile(subtitles):
- url = 'http://www.vevo.com/data/VideoLyrics/'+vevoID
- data = getURL(url,browser=True,alert=False)
- if data:
- json = demjson.decode(data)
- lyrics = json['Text'].replace('\r','').split('\n')
- sets = []
- set=''
- setlength = 0
- for lyric in lyrics:
- sub = lyric.strip().encode('utf-8')
- if setlength > 7 and set <> '':
- sets.append(set)
- set=''
- setlength = 0
- if sub == '' and set <> '':
- sets.append(set)
- set=''
- setlength = 0
- elif sub <> '':
- set += sub+'\n'
- setlength += 1
- if set <> '':
- sets.append(set)
- lines = len(sets)
- duration = float(duration)*1000
- offset = duration*0.025
- rate = (duration*0.95)/lines
- count = 0
- srt_output = ''
- for set in sets:
- start = convert_time( (count*rate)+offset )
- end = convert_time( ( (count+1)*rate ) + offset)
- count += 1
- line = str(count)+"\n"+start+" --> "+end+"\n"+set+"\n"
- srt_output += line
- if srt_output <> '':
- SaveFile(subtitles, srt_output)
-
-def YouTube():
- vevoID = params['url'].split('/')[-1]
- url = 'http://videoplayer.vevo.com/VideoService/AuthenticateVideo?isrc=%s' % vevoID
- data = getURL(url)
- youtubeID = demjson.decode(data)['video']['videoVersions'][0]['id']
- youtubeurl = 'plugin://plugin.video.youtube/?action=play_video&videoid=%s' % youtubeID
- item = xbmcgui.ListItem(path=youtubeurl)
- xbmcplugin.setResolvedUrl(pluginhandle, True, item)
-
-def HLS():
- vevoID = params['url'].split('/')[-1]
- url = 'http://videoplayer.vevo.com/VideoService/AuthenticateVideo?isrc=%s' % vevoID
- data = getURL(url)
- video = demjson.decode(data)['video']
- for version in video['videoVersions']:
- if version['sourceType']== 4:
- video_url = re.compile('url="(.+?)"').search(version['data']).group(1)
- item = xbmcgui.ListItem(path=video_url)
- xbmcplugin.setResolvedUrl(pluginhandle, True, item)
-
-def RTMP():
- item = xbmcgui.ListItem(path=getVideoRTMP(params['url']))
- xbmcplugin.setResolvedUrl(pluginhandle, True, item)
-
-def getVideoRTMP(pageurl):
- quality = [564000, 864000, 1328000, 1728000, 2528000, 3328000, 4392000, 5392000]
- select = int(addon.getSetting('bitrate'))
- maxbitrate = quality[select]
- vevoID = pageurl.split('/')[-1]
- url = 'http://vevoodfs.fplive.net/Video/V2/VFILE/%s/%sr.smil' % (vevoID,vevoID.lower())
- data = getURL(url,alert=False)
- tree=BeautifulStoneSoup(data, convertEntities=BeautifulStoneSoup.HTML_ENTITIES)
- print tree.prettify()
- rtmp = tree.find('meta')['base']
- videos = tree.findAll('video')
- number = len(videos)-1
- if number < select:
- select = number
- playpath = videos[select]['src']
- final = rtmp+' playpath='+playpath
- return final
-
-def getVideo(pageurl):
- quality = [564000, 864000, 1328000, 1728000, 2528000, 3328000, 4392000, 5392000]
- select = int(addon.getSetting('bitrate'))
- maxbitrate = quality[select]
- vevoID = pageurl.split('/')[-1]
- url = 'http://smilstream.vevo.com/HDFlash/v1/smil/%s/%s.smil' % (vevoID,vevoID.lower())
- data = getURL(url,alert=False)
- tree=BeautifulStoneSoup(data, convertEntities=BeautifulStoneSoup.HTML_ENTITIES)
- print tree.prettify()
- videobase = tree.find(attrs={'name':'httpBase'})['content']
- videos = tree.findAll('video')
- filenames = ''
- number = len(videos) - 1
- if number < select:
- select = number
- if '_' in videos[number]:
- for video in videos:
- filepath = video['src']
- path = filepath.split('_')[0]
- filename = filepath.replace(path,'').replace('.mp4','')
- filenames += filename+','
- else:
- for video in videos:
- filepath = video['src']
- filename = filepath.split('/')[-1]
- path = filepath.replace(filename,'')
- filenames += filename.replace('.mp4','')+','
- finalUrl = videobase+path+','+filenames+'.mp4.csmil/bitrate='+str(select)+'?seek=0'
- return finalUrl
-
-# Common
-def addDir(name, url, mode, plot='', iconimage=vicon ,folder=True,total=0,page=1,cm=False):
- u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+urllib.quote_plus(mode)+'&page='+str(page)
- item=xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage)
- if iconimage <> vicon:
- item.setProperty('fanart_image',iconimage)
- else:
- item.setProperty('fanart_image',fanart)
- item.setInfo( type="Video", infoLabels={ "Title":name,
- "plot":plot
- })
- if cm:
- item.addContextMenuItems( cm )
- return xbmcplugin.addDirectoryItem(pluginhandle,url=u,listitem=item,isFolder=folder,totalItems=total)
-
-def setView(override=False):
- confluence_views = [50,500,511]
- if addon.getSetting('viewenable') == 'true':
- if override:
- view = str(override)
- else:
- view=int(addon.getSetting('defaultview'))
- view = str(confluence_views[view])
- xbmc.executebuiltin("Container.SetViewMode("+view+")")
-
-def setLocation():
- try:
- url = 'http://www.geobytes.com/IpLocator.htm?GetLocation&template=json.txt'
- data = getURL(url)
- locationdata = demjson.decode(data)['geobytes']
- latitude=str(locationdata['latitude'])
- longitude=str(locationdata['longitude'])
- addon.setSetting(id='latitude',value=latitude)
- addon.setSetting(id='longitude',value=longitude)
- xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( 'Set Location', '%s , %s' % (latitude, longitude), 8000) )
- except:
- addon.setSetting(id='latitude',value='')
- addon.setSetting(id='longitude',value='')
- xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( 'Failed', 'No Location Set', 10000) )
-
-def newGraph(email,password,uid=None,token=None,new_token_callback=None):
- graph = facebook.GraphWrap(token,new_token_callback=new_token_callback)
- graph.setAppData('184548202936',scope='email,user_birthday,user_likes,user_interests,publish_actions')
- graph.setLogin(email,password,uid)
- return graph
-
-def getFBAuth():
- email = addon.getSetting("login_name")
- password = addon.getSetting("login_pass")
- cj = cookielib.LWPCookieJar()
- br = mechanize.Browser()
- br.set_handle_robots(False)
- br.set_cookiejar(cj)
- user = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0'
- #user = 'Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A405'
- br.addheaders = [('User-agent', user)]
- #redirect = urllib.quote('fbconnect://success')
- redirect = urllib.quote('https://www.vevo.com')
- #scope = urllib.quote('email,user_birthday,user_likes,user_interests,publish_actions')
- scope = urllib.quote('email')
- url = 'https://graph.facebook.com/oauth/authorize?client_id=184548202936&local_client_id=vevo&redirect_uri=%s&type=user_agent&scope=%s&sdk=ios&display=touch' % (redirect,scope)
- br.open(url)
- response = br.response()
- headers = response.info()
- headers["Content-type"] = "text/html; charset=utf-8"
- response.set_data(response.get_data().replace('',''))
- br.set_response(response)
- br.select_form(nr=0)
- br["email"] = email
- br["pass"] = password
- logged_in = br.submit()
- data = logged_in.read()
- url = logged_in.geturl()
- graph = newGraph(email, password)
- token = graph.extractTokenFromURL(url)
- if graph.tokenIsValid(token):
- addon.setSetting(id='fbtoken',value=token)
- return True
- else:
- return False
-
-def getVEVOAccount():
- url = 'http://api.vevo.com/mobile/v1/user/facebookauth.json'
- sendtoken = {}
- sendtoken['accessToken'] = addon.getSetting(id='fbtoken')
- data = getURL( url , postdata=demjson.encode(sendtoken), VEVOKey=True)
- json = demjson.decode(data)
- addon.setSetting(id='vevo_user_id',value=json['user_id'])
- addon.setSetting(id='session_token',value=json['session_token'])
-
-def getURL( url , postdata=False, method=False, extendTimeout=False, VEVOToken=False, VEVOKey=False, browser=False, alert=True):
- try:
- print 'VEVO --> common :: getURL :: url = '+url
- #proxy = 'http://localhost:8888'
- #proxy_handler = urllib2.ProxyHandler({'http':proxy})
- #opener = urllib2.build_opener(proxy_handler)
- if addon.getSetting('us_proxy_enable') == 'true':
- us_proxy = 'http://' + addon.getSetting('us_proxy') + ':' + addon.getSetting('us_proxy_port')
- proxy_handler = urllib2.ProxyHandler({'http':us_proxy})
- if addon.getSetting('us_proxy_pass') <> '' and addon.getSetting('us_proxy_user') <> '':
- print 'Using authenticated proxy: ' + us_proxy
- password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
- password_mgr.add_password(None, us_proxy, addon.getSetting('us_proxy_user'), addon.getSetting('us_proxy_pass'))
- proxy_auth_handler = urllib2.ProxyBasicAuthHandler(password_mgr)
- opener = urllib2.build_opener(proxy_handler, proxy_auth_handler)
- else:
- print 'Using proxy: ' + us_proxy
- opener = urllib2.build_opener(proxy_handler)
- else:
- opener = urllib2.build_opener()
- if browser:
- opener.addheaders = [('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0')]
- else:
- opener.addheaders = [('User-Agent', 'VEVO 1.5 rv:5529 (iPad; iPhone OS 5.0.1; en_US)')]
- if VEVOToken:
- opener.addheaders = [('X-VEVO-Session-Token', addon.getSetting('session_token') )]
- if VEVOKey:
- opener.addheaders = [('X-VEVO-Private-Key', 'G05bmz9x--_6-J-qpR4_' )]
- if postdata:
- if method:
- request = urllib2.Request(url, data=postdata)
- #request.add_header('Content-Type', 'your/contenttype')
- request.get_method = lambda: method
- usock=opener.open(request)
- elif extendTimeout <> False:
- try:usock=opener.open(url,postdata,extendTimeout)
- except:usock=opener.open(url,postdata)
- else:
- usock=opener.open(url,postdata)
- else:
- usock=opener.open(url)
- response=usock.read()
- usock.close()
- return response
- except urllib2.URLError, e:
- print 'Error reason: ', e
- heading = 'Error'
- message = e
- duration = 10000
- if alert:
- xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( heading, message, duration) )
- return False
-
-def _unicode( text, encoding='utf-8' ):
- try: text = unicode( text, encoding )
- except: pass
- return text
-
-def cleanartists(name):
- try: name = unicodedata.normalize( 'NFKD', _unicode( name ) ).encode( 'ascii', 'ignore' )
- except: pass
- return name.replace('"','').replace("'",'').replace('<','').replace('>','').replace('(','').replace(')','').replace('\n',' ').replace('-',' ')
-
-def SaveFile(path, data):
- file = open(path,'w')
- file.write(data)
- file.close()
-
-def OpenFile(path):
- file = open(path, 'r')
- contents=file.read()
- file.close()
- return contents
-
-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]]=urllib.unquote_plus(splitparams[1])
- return param
-
-params=get_params()
-try:
- mode=params["mode"]
-except:
- mode=None
-print "Mode: "+str(mode)
-print "Parameters: "+str(params)
-
-if mode==None:
- listCategories()
-else:
- exec '%s()' % mode
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/demjson.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/demjson.py
deleted file mode 100644
index a513ee134a487cea3bbc2d165a2541a97ff523f2..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/demjson.py
+++ /dev/null
@@ -1,2138 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-r""" A JSON data encoder and decoder.
-
- This Python module implements the JSON (http://json.org/) data
- encoding format; a subset of ECMAScript (aka JavaScript) for encoding
- primitive data types (numbers, strings, booleans, lists, and
- associative arrays) in a language-neutral simple text-based syntax.
-
- It can encode or decode between JSON formatted strings and native
- Python data types. Normally you would use the encode() and decode()
- functions defined by this module, but if you want more control over
- the processing you can use the JSON class.
-
- This implementation tries to be as completely cormforming to all
- intricacies of the standards as possible. It can operate in strict
- mode (which only allows JSON-compliant syntax) or a non-strict mode
- (which allows much more of the whole ECMAScript permitted syntax).
- This includes complete support for Unicode strings (including
- surrogate-pairs for non-BMP characters), and all number formats
- including negative zero and IEEE 754 non-numbers such a NaN or
- Infinity.
-
- The JSON/ECMAScript to Python type mappings are:
- ---JSON--- ---Python---
- null None
- undefined undefined (note 1)
- Boolean (true,false) bool (True or False)
- Integer int or long (note 2)
- Float float
- String str or unicode ( "..." or u"..." )
- Array [a, ...] list ( [...] )
- Object {a:b, ...} dict ( {...} )
-
- -- Note 1. an 'undefined' object is declared in this module which
- represents the native Python value for this type when in
- non-strict mode.
-
- -- Note 2. some ECMAScript integers may be up-converted to Python
- floats, such as 1e+40. Also integer -0 is converted to
- float -0, so as to preserve the sign (which ECMAScript requires).
-
- In addition, when operating in non-strict mode, several IEEE 754
- non-numbers are also handled, and are mapped to specific Python
- objects declared in this module:
-
- NaN (not a number) nan (float('nan'))
- Infinity, +Infinity inf (float('inf'))
- -Infinity neginf (float('-inf'))
-
- When encoding Python objects into JSON, you may use types other than
- native lists or dictionaries, as long as they support the minimal
- interfaces required of all sequences or mappings. This means you can
- use generators and iterators, tuples, UserDict subclasses, etc.
-
- To make it easier to produce JSON encoded representations of user
- defined classes, if the object has a method named json_equivalent(),
- then it will call that method and attempt to encode the object
- returned from it instead. It will do this recursively as needed and
- before any attempt to encode the object using it's default
- strategies. Note that any json_equivalent() method should return
- "equivalent" Python objects to be encoded, not an already-encoded
- JSON-formatted string. There is no such aid provided to decode
- JSON back into user-defined classes as that would dramatically
- complicate the interface.
-
- When decoding strings with this module it may operate in either
- strict or non-strict mode. The strict mode only allows syntax which
- is conforming to RFC 4627 (JSON), while the non-strict allows much
- more of the permissible ECMAScript syntax.
-
- The following are permitted when processing in NON-STRICT mode:
-
- * Unicode format control characters are allowed anywhere in the input.
- * All Unicode line terminator characters are recognized.
- * All Unicode white space characters are recognized.
- * The 'undefined' keyword is recognized.
- * Hexadecimal number literals are recognized (e.g., 0xA6, 0177).
- * String literals may use either single or double quote marks.
- * Strings may contain \x (hexadecimal) escape sequences, as well as the
- \v and \0 escape sequences.
- * Lists may have omitted (elided) elements, e.g., [,,,,,], with
- missing elements interpreted as 'undefined' values.
- * Object properties (dictionary keys) can be of any of the
- types: string literals, numbers, or identifiers (the later of
- which are treated as if they are string literals)---as permitted
- by ECMAScript. JSON only permits strings literals as keys.
-
- Concerning non-strict and non-ECMAScript allowances:
-
- * Octal numbers: If you allow the 'octal_numbers' behavior (which
- is never enabled by default), then you can use octal integers
- and octal character escape sequences (per the ECMAScript
- standard Annex B.1.2). This behavior is allowed, if enabled,
- because it was valid JavaScript at one time.
-
- * Multi-line string literals: Strings which are more than one
- line long (contain embedded raw newline characters) are never
- permitted. This is neither valid JSON nor ECMAScript. Some other
- JSON implementations may allow this, but this module considers
- that behavior to be a mistake.
-
- References:
- * JSON (JavaScript Object Notation)
-
- * RFC 4627. The application/json Media Type for JavaScript Object Notation (JSON)
-
- * ECMA-262 3rd edition (1999)
-
- * IEEE 754-1985: Standard for Binary Floating-Point Arithmetic.
-
-
-"""
-
-__author__ = "Deron Meranda "
-__date__ = "2008-12-17"
-__version__ = "1.4"
-__credits__ = """Copyright (c) 2006-2008 Deron E. Meranda
-Licensed under GNU LGPL 3.0 (GNU Lesser General Public License) or
-later. See LICENSE.txt included with this software.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser 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 Lesser General Public License
-along with this program. If not, see
-or .
-
-"""
-
-# ------------------------------
-# useful global constants
-
-content_type = 'application/json'
-file_ext = 'json'
-hexdigits = '0123456789ABCDEFabcdef'
-octaldigits = '01234567'
-
-# ----------------------------------------------------------------------
-# Decimal and float types.
-#
-# If a JSON number can not be stored in a Python float without loosing
-# precision and the Python has the decimal type, then we will try to
-# use decimal instead of float. To make this determination we need to
-# know the limits of the float type, but Python doesn't have an easy
-# way to tell what the largest floating-point number it supports. So,
-# we detemine the precision and scale of the float type by testing it.
-
-try:
- # decimal module was introduced in Python 2.4
- import decimal
-except ImportError:
- decimal = None
-
-def determine_float_precision():
- """Returns a tuple (significant_digits, max_exponent) for the float type.
- """
- import math
- # Just count the digits in pi. The last two decimal digits
- # may only be partial digits, so discount for them.
- whole, frac = repr(math.pi).split('.')
- sigdigits = len(whole) + len(frac) - 2
-
- # This is a simple binary search. We find the largest exponent
- # that the float() type can handle without going infinite or
- # raising errors.
- maxexp = None
- minv = 0; maxv = 1000
- while True:
- if minv+1 == maxv:
- maxexp = minv - 1
- break
- elif maxv < minv:
- maxexp = None
- break
- m = (minv + maxv) // 2
- try:
- f = repr(float( '1e+%d' % m ))
- except ValueError:
- f = None
- else:
- if not f or f[0] < '0' or f[0] > '9':
- f = None
- if not f:
- # infinite
- maxv = m
- else:
- minv = m
- return sigdigits, maxexp
-
-float_sigdigits, float_maxexp = determine_float_precision()
-
-# ----------------------------------------------------------------------
-# The undefined value.
-#
-# ECMAScript has an undefined value (similar to yet distinct from null).
-# Neither Python or strict JSON have support undefined, but to allow
-# JavaScript behavior we must simulate it.
-
-class _undefined_class(object):
- """Represents the ECMAScript 'undefined' value."""
- __slots__ = []
- def __repr__(self):
- return self.__module__ + '.undefined'
- def __str__(self):
- return 'undefined'
- def __nonzero__(self):
- return False
-undefined = _undefined_class()
-del _undefined_class
-
-
-# ----------------------------------------------------------------------
-# Non-Numbers: NaN, Infinity, -Infinity
-#
-# ECMAScript has official support for non-number floats, although
-# strict JSON does not. Python doesn't either. So to support the
-# full JavaScript behavior we must try to add them into Python, which
-# is unfortunately a bit of black magic. If our python implementation
-# happens to be built on top of IEEE 754 we can probably trick python
-# into using real floats. Otherwise we must simulate it with classes.
-
-def _nonnumber_float_constants():
- """Try to return the Nan, Infinity, and -Infinity float values.
-
- This is unnecessarily complex because there is no standard
- platform- independent way to do this in Python as the language
- (opposed to some implementation of it) doesn't discuss
- non-numbers. We try various strategies from the best to the
- worst.
-
- If this Python interpreter uses the IEEE 754 floating point
- standard then the returned values will probably be real instances
- of the 'float' type. Otherwise a custom class object is returned
- which will attempt to simulate the correct behavior as much as
- possible.
-
- """
- try:
- # First, try (mostly portable) float constructor. Works under
- # Linux x86 (gcc) and some Unices.
- nan = float('nan')
- inf = float('inf')
- neginf = float('-inf')
- except ValueError:
- try:
- # Try the AIX (PowerPC) float constructors
- nan = float('NaNQ')
- inf = float('INF')
- neginf = float('-INF')
- except ValueError:
- try:
- # Next, try binary unpacking. Should work under
- # platforms using IEEE 754 floating point.
- import struct, sys
- xnan = '7ff8000000000000'.decode('hex') # Quiet NaN
- xinf = '7ff0000000000000'.decode('hex')
- xcheck = 'bdc145651592979d'.decode('hex') # -3.14159e-11
- # Could use float.__getformat__, but it is a new python feature,
- # so we use sys.byteorder.
- if sys.byteorder == 'big':
- nan = struct.unpack('d', xnan)[0]
- inf = struct.unpack('d', xinf)[0]
- check = struct.unpack('d', xcheck)[0]
- else:
- nan = struct.unpack('d', xnan[::-1])[0]
- inf = struct.unpack('d', xinf[::-1])[0]
- check = struct.unpack('d', xcheck[::-1])[0]
- neginf = - inf
- if check != -3.14159e-11:
- raise ValueError('Unpacking raw IEEE 754 floats does not work')
- except (ValueError, TypeError):
- # Punt, make some fake classes to simulate. These are
- # not perfect though. For instance nan * 1.0 == nan,
- # as expected, but 1.0 * nan == 0.0, which is wrong.
- class nan(float):
- """An approximation of the NaN (not a number) floating point number."""
- def __repr__(self): return 'nan'
- def __str__(self): return 'nan'
- def __add__(self,x): return self
- def __radd__(self,x): return self
- def __sub__(self,x): return self
- def __rsub__(self,x): return self
- def __mul__(self,x): return self
- def __rmul__(self,x): return self
- def __div__(self,x): return self
- def __rdiv__(self,x): return self
- def __divmod__(self,x): return (self,self)
- def __rdivmod__(self,x): return (self,self)
- def __mod__(self,x): return self
- def __rmod__(self,x): return self
- def __pow__(self,exp): return self
- def __rpow__(self,exp): return self
- def __neg__(self): return self
- def __pos__(self): return self
- def __abs__(self): return self
- def __lt__(self,x): return False
- def __le__(self,x): return False
- def __eq__(self,x): return False
- def __neq__(self,x): return True
- def __ge__(self,x): return False
- def __gt__(self,x): return False
- def __complex__(self,*a): raise NotImplementedError('NaN can not be converted to a complex')
- if decimal:
- nan = decimal.Decimal('NaN')
- else:
- nan = nan()
- class inf(float):
- """An approximation of the +Infinity floating point number."""
- def __repr__(self): return 'inf'
- def __str__(self): return 'inf'
- def __add__(self,x): return self
- def __radd__(self,x): return self
- def __sub__(self,x): return self
- def __rsub__(self,x): return self
- def __mul__(self,x):
- if x is neginf or x < 0:
- return neginf
- elif x == 0:
- return nan
- else:
- return self
- def __rmul__(self,x): return self.__mul__(x)
- def __div__(self,x):
- if x == 0:
- raise ZeroDivisionError('float division')
- elif x < 0:
- return neginf
- else:
- return self
- def __rdiv__(self,x):
- if x is inf or x is neginf or x is nan:
- return nan
- return 0.0
- def __divmod__(self,x):
- if x == 0:
- raise ZeroDivisionError('float divmod()')
- elif x < 0:
- return (nan,nan)
- else:
- return (self,self)
- def __rdivmod__(self,x):
- if x is inf or x is neginf or x is nan:
- return (nan, nan)
- return (0.0, x)
- def __mod__(self,x):
- if x == 0:
- raise ZeroDivisionError('float modulo')
- else:
- return nan
- def __rmod__(self,x):
- if x is inf or x is neginf or x is nan:
- return nan
- return x
- def __pow__(self, exp):
- if exp == 0:
- return 1.0
- else:
- return self
- def __rpow__(self, x):
- if -1 < x < 1: return 0.0
- elif x == 1.0: return 1.0
- elif x is nan or x is neginf or x < 0:
- return nan
- else:
- return self
- def __neg__(self): return neginf
- def __pos__(self): return self
- def __abs__(self): return self
- def __lt__(self,x): return False
- def __le__(self,x):
- if x is self:
- return True
- else:
- return False
- def __eq__(self,x):
- if x is self:
- return True
- else:
- return False
- def __neq__(self,x):
- if x is self:
- return False
- else:
- return True
- def __ge__(self,x): return True
- def __gt__(self,x): return True
- def __complex__(self,*a): raise NotImplementedError('Infinity can not be converted to a complex')
- if decimal:
- inf = decimal.Decimal('Infinity')
- else:
- inf = inf()
- class neginf(float):
- """An approximation of the -Infinity floating point number."""
- def __repr__(self): return '-inf'
- def __str__(self): return '-inf'
- def __add__(self,x): return self
- def __radd__(self,x): return self
- def __sub__(self,x): return self
- def __rsub__(self,x): return self
- def __mul__(self,x):
- if x is self or x < 0:
- return inf
- elif x == 0:
- return nan
- else:
- return self
- def __rmul__(self,x): return self.__mul__(self)
- def __div__(self,x):
- if x == 0:
- raise ZeroDivisionError('float division')
- elif x < 0:
- return inf
- else:
- return self
- def __rdiv__(self,x):
- if x is inf or x is neginf or x is nan:
- return nan
- return -0.0
- def __divmod__(self,x):
- if x == 0:
- raise ZeroDivisionError('float divmod()')
- elif x < 0:
- return (nan,nan)
- else:
- return (self,self)
- def __rdivmod__(self,x):
- if x is inf or x is neginf or x is nan:
- return (nan, nan)
- return (-0.0, x)
- def __mod__(self,x):
- if x == 0:
- raise ZeroDivisionError('float modulo')
- else:
- return nan
- def __rmod__(self,x):
- if x is inf or x is neginf or x is nan:
- return nan
- return x
- def __pow__(self,exp):
- if exp == 0:
- return 1.0
- else:
- return self
- def __rpow__(self, x):
- if x is nan or x is inf or x is inf:
- return nan
- return 0.0
- def __neg__(self): return inf
- def __pos__(self): return self
- def __abs__(self): return inf
- def __lt__(self,x): return True
- def __le__(self,x): return True
- def __eq__(self,x):
- if x is self:
- return True
- else:
- return False
- def __neq__(self,x):
- if x is self:
- return False
- else:
- return True
- def __ge__(self,x):
- if x is self:
- return True
- else:
- return False
- def __gt__(self,x): return False
- def __complex__(self,*a): raise NotImplementedError('-Infinity can not be converted to a complex')
- if decimal:
- neginf = decimal.Decimal('-Infinity')
- else:
- neginf = neginf(0)
- return nan, inf, neginf
-
-nan, inf, neginf = _nonnumber_float_constants()
-del _nonnumber_float_constants
-
-
-# ----------------------------------------------------------------------
-# String processing helpers
-
-unsafe_string_chars = '"\\' + ''.join([chr(i) for i in range(0x20)])
-def skipstringsafe( s, start=0, end=None ):
- i = start
- #if end is None:
- # end = len(s)
- while i < end and s[i] not in unsafe_string_chars:
- #c = s[i]
- #if c in unsafe_string_chars:
- # break
- i += 1
- return i
-def skipstringsafe_slow( s, start=0, end=None ):
- i = start
- if end is None:
- end = len(s)
- while i < end:
- c = s[i]
- if c == '"' or c == '\\' or ord(c) <= 0x1f:
- break
- i += 1
- return i
-
-def extend_list_with_sep( orig_seq, extension_seq, sepchar='' ):
- if not sepchar:
- orig_seq.extend( extension_seq )
- else:
- for i, x in enumerate(extension_seq):
- if i > 0:
- orig_seq.append( sepchar )
- orig_seq.append( x )
-
-def extend_and_flatten_list_with_sep( orig_seq, extension_seq, separator='' ):
- for i, part in enumerate(extension_seq):
- if i > 0 and separator:
- orig_seq.append( separator )
- orig_seq.extend( part )
-
-
-# ----------------------------------------------------------------------
-# Unicode helpers
-#
-# JSON requires that all JSON implementations must support the UTF-32
-# encoding (as well as UTF-8 and UTF-16). But earlier versions of
-# Python did not provide a UTF-32 codec. So we must implement UTF-32
-# ourselves in case we need it.
-
-def utf32le_encode( obj, errors='strict' ):
- """Encodes a Unicode string into a UTF-32LE encoded byte string."""
- import struct
- try:
- import cStringIO as sio
- except ImportError:
- import StringIO as sio
- f = sio.StringIO()
- write = f.write
- pack = struct.pack
- for c in obj:
- n = ord(c)
- if 0xD800 <= n <= 0xDFFF: # surrogate codepoints are prohibited by UTF-32
- if errors == 'ignore':
- continue
- elif errors == 'replace':
- n = ord('?')
- else:
- cname = 'U+%04X'%n
- raise UnicodeError('UTF-32 can not encode surrogate characters',cname)
- write( pack('L', n) )
- return f.getvalue()
-
-
-def utf32le_decode( obj, errors='strict' ):
- """Decodes a UTF-32LE byte string into a Unicode string."""
- if len(obj) % 4 != 0:
- raise UnicodeError('UTF-32 decode error, data length not a multiple of 4 bytes')
- import struct
- unpack = struct.unpack
- chars = []
- i = 0
- for i in range(0, len(obj), 4):
- seq = obj[i:i+4]
- n = unpack('L',seq)[0]
- chars.append( unichr(n) )
- return u''.join( chars )
-
-
-def auto_unicode_decode( s ):
- """Takes a string and tries to convert it to a Unicode string.
-
- This will return a Python unicode string type corresponding to the
- input string (either str or unicode). The character encoding is
- guessed by looking for either a Unicode BOM prefix, or by the
- rules specified by RFC 4627. When in doubt it is assumed the
- input is encoded in UTF-8 (the default for JSON).
-
- """
- if isinstance(s, unicode):
- return s
- if len(s) < 4:
- return s.decode('utf8') # not enough bytes, assume default of utf-8
- # Look for BOM marker
- import codecs
- bom2 = s[:2]
- bom4 = s[:4]
- a, b, c, d = map(ord, s[:4]) # values of first four bytes
- if bom4 == codecs.BOM_UTF32_LE:
- encoding = 'utf-32le'
- s = s[4:]
- elif bom4 == codecs.BOM_UTF32_BE:
- encoding = 'utf-32be'
- s = s[4:]
- elif bom2 == codecs.BOM_UTF16_LE:
- encoding = 'utf-16le'
- s = s[2:]
- elif bom2 == codecs.BOM_UTF16_BE:
- encoding = 'utf-16be'
- s = s[2:]
- # No BOM, so autodetect encoding used by looking at first four bytes
- # according to RFC 4627 section 3.
- elif a==0 and b==0 and c==0 and d!=0: # UTF-32BE
- encoding = 'utf-32be'
- elif a==0 and b!=0 and c==0 and d!=0: # UTF-16BE
- encoding = 'utf-16be'
- elif a!=0 and b==0 and c==0 and d==0: # UTF-32LE
- encoding = 'utf-32le'
- elif a!=0 and b==0 and c!=0 and d==0: # UTF-16LE
- encoding = 'utf-16le'
- else: #if a!=0 and b!=0 and c!=0 and d!=0: # UTF-8
- # JSON spec says default is UTF-8, so always guess it
- # if we can't guess otherwise
- encoding = 'utf8'
- # Make sure the encoding is supported by Python
- try:
- cdk = codecs.lookup(encoding)
- except LookupError:
- if encoding.startswith('utf-32') \
- or encoding.startswith('ucs4') \
- or encoding.startswith('ucs-4'):
- # Python doesn't natively have a UTF-32 codec, but JSON
- # requires that it be supported. So we must decode these
- # manually.
- if encoding.endswith('le'):
- unis = utf32le_decode(s)
- else:
- unis = utf32be_decode(s)
- else:
- raise JSONDecodeError('this python has no codec for this character encoding',encoding)
- else:
- # Convert to unicode using a standard codec
- unis = s.decode(encoding)
- return unis
-
-
-def surrogate_pair_as_unicode( c1, c2 ):
- """Takes a pair of unicode surrogates and returns the equivalent unicode character.
-
- The input pair must be a surrogate pair, with c1 in the range
- U+D800 to U+DBFF and c2 in the range U+DC00 to U+DFFF.
-
- """
- n1, n2 = ord(c1), ord(c2)
- if n1 < 0xD800 or n1 > 0xDBFF or n2 < 0xDC00 or n2 > 0xDFFF:
- raise JSONDecodeError('illegal Unicode surrogate pair',(c1,c2))
- a = n1 - 0xD800
- b = n2 - 0xDC00
- v = (a << 10) | b
- v += 0x10000
- return unichr(v)
-
-
-def unicode_as_surrogate_pair( c ):
- """Takes a single unicode character and returns a sequence of surrogate pairs.
-
- The output of this function is a tuple consisting of one or two unicode
- characters, such that if the input character is outside the BMP range
- then the output is a two-character surrogate pair representing that character.
-
- If the input character is inside the BMP then the output tuple will have
- just a single character...the same one.
-
- """
- n = ord(c)
- if n < 0x10000:
- return (unichr(n),) # in BMP, surrogate pair not required
- v = n - 0x10000
- vh = (v >> 10) & 0x3ff # highest 10 bits
- vl = v & 0x3ff # lowest 10 bits
- w1 = 0xD800 | vh
- w2 = 0xDC00 | vl
- return (unichr(w1), unichr(w2))
-
-
-# ----------------------------------------------------------------------
-# Type identification
-
-def isnumbertype( obj ):
- """Is the object of a Python number type (excluding complex)?"""
- return isinstance(obj, (int,long,float)) \
- and not isinstance(obj, bool) \
- or obj is nan or obj is inf or obj is neginf
-
-
-def isstringtype( obj ):
- """Is the object of a Python string type?"""
- if isinstance(obj, basestring):
- return True
- # Must also check for some other pseudo-string types
- import types, UserString
- return isinstance(obj, types.StringTypes) \
- or isinstance(obj, UserString.UserString) \
- or isinstance(obj, UserString.MutableString)
-
-
-# ----------------------------------------------------------------------
-# Numeric helpers
-
-def decode_hex( hexstring ):
- """Decodes a hexadecimal string into it's integer value."""
- # We don't use the builtin 'hex' codec in python since it can
- # not handle odd numbers of digits, nor raise the same type
- # of exceptions we want to.
- n = 0
- for c in hexstring:
- if '0' <= c <= '9':
- d = ord(c) - ord('0')
- elif 'a' <= c <= 'f':
- d = ord(c) - ord('a') + 10
- elif 'A' <= c <= 'F':
- d = ord(c) - ord('A') + 10
- else:
- raise JSONDecodeError('not a hexadecimal number',hexstring)
- # Could use ((n << 4 ) | d), but python 2.3 issues a FutureWarning.
- n = (n * 16) + d
- return n
-
-
-def decode_octal( octalstring ):
- """Decodes an octal string into it's integer value."""
- n = 0
- for c in octalstring:
- if '0' <= c <= '7':
- d = ord(c) - ord('0')
- else:
- raise JSONDecodeError('not an octal number',octalstring)
- # Could use ((n << 3 ) | d), but python 2.3 issues a FutureWarning.
- n = (n * 8) + d
- return n
-
-
-# ----------------------------------------------------------------------
-# Exception classes.
-
-class JSONError(ValueError):
- """Our base class for all JSON-related errors.
-
- """
- def pretty_description(self):
- err = self.args[0]
- if len(self.args) > 1:
- err += ': '
- for anum, a in enumerate(self.args[1:]):
- if anum > 1:
- err += ', '
- astr = repr(a)
- if len(astr) > 20:
- astr = astr[:20] + '...'
- err += astr
- return err
-
-class JSONDecodeError(JSONError):
- """An exception class raised when a JSON decoding error (syntax error) occurs."""
-
-
-class JSONEncodeError(JSONError):
- """An exception class raised when a python object can not be encoded as a JSON string."""
-
-
-#----------------------------------------------------------------------
-# The main JSON encoder/decoder class.
-
-class JSON(object):
- """An encoder/decoder for JSON data streams.
-
- Usually you will call the encode() or decode() methods. The other
- methods are for lower-level processing.
-
- Whether the JSON parser runs in strict mode (which enforces exact
- compliance with the JSON spec) or the more forgiving non-string mode
- can be affected by setting the 'strict' argument in the object's
- initialization; or by assigning True or False to the 'strict'
- property of the object.
-
- You can also adjust a finer-grained control over strictness by
- allowing or preventing specific behaviors. You can get a list of
- all the available behaviors by accessing the 'behaviors' property.
- Likewise the allowed_behaviors and prevented_behaviors list which
- behaviors will be allowed and which will not. Call the allow()
- or prevent() methods to adjust these.
-
- """
- _escapes_json = { # character escapes in JSON
- '"': '"',
- '/': '/',
- '\\': '\\',
- 'b': '\b',
- 'f': '\f',
- 'n': '\n',
- 'r': '\r',
- 't': '\t',
- }
-
- _escapes_js = { # character escapes in Javascript
- '"': '"',
- '\'': '\'',
- '\\': '\\',
- 'b': '\b',
- 'f': '\f',
- 'n': '\n',
- 'r': '\r',
- 't': '\t',
- 'v': '\v',
- '0': '\x00'
- }
-
- # Following is a reverse mapping of escape characters, used when we
- # output JSON. Only those escapes which are always safe (e.g., in JSON)
- # are here. It won't hurt if we leave questionable ones out.
- _rev_escapes = {'\n': '\\n',
- '\t': '\\t',
- '\b': '\\b',
- '\r': '\\r',
- '\f': '\\f',
- '"': '\\"',
- '\\': '\\\\'}
-
- def __init__(self, strict=False, compactly=True, escape_unicode=False):
- """Creates a JSON encoder/decoder object.
-
- If 'strict' is set to True, then only strictly-conforming JSON
- output will be produced. Note that this means that some types
- of values may not be convertable and will result in a
- JSONEncodeError exception.
-
- If 'compactly' is set to True, then the resulting string will
- have all extraneous white space removed; if False then the
- string will be "pretty printed" with whitespace and indentation
- added to make it more readable.
-
- If 'escape_unicode' is set to True, then all non-ASCII characters
- will be represented as a unicode escape sequence; if False then
- the actual real unicode character will be inserted if possible.
-
- The 'escape_unicode' can also be a function, which when called
- with a single argument of a unicode character will return True
- if the character should be escaped or False if it should not.
-
- If you wish to extend the encoding to ba able to handle
- additional types, you should subclass this class and override
- the encode_default() method.
-
- """
- import sys
- self._set_strictness(strict)
- self._encode_compactly = compactly
- try:
- # see if we were passed a predicate function
- b = escape_unicode(u'A')
- self._encode_unicode_as_escapes = escape_unicode
- except (ValueError, NameError, TypeError):
- # Just set to True or False. We could use lambda x:True
- # to make it more consistent (always a function), but it
- # will be too slow, so we'll make explicit tests later.
- self._encode_unicode_as_escapes = bool(escape_unicode)
- self._sort_dictionary_keys = True
-
- # The following is a boolean map of the first 256 characters
- # which will quickly tell us which of those characters never
- # need to be escaped.
-
- self._asciiencodable = [32 <= c < 128 and not self._rev_escapes.has_key(chr(c))
- for c in range(0,255)]
-
- def _set_strictness(self, strict):
- """Changes the strictness behavior.
-
- Pass True to be very strict about JSON syntax, or False to be looser.
- """
- self._allow_any_type_at_start = not strict
- self._allow_all_numeric_signs = not strict
- self._allow_comments = not strict
- self._allow_control_char_in_string = not strict
- self._allow_hex_numbers = not strict
- self._allow_initial_decimal_point = not strict
- self._allow_js_string_escapes = not strict
- self._allow_non_numbers = not strict
- self._allow_nonescape_characters = not strict # "\z" -> "z"
- self._allow_nonstring_keys = not strict
- self._allow_omitted_array_elements = not strict
- self._allow_single_quoted_strings = not strict
- self._allow_trailing_comma_in_literal = not strict
- self._allow_undefined_values = not strict
- self._allow_unicode_format_control_chars = not strict
- self._allow_unicode_whitespace = not strict
- # Always disable this by default
- self._allow_octal_numbers = False
-
- def allow(self, behavior):
- """Allow the specified behavior (turn off a strictness check).
-
- The list of all possible behaviors is available in the behaviors property.
- You can see which behaviors are currently allowed by accessing the
- allowed_behaviors property.
-
- """
- p = '_allow_' + behavior
- if hasattr(self, p):
- setattr(self, p, True)
- else:
- raise AttributeError('Behavior is not known',behavior)
-
- def prevent(self, behavior):
- """Prevent the specified behavior (turn on a strictness check).
-
- The list of all possible behaviors is available in the behaviors property.
- You can see which behaviors are currently prevented by accessing the
- prevented_behaviors property.
-
- """
- p = '_allow_' + behavior
- if hasattr(self, p):
- setattr(self, p, False)
- else:
- raise AttributeError('Behavior is not known',behavior)
-
- def _get_behaviors(self):
- return sorted([ n[len('_allow_'):] for n in self.__dict__ \
- if n.startswith('_allow_')])
- behaviors = property(_get_behaviors,
- doc='List of known behaviors that can be passed to allow() or prevent() methods')
-
- def _get_allowed_behaviors(self):
- return sorted([ n[len('_allow_'):] for n in self.__dict__ \
- if n.startswith('_allow_') and getattr(self,n)])
- allowed_behaviors = property(_get_allowed_behaviors,
- doc='List of known behaviors that are currently allowed')
-
- def _get_prevented_behaviors(self):
- return sorted([ n[len('_allow_'):] for n in self.__dict__ \
- if n.startswith('_allow_') and not getattr(self,n)])
- prevented_behaviors = property(_get_prevented_behaviors,
- doc='List of known behaviors that are currently prevented')
-
- def _is_strict(self):
- return not self.allowed_behaviors
- strict = property(_is_strict, _set_strictness,
- doc='True if adherence to RFC 4627 syntax is strict, or False is more generous ECMAScript syntax is permitted')
-
-
- def isws(self, c):
- """Determines if the given character is considered as white space.
-
- Note that Javscript is much more permissive on what it considers
- to be whitespace than does JSON.
-
- Ref. ECMAScript section 7.2
-
- """
- if not self._allow_unicode_whitespace:
- return c in ' \t\n\r'
- else:
- if not isinstance(c,unicode):
- c = unicode(c)
- if c in u' \t\n\r\f\v':
- return True
- import unicodedata
- return unicodedata.category(c) == 'Zs'
-
- def islineterm(self, c):
- """Determines if the given character is considered a line terminator.
-
- Ref. ECMAScript section 7.3
-
- """
- if c == '\r' or c == '\n':
- return True
- if c == u'\u2028' or c == u'\u2029': # unicodedata.category(c) in ['Zl', 'Zp']
- return True
- return False
-
- def strip_format_control_chars(self, txt):
- """Filters out all Unicode format control characters from the string.
-
- ECMAScript permits any Unicode "format control characters" to
- appear at any place in the source code. They are to be
- ignored as if they are not there before any other lexical
- tokenization occurs. Note that JSON does not allow them.
-
- Ref. ECMAScript section 7.1.
-
- """
- import unicodedata
- txt2 = filter( lambda c: unicodedata.category(unicode(c)) != 'Cf',
- txt )
- return txt2
-
-
- def decode_null(self, s, i=0):
- """Intermediate-level decoder for ECMAScript 'null' keyword.
-
- Takes a string and a starting index, and returns a Python
- None object and the index of the next unparsed character.
-
- """
- if i < len(s) and s[i:i+4] == 'null':
- return None, i+4
- raise JSONDecodeError('literal is not the JSON "null" keyword', s)
-
- def encode_undefined(self):
- """Produces the ECMAScript 'undefined' keyword."""
- return 'undefined'
-
- def encode_null(self):
- """Produces the JSON 'null' keyword."""
- return 'null'
-
- def decode_boolean(self, s, i=0):
- """Intermediate-level decode for JSON boolean literals.
-
- Takes a string and a starting index, and returns a Python bool
- (True or False) and the index of the next unparsed character.
-
- """
- if s[i:i+4] == 'true':
- return True, i+4
- elif s[i:i+5] == 'false':
- return False, i+5
- raise JSONDecodeError('literal value is not a JSON boolean keyword',s)
-
- def encode_boolean(self, b):
- """Encodes the Python boolean into a JSON Boolean literal."""
- if bool(b):
- return 'true'
- return 'false'
-
- def decode_number(self, s, i=0, imax=None):
- """Intermediate-level decoder for JSON numeric literals.
-
- Takes a string and a starting index, and returns a Python
- suitable numeric type and the index of the next unparsed character.
-
- The returned numeric type can be either of a Python int,
- long, or float. In addition some special non-numbers may
- also be returned such as nan, inf, and neginf (technically
- which are Python floats, but have no numeric value.)
-
- Ref. ECMAScript section 8.5.
-
- """
- if imax is None:
- imax = len(s)
- # Detect initial sign character(s)
- if not self._allow_all_numeric_signs:
- if s[i] == '+' or (s[i] == '-' and i+1 < imax and \
- s[i+1] in '+-'):
- raise JSONDecodeError('numbers in strict JSON may only have a single "-" as a sign prefix',s[i:])
- sign = +1
- j = i # j will point after the sign prefix
- while j < imax and s[j] in '+-':
- if s[j] == '-': sign = sign * -1
- j += 1
- # Check for ECMAScript symbolic non-numbers
- if s[j:j+3] == 'NaN':
- if self._allow_non_numbers:
- return nan, j+3
- else:
- raise JSONDecodeError('NaN literals are not allowed in strict JSON')
- elif s[j:j+8] == 'Infinity':
- if self._allow_non_numbers:
- if sign < 0:
- return neginf, j+8
- else:
- return inf, j+8
- else:
- raise JSONDecodeError('Infinity literals are not allowed in strict JSON')
- elif s[j:j+2] in ('0x','0X'):
- if self._allow_hex_numbers:
- k = j+2
- while k < imax and s[k] in hexdigits:
- k += 1
- n = sign * decode_hex( s[j+2:k] )
- return n, k
- else:
- raise JSONDecodeError('hexadecimal literals are not allowed in strict JSON',s[i:])
- else:
- # Decimal (or octal) number, find end of number.
- # General syntax is: \d+[\.\d+][e[+-]?\d+]
- k = j # will point to end of digit sequence
- could_be_octal = ( k+1 < imax and s[k] == '0' ) # first digit is 0
- decpt = None # index into number of the decimal point, if any
- ept = None # index into number of the e|E exponent start, if any
- esign = '+' # sign of exponent
- sigdigits = 0 # number of significant digits (approx, counts end zeros)
- while k < imax and (s[k].isdigit() or s[k] in '.+-eE'):
- c = s[k]
- if c not in octaldigits:
- could_be_octal = False
- if c == '.':
- if decpt is not None or ept is not None:
- break
- else:
- decpt = k-j
- elif c in 'eE':
- if ept is not None:
- break
- else:
- ept = k-j
- elif c in '+-':
- if not ept:
- break
- esign = c
- else: #digit
- if not ept:
- sigdigits += 1
- k += 1
- number = s[j:k] # The entire number as a string
- #print 'NUMBER IS: ', repr(number), ', sign', sign, ', esign', esign, \
- # ', sigdigits', sigdigits, \
- # ', decpt', decpt, ', ept', ept
-
- # Handle octal integers first as an exception. If octal
- # is not enabled (the ECMAScipt standard) then just do
- # nothing and treat the string as a decimal number.
- if could_be_octal and self._allow_octal_numbers:
- n = sign * decode_octal( number )
- return n, k
-
- # A decimal number. Do a quick check on JSON syntax restrictions.
- if number[0] == '.' and not self._allow_initial_decimal_point:
- raise JSONDecodeError('numbers in strict JSON must have at least one digit before the decimal point',s[i:])
- elif number[0] == '0' and \
- len(number) > 1 and number[1].isdigit():
- if self._allow_octal_numbers:
- raise JSONDecodeError('initial zero digit is only allowed for octal integers',s[i:])
- else:
- raise JSONDecodeError('initial zero digit must not be followed by other digits (octal numbers are not permitted)',s[i:])
- # Make sure decimal point is followed by a digit
- if decpt is not None:
- if decpt+1 >= len(number) or not number[decpt+1].isdigit():
- raise JSONDecodeError('decimal point must be followed by at least one digit',s[i:])
- # Determine the exponential part
- if ept is not None:
- if ept+1 >= len(number):
- raise JSONDecodeError('exponent in number is truncated',s[i:])
- try:
- exponent = int(number[ept+1:])
- except ValueError:
- raise JSONDecodeError('not a valid exponent in number',s[i:])
- ##print 'EXPONENT', exponent
- else:
- exponent = 0
- # Try to make an int/long first.
- if decpt is None and exponent >= 0:
- # An integer
- if ept:
- n = int(number[:ept])
- else:
- n = int(number)
- n *= sign
- if exponent:
- n *= 10**exponent
- if n == 0 and sign < 0:
- # minus zero, must preserve negative sign so make a float
- n = -0.0
- else:
- try:
- if decimal and (abs(exponent) > float_maxexp or sigdigits > float_sigdigits):
- try:
- n = decimal.Decimal(number)
- n = n.normalize()
- except decimal.Overflow:
- if sign<0:
- n = neginf
- else:
- n = inf
- else:
- n *= sign
- else:
- n = float(number) * sign
- except ValueError:
- raise JSONDecodeError('not a valid JSON numeric literal', s[i:j])
- return n, k
-
- def encode_number(self, n):
- """Encodes a Python numeric type into a JSON numeric literal.
-
- The special non-numeric values of float('nan'), float('inf')
- and float('-inf') are translated into appropriate JSON
- literals.
-
- Note that Python complex types are not handled, as there is no
- ECMAScript equivalent type.
-
- """
- if isinstance(n, complex):
- if n.imag:
- raise JSONEncodeError('Can not encode a complex number that has a non-zero imaginary part',n)
- n = n.real
- if isinstance(n, (int,long)):
- return str(n)
- if decimal and isinstance(n, decimal.Decimal):
- return str(n)
- global nan, inf, neginf
- if n is nan:
- return 'NaN'
- elif n is inf:
- return 'Infinity'
- elif n is neginf:
- return '-Infinity'
- elif isinstance(n, float):
- # Check for non-numbers.
- # In python nan == inf == -inf, so must use repr() to distinguish
- reprn = repr(n).lower()
- if ('inf' in reprn and '-' in reprn) or n == neginf:
- return '-Infinity'
- elif 'inf' in reprn or n is inf:
- return 'Infinity'
- elif 'nan' in reprn or n is nan:
- return 'NaN'
- return repr(n)
- else:
- raise TypeError('encode_number expected an integral, float, or decimal number type',type(n))
-
- def decode_string(self, s, i=0, imax=None):
- """Intermediate-level decoder for JSON string literals.
-
- Takes a string and a starting index, and returns a Python
- string (or unicode string) and the index of the next unparsed
- character.
-
- """
- if imax is None:
- imax = len(s)
- if imax < i+2 or s[i] not in '"\'':
- raise JSONDecodeError('string literal must be properly quoted',s[i:])
- closer = s[i]
- if closer == '\'' and not self._allow_single_quoted_strings:
- raise JSONDecodeError('string literals must use double quotation marks in strict JSON',s[i:])
- i += 1 # skip quote
- if self._allow_js_string_escapes:
- escapes = self._escapes_js
- else:
- escapes = self._escapes_json
- ccallowed = self._allow_control_char_in_string
- chunks = []
- _append = chunks.append
- done = False
- high_surrogate = None
- while i < imax:
- c = s[i]
- # Make sure a high surrogate is immediately followed by a low surrogate
- if high_surrogate and (i+1 >= imax or s[i:i+2] != '\\u'):
- raise JSONDecodeError('High unicode surrogate must be followed by a low surrogate',s[i:])
- if c == closer:
- i += 1 # skip end quote
- done = True
- break
- elif c == '\\':
- # Escaped character
- i += 1
- if i >= imax:
- raise JSONDecodeError('escape in string literal is incomplete',s[i-1:])
- c = s[i]
-
- if '0' <= c <= '7' and self._allow_octal_numbers:
- # Handle octal escape codes first so special \0 doesn't kick in yet.
- # Follow Annex B.1.2 of ECMAScript standard.
- if '0' <= c <= '3':
- maxdigits = 3
- else:
- maxdigits = 2
- for k in range(i, i+maxdigits+1):
- if k >= imax or s[k] not in octaldigits:
- break
- n = decode_octal(s[i:k])
- if n < 128:
- _append( chr(n) )
- else:
- _append( unichr(n) )
- i = k
- continue
-
- if escapes.has_key(c):
- _append(escapes[c])
- i += 1
- elif c == 'u' or c == 'x':
- i += 1
- if c == 'u':
- digits = 4
- else: # c== 'x'
- if not self._allow_js_string_escapes:
- raise JSONDecodeError(r'string literals may not use the \x hex-escape in strict JSON',s[i-1:])
- digits = 2
- if i+digits >= imax:
- raise JSONDecodeError('numeric character escape sequence is truncated',s[i-1:])
- n = decode_hex( s[i:i+digits] )
- if high_surrogate:
- # Decode surrogate pair and clear high surrogate
- _append( surrogate_pair_as_unicode( high_surrogate, unichr(n) ) )
- high_surrogate = None
- elif n < 128:
- # ASCII chars always go in as a str
- _append( chr(n) )
- elif 0xd800 <= n <= 0xdbff: # high surrogate
- if imax < i + digits + 2 or s[i+digits] != '\\' or s[i+digits+1] != 'u':
- raise JSONDecodeError('High unicode surrogate must be followed by a low surrogate',s[i-2:])
- high_surrogate = unichr(n) # remember until we get to the low surrogate
- elif 0xdc00 <= n <= 0xdfff: # low surrogate
- raise JSONDecodeError('Low unicode surrogate must be proceeded by a high surrogate',s[i-2:])
- else:
- # Other chars go in as a unicode char
- _append( unichr(n) )
- i += digits
- else:
- # Unknown escape sequence
- if self._allow_nonescape_characters:
- _append( c )
- i += 1
- else:
- raise JSONDecodeError('unsupported escape code in JSON string literal',s[i-1:])
- elif ord(c) <= 0x1f: # A control character
- if self.islineterm(c):
- raise JSONDecodeError('line terminator characters must be escaped inside string literals',s[i:])
- elif ccallowed:
- _append( c )
- i += 1
- else:
- raise JSONDecodeError('control characters must be escaped inside JSON string literals',s[i:])
- else: # A normal character; not an escape sequence or end-quote.
- # Find a whole sequence of "safe" characters so we can append them
- # all at once rather than one a time, for speed.
- j = i
- i += 1
- while i < imax and s[i] not in unsafe_string_chars and s[i] != closer:
- i += 1
- _append(s[j:i])
- if not done:
- raise JSONDecodeError('string literal is not terminated with a quotation mark',s)
- s = ''.join( chunks )
- return s, i
-
- def encode_string(self, s):
- """Encodes a Python string into a JSON string literal.
-
- """
- # Must handle instances of UserString specially in order to be
- # able to use ord() on it's simulated "characters".
- import UserString
- if isinstance(s, (UserString.UserString, UserString.MutableString)):
- def tochar(c):
- return c.data
- else:
- # Could use "lambda c:c", but that is too slow. So we set to None
- # and use an explicit if test inside the loop.
- tochar = None
-
- chunks = []
- chunks.append('"')
- revesc = self._rev_escapes
- asciiencodable = self._asciiencodable
- encunicode = self._encode_unicode_as_escapes
- i = 0
- imax = len(s)
- while i < imax:
- if tochar:
- c = tochar(s[i])
- else:
- c = s[i]
- cord = ord(c)
- if cord < 256 and asciiencodable[cord] and isinstance(encunicode, bool):
- # Contiguous runs of plain old printable ASCII can be copied
- # directly to the JSON output without worry (unless the user
- # has supplied a custom is-encodable function).
- j = i
- i += 1
- while i < imax:
- if tochar:
- c = tochar(s[i])
- else:
- c = s[i]
- cord = ord(c)
- if cord < 256 and asciiencodable[cord]:
- i += 1
- else:
- break
- chunks.append( unicode(s[j:i]) )
- elif revesc.has_key(c):
- # Has a shortcut escape sequence, like "\n"
- chunks.append(revesc[c])
- i += 1
- elif cord <= 0x1F:
- # Always unicode escape ASCII-control characters
- chunks.append(r'\u%04x' % cord)
- i += 1
- elif 0xD800 <= cord <= 0xDFFF:
- # A raw surrogate character! This should never happen
- # and there's no way to include it in the JSON output.
- # So all we can do is complain.
- cname = 'U+%04X' % cord
- raise JSONEncodeError('can not include or escape a Unicode surrogate character',cname)
- elif cord <= 0xFFFF:
- # Other BMP Unicode character
- if isinstance(encunicode, bool):
- doesc = encunicode
- else:
- doesc = encunicode( c )
- if doesc:
- chunks.append(r'\u%04x' % cord)
- else:
- chunks.append( c )
- i += 1
- else: # ord(c) >= 0x10000
- # Non-BMP Unicode
- if isinstance(encunicode, bool):
- doesc = encunicode
- else:
- doesc = encunicode( c )
- if doesc:
- for surrogate in unicode_as_surrogate_pair(c):
- chunks.append(r'\u%04x' % ord(surrogate))
- else:
- chunks.append( c )
- i += 1
- chunks.append('"')
- return ''.join( chunks )
-
- def skip_comment(self, txt, i=0):
- """Skips an ECMAScript comment, either // or /* style.
-
- The contents of the comment are returned as a string, as well
- as the index of the character immediately after the comment.
-
- """
- if i+1 >= len(txt) or txt[i] != '/' or txt[i+1] not in '/*':
- return None, i
- if not self._allow_comments:
- raise JSONDecodeError('comments are not allowed in strict JSON',txt[i:])
- multiline = (txt[i+1] == '*')
- istart = i
- i += 2
- while i < len(txt):
- if multiline:
- if txt[i] == '*' and i+1 < len(txt) and txt[i+1] == '/':
- j = i+2
- break
- elif txt[i] == '/' and i+1 < len(txt) and txt[i+1] == '*':
- raise JSONDecodeError('multiline /* */ comments may not nest',txt[istart:i+1])
- else:
- if self.islineterm(txt[i]):
- j = i # line terminator is not part of comment
- break
- i += 1
-
- if i >= len(txt):
- if not multiline:
- j = len(txt) # // comment terminated by end of file is okay
- else:
- raise JSONDecodeError('comment was never terminated',txt[istart:])
- return txt[istart:j], j
-
- def skipws(self, txt, i=0, imax=None, skip_comments=True):
- """Skips whitespace.
- """
- if not self._allow_comments and not self._allow_unicode_whitespace:
- if imax is None:
- imax = len(txt)
- while i < imax and txt[i] in ' \r\n\t':
- i += 1
- return i
- else:
- return self.skipws_any(txt, i, imax, skip_comments)
-
- def skipws_any(self, txt, i=0, imax=None, skip_comments=True):
- """Skips all whitespace, including comments and unicode whitespace
-
- Takes a string and a starting index, and returns the index of the
- next non-whitespace character.
-
- If skip_comments is True and not running in strict JSON mode, then
- comments will be skipped over just like whitespace.
-
- """
- if imax is None:
- imax = len(txt)
- while i < imax:
- if txt[i] == '/':
- cmt, i = self.skip_comment(txt, i)
- if i < imax and self.isws(txt[i]):
- i += 1
- else:
- break
- return i
-
- def decode_composite(self, txt, i=0, imax=None):
- """Intermediate-level JSON decoder for composite literal types (array and object).
-
- Takes text and a starting index, and returns either a Python list or
- dictionary and the index of the next unparsed character.
-
- """
- if imax is None:
- imax = len(txt)
- i = self.skipws(txt, i, imax)
- starti = i
- if i >= imax or txt[i] not in '{[':
- raise JSONDecodeError('composite object must start with "[" or "{"',txt[i:])
- if txt[i] == '[':
- isdict = False
- closer = ']'
- obj = []
- else:
- isdict = True
- closer = '}'
- obj = {}
- i += 1 # skip opener
- i = self.skipws(txt, i, imax)
-
- if i < imax and txt[i] == closer:
- # empty composite
- i += 1
- done = True
- else:
- saw_value = False # set to false at beginning and after commas
- done = False
- while i < imax:
- i = self.skipws(txt, i, imax)
- if i < imax and (txt[i] == ',' or txt[i] == closer):
- c = txt[i]
- i += 1
- if c == ',':
- if not saw_value:
- # no preceeding value, an elided (omitted) element
- if isdict:
- raise JSONDecodeError('can not omit elements of an object (dictionary)')
- if self._allow_omitted_array_elements:
- if self._allow_undefined_values:
- obj.append( undefined )
- else:
- obj.append( None )
- else:
- raise JSONDecodeError('strict JSON does not permit omitted array (list) elements',txt[i:])
- saw_value = False
- continue
- else: # c == closer
- if not saw_value and not self._allow_trailing_comma_in_literal:
- if isdict:
- raise JSONDecodeError('strict JSON does not allow a final comma in an object (dictionary) literal',txt[i-2:])
- else:
- raise JSONDecodeError('strict JSON does not allow a final comma in an array (list) literal',txt[i-2:])
- done = True
- break
-
- # Decode the item
- if isdict and self._allow_nonstring_keys:
- r = self.decodeobj(txt, i, identifier_as_string=True)
- else:
- r = self.decodeobj(txt, i, identifier_as_string=False)
- if r:
- if saw_value:
- # two values without a separating comma
- raise JSONDecodeError('values must be separated by a comma', txt[i:r[1]])
- saw_value = True
- i = self.skipws(txt, r[1], imax)
- if isdict:
- key = r[0] # Ref 11.1.5
- if not isstringtype(key):
- if isnumbertype(key):
- if not self._allow_nonstring_keys:
- raise JSONDecodeError('strict JSON only permits string literals as object properties (dictionary keys)',txt[starti:])
- else:
- raise JSONDecodeError('object properties (dictionary keys) must be either string literals or numbers',txt[starti:])
- if i >= imax or txt[i] != ':':
- raise JSONDecodeError('object property (dictionary key) has no value, expected ":"',txt[starti:])
- i += 1
- i = self.skipws(txt, i, imax)
- rval = self.decodeobj(txt, i)
- if rval:
- i = self.skipws(txt, rval[1], imax)
- obj[key] = rval[0]
- else:
- raise JSONDecodeError('object property (dictionary key) has no value',txt[starti:])
- else: # list
- obj.append( r[0] )
- else: # not r
- if isdict:
- raise JSONDecodeError('expected a value, or "}"',txt[i:])
- elif not self._allow_omitted_array_elements:
- raise JSONDecodeError('expected a value or "]"',txt[i:])
- else:
- raise JSONDecodeError('expected a value, "," or "]"',txt[i:])
- # end while
- if not done:
- if isdict:
- raise JSONDecodeError('object literal (dictionary) is not terminated',txt[starti:])
- else:
- raise JSONDecodeError('array literal (list) is not terminated',txt[starti:])
- return obj, i
-
- def decode_javascript_identifier(self, name):
- """Convert a JavaScript identifier into a Python string object.
-
- This method can be overriden by a subclass to redefine how JavaScript
- identifiers are turned into Python objects. By default this just
- converts them into strings.
-
- """
- return name
-
- def decodeobj(self, txt, i=0, imax=None, identifier_as_string=False, only_object_or_array=False):
- """Intermediate-level JSON decoder.
-
- Takes a string and a starting index, and returns a two-tuple consting
- of a Python object and the index of the next unparsed character.
-
- If there is no value at all (empty string, etc), the None is
- returned instead of a tuple.
-
- """
- if imax is None:
- imax = len(txt)
- obj = None
- i = self.skipws(txt, i, imax)
- if i >= imax:
- raise JSONDecodeError('Unexpected end of input')
- c = txt[i]
-
- if c == '[' or c == '{':
- obj, i = self.decode_composite(txt, i, imax)
- elif only_object_or_array:
- raise JSONDecodeError('JSON document must start with an object or array type only', txt[i:i+20])
- elif c == '"' or c == '\'':
- obj, i = self.decode_string(txt, i, imax)
- elif c.isdigit() or c in '.+-':
- obj, i = self.decode_number(txt, i, imax)
- elif c.isalpha() or c in'_$':
- j = i
- while j < imax and (txt[j].isalnum() or txt[j] in '_$'):
- j += 1
- kw = txt[i:j]
- if kw == 'null':
- obj, i = None, j
- elif kw == 'true':
- obj, i = True, j
- elif kw == 'false':
- obj, i = False, j
- elif kw == 'undefined':
- if self._allow_undefined_values:
- obj, i = undefined, j
- else:
- raise JSONDecodeError('strict JSON does not allow undefined elements',txt[i:])
- elif kw == 'NaN' or kw == 'Infinity':
- obj, i = self.decode_number(txt, i)
- else:
- if identifier_as_string:
- obj, i = self.decode_javascript_identifier(kw), j
- else:
- raise JSONDecodeError('unknown keyword or identifier',kw)
- else:
- raise JSONDecodeError('can not decode value',txt[i:])
- return obj, i
-
-
-
- def decode(self, txt):
- """Decodes a JSON-endoded string into a Python object."""
- if self._allow_unicode_format_control_chars:
- txt = self.strip_format_control_chars(txt)
- r = self.decodeobj(txt, 0, only_object_or_array=not self._allow_any_type_at_start)
- if not r:
- raise JSONDecodeError('can not decode value',txt)
- else:
- obj, i = r
- i = self.skipws(txt, i)
- if i < len(txt):
- raise JSONDecodeError('unexpected or extra text',txt[i:])
- return obj
-
- def encode(self, obj, nest_level=0):
- """Encodes the Python object into a JSON string representation.
-
- This method will first attempt to encode an object by seeing
- if it has a json_equivalent() method. If so than it will
- call that method and then recursively attempt to encode
- the object resulting from that call.
-
- Next it will attempt to determine if the object is a native
- type or acts like a squence or dictionary. If so it will
- encode that object directly.
-
- Finally, if no other strategy for encoding the object of that
- type exists, it will call the encode_default() method. That
- method currently raises an error, but it could be overridden
- by subclasses to provide a hook for extending the types which
- can be encoded.
-
- """
- chunks = []
- self.encode_helper(chunks, obj, nest_level)
- return ''.join( chunks )
-
- def encode_helper(self, chunklist, obj, nest_level):
- #print 'encode_helper(chunklist=%r, obj=%r, nest_level=%r)'%(chunklist,obj,nest_level)
- if hasattr(obj, 'json_equivalent'):
- json = self.encode_equivalent( obj, nest_level=nest_level )
- if json is not None:
- chunklist.append( json )
- return
- if obj is None:
- chunklist.append( self.encode_null() )
- elif obj is undefined:
- if self._allow_undefined_values:
- chunklist.append( self.encode_undefined() )
- else:
- raise JSONEncodeError('strict JSON does not permit "undefined" values')
- elif isinstance(obj, bool):
- chunklist.append( self.encode_boolean(obj) )
- elif isinstance(obj, (int,long,float,complex)) or \
- (decimal and isinstance(obj, decimal.Decimal)):
- chunklist.append( self.encode_number(obj) )
- elif isinstance(obj, basestring) or isstringtype(obj):
- chunklist.append( self.encode_string(obj) )
- else:
- self.encode_composite(chunklist, obj, nest_level)
-
- def encode_composite(self, chunklist, obj, nest_level):
- """Encodes just dictionaries, lists, or sequences.
-
- Basically handles any python type for which iter() can create
- an iterator object.
-
- This method is not intended to be called directly. Use the
- encode() method instead.
-
- """
- #print 'encode_complex_helper(chunklist=%r, obj=%r, nest_level=%r)'%(chunklist,obj,nest_level)
- try:
- # Is it a dictionary or UserDict? Try iterkeys method first.
- it = obj.iterkeys()
- except AttributeError:
- try:
- # Is it a sequence? Try to make an iterator for it.
- it = iter(obj)
- except TypeError:
- it = None
- if it is not None:
- # Does it look like a dictionary? Check for a minimal dict or
- # UserDict interface.
- isdict = hasattr(obj, '__getitem__') and hasattr(obj, 'keys')
- compactly = self._encode_compactly
- if isdict:
- chunklist.append('{')
- if compactly:
- dictcolon = ':'
- else:
- dictcolon = ' : '
- else:
- chunklist.append('[')
- #print nest_level, 'opening sequence:', repr(chunklist)
- if not compactly:
- indent0 = ' ' * nest_level
- indent = ' ' * (nest_level+1)
- chunklist.append(' ')
- sequence_chunks = [] # use this to allow sorting afterwards if dict
- try: # while not StopIteration
- numitems = 0
- while True:
- obj2 = it.next()
- if obj2 is obj:
- raise JSONEncodeError('trying to encode an infinite sequence',obj)
- if isdict and not isstringtype(obj2):
- # Check JSON restrictions on key types
- if isnumbertype(obj2):
- if not self._allow_nonstring_keys:
- raise JSONEncodeError('object properties (dictionary keys) must be strings in strict JSON',obj2)
- else:
- raise JSONEncodeError('object properties (dictionary keys) can only be strings or numbers in ECMAScript',obj2)
-
- # Encode this item in the sequence and put into item_chunks
- item_chunks = []
- self.encode_helper( item_chunks, obj2, nest_level=nest_level+1 )
- if isdict:
- item_chunks.append(dictcolon)
- obj3 = obj[obj2]
- self.encode_helper(item_chunks, obj3, nest_level=nest_level+2)
-
- #print nest_level, numitems, 'item:', repr(obj2)
- #print nest_level, numitems, 'sequence_chunks:', repr(sequence_chunks)
- #print nest_level, numitems, 'item_chunks:', repr(item_chunks)
- #extend_list_with_sep(sequence_chunks, item_chunks)
- sequence_chunks.append(item_chunks)
- #print nest_level, numitems, 'new sequence_chunks:', repr(sequence_chunks)
- numitems += 1
- except StopIteration:
- pass
-
- if isdict and self._sort_dictionary_keys:
- sequence_chunks.sort() # Note sorts by JSON repr, not original Python object
- if compactly:
- sep = ','
- else:
- sep = ',\n' + indent
-
- #print nest_level, 'closing sequence'
- #print nest_level, 'chunklist:', repr(chunklist)
- #print nest_level, 'sequence_chunks:', repr(sequence_chunks)
- extend_and_flatten_list_with_sep( chunklist, sequence_chunks, sep )
- #print nest_level, 'new chunklist:', repr(chunklist)
-
- if not compactly:
- if numitems > 1:
- chunklist.append('\n' + indent0)
- else:
- chunklist.append(' ')
- if isdict:
- chunklist.append('}')
- else:
- chunklist.append(']')
- else: # Can't create an iterator for the object
- json2 = self.encode_default( obj, nest_level=nest_level )
- chunklist.append( json2 )
-
- def encode_equivalent( self, obj, nest_level=0 ):
- """This method is used to encode user-defined class objects.
-
- The object being encoded should have a json_equivalent()
- method defined which returns another equivalent object which
- is easily JSON-encoded. If the object in question has no
- json_equivalent() method available then None is returned
- instead of a string so that the encoding will attempt the next
- strategy.
-
- If a caller wishes to disable the calling of json_equivalent()
- methods, then subclass this class and override this method
- to just return None.
-
- """
- if hasattr(obj, 'json_equivalent') \
- and callable(getattr(obj,'json_equivalent')):
- obj2 = obj.json_equivalent()
- if obj2 is obj:
- # Try to prevent careless infinite recursion
- raise JSONEncodeError('object has a json_equivalent() method that returns itself',obj)
- json2 = self.encode( obj2, nest_level=nest_level )
- return json2
- else:
- return None
-
- def encode_default( self, obj, nest_level=0 ):
- """This method is used to encode objects into JSON which are not straightforward.
-
- This method is intended to be overridden by subclasses which wish
- to extend this encoder to handle additional types.
-
- """
- raise JSONEncodeError('can not encode object into a JSON representation',obj)
-
-
-# ------------------------------
-
-def encode( obj, strict=False, compactly=True, escape_unicode=False, encoding=None ):
- """Encodes a Python object into a JSON-encoded string.
-
- If 'strict' is set to True, then only strictly-conforming JSON
- output will be produced. Note that this means that some types
- of values may not be convertable and will result in a
- JSONEncodeError exception.
-
- If 'compactly' is set to True, then the resulting string will
- have all extraneous white space removed; if False then the
- string will be "pretty printed" with whitespace and indentation
- added to make it more readable.
-
- If 'escape_unicode' is set to True, then all non-ASCII characters
- will be represented as a unicode escape sequence; if False then
- the actual real unicode character will be inserted.
-
- If no encoding is specified (encoding=None) then the output will
- either be a Python string (if entirely ASCII) or a Python unicode
- string type.
-
- However if an encoding name is given then the returned value will
- be a python string which is the byte sequence encoding the JSON
- value. As the default/recommended encoding for JSON is UTF-8,
- you should almost always pass in encoding='utf8'.
-
- """
- import sys
- encoder = None # Custom codec encoding function
- bom = None # Byte order mark to prepend to final output
- cdk = None # Codec to use
- if encoding is not None:
- import codecs
- try:
- cdk = codecs.lookup(encoding)
- except LookupError:
- cdk = None
-
- if cdk:
- pass
- elif not cdk:
- # No built-in codec was found, see if it is something we
- # can do ourself.
- encoding = encoding.lower()
- if encoding.startswith('utf-32') or encoding.startswith('utf32') \
- or encoding.startswith('ucs4') \
- or encoding.startswith('ucs-4'):
- # Python doesn't natively have a UTF-32 codec, but JSON
- # requires that it be supported. So we must decode these
- # manually.
- if encoding.endswith('le'):
- encoder = utf32le_encode
- elif encoding.endswith('be'):
- encoder = utf32be_encode
- else:
- encoder = utf32be_encode
- bom = codecs.BOM_UTF32_BE
- elif encoding.startswith('ucs2') or encoding.startswith('ucs-2'):
- # Python has no UCS-2, but we can simulate with
- # UTF-16. We just need to force us to not try to
- # encode anything past the BMP.
- encoding = 'utf-16'
- if not escape_unicode and not callable(escape_unicode):
- escape_unicode = lambda c: (0xD800 <= ord(c) <= 0xDFFF) or ord(c) >= 0x10000
- else:
- raise JSONEncodeError('this python has no codec for this character encoding',encoding)
-
- if not escape_unicode and not callable(escape_unicode):
- if encoding and encoding.startswith('utf'):
- # All UTF-x encodings can do the whole Unicode repertoire, so
- # do nothing special.
- pass
- else:
- # Even though we don't want to escape all unicode chars,
- # the encoding being used may force us to do so anyway.
- # We must pass in a function which says which characters
- # the encoding can handle and which it can't.
- def in_repertoire( c, encoding_func ):
- try:
- x = encoding_func( c, errors='strict' )
- except UnicodeError:
- return False
- return True
- if encoder:
- escape_unicode = lambda c: not in_repertoire(c, encoder)
- elif cdk:
- escape_unicode = lambda c: not in_repertoire(c, cdk[0])
- else:
- pass # Let the JSON object deal with it
-
- j = JSON( strict=strict, compactly=compactly, escape_unicode=escape_unicode )
-
- unitxt = j.encode( obj )
- if encoder:
- txt = encoder( unitxt )
- elif encoding is not None:
- txt = unitxt.encode( encoding )
- else:
- txt = unitxt
- if bom:
- txt = bom + txt
- return txt
-
-
-def decode( txt, strict=False, encoding=None, **kw ):
- """Decodes a JSON-encoded string into a Python object.
-
- If 'strict' is set to True, then those strings that are not
- entirely strictly conforming to JSON will result in a
- JSONDecodeError exception.
-
- The input string can be either a python string or a python unicode
- string. If it is already a unicode string, then it is assumed
- that no character set decoding is required.
-
- However, if you pass in a non-Unicode text string (i.e., a python
- type 'str') then an attempt will be made to auto-detect and decode
- the character encoding. This will be successful if the input was
- encoded in any of UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE),
- and of course plain ASCII works too.
-
- Note though that if you know the character encoding, then you
- should convert to a unicode string yourself, or pass it the name
- of the 'encoding' to avoid the guessing made by the auto
- detection, as with
-
- python_object = demjson.decode( input_bytes, encoding='utf8' )
-
- Optional keywords arguments must be of the form
- allow_xxxx=True/False
- or
- prevent_xxxx=True/False
- where each will allow or prevent the specific behavior, after the
- evaluation of the 'strict' argument. For example, if strict=True
- then by also passing 'allow_comments=True' then comments will be
- allowed. If strict=False then prevent_comments=True will allow
- everything except comments.
-
- """
- # Initialize the JSON object
- j = JSON( strict=strict )
- for keyword, value in kw.items():
- if keyword.startswith('allow_'):
- behavior = keyword[6:]
- allow = bool(value)
- elif keyword.startswith('prevent_'):
- behavior = keyword[8:]
- allow = not bool(value)
- else:
- raise ValueError('unknown keyword argument', keyword)
- if allow:
- j.allow(behavior)
- else:
- j.prevent(behavior)
-
- # Convert the input string into unicode if needed.
- if isinstance(txt,unicode):
- unitxt = txt
- else:
- if encoding is None:
- unitxt = auto_unicode_decode( txt )
- else:
- cdk = None # codec
- decoder = None
- import codecs
- try:
- cdk = codecs.lookup(encoding)
- except LookupError:
- encoding = encoding.lower()
- decoder = None
- if encoding.startswith('utf-32') \
- or encoding.startswith('ucs4') \
- or encoding.startswith('ucs-4'):
- # Python doesn't natively have a UTF-32 codec, but JSON
- # requires that it be supported. So we must decode these
- # manually.
- if encoding.endswith('le'):
- decoder = utf32le_decode
- elif encoding.endswith('be'):
- decoder = utf32be_decode
- else:
- if txt.startswith( codecs.BOM_UTF32_BE ):
- decoder = utf32be_decode
- txt = txt[4:]
- elif txt.startswith( codecs.BOM_UTF32_LE ):
- decoder = utf32le_decode
- txt = txt[4:]
- else:
- if encoding.startswith('ucs'):
- raise JSONDecodeError('UCS-4 encoded string must start with a BOM')
- decoder = utf32be_decode # Default BE for UTF, per unicode spec
- elif encoding.startswith('ucs2') or encoding.startswith('ucs-2'):
- # Python has no UCS-2, but we can simulate with
- # UTF-16. We just need to force us to not try to
- # encode anything past the BMP.
- encoding = 'utf-16'
-
- if decoder:
- unitxt = decoder(txt)
- elif encoding:
- unitxt = txt.decode(encoding)
- else:
- raise JSONDecodeError('this python has no codec for this character encoding',encoding)
-
- # Check that the decoding seems sane. Per RFC 4627 section 3:
- # "Since the first two characters of a JSON text will
- # always be ASCII characters [RFC0020], ..."
- #
- # This check is probably not necessary, but it allows us to
- # raise a suitably descriptive error rather than an obscure
- # syntax error later on.
- #
- # Note that the RFC requirements of two ASCII characters seems
- # to be an incorrect statement as a JSON string literal may
- # have as it's first character any unicode character. Thus
- # the first two characters will always be ASCII, unless the
- # first character is a quotation mark. And in non-strict
- # mode we can also have a few other characters too.
- if len(unitxt) > 2:
- first, second = unitxt[:2]
- if first in '"\'':
- pass # second can be anything inside string literal
- else:
- if ((ord(first) < 0x20 or ord(first) > 0x7f) or \
- (ord(second) < 0x20 or ord(second) > 0x7f)) and \
- (not j.isws(first) and not j.isws(second)):
- # Found non-printable ascii, must check unicode
- # categories to see if the character is legal.
- # Only whitespace, line and paragraph separators,
- # and format control chars are legal here.
- import unicodedata
- catfirst = unicodedata.category(unicode(first))
- catsecond = unicodedata.category(unicode(second))
- if catfirst not in ('Zs','Zl','Zp','Cf') or \
- catsecond not in ('Zs','Zl','Zp','Cf'):
- raise JSONDecodeError('the decoded string is gibberish, is the encoding correct?',encoding)
- # Now ready to do the actual decoding
- obj = j.decode( unitxt )
- return obj
-
-# end file
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/facebook.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/facebook.py
deleted file mode 100644
index a2c6a8fdd00db4e787eaf5f6b83dd5390f7d665f..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/facebook.py
+++ /dev/null
@@ -1,809 +0,0 @@
-# coding: utf-8
-#!/usr/bin/env python
-#
-# Copyright 2010 Facebook
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Python client library for the Facebook Platform.
-
-This client library is designed to support the Graph API and the official
-Facebook JavaScript SDK, which is the canonical way to implement
-Facebook authentication. Read more about the Graph API at
-http://developers.facebook.com/docs/api. You can download the Facebook
-JavaScript SDK at http://github.com/facebook/connect-js/.
-
-If your application is using Google AppEngine's webapp framework, your
-usage of this module might look like this:
-
- user = facebook.get_user_from_cookie(self.request.cookies, key, secret)
- if user:
- graph = facebook.GraphAPI(user["access_token"])
- profile = graph.get_object("me")
- friends = graph.get_connections("me", "friends")
-
-"""
-from poster.encode import multipart_encode
-import poster.streaminghttp
-import urllib, urllib2
-import sys, re, codecs
-from urllib2 import HTTPError
-from cgi import parse_qs
-
-import os, xbmc, xbmcaddon
-__addon__ = xbmcaddon.Addon(id='script.facebook.media')
-
-poster.streaminghttp.register_openers()
-
-# Find a JSON parser
-try:
- import json
- _parse_json = lambda s: json.loads(s)
- _dump_json = lambda s: json.dumps(s)
-except ImportError:
- try:
- import simplejson
- _parse_json = lambda s: simplejson.loads(s)
- _dump_json = lambda s: simplejson.dumps(s)
- except ImportError:
- # For Google AppEngine
- from django.utils import simplejson
- _parse_json = lambda s: simplejson.loads(s)
- _dump_json = lambda s: simplejson.dumps(s)
-
-import locale
-loc = locale.getdefaultlocale()
-print loc
-ENCODING = loc[1] or 'utf-8'
-
-def ENCODE(string):
- return string.encode(ENCODING,'replace')
-
-def LOG(string):
- try:
- print 'FACEBOOK MEDIA:facebook.py - %s' % ENCODE(str(string))
- return
- except:
- print "FACEBOOK MEDIA:facebook.py - COULDN'T ENCODE FOR LOG - RETRYING"
-
- try:
- print 'FACEBOOK MEDIA:facebook.py - %s' % repr(string)
- return
- except:
- print "FACEBOOK MEDIA:facebook.py - COULDN'T ENCODE FOR LOG - FINAL"
-
-class GraphAPI(object):
- """A client for the Facebook Graph API.
-
- See http://developers.facebook.com/docs/api for complete documentation
- for the API.
-
- The Graph API is made up of the objects in Facebook (e.g., people, pages,
- events, photos) and the connections between them (e.g., friends,
- photo tags, and event RSVPs). This client provides access to those
- primitive types in a generic way. For example, given an OAuth access
- token, this will fetch the profile of the active user and the list
- of the user's friends:
-
- graph = facebook.GraphAPI(access_token)
- user = graph.get_object("me")
- friends = graph.get_connections(user["id"], "friends")
-
- You can see a list of all of the objects and connections supported
- by the API at http://developers.facebook.com/docs/reference/api/.
-
- You can obtain an access token via OAuth or by using the Facebook
- JavaScript SDK. See http://developers.facebook.com/docs/authentication/
- for details.
-
- If you are using the JavaScript SDK, you can use the
- get_user_from_cookie() method below to get the OAuth access token
- for the active user from the cookie saved by the SDK.
- """
- def __init__(self, access_token=None):
- self.access_token = access_token
-
- def get_object(self, ID, **args):
- """Fetchs the given object from the graph."""
- return self.request(ID, args)
-
- def get_objects(self, ids, **args):
- """Fetchs all of the given object from the graph.
-
- We return a map from ID to object. If any of the IDs are invalid,
- we raise an exception.
- """
- args["ids"] = ",".join(ids)
- return self.request("", args)
-
- def get_connections(self, ID, connection_name, **args):
- """Fetchs the connections for given object."""
- return self.request(ID + "/" + connection_name, args,update_prog=True)
-
- def put_object(self, parent_object, connection_name, **data):
- """Writes the given object to the graph, connected to the given parent.
-
- For example,
-
- graph.put_object("me", "feed", message="Hello, world")
-
- writes "Hello, world" to the active user's wall. Likewise, this
- will comment on a the first post of the active user's feed:
-
- feed = graph.get_connections("me", "feed")
- post = feed["data"][0]
- graph.put_object(post["id"], "comments", message="First!")
-
- See http://developers.facebook.com/docs/api#publishing for all of
- the supported writeable objects.
-
- Most write operations require extended permissions. For example,
- publishing wall posts requires the "publish_stream" permission. See
- http://developers.facebook.com/docs/authentication/ for details about
- extended permissions.
- """
- assert self.access_token, "Write operations require an access token"
- return self.request(parent_object + "/" + connection_name, post_args=data)
-
- def put_wall_post(self, message, attachment={}, profile_id="me"):
- """Writes a wall post to the given profile's wall.
-
- We default to writing to the authenticated user's wall if no
- profile_id is specified.
-
- attachment adds a structured attachment to the status message being
- posted to the Wall. It should be a dictionary of the form:
-
- {"name": "Link name"
- "link": "http://www.example.com/",
- "caption": "{*actor*} posted a new review",
- "description": "This is a longer description of the attachment",
- "picture": "http://www.example.com/thumbnail.jpg"}
-
- """
- return self.put_object(profile_id, "feed", message=message, **attachment)
-
- def put_comment(self, object_id, message):
- """Writes the given comment on the given post."""
- return self.put_object(object_id, "comments", message=message)
-
- def put_like(self, object_id):
- """Likes the given post."""
- return self.put_object(object_id, "likes")
-
- def delete_object(self, ID):
- """Deletes the object with the given ID from the graph."""
- self.request(ID, post_args={"method": "delete"})
-
- def request(self, path, args=None, post_args=None,update_prog=False):
- """Fetches the given path in the Graph API.
-
- We translate args to a valid query string. If post_args is given,
- we send a POST request to the given path with the given arguments.
- """
- if not args: args = {}
- headers = None
- post_data = None
- if self.access_token:
- if post_args is None:
- args["access_token"] = self.access_token
- post_data = None
- else:
- post_args["access_token"] = self.access_token
- post_data, headers = multipart_encode(post_args)
-
- pre = "https://graph.facebook.com/"
- args = "?" + urllib.urlencode(args)
- if path.startswith('http'):
- pre = ''
- args = ''
-
- url = pre + path + args
- try:
- if headers:
- request = urllib2.Request(url, post_data, headers)
- fileob = urllib2.urlopen(request)
- else:
- fileob = urllib2.urlopen(url,post_data)
- except HTTPError, e:
- if e.code == 400:
- reason = e.headers.get('WWW-Authenticate')
- LOG('\nMessage: %s\nReason: %s' % (e.msg,reason))
- if 'invalid_token' in reason or 'invalid_request' in reason:
- if 'unsupported get request' in reason.lower():
- raise GraphAPIError( 'BadGetException',
- 'Unsupported get request')
- else:
- raise GraphAPIError( 'OAuthException',
- 'Expired/bad token')
- raise
-
- encoding = fileob.info().get('content-type').split('charset=')[-1]
- fileob = codecs.EncodedFile(fileob, encoding)
-
- if update_prog: self.updateProgress(30)
- try:
- data = ''
- try:
- total = int(fileob.info()['content-length'])
- except:
- total = 1
- update_prog = False
- chunk = 4096
- sofar = 0
- while True:
- d = fileob.read(chunk)
- if not d: break
- data += d
- if update_prog:
- sofar += chunk
- prog = int((sofar * 40) / total)
- if update_prog and not self.updateProgress(30 + prog): return
- response = _parse_json(data)
- finally:
- fileob.close()
-
- if type(response) == type({}) and response.get("error"):
- raise GraphAPIError(response["error"]["type"],
- response["error"]["message"])
- return response
-
- def updateProgress(self,pct):
- return True
-
-
-class GraphAPIError(Exception):
- def __init__(self, type_, message):
- Exception.__init__(self, message)
- self.type = type_
-
-class GraphWrapAuthError(Exception):
- def __init__(self, type_, message):
- Exception.__init__(self, message)
- self.type = type_
- self.message = message
-
-class Connections(list):
- def __init__(self,graph,connections=None,first=True,progress=True):
- list.__init__(self)
- self.first = first
- self.graph = graph
- self.progress = progress
- self.previous = ''
- self.next = ''
- self.count = 0
- if connections:
- self.count = connections.get('count',0)
- if connections: self.processConnections(connections)
-
- def processConnections(self,connections):
- cons = []
- for c in connections['data']:
- if hasattr(c,'get'):
- cons.append(GraphObject(c.get('id'),self.graph,c))
- self._getPaging(connections,len(cons))
- self.extend(cons)
- if self.progress: self.graph.updateProgress(100)
-
- def _getPaging(self,obj,count):
- paging = obj.get('paging')
- if not paging: return
- next_ = paging.get('next','')
- prev = paging.get('previous','')
- limit = self._areTheSame(next_, prev, count)
- if limit:
- self.previous = self._checkForContent(prev)
- if not self.previous and count < limit and self.first: return
- self.next = self._checkForContent(next_)
-
- def _checkForContent(self,url):
- if not url: return ''
- connections = self.graph.request(url)
- if not 'data' in connections: return ''
- if not len(connections['data']): return ''
- return url
-
- def _areTheSame(self,next_,prev,count):
- try:
- limit = int(parse_qs(next_.split('?')[-1])['limit'][0])
- except:
- limit = count
-
- try:
- next_ut = int(parse_qs(next_.split('?')[-1])['until'][0])
- prev_ut = int(parse_qs(prev.split('?')[-1])['since'][0])
- if prev_ut == next_ut: return 0
- return limit
- except:
- return limit
-
-import UserDict
-class UTF8DictWrap(UserDict.UserDict):
- def get(self,key,failobj=None):
- val = UserDict.UserDict.get(self, key, failobj)
- if hasattr(val,'encode'): return unicode(val.encode('utf-8'),'utf-8')
- return val
-
-
-class GraphObject:
- def __init__(self,ID=None,graph=None,data=None,**args):
- if (not ID) and data:
- if 'id' in data: ID = data['id']
- self.id = ID
- self.args = args
- self.graph = graph
- self._cache = {}
- self._data = data
- self.connections = GraphConnections(self)
- if ID == 'me':
- self._data = self._getObjectData(ID,**args)
- self.id = self._data.get('id') or 'me'
-
- def updateData(self):
- self._data = self._getObjectData(self.id,**self.args)
- return self
-
- def toJSON(self):
- return self._toJSON(self._data)
-
- def get(self,key,default=None,as_json=False):
- return self._getData(key,default,as_json)
-
- def hasProperty(self,prop):
- return prop in self._data
-
- def comment(self,comment):
- self.graph.put_comment(self.id,comment)
-
- def like(self):
- self.graph.put_like(self.id)
-
- def __getattr__(self, prop):
- if prop.startswith('_'): return object.__getattr__(self,prop)
- if prop.endswith('_'): prop = prop[:-1]
- if prop in self._cache:
- return self._cache[prop]
-
- if not self._data:
- self._data = self._getObjectData(self.id,**self.args)
- if self.id == 'me': self.id = self._data.get('id') or 'me'
-
- def handler(default=None,as_json=False):
- return self._getData(prop,default,as_json)
-
- handler.method = prop
-
- self._cache[prop] = handler
- return handler
-
- def _getData(self,prop,default,as_json):
- val = self._data.get(prop)
- if not val: return default
- if type(val) == type({}):
- if 'data' in val:
- if as_json:
- return self._toJSON(val)
- elif isinstance(val['data'],list):
- return Connections(self.graph,val,progress=False)
- else:
- val = val['data']
- return UTF8DictWrap(val)
- if hasattr(val,'encode'): return unicode(val.encode('utf-8'),'utf-8')
- return val
-
- def _getObjectData(self,ID,**args):
- fail = False
- try:
- return self.graph.get_object(ID,**args)
- except GraphAPIError,e:
- if not e.type == 'OAuthException': raise
- fail = True
-
- if fail:
- LOG("ERROR GETTING OBJECT - GETTING NEW TOKEN")
- if not self.graph.getNewToken():
- if self.graph.access_token: raise GraphWrapAuthError('RENEW_TOKEN_FAILURE','Failed to get new token')
- else: return None
- return self.graph.get_object(ID,**args)
-
- def _toJSON(self,data_obj):
- return _dump_json(data_obj)
-
-class GraphData:
- def __init__(self,graphObject,data=None):
- self.graphObject = graphObject
- self.graph = self.graphObject.graph
-
-
- def __getattr__(self, prop):
- if prop.startswith('_'): return object.__getattr__(self,prop)
- if prop in self._cache:
- return self._cache[prop]
-
- if not self._data: self._data = self._getObjectData(self.graphObject.id)
-
- def handler(default=None):
- val = self._data.get(prop,default)
- if hasattr(val,'encode'): return unicode(val.encode('utf-8'),'utf-8')
- return val
-
- handler.method = prop
-
- self._cache[prop] = handler
- return handler
-
- def _getObjectData(self,ID,**args):
- fail = False
- try:
- return self.graph.get_object(ID,**args)
- except GraphAPIError,e:
- if not e.type == 'OAuthException': raise
- fail = True
-
- if fail:
- LOG("ERROR GETTING OBJECT - GETTING NEW TOKEN")
- if not self.graph.getNewToken():
- if self.graph.access_token: raise GraphWrapAuthError('RENEW_TOKEN_FAILURE','Failed to get new token')
- else: return None
- return self.graph.get_object(ID,**args)
-
-class GraphConnections:
- def __init__(self,graphObject):
- self.graphObject = graphObject
- self.graph = self.graphObject.graph
- self.cache = {}
-
- def __getattr__(self, method):
- if method.startswith('_'): return object.__getattr__(self,method)
- if method in self.cache:
- return self.cache[method]
-
- def handler(**args):
- fail = False
- try:
- return self._getConnections(method,**args)
- except GraphAPIError,e:
- LOG(e.type)
- if not e.type == 'OAuthException': raise
- fail = True
-
- if fail:
- LOG("ERROR GETTING CONNECTIONS - GETTING NEW TOKEN")
- if not self.graph.getNewToken():
- if self.graph.access_token: raise GraphWrapAuthError('RENEW_TOKEN_FAILURE','Failed to get new token')
- else: return None
- return self._getConnections(method,**args)
- handler.method = method
-
- self.cache[method] = handler
- return handler
-
- def _getConnections(self,method,**args):
- connections = self.graph.get_connections(self.graphObject.id, method.replace('__','/'), **args)
- self.graph.updateProgress(70)
- return Connections(self.graph,connections)
-
- def _processConnections(self,connections,paging):
- return self.graph._processConnections(connections,paging)
-
-class GraphWrap(GraphAPI):
- def __init__(self,token,new_token_callback=None,version='8.0'):
- GraphAPI.__init__(self,token)
- self.uid = None
- self._newTokenCallback = new_token_callback
- self._progCallback = None
- self._progModifier = 1
- self._progTotal = 100
- self._progMessage = ''
- self.uid = None
- self.cookieJar = None
- self.version = version
-
- def withProgress(self,callback,modifier=1,total=100,message=''):
- poster.streaminghttp.PROGRESS_CALLBACK = callback
- self._progCallback = callback
- self._progModifier = modifier
- self._progTotal = total
- self._progMessage = message
- return self
-
- def updateProgress(self,level):
- if self._progCallback:
- level *= self._progModifier
- return self._progCallback(int(level),self._progTotal,self._progMessage)
- return True
-
- def fromJSON(self,json_string):
- if not json_string: return None
- data_obj = _parse_json(json_string)
- if type(data_obj) == type({}):
- if 'data' in data_obj:
- return Connections(self,data_obj,progress=False)
- elif 'id' in data_obj:
- return GraphObject(graph=self,data=data_obj)
- return data_obj
-
- def putWallPost(self,message, attachment={}, profile_id="me"):
- fail = False
- try:
- return self.put_wall_post(message, attachment, profile_id)
- except GraphAPIError,e:
- LOG(e.type)
- if not e.type == 'OAuthException': raise
- fail = True
-
- if fail:
- LOG("ERROR POSTING TO WALL - GETTING NEW TOKEN")
- if not self.getNewToken():
- if self.access_token: raise GraphWrapAuthError('RENEW_TOKEN_FAILURE','Failed to get new token')
- else: return None
- return self.put_wall_post(message, attachment, profile_id)
-
- def putObject(self,parent_object, connection_name, **data):
- fail = False
- try:
- return self.put_object(parent_object, connection_name, **data)
- except GraphAPIError,e:
- LOG(e.type)
- if not e.type == 'OAuthException': raise
- fail = True
-
- if fail:
- LOG("ERROR POSTING OBJECT - GETTING NEW TOKEN")
- if not self.getNewToken():
- if self.access_token: raise GraphWrapAuthError('RENEW_TOKEN_FAILURE','Failed to get new token')
- else: return None
- return self.put_object(parent_object, connection_name, **data)
-
- def getObject(self,ID,**args):
- return GraphObject(ID,self,**args)
-
- def getObjects(self,ids=[]):
- data = self.get_objects(ids)
- objects = {}
- for ID in data:
- objects[ID] = GraphObject(ID,self,data[ID])
- return objects
-
- def urlRequest(self,url):
- connections = self.request(url)
- return Connections(self,connections,first=False)
-
- def setLogin(self,email,passw,uid=None,token=None):
- self.uid = uid or self.uid
- self.login_email = email
- self.login_pass = passw
- if token: self.access_token = token
-
- def setAppData(self,aid,redirect='https://www.facebook.com/connect/login_success.html',scope=None):
- self.client_id = aid
- self.redirect = redirect
- self.scope = scope
-
- def checkHasPermission(self,permission):
- url = 'https://api.facebook.com/method/users.hasAppPermission?format=json&ext_perm='+permission+'&access_token='+self.access_token
- fobj = urllib2.urlopen(url)
- try:
- response = _parse_json(fobj.read())
- finally:
- fobj.close()
- return (response == 1)
-
- def browserRead(self,readable,post=''):
- html = readable.read()
- if False:
- htmlFile = os.path.join(xbmc.translatePath(__addon__.getAddonInfo('profile')),'cache','DEBUG_HTML%s.html' % post)
- with open(htmlFile,'w') as f:
- f.write(html.strip("'"))
- return html
-
- def checkIsAppUser(self):
- url = 'https://api.facebook.com/method/users.isAppUser?format=json&access_token='+self.access_token
- fobj = urllib2.urlopen(url)
- try:
- response = _parse_json(fobj.read())
- finally:
- fobj.close()
- return response
-
- def getNewToken(self):
- import mechanize #@UnresolvedImport
- br = mechanize.Browser()
- __addon__ = xbmcaddon.Addon(id='script.facebook.media')
- cookiesPath = os.path.join(xbmc.translatePath(__addon__.getAddonInfo('profile')),'cache','cookies')
- LOG('Cookies will be saved to: ' + cookiesPath)
- cookies = mechanize.LWPCookieJar(cookiesPath)
- if os.path.exists(cookiesPath): cookies.load()
- self.cookieJar = cookies
- opener = mechanize.build_opener(mechanize.HTTPCookieProcessor(cookies))
- mechanize.install_opener(opener)
- br.set_cookiejar(self.cookieJar)
- br._ua_handlers["_cookies"].cookiejar.clear()
- br.set_handle_robots(False)
- agent = 'XBMC/{0} Facebook-Media/{1}'.format(xbmc.getInfoLabel('System.BuildVersion'),self.version)
- LOG('Setting User Agent: {0}'.format(agent))
- br.addheaders = [('User-agent',agent)]
- scope = ''
- if self.scope: scope = '&scope=' + self.scope
- url = 'https://www.facebook.com/dialog/oauth?client_id='+self.client_id+\
- '&redirect_uri='+self.redirect+\
- '&type=user_agent&display=popup'+scope
- LOG(url)
- try:
- res = br.open(url)
- html = res.read()
- except:
- LOG("ERROR: TOKEN PAGE INITIAL READ")
- raise
-
- script = False
- try:
- #check for login form
- br.select_form(nr=0)
- LOG("HTML")
- except:
- self.genericError()
- script = True
- LOG("SCRIPT")
-
- if script:
- #no form, maybe we're logged in and the token is in javascript on the page
- url = res.geturl()
- token = self.extractTokenFromURL(url)
- if not token: token = self.parseTokenFromScript(html)
- else:
- try:
- #fill out the form and submit
- br['email'] = self.login_email
- br['pass'] = self.login_pass
- res = br.submit()
- url = res.geturl()
- LOG("FORM")
- except:
- LOG("FORM ERROR")
- raise
-
- script = False
- token = self.extractTokenFromURL(url)
- html = self.browserRead(res,'-noscript')
- if not token:
- #if 'class="checkpoint"' in html:
- token = self.handleLoginNotificationCrap(br)
-
- if not token: script = True
-
- if script:
- LOG("SCRIPT TOKEN")
- #no token in the url, let's try to parse it from javascript on the page
- try:
- __addon__ = xbmcaddon.Addon(id='script.facebook.media')
- htmlFile = os.path.join(xbmc.translatePath(__addon__.getAddonInfo('profile')),'cache','DEBUG_HTML.html')
- open(htmlFile,'w').write(html)
- LOG('html output written to: ' + htmlFile)
- except:
- pass
- token = self.parseTokenFromScript(html)
- token = urllib.unquote(token.decode('unicode-escape'))
-
- if not self.tokenIsValid(token):
- #if script: LOG("HTML:" + html)
- return False
- LOG("\n|--------------------\n|TOKEN: %s\n|--------------------" % token)
- self.saveToken(token)
- if self.cookieJar is not None:
- self.cookieJar.save()
- return token
-
- def handleLoginNotificationCrap(self,br):
- LOG('Handling Login Notification Crap')
- br.select_form(nr=0)
- res = br.submit()
- self.browserRead(res,'-loginnotifycrap1')
- #if not 'Media XBMC' in html: return None
- url = res.geturl()
- LOG('LN First URL: ' + url)
- if 'login.php' in url:
- raise GraphWrapAuthError('BAD_USERPASS','Failed: Probable bad user/pass')
- if 'access_token' in url: return self.extractTokenFromURL(url)
- br.select_form(nr=0)
- try:
- res = br.submit(name='submit[Continue]')
- except:
- res = br.submit()
- res.read()
- url = res.geturl()
- LOG('LN Second URL: ' + url)
- if 'access_token' in url: return self.extractTokenFromURL(url)
- br.select_form(nr=0)
- self.isolateSubmitButton(br, 'save_device')
- res = br.submit()
-
- html = res.read()
- url = res.geturl()
- LOG('LN Third URL: ' + url)
- if 'access_token' in url: return self.extractTokenFromURL(url)
- if 'name="submit[Continue]"' in html:
- LOG("Found 'Continue' page: submitting")
- br.select_form(nr=0)
- res = br.submit()
- url = res.geturl()
- if 'access_token' in url:
- return self.extractTokenFromURL(url)
- else:
- LOG("No Token In URL: {0}".format(url))
- return None
-
- def isolateSubmitButton(self,br,value):
- return
- submit_buttons = self.find_controls(br,ctype="submit")
- for button in submit_buttons[:]:
- if button.value != value: br.form.controls.remove(button)
-
- def find_controls(self, br,name=None, ctype=None, kind=None, cid=None, predicate=None, label=None):
- i = 0
- results = []
-
- try :
- while(True):
- results.append(br.find_control(name, ctype, kind, cid, predicate, label, nr=i))
- i += 1
- except Exception as e: #Exception tossed if control not found @UnusedVariable
- pass
- return results
-
- def extractTokenFromURL(self,url):
- try:
- #we submitted the form, check the result url for the access token
- import urlparse
- token = parse_qs(urlparse.urlparse(url.replace('#','?',1).replace('??','?'))[4])['access_token'][0]
- LOG("URL TOKEN: %s" % token)
- return token
- except:
- LOG("TOKEN URL: %s" % url)
- self.genericError()
- return None
-
- def tokenIsValid(self,token):
- if not token: return False
- if 'login_form' in token and 'standard_explanation' in token:
- reason = re.findall('id="standard_explanation">(?:
)?([^<]*)<',token)
- if reason: LOG(reason[0])
- LOG("TOKEN: " + token)
- raise GraphWrapAuthError('LOGIN_FAILURE',reason)
- return False
- if 'html' in token or 'script' in token or len(token) > 250:
- LOG("TOKEN: " + token)
- raise GraphWrapAuthError('RENEW_TOKEN_FAILURE','Failed to get new token')
- return False
- if 'login notifications' in token:
- LOG("TOKEN: " + token)
- raise GraphWrapAuthError('RENEW_TOKEN_FAILURE','Disable login notifications, then retry')
- return False
- if 'temporarily locked' in token:
- LOG("TOKEN: " + token)
- raise GraphWrapAuthError('RENEW_TOKEN_FAILURE','Facebook account is locked')
- return False
- #Because you enabled login notifications, your account is temporarily locked.
- return True
-
- def genericError(self):
- LOG('ERROR: %s::%s (%d) - %s' % (self.__class__.__name__
- , sys.exc_info()[2].tb_frame.f_code.co_name, sys.exc_info()[2].tb_lineno, sys.exc_info()[1]))
-
- def parseTokenFromScript(self,html):
- return urllib.unquote_plus(html.split("#access_token=")[-1].split("&expires")[0])
-
- def saveToken(self,token=None):
- if token:
- self.access_token = token
- if self._newTokenCallback: self._newTokenCallback(token)
\ No newline at end of file
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/fanart.jpg b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/fanart.jpg
deleted file mode 100644
index 7f1cf7f07e2bb91b71c1aca38c3b4d4fe56d6e5d..0000000000000000000000000000000000000000
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/fanart.jpg and /dev/null differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/icon.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/icon.png
deleted file mode 100644
index 2beeb9020e61fd72e34220bbc79717a19f9f8d5b..0000000000000000000000000000000000000000
Binary files a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/icon.png and /dev/null differ
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/__init__.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/__init__.py
deleted file mode 100644
index c4429be394a39a739b8ceae874a79013a297c3d4..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/__init__.py
+++ /dev/null
@@ -1,211 +0,0 @@
-__all__ = [
- 'AbstractBasicAuthHandler',
- 'AbstractDigestAuthHandler',
- 'BaseHandler',
- 'Browser',
- 'BrowserStateError',
- 'CacheFTPHandler',
- 'ContentTooShortError',
- 'Cookie',
- 'CookieJar',
- 'CookiePolicy',
- 'DefaultCookiePolicy',
- 'DefaultFactory',
- 'FTPHandler',
- 'Factory',
- 'FileCookieJar',
- 'FileHandler',
- 'FormNotFoundError',
- 'FormsFactory',
- 'HTTPBasicAuthHandler',
- 'HTTPCookieProcessor',
- 'HTTPDefaultErrorHandler',
- 'HTTPDigestAuthHandler',
- 'HTTPEquivProcessor',
- 'HTTPError',
- 'HTTPErrorProcessor',
- 'HTTPHandler',
- 'HTTPPasswordMgr',
- 'HTTPPasswordMgrWithDefaultRealm',
- 'HTTPProxyPasswordMgr',
- 'HTTPRedirectDebugProcessor',
- 'HTTPRedirectHandler',
- 'HTTPRefererProcessor',
- 'HTTPRefreshProcessor',
- 'HTTPResponseDebugProcessor',
- 'HTTPRobotRulesProcessor',
- 'HTTPSClientCertMgr',
- 'HeadParser',
- 'History',
- 'LWPCookieJar',
- 'Link',
- 'LinkNotFoundError',
- 'LinksFactory',
- 'LoadError',
- 'MSIECookieJar',
- 'MozillaCookieJar',
- 'OpenerDirector',
- 'OpenerFactory',
- 'ParseError',
- 'ProxyBasicAuthHandler',
- 'ProxyDigestAuthHandler',
- 'ProxyHandler',
- 'Request',
- 'RobotExclusionError',
- 'RobustFactory',
- 'RobustFormsFactory',
- 'RobustLinksFactory',
- 'RobustTitleFactory',
- 'SeekableResponseOpener',
- 'TitleFactory',
- 'URLError',
- 'USE_BARE_EXCEPT',
- 'UnknownHandler',
- 'UserAgent',
- 'UserAgentBase',
- 'XHTMLCompatibleHeadParser',
- '__version__',
- 'build_opener',
- 'install_opener',
- 'lwp_cookie_str',
- 'make_response',
- 'request_host',
- 'response_seek_wrapper', # XXX deprecate in public interface?
- 'seek_wrapped_response', # XXX should probably use this internally in place of response_seek_wrapper()
- 'str2time',
- 'urlopen',
- 'urlretrieve',
- 'urljoin',
-
- # ClientForm API
- 'AmbiguityError',
- 'ControlNotFoundError',
- 'FormParser',
- 'ItemCountError',
- 'ItemNotFoundError',
- 'LocateError',
- 'Missing',
- 'ParseFile',
- 'ParseFileEx',
- 'ParseResponse',
- 'ParseResponseEx',
- 'ParseString',
- 'XHTMLCompatibleFormParser',
- # deprecated
- 'CheckboxControl',
- 'Control',
- 'FileControl',
- 'HTMLForm',
- 'HiddenControl',
- 'IgnoreControl',
- 'ImageControl',
- 'IsindexControl',
- 'Item',
- 'Label',
- 'ListControl',
- 'PasswordControl',
- 'RadioControl',
- 'ScalarControl',
- 'SelectControl',
- 'SubmitButtonControl',
- 'SubmitControl',
- 'TextControl',
- 'TextareaControl',
- ]
-
-import logging
-import sys
-
-from _version import __version__
-
-# high-level stateful browser-style interface
-from _mechanize import \
- Browser, History, \
- BrowserStateError, LinkNotFoundError, FormNotFoundError
-
-# configurable URL-opener interface
-from _useragent import UserAgentBase, UserAgent
-from _html import \
- Link, \
- Factory, DefaultFactory, RobustFactory, \
- FormsFactory, LinksFactory, TitleFactory, \
- RobustFormsFactory, RobustLinksFactory, RobustTitleFactory
-
-# urllib2 work-alike interface. This is a superset of the urllib2 interface.
-from _urllib2 import *
-import _urllib2
-if hasattr(_urllib2, "HTTPSHandler"):
- __all__.append("HTTPSHandler")
-del _urllib2
-
-# misc
-from _http import HeadParser
-from _http import XHTMLCompatibleHeadParser
-from _opener import ContentTooShortError, OpenerFactory, urlretrieve
-from _response import \
- response_seek_wrapper, seek_wrapped_response, make_response
-from _rfc3986 import urljoin
-from _util import http2time as str2time
-
-# cookies
-from _clientcookie import Cookie, CookiePolicy, DefaultCookiePolicy, \
- CookieJar, FileCookieJar, LoadError, request_host_lc as request_host, \
- effective_request_host
-from _lwpcookiejar import LWPCookieJar, lwp_cookie_str
-# 2.4 raises SyntaxError due to generator / try/finally use
-if sys.version_info[:2] > (2,4):
- try:
- import sqlite3
- except ImportError:
- pass
- else:
- from _firefox3cookiejar import Firefox3CookieJar
-from _mozillacookiejar import MozillaCookieJar
-from _msiecookiejar import MSIECookieJar
-
-# forms
-from _form import (
- AmbiguityError,
- ControlNotFoundError,
- FormParser,
- ItemCountError,
- ItemNotFoundError,
- LocateError,
- Missing,
- ParseError,
- ParseFile,
- ParseFileEx,
- ParseResponse,
- ParseResponseEx,
- ParseString,
- XHTMLCompatibleFormParser,
- # deprecated
- CheckboxControl,
- Control,
- FileControl,
- HTMLForm,
- HiddenControl,
- IgnoreControl,
- ImageControl,
- IsindexControl,
- Item,
- Label,
- ListControl,
- PasswordControl,
- RadioControl,
- ScalarControl,
- SelectControl,
- SubmitButtonControl,
- SubmitControl,
- TextControl,
- TextareaControl,
- )
-
-# If you hate the idea of turning bugs into warnings, do:
-# import mechanize; mechanize.USE_BARE_EXCEPT = False
-USE_BARE_EXCEPT = True
-
-logger = logging.getLogger("mechanize")
-if logger.level is logging.NOTSET:
- logger.setLevel(logging.CRITICAL)
-del logger
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_auth.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_auth.py
deleted file mode 100644
index 900e201ea6029d502a17cdab9e043c95b49056e2..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_auth.py
+++ /dev/null
@@ -1,68 +0,0 @@
-"""HTTP Authentication and Proxy support.
-
-
-Copyright 2006 John J. Lee
-
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD or ZPL 2.1 licenses (see the file COPYING.txt
-included with the distribution).
-
-"""
-
-from _urllib2_fork import HTTPPasswordMgr
-
-
-# TODO: stop deriving from HTTPPasswordMgr
-class HTTPProxyPasswordMgr(HTTPPasswordMgr):
- # has default realm and host/port
- def add_password(self, realm, uri, user, passwd):
- # uri could be a single URI or a sequence
- if uri is None or isinstance(uri, basestring):
- uris = [uri]
- else:
- uris = uri
- passwd_by_domain = self.passwd.setdefault(realm, {})
- for uri in uris:
- for default_port in True, False:
- reduced_uri = self.reduce_uri(uri, default_port)
- passwd_by_domain[reduced_uri] = (user, passwd)
-
- def find_user_password(self, realm, authuri):
- attempts = [(realm, authuri), (None, authuri)]
- # bleh, want default realm to take precedence over default
- # URI/authority, hence this outer loop
- for default_uri in False, True:
- for realm, authuri in attempts:
- authinfo_by_domain = self.passwd.get(realm, {})
- for default_port in True, False:
- reduced_authuri = self.reduce_uri(authuri, default_port)
- for uri, authinfo in authinfo_by_domain.iteritems():
- if uri is None and not default_uri:
- continue
- if self.is_suburi(uri, reduced_authuri):
- return authinfo
- user, password = None, None
-
- if user is not None:
- break
- return user, password
-
- def reduce_uri(self, uri, default_port=True):
- if uri is None:
- return None
- return HTTPPasswordMgr.reduce_uri(self, uri, default_port)
-
- def is_suburi(self, base, test):
- if base is None:
- # default to the proxy's host/port
- hostport, path = test
- base = (hostport, "/")
- return HTTPPasswordMgr.is_suburi(self, base, test)
-
-
-class HTTPSClientCertMgr(HTTPPasswordMgr):
- # implementation inheritance: this is not a proper subclass
- def add_key_cert(self, uri, key_file, cert_file):
- self.add_password(None, uri, key_file, cert_file)
- def find_key_cert(self, authuri):
- return HTTPPasswordMgr.find_user_password(self, None, authuri)
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_beautifulsoup.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_beautifulsoup.py
deleted file mode 100644
index 0040140d041b25bd63bc49a59aec8f6018ba5275..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_beautifulsoup.py
+++ /dev/null
@@ -1,1077 +0,0 @@
-"""Beautiful Soup
-Elixir and Tonic
-"The Screen-Scraper's Friend"
-v2.1.1
-http://www.crummy.com/software/BeautifulSoup/
-
-Beautiful Soup parses arbitrarily invalid XML- or HTML-like substance
-into a tree representation. It provides methods and Pythonic idioms
-that make it easy to search and modify the tree.
-
-A well-formed XML/HTML document will yield a well-formed data
-structure. An ill-formed XML/HTML document will yield a
-correspondingly ill-formed data structure. If your document is only
-locally well-formed, you can use this library to find and process the
-well-formed part of it. The BeautifulSoup class has heuristics for
-obtaining a sensible parse tree in the face of common HTML errors.
-
-Beautiful Soup has no external dependencies. It works with Python 2.2
-and up.
-
-Beautiful Soup defines classes for four different parsing strategies:
-
- * BeautifulStoneSoup, for parsing XML, SGML, or your domain-specific
- language that kind of looks like XML.
-
- * BeautifulSoup, for parsing run-of-the-mill HTML code, be it valid
- or invalid.
-
- * ICantBelieveItsBeautifulSoup, for parsing valid but bizarre HTML
- that trips up BeautifulSoup.
-
- * BeautifulSOAP, for making it easier to parse XML documents that use
- lots of subelements containing a single string, where you'd prefer
- they put that string into an attribute (such as SOAP messages).
-
-You can subclass BeautifulStoneSoup or BeautifulSoup to create a
-parsing strategy specific to an XML schema or a particular bizarre
-HTML document. Typically your subclass would just override
-SELF_CLOSING_TAGS and/or NESTABLE_TAGS.
-""" #"
-from __future__ import generators
-
-__author__ = "Leonard Richardson (leonardr@segfault.org)"
-__version__ = "2.1.1"
-__date__ = "$Date: 2004/10/18 00:14:20 $"
-__copyright__ = "Copyright (c) 2004-2005 Leonard Richardson"
-__license__ = "PSF"
-
-from _sgmllib_copy import SGMLParser, SGMLParseError
-import types
-import re
-import _sgmllib_copy as sgmllib
-
-class NullType(object):
-
- """Similar to NoneType with a corresponding singleton instance
- 'Null' that, unlike None, accepts any message and returns itself.
-
- Examples:
- >>> Null("send", "a", "message")("and one more",
- ... "and what you get still") is Null
- True
- """
-
- def __new__(cls): return Null
- def __call__(self, *args, **kwargs): return Null
-## def __getstate__(self, *args): return Null
- def __getattr__(self, attr): return Null
- def __getitem__(self, item): return Null
- def __setattr__(self, attr, value): pass
- def __setitem__(self, item, value): pass
- def __len__(self): return 0
- # FIXME: is this a python bug? otherwise ``for x in Null: pass``
- # never terminates...
- def __iter__(self): return iter([])
- def __contains__(self, item): return False
- def __repr__(self): return "Null"
-Null = object.__new__(NullType)
-
-class PageElement:
- """Contains the navigational information for some part of the page
- (either a tag or a piece of text)"""
-
- def setup(self, parent=Null, previous=Null):
- """Sets up the initial relations between this element and
- other elements."""
- self.parent = parent
- self.previous = previous
- self.next = Null
- self.previousSibling = Null
- self.nextSibling = Null
- if self.parent and self.parent.contents:
- self.previousSibling = self.parent.contents[-1]
- self.previousSibling.nextSibling = self
-
- def findNext(self, name=None, attrs={}, text=None):
- """Returns the first item that matches the given criteria and
- appears after this Tag in the document."""
- return self._first(self.fetchNext, name, attrs, text)
- firstNext = findNext
-
- def fetchNext(self, name=None, attrs={}, text=None, limit=None):
- """Returns all items that match the given criteria and appear
- before after Tag in the document."""
- return self._fetch(name, attrs, text, limit, self.nextGenerator)
-
- def findNextSibling(self, name=None, attrs={}, text=None):
- """Returns the closest sibling to this Tag that matches the
- given criteria and appears after this Tag in the document."""
- return self._first(self.fetchNextSiblings, name, attrs, text)
- firstNextSibling = findNextSibling
-
- def fetchNextSiblings(self, name=None, attrs={}, text=None, limit=None):
- """Returns the siblings of this Tag that match the given
- criteria and appear after this Tag in the document."""
- return self._fetch(name, attrs, text, limit, self.nextSiblingGenerator)
-
- def findPrevious(self, name=None, attrs={}, text=None):
- """Returns the first item that matches the given criteria and
- appears before this Tag in the document."""
- return self._first(self.fetchPrevious, name, attrs, text)
-
- def fetchPrevious(self, name=None, attrs={}, text=None, limit=None):
- """Returns all items that match the given criteria and appear
- before this Tag in the document."""
- return self._fetch(name, attrs, text, limit, self.previousGenerator)
- firstPrevious = findPrevious
-
- def findPreviousSibling(self, name=None, attrs={}, text=None):
- """Returns the closest sibling to this Tag that matches the
- given criteria and appears before this Tag in the document."""
- return self._first(self.fetchPreviousSiblings, name, attrs, text)
- firstPreviousSibling = findPreviousSibling
-
- def fetchPreviousSiblings(self, name=None, attrs={}, text=None,
- limit=None):
- """Returns the siblings of this Tag that match the given
- criteria and appear before this Tag in the document."""
- return self._fetch(name, attrs, text, limit,
- self.previousSiblingGenerator)
-
- def findParent(self, name=None, attrs={}):
- """Returns the closest parent of this Tag that matches the given
- criteria."""
- r = Null
- l = self.fetchParents(name, attrs, 1)
- if l:
- r = l[0]
- return r
- firstParent = findParent
-
- def fetchParents(self, name=None, attrs={}, limit=None):
- """Returns the parents of this Tag that match the given
- criteria."""
- return self._fetch(name, attrs, None, limit, self.parentGenerator)
-
- #These methods do the real heavy lifting.
-
- def _first(self, method, name, attrs, text):
- r = Null
- l = method(name, attrs, text, 1)
- if l:
- r = l[0]
- return r
-
- def _fetch(self, name, attrs, text, limit, generator):
- "Iterates over a generator looking for things that match."
- if not hasattr(attrs, 'items'):
- attrs = {'class' : attrs}
-
- results = []
- g = generator()
- while True:
- try:
- i = g.next()
- except StopIteration:
- break
- found = None
- if isinstance(i, Tag):
- if not text:
- if not name or self._matches(i, name):
- match = True
- for attr, matchAgainst in attrs.items():
- check = i.get(attr)
- if not self._matches(check, matchAgainst):
- match = False
- break
- if match:
- found = i
- elif text:
- if self._matches(i, text):
- found = i
- if found:
- results.append(found)
- if limit and len(results) >= limit:
- break
- return results
-
- #Generators that can be used to navigate starting from both
- #NavigableTexts and Tags.
- def nextGenerator(self):
- i = self
- while i:
- i = i.next
- yield i
-
- def nextSiblingGenerator(self):
- i = self
- while i:
- i = i.nextSibling
- yield i
-
- def previousGenerator(self):
- i = self
- while i:
- i = i.previous
- yield i
-
- def previousSiblingGenerator(self):
- i = self
- while i:
- i = i.previousSibling
- yield i
-
- def parentGenerator(self):
- i = self
- while i:
- i = i.parent
- yield i
-
- def _matches(self, chunk, howToMatch):
- #print 'looking for %s in %s' % (howToMatch, chunk)
- #
- # If given a list of items, return true if the list contains a
- # text element that matches.
- if isList(chunk) and not isinstance(chunk, Tag):
- for tag in chunk:
- if isinstance(tag, NavigableText) and self._matches(tag, howToMatch):
- return True
- return False
- if callable(howToMatch):
- return howToMatch(chunk)
- if isinstance(chunk, Tag):
- #Custom match methods take the tag as an argument, but all other
- #ways of matching match the tag name as a string
- chunk = chunk.name
- #Now we know that chunk is a string
- if not isinstance(chunk, basestring):
- chunk = str(chunk)
- if hasattr(howToMatch, 'match'):
- # It's a regexp object.
- return howToMatch.search(chunk)
- if isList(howToMatch):
- return chunk in howToMatch
- if hasattr(howToMatch, 'items'):
- return howToMatch.has_key(chunk)
- #It's just a string
- return str(howToMatch) == chunk
-
-class NavigableText(PageElement):
-
- def __getattr__(self, attr):
- "For backwards compatibility, text.string gives you text"
- if attr == 'string':
- return self
- else:
- raise AttributeError, "'%s' object has no attribute '%s'" % (self.__class__.__name__, attr)
-
-class NavigableString(str, NavigableText):
- pass
-
-class NavigableUnicodeString(unicode, NavigableText):
- pass
-
-class Tag(PageElement):
-
- """Represents a found HTML tag with its attributes and contents."""
-
- def __init__(self, name, attrs=None, parent=Null, previous=Null):
- "Basic constructor."
- self.name = name
- if attrs == None:
- attrs = []
- self.attrs = attrs
- self.contents = []
- self.setup(parent, previous)
- self.hidden = False
-
- def get(self, key, default=None):
- """Returns the value of the 'key' attribute for the tag, or
- the value given for 'default' if it doesn't have that
- attribute."""
- return self._getAttrMap().get(key, default)
-
- def __getitem__(self, key):
- """tag[key] returns the value of the 'key' attribute for the tag,
- and throws an exception if it's not there."""
- return self._getAttrMap()[key]
-
- def __iter__(self):
- "Iterating over a tag iterates over its contents."
- return iter(self.contents)
-
- def __len__(self):
- "The length of a tag is the length of its list of contents."
- return len(self.contents)
-
- def __contains__(self, x):
- return x in self.contents
-
- def __nonzero__(self):
- "A tag is non-None even if it has no contents."
- return True
-
- def __setitem__(self, key, value):
- """Setting tag[key] sets the value of the 'key' attribute for the
- tag."""
- self._getAttrMap()
- self.attrMap[key] = value
- found = False
- for i in range(0, len(self.attrs)):
- if self.attrs[i][0] == key:
- self.attrs[i] = (key, value)
- found = True
- if not found:
- self.attrs.append((key, value))
- self._getAttrMap()[key] = value
-
- def __delitem__(self, key):
- "Deleting tag[key] deletes all 'key' attributes for the tag."
- for item in self.attrs:
- if item[0] == key:
- self.attrs.remove(item)
- #We don't break because bad HTML can define the same
- #attribute multiple times.
- self._getAttrMap()
- if self.attrMap.has_key(key):
- del self.attrMap[key]
-
- def __call__(self, *args, **kwargs):
- """Calling a tag like a function is the same as calling its
- fetch() method. Eg. tag('a') returns a list of all the A tags
- found within this tag."""
- return apply(self.fetch, args, kwargs)
-
- def __getattr__(self, tag):
- if len(tag) > 3 and tag.rfind('Tag') == len(tag)-3:
- return self.first(tag[:-3])
- elif tag.find('__') != 0:
- return self.first(tag)
-
- def __eq__(self, other):
- """Returns true iff this tag has the same name, the same attributes,
- and the same contents (recursively) as the given tag.
-
- NOTE: right now this will return false if two tags have the
- same attributes in a different order. Should this be fixed?"""
- if not hasattr(other, 'name') or not hasattr(other, 'attrs') or not hasattr(other, 'contents') or self.name != other.name or self.attrs != other.attrs or len(self) != len(other):
- return False
- for i in range(0, len(self.contents)):
- if self.contents[i] != other.contents[i]:
- return False
- return True
-
- def __ne__(self, other):
- """Returns true iff this tag is not identical to the other tag,
- as defined in __eq__."""
- return not self == other
-
- def __repr__(self):
- """Renders this tag as a string."""
- return str(self)
-
- def __unicode__(self):
- return self.__str__(1)
-
- def __str__(self, needUnicode=None, showStructureIndent=None):
- """Returns a string or Unicode representation of this tag and
- its contents.
-
- NOTE: since Python's HTML parser consumes whitespace, this
- method is not certain to reproduce the whitespace present in
- the original string."""
-
- attrs = []
- if self.attrs:
- for key, val in self.attrs:
- attrs.append('%s="%s"' % (key, val))
- close = ''
- closeTag = ''
- if self.isSelfClosing():
- close = ' /'
- else:
- closeTag = '%s>' % self.name
- indentIncrement = None
- if showStructureIndent != None:
- indentIncrement = showStructureIndent
- if not self.hidden:
- indentIncrement += 1
- contents = self.renderContents(indentIncrement, needUnicode=needUnicode)
- if showStructureIndent:
- space = '\n%s' % (' ' * showStructureIndent)
- if self.hidden:
- s = contents
- else:
- s = []
- attributeString = ''
- if attrs:
- attributeString = ' ' + ' '.join(attrs)
- if showStructureIndent:
- s.append(space)
- s.append('<%s%s%s>' % (self.name, attributeString, close))
- s.append(contents)
- if closeTag and showStructureIndent != None:
- s.append(space)
- s.append(closeTag)
- s = ''.join(s)
- isUnicode = type(s) == types.UnicodeType
- if needUnicode and not isUnicode:
- s = unicode(s)
- elif isUnicode and needUnicode==False:
- s = str(s)
- return s
-
- def prettify(self, needUnicode=None):
- return self.__str__(needUnicode, showStructureIndent=True)
-
- def renderContents(self, showStructureIndent=None, needUnicode=None):
- """Renders the contents of this tag as a (possibly Unicode)
- string."""
- s=[]
- for c in self:
- text = None
- if isinstance(c, NavigableUnicodeString) or type(c) == types.UnicodeType:
- text = unicode(c)
- elif isinstance(c, Tag):
- s.append(c.__str__(needUnicode, showStructureIndent))
- elif needUnicode:
- text = unicode(c)
- else:
- text = str(c)
- if text:
- if showStructureIndent != None:
- if text[-1] == '\n':
- text = text[:-1]
- s.append(text)
- return ''.join(s)
-
- #Soup methods
-
- def firstText(self, text, recursive=True):
- """Convenience method to retrieve the first piece of text matching the
- given criteria. 'text' can be a string, a regular expression object,
- a callable that takes a string and returns whether or not the
- string 'matches', etc."""
- return self.first(recursive=recursive, text=text)
-
- def fetchText(self, text, recursive=True, limit=None):
- """Convenience method to retrieve all pieces of text matching the
- given criteria. 'text' can be a string, a regular expression object,
- a callable that takes a string and returns whether or not the
- string 'matches', etc."""
- return self.fetch(recursive=recursive, text=text, limit=limit)
-
- def first(self, name=None, attrs={}, recursive=True, text=None):
- """Return only the first child of this
- Tag matching the given criteria."""
- r = Null
- l = self.fetch(name, attrs, recursive, text, 1)
- if l:
- r = l[0]
- return r
- findChild = first
-
- def fetch(self, name=None, attrs={}, recursive=True, text=None,
- limit=None):
- """Extracts a list of Tag objects that match the given
- criteria. You can specify the name of the Tag and any
- attributes you want the Tag to have.
-
- The value of a key-value pair in the 'attrs' map can be a
- string, a list of strings, a regular expression object, or a
- callable that takes a string and returns whether or not the
- string matches for some custom definition of 'matches'. The
- same is true of the tag name."""
- generator = self.recursiveChildGenerator
- if not recursive:
- generator = self.childGenerator
- return self._fetch(name, attrs, text, limit, generator)
- fetchChildren = fetch
-
- #Utility methods
-
- def isSelfClosing(self):
- """Returns true iff this is a self-closing tag as defined in the HTML
- standard.
-
- TODO: This is specific to BeautifulSoup and its subclasses, but it's
- used by __str__"""
- return self.name in BeautifulSoup.SELF_CLOSING_TAGS
-
- def append(self, tag):
- """Appends the given tag to the contents of this tag."""
- self.contents.append(tag)
-
- #Private methods
-
- def _getAttrMap(self):
- """Initializes a map representation of this tag's attributes,
- if not already initialized."""
- if not getattr(self, 'attrMap'):
- self.attrMap = {}
- for (key, value) in self.attrs:
- self.attrMap[key] = value
- return self.attrMap
-
- #Generator methods
- def childGenerator(self):
- for i in range(0, len(self.contents)):
- yield self.contents[i]
- raise StopIteration
-
- def recursiveChildGenerator(self):
- stack = [(self, 0)]
- while stack:
- tag, start = stack.pop()
- if isinstance(tag, Tag):
- for i in range(start, len(tag.contents)):
- a = tag.contents[i]
- yield a
- if isinstance(a, Tag) and tag.contents:
- if i < len(tag.contents) - 1:
- stack.append((tag, i+1))
- stack.append((a, 0))
- break
- raise StopIteration
-
-
-def isList(l):
- """Convenience method that works with all 2.x versions of Python
- to determine whether or not something is listlike."""
- return hasattr(l, '__iter__') \
- or (type(l) in (types.ListType, types.TupleType))
-
-def buildTagMap(default, *args):
- """Turns a list of maps, lists, or scalars into a single map.
- Used to build the SELF_CLOSING_TAGS and NESTABLE_TAGS maps out
- of lists and partial maps."""
- built = {}
- for portion in args:
- if hasattr(portion, 'items'):
- #It's a map. Merge it.
- for k,v in portion.items():
- built[k] = v
- elif isList(portion):
- #It's a list. Map each item to the default.
- for k in portion:
- built[k] = default
- else:
- #It's a scalar. Map it to the default.
- built[portion] = default
- return built
-
-class BeautifulStoneSoup(Tag, SGMLParser):
-
- """This class contains the basic parser and fetch code. It defines
- a parser that knows nothing about tag behavior except for the
- following:
-
- You can't close a tag without closing all the tags it encloses.
- That is, "" actually means
- "".
-
- [Another possible explanation is "", but since
- this class defines no SELF_CLOSING_TAGS, it will never use that
- explanation.]
-
- This class is useful for parsing XML or made-up markup languages,
- or when BeautifulSoup makes an assumption counter to what you were
- expecting."""
-
- SELF_CLOSING_TAGS = {}
- NESTABLE_TAGS = {}
- RESET_NESTING_TAGS = {}
- QUOTE_TAGS = {}
-
- #As a public service we will by default silently replace MS smart quotes
- #and similar characters with their HTML or ASCII equivalents.
- MS_CHARS = { '\x80' : '€',
- '\x81' : ' ',
- '\x82' : '‚',
- '\x83' : 'ƒ',
- '\x84' : '„',
- '\x85' : '…',
- '\x86' : '†',
- '\x87' : '‡',
- '\x88' : '⁁',
- '\x89' : '%',
- '\x8A' : 'Š',
- '\x8B' : '<',
- '\x8C' : 'Œ',
- '\x8D' : '?',
- '\x8E' : 'Z',
- '\x8F' : '?',
- '\x90' : '?',
- '\x91' : '‘',
- '\x92' : '’',
- '\x93' : '“',
- '\x94' : '”',
- '\x95' : '•',
- '\x96' : '–',
- '\x97' : '—',
- '\x98' : '˜',
- '\x99' : '™',
- '\x9a' : 'š',
- '\x9b' : '>',
- '\x9c' : 'œ',
- '\x9d' : '?',
- '\x9e' : 'z',
- '\x9f' : 'Ÿ',}
-
- PARSER_MASSAGE = [(re.compile('(<[^<>]*)/>'),
- lambda(x):x.group(1) + ' />'),
- (re.compile(']*)>'),
- lambda(x):''),
- (re.compile("([\x80-\x9f])"),
- lambda(x): BeautifulStoneSoup.MS_CHARS.get(x.group(1)))
- ]
-
- ROOT_TAG_NAME = '[document]'
-
- def __init__(self, text=None, avoidParserProblems=True,
- initialTextIsEverything=True):
- """Initialize this as the 'root tag' and feed in any text to
- the parser.
-
- NOTE about avoidParserProblems: sgmllib will process most bad
- HTML, and BeautifulSoup has tricks for dealing with some HTML
- that kills sgmllib, but Beautiful Soup can nonetheless choke
- or lose data if your data uses self-closing tags or
- declarations incorrectly. By default, Beautiful Soup sanitizes
- its input to avoid the vast majority of these problems. The
- problems are relatively rare, even in bad HTML, so feel free
- to pass in False to avoidParserProblems if they don't apply to
- you, and you'll get better performance. The only reason I have
- this turned on by default is so I don't get so many tech
- support questions.
-
- The two most common instances of invalid HTML that will choke
- sgmllib are fixed by the default parser massage techniques:
-
- (No space between name of closing tag and tag close)
- (Extraneous whitespace in declaration)
-
- You can pass in a custom list of (RE object, replace method)
- tuples to get Beautiful Soup to scrub your input the way you
- want."""
- Tag.__init__(self, self.ROOT_TAG_NAME)
- if avoidParserProblems \
- and not isList(avoidParserProblems):
- avoidParserProblems = self.PARSER_MASSAGE
- self.avoidParserProblems = avoidParserProblems
- SGMLParser.__init__(self)
- self.quoteStack = []
- self.hidden = 1
- self.reset()
- if hasattr(text, 'read'):
- #It's a file-type object.
- text = text.read()
- if text:
- self.feed(text)
- if initialTextIsEverything:
- self.done()
-
- def __getattr__(self, methodName):
- """This method routes method call requests to either the SGMLParser
- superclass or the Tag superclass, depending on the method name."""
- if methodName.find('start_') == 0 or methodName.find('end_') == 0 \
- or methodName.find('do_') == 0:
- return SGMLParser.__getattr__(self, methodName)
- elif methodName.find('__') != 0:
- return Tag.__getattr__(self, methodName)
- else:
- raise AttributeError
-
- def feed(self, text):
- if self.avoidParserProblems:
- for fix, m in self.avoidParserProblems:
- text = fix.sub(m, text)
- SGMLParser.feed(self, text)
-
- def done(self):
- """Called when you're done parsing, so that the unclosed tags can be
- correctly processed."""
- self.endData() #NEW
- while self.currentTag.name != self.ROOT_TAG_NAME:
- self.popTag()
-
- def reset(self):
- SGMLParser.reset(self)
- self.currentData = []
- self.currentTag = None
- self.tagStack = []
- self.pushTag(self)
-
- def popTag(self):
- tag = self.tagStack.pop()
- # Tags with just one string-owning child get the child as a
- # 'string' property, so that soup.tag.string is shorthand for
- # soup.tag.contents[0]
- if len(self.currentTag.contents) == 1 and \
- isinstance(self.currentTag.contents[0], NavigableText):
- self.currentTag.string = self.currentTag.contents[0]
-
- #print "Pop", tag.name
- if self.tagStack:
- self.currentTag = self.tagStack[-1]
- return self.currentTag
-
- def pushTag(self, tag):
- #print "Push", tag.name
- if self.currentTag:
- self.currentTag.append(tag)
- self.tagStack.append(tag)
- self.currentTag = self.tagStack[-1]
-
- def endData(self):
- currentData = ''.join(self.currentData)
- if currentData:
- if not currentData.strip():
- if '\n' in currentData:
- currentData = '\n'
- else:
- currentData = ' '
- c = NavigableString
- if type(currentData) == types.UnicodeType:
- c = NavigableUnicodeString
- o = c(currentData)
- o.setup(self.currentTag, self.previous)
- if self.previous:
- self.previous.next = o
- self.previous = o
- self.currentTag.contents.append(o)
- self.currentData = []
-
- def _popToTag(self, name, inclusivePop=True):
- """Pops the tag stack up to and including the most recent
- instance of the given tag. If inclusivePop is false, pops the tag
- stack up to but *not* including the most recent instqance of
- the given tag."""
- if name == self.ROOT_TAG_NAME:
- return
-
- numPops = 0
- mostRecentTag = None
- for i in range(len(self.tagStack)-1, 0, -1):
- if name == self.tagStack[i].name:
- numPops = len(self.tagStack)-i
- break
- if not inclusivePop:
- numPops = numPops - 1
-
- for i in range(0, numPops):
- mostRecentTag = self.popTag()
- return mostRecentTag
-
- def _smartPop(self, name):
-
- """We need to pop up to the previous tag of this type, unless
- one of this tag's nesting reset triggers comes between this
- tag and the previous tag of this type, OR unless this tag is a
- generic nesting trigger and another generic nesting trigger
- comes between this tag and the previous tag of this type.
-
- Examples:
-
FooBar
should pop to 'p', not 'b'.
-
Foo
Bar
should pop to 'table', not 'p'.
-
Foo
Bar
should pop to 'tr', not 'p'.
-
FooBar
should pop to 'p', not 'b'.
-
-
*
* should pop to 'ul', not the first 'li'.
-
*
* should pop to 'table', not the first 'tr'
-
*
* should pop to 'tr', not the first 'td'
- """
-
- nestingResetTriggers = self.NESTABLE_TAGS.get(name)
- isNestable = nestingResetTriggers != None
- isResetNesting = self.RESET_NESTING_TAGS.has_key(name)
- popTo = None
- inclusive = True
- for i in range(len(self.tagStack)-1, 0, -1):
- p = self.tagStack[i]
- if (not p or p.name == name) and not isNestable:
- #Non-nestable tags get popped to the top or to their
- #last occurance.
- popTo = name
- break
- if (nestingResetTriggers != None
- and p.name in nestingResetTriggers) \
- or (nestingResetTriggers == None and isResetNesting
- and self.RESET_NESTING_TAGS.has_key(p.name)):
-
- #If we encounter one of the nesting reset triggers
- #peculiar to this tag, or we encounter another tag
- #that causes nesting to reset, pop up to but not
- #including that tag.
-
- popTo = p.name
- inclusive = False
- break
- p = p.parent
- if popTo:
- self._popToTag(popTo, inclusive)
-
- def unknown_starttag(self, name, attrs, selfClosing=0):
- #print "Start tag %s" % name
- if self.quoteStack:
- #This is not a real tag.
- #print "<%s> is not real!" % name
- attrs = ''.join(map(lambda(x, y): ' %s="%s"' % (x, y), attrs))
- self.handle_data('<%s%s>' % (name, attrs))
- return
- self.endData()
- if not name in self.SELF_CLOSING_TAGS and not selfClosing:
- self._smartPop(name)
- tag = Tag(name, attrs, self.currentTag, self.previous)
- if self.previous:
- self.previous.next = tag
- self.previous = tag
- self.pushTag(tag)
- if selfClosing or name in self.SELF_CLOSING_TAGS:
- self.popTag()
- if name in self.QUOTE_TAGS:
- #print "Beginning quote (%s)" % name
- self.quoteStack.append(name)
- self.literal = 1
-
- def unknown_endtag(self, name):
- if self.quoteStack and self.quoteStack[-1] != name:
- #This is not a real end tag.
- #print "%s> is not real!" % name
- self.handle_data('%s>' % name)
- return
- self.endData()
- self._popToTag(name)
- if self.quoteStack and self.quoteStack[-1] == name:
- self.quoteStack.pop()
- self.literal = (len(self.quoteStack) > 0)
-
- def handle_data(self, data):
- self.currentData.append(data)
-
- def handle_pi(self, text):
- "Propagate processing instructions right through."
- self.handle_data("%s>" % text)
-
- def handle_comment(self, text):
- "Propagate comments right through."
- self.handle_data("" % text)
-
- def handle_charref(self, ref):
- "Propagate char refs right through."
- self.handle_data('%s;' % ref)
-
- def handle_entityref(self, ref):
- "Propagate entity refs right through."
- self.handle_data('&%s;' % ref)
-
- def handle_decl(self, data):
- "Propagate DOCTYPEs and the like right through."
- self.handle_data('' % data)
-
- def parse_declaration(self, i):
- """Treat a bogus SGML declaration as raw data. Treat a CDATA
- declaration as regular data."""
- j = None
- if self.rawdata[i:i+9] == '', i)
- if k == -1:
- k = len(self.rawdata)
- self.handle_data(self.rawdata[i+9:k])
- j = k+3
- else:
- try:
- j = SGMLParser.parse_declaration(self, i)
- except SGMLParseError:
- toHandle = self.rawdata[i:]
- self.handle_data(toHandle)
- j = i + len(toHandle)
- return j
-
-class BeautifulSoup(BeautifulStoneSoup):
-
- """This parser knows the following facts about HTML:
-
- * Some tags have no closing tag and should be interpreted as being
- closed as soon as they are encountered.
-
- * The text inside some tags (ie. 'script') may contain tags which
- are not really part of the document and which should be parsed
- as text, not tags. If you want to parse the text as tags, you can
- always fetch it and parse it explicitly.
-
- * Tag nesting rules:
-
- Most tags can't be nested at all. For instance, the occurance of
- a
tag should implicitly close the previous
tag.
-
-
Para1
Para2
- should be transformed into:
-
Para1
Para2
-
- Some tags can be nested arbitrarily. For instance, the occurance
- of a
tag should _not_ implicitly close the previous
-
tag.
-
- Alice said:
Bob said:
Blah
- should NOT be transformed into:
- Alice said:
Bob said:
Blah
-
- Some tags can be nested, but the nesting is reset by the
- interposition of other tags. For instance, a
tag should
- implicitly close the previous
tag within the same
,
- but not close a
tag in another table.
-
-
Blah
Blah
- should be transformed into:
-
Blah
Blah
- but,
-
Blah
Blah
- should NOT be transformed into
-
Blah
Blah
-
- Differing assumptions about tag nesting rules are a major source
- of problems with the BeautifulSoup class. If BeautifulSoup is not
- treating as nestable a tag your page author treats as nestable,
- try ICantBelieveItsBeautifulSoup before writing your own
- subclass."""
-
- SELF_CLOSING_TAGS = buildTagMap(None, ['br' , 'hr', 'input', 'img', 'meta',
- 'spacer', 'link', 'frame', 'base'])
-
- QUOTE_TAGS = {'script': None}
-
- #According to the HTML standard, each of these inline tags can
- #contain another tag of the same type. Furthermore, it's common
- #to actually use these tags this way.
- NESTABLE_INLINE_TAGS = ['span', 'font', 'q', 'object', 'bdo', 'sub', 'sup',
- 'center']
-
- #According to the HTML standard, these block tags can contain
- #another tag of the same type. Furthermore, it's common
- #to actually use these tags this way.
- NESTABLE_BLOCK_TAGS = ['blockquote', 'div', 'fieldset', 'ins', 'del']
-
- #Lists can contain other lists, but there are restrictions.
- NESTABLE_LIST_TAGS = { 'ol' : [],
- 'ul' : [],
- 'li' : ['ul', 'ol'],
- 'dl' : [],
- 'dd' : ['dl'],
- 'dt' : ['dl'] }
-
- #Tables can contain other tables, but there are restrictions.
- NESTABLE_TABLE_TAGS = {'table' : [],
- 'tr' : ['table', 'tbody', 'tfoot', 'thead'],
- 'td' : ['tr'],
- 'th' : ['tr'],
- }
-
- NON_NESTABLE_BLOCK_TAGS = ['address', 'form', 'p', 'pre']
-
- #If one of these tags is encountered, all tags up to the next tag of
- #this type are popped.
- RESET_NESTING_TAGS = buildTagMap(None, NESTABLE_BLOCK_TAGS, 'noscript',
- NON_NESTABLE_BLOCK_TAGS,
- NESTABLE_LIST_TAGS,
- NESTABLE_TABLE_TAGS)
-
- NESTABLE_TAGS = buildTagMap([], NESTABLE_INLINE_TAGS, NESTABLE_BLOCK_TAGS,
- NESTABLE_LIST_TAGS, NESTABLE_TABLE_TAGS)
-
-class ICantBelieveItsBeautifulSoup(BeautifulSoup):
-
- """The BeautifulSoup class is oriented towards skipping over
- common HTML errors like unclosed tags. However, sometimes it makes
- errors of its own. For instance, consider this fragment:
-
- FooBar
-
- This is perfectly valid (if bizarre) HTML. However, the
- BeautifulSoup class will implicitly close the first b tag when it
- encounters the second 'b'. It will think the author wrote
- "FooBar", and didn't close the first 'b' tag, because
- there's no real-world reason to bold something that's already
- bold. When it encounters '' it will close two more 'b'
- tags, for a grand total of three tags closed instead of two. This
- can throw off the rest of your document structure. The same is
- true of a number of other tags, listed below.
-
- It's much more common for someone to forget to close (eg.) a 'b'
- tag than to actually use nested 'b' tags, and the BeautifulSoup
- class handles the common case. This class handles the
- not-co-common case: where you can't believe someone wrote what
- they did, but it's valid HTML and BeautifulSoup screwed up by
- assuming it wouldn't be.
-
- If this doesn't do what you need, try subclassing this class or
- BeautifulSoup, and providing your own list of NESTABLE_TAGS."""
-
- I_CANT_BELIEVE_THEYRE_NESTABLE_INLINE_TAGS = \
- ['em', 'big', 'i', 'small', 'tt', 'abbr', 'acronym', 'strong',
- 'cite', 'code', 'dfn', 'kbd', 'samp', 'strong', 'var', 'b',
- 'big']
-
- I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS = ['noscript']
-
- NESTABLE_TAGS = buildTagMap([], BeautifulSoup.NESTABLE_TAGS,
- I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS,
- I_CANT_BELIEVE_THEYRE_NESTABLE_INLINE_TAGS)
-
-class BeautifulSOAP(BeautifulStoneSoup):
- """This class will push a tag with only a single string child into
- the tag's parent as an attribute. The attribute's name is the tag
- name, and the value is the string child. An example should give
- the flavor of the change:
-
- baz
- =>
- baz
-
- You can then access fooTag['bar'] instead of fooTag.barTag.string.
-
- This is, of course, useful for scraping structures that tend to
- use subelements instead of attributes, such as SOAP messages. Note
- that it modifies its input, so don't print the modified version
- out.
-
- I'm not sure how many people really want to use this class; let me
- know if you do. Mainly I like the name."""
-
- def popTag(self):
- if len(self.tagStack) > 1:
- tag = self.tagStack[-1]
- parent = self.tagStack[-2]
- parent._getAttrMap()
- if (isinstance(tag, Tag) and len(tag.contents) == 1 and
- isinstance(tag.contents[0], NavigableText) and
- not parent.attrMap.has_key(tag.name)):
- parent[tag.name] = tag.contents[0]
- BeautifulStoneSoup.popTag(self)
-
-#Enterprise class names! It has come to our attention that some people
-#think the names of the Beautiful Soup parser classes are too silly
-#and "unprofessional" for use in enterprise screen-scraping. We feel
-#your pain! For such-minded folk, the Beautiful Soup Consortium And
-#All-Night Kosher Bakery recommends renaming this file to
-#"RobustParser.py" (or, in cases of extreme enterprisitude,
-#"RobustParserBeanInterface.class") and using the following
-#enterprise-friendly class aliases:
-class RobustXMLParser(BeautifulStoneSoup):
- pass
-class RobustHTMLParser(BeautifulSoup):
- pass
-class RobustWackAssHTMLParser(ICantBelieveItsBeautifulSoup):
- pass
-class SimplifyingSOAPParser(BeautifulSOAP):
- pass
-
-###
-
-
-#By default, act as an HTML pretty-printer.
-if __name__ == '__main__':
- import sys
- soup = BeautifulStoneSoup(sys.stdin.read())
- print soup.prettify()
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_clientcookie.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_clientcookie.py
deleted file mode 100644
index 2ed4c878271a11bf564b0a64b377fd8a7fbe6a2a..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_clientcookie.py
+++ /dev/null
@@ -1,1725 +0,0 @@
-"""HTTP cookie handling for web clients.
-
-This module originally developed from my port of Gisle Aas' Perl module
-HTTP::Cookies, from the libwww-perl library.
-
-Docstrings, comments and debug strings in this code refer to the
-attributes of the HTTP cookie system as cookie-attributes, to distinguish
-them clearly from Python attributes.
-
- CookieJar____
- / \ \
- FileCookieJar \ \
- / | \ \ \
- MozillaCookieJar | LWPCookieJar \ \
- | | \
- | ---MSIEBase | \
- | / | | \
- | / MSIEDBCookieJar BSDDBCookieJar
- |/
- MSIECookieJar
-
-Comments to John J Lee .
-
-
-Copyright 2002-2006 John J Lee
-Copyright 1997-1999 Gisle Aas (original libwww-perl code)
-Copyright 2002-2003 Johnny Lee (original MSIE Perl code)
-
-This code is free software; you can redistribute it and/or modify it
-under the terms of the BSD or ZPL 2.1 licenses (see the file
-COPYING.txt included with the distribution).
-
-"""
-
-import sys, re, copy, time, urllib, types, logging
-try:
- import threading
- _threading = threading; del threading
-except ImportError:
- import dummy_threading
- _threading = dummy_threading; del dummy_threading
-
-MISSING_FILENAME_TEXT = ("a filename was not supplied (nor was the CookieJar "
- "instance initialised with one)")
-DEFAULT_HTTP_PORT = "80"
-
-from _headersutil import split_header_words, parse_ns_headers
-from _util import isstringlike
-import _rfc3986
-
-debug = logging.getLogger("mechanize.cookies").debug
-
-
-def reraise_unmasked_exceptions(unmasked=()):
- # There are a few catch-all except: statements in this module, for
- # catching input that's bad in unexpected ways.
- # This function re-raises some exceptions we don't want to trap.
- import mechanize, warnings
- if not mechanize.USE_BARE_EXCEPT:
- raise
- unmasked = unmasked + (KeyboardInterrupt, SystemExit, MemoryError)
- etype = sys.exc_info()[0]
- if issubclass(etype, unmasked):
- raise
- # swallowed an exception
- import traceback, StringIO
- f = StringIO.StringIO()
- traceback.print_exc(None, f)
- msg = f.getvalue()
- warnings.warn("mechanize bug!\n%s" % msg, stacklevel=2)
-
-
-IPV4_RE = re.compile(r"\.\d+$")
-def is_HDN(text):
- """Return True if text is a host domain name."""
- # XXX
- # This may well be wrong. Which RFC is HDN defined in, if any (for
- # the purposes of RFC 2965)?
- # For the current implementation, what about IPv6? Remember to look
- # at other uses of IPV4_RE also, if change this.
- return not (IPV4_RE.search(text) or
- text == "" or
- text[0] == "." or text[-1] == ".")
-
-def domain_match(A, B):
- """Return True if domain A domain-matches domain B, according to RFC 2965.
-
- A and B may be host domain names or IP addresses.
-
- RFC 2965, section 1:
-
- Host names can be specified either as an IP address or a HDN string.
- Sometimes we compare one host name with another. (Such comparisons SHALL
- be case-insensitive.) Host A's name domain-matches host B's if
-
- * their host name strings string-compare equal; or
-
- * A is a HDN string and has the form NB, where N is a non-empty
- name string, B has the form .B', and B' is a HDN string. (So,
- x.y.com domain-matches .Y.com but not Y.com.)
-
- Note that domain-match is not a commutative operation: a.b.c.com
- domain-matches .c.com, but not the reverse.
-
- """
- # Note that, if A or B are IP addresses, the only relevant part of the
- # definition of the domain-match algorithm is the direct string-compare.
- A = A.lower()
- B = B.lower()
- if A == B:
- return True
- if not is_HDN(A):
- return False
- i = A.rfind(B)
- has_form_nb = not (i == -1 or i == 0)
- return (
- has_form_nb and
- B.startswith(".") and
- is_HDN(B[1:])
- )
-
-def liberal_is_HDN(text):
- """Return True if text is a sort-of-like a host domain name.
-
- For accepting/blocking domains.
-
- """
- return not IPV4_RE.search(text)
-
-def user_domain_match(A, B):
- """For blocking/accepting domains.
-
- A and B may be host domain names or IP addresses.
-
- """
- A = A.lower()
- B = B.lower()
- if not (liberal_is_HDN(A) and liberal_is_HDN(B)):
- if A == B:
- # equal IP addresses
- return True
- return False
- initial_dot = B.startswith(".")
- if initial_dot and A.endswith(B):
- return True
- if not initial_dot and A == B:
- return True
- return False
-
-cut_port_re = re.compile(r":\d+$")
-def request_host(request):
- """Return request-host, as defined by RFC 2965.
-
- Variation from RFC: returned value is lowercased, for convenient
- comparison.
-
- """
- url = request.get_full_url()
- host = _rfc3986.urlsplit(url)[1]
- if host is None:
- host = request.get_header("Host", "")
- # remove port, if present
- return cut_port_re.sub("", host, 1)
-
-def request_host_lc(request):
- return request_host(request).lower()
-
-def eff_request_host(request):
- """Return a tuple (request-host, effective request-host name)."""
- erhn = req_host = request_host(request)
- if req_host.find(".") == -1 and not IPV4_RE.search(req_host):
- erhn = req_host + ".local"
- return req_host, erhn
-
-def eff_request_host_lc(request):
- req_host, erhn = eff_request_host(request)
- return req_host.lower(), erhn.lower()
-
-def effective_request_host(request):
- """Return the effective request-host, as defined by RFC 2965."""
- return eff_request_host(request)[1]
-
-def request_path(request):
- """Return path component of request-URI, as defined by RFC 2965."""
- url = request.get_full_url()
- path = escape_path(_rfc3986.urlsplit(url)[2])
- if not path.startswith("/"):
- path = "/" + path
- return path
-
-def request_port(request):
- host = request.get_host()
- i = host.find(':')
- if i >= 0:
- port = host[i+1:]
- try:
- int(port)
- except ValueError:
- debug("nonnumeric port: '%s'", port)
- return None
- else:
- port = DEFAULT_HTTP_PORT
- return port
-
-def request_is_unverifiable(request):
- try:
- return request.is_unverifiable()
- except AttributeError:
- if hasattr(request, "unverifiable"):
- return request.unverifiable
- else:
- raise
-
-# Characters in addition to A-Z, a-z, 0-9, '_', '.', and '-' that don't
-# need to be escaped to form a valid HTTP URL (RFCs 2396 and 1738).
-HTTP_PATH_SAFE = "%/;:@&=+$,!~*'()"
-ESCAPED_CHAR_RE = re.compile(r"%([0-9a-fA-F][0-9a-fA-F])")
-def uppercase_escaped_char(match):
- return "%%%s" % match.group(1).upper()
-def escape_path(path):
- """Escape any invalid characters in HTTP URL, and uppercase all escapes."""
- # There's no knowing what character encoding was used to create URLs
- # containing %-escapes, but since we have to pick one to escape invalid
- # path characters, we pick UTF-8, as recommended in the HTML 4.0
- # specification:
- # http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.2.1
- # And here, kind of: draft-fielding-uri-rfc2396bis-03
- # (And in draft IRI specification: draft-duerst-iri-05)
- # (And here, for new URI schemes: RFC 2718)
- if isinstance(path, types.UnicodeType):
- path = path.encode("utf-8")
- path = urllib.quote(path, HTTP_PATH_SAFE)
- path = ESCAPED_CHAR_RE.sub(uppercase_escaped_char, path)
- return path
-
-def reach(h):
- """Return reach of host h, as defined by RFC 2965, section 1.
-
- The reach R of a host name H is defined as follows:
-
- * If
-
- - H is the host domain name of a host; and,
-
- - H has the form A.B; and
-
- - A has no embedded (that is, interior) dots; and
-
- - B has at least one embedded dot, or B is the string "local".
- then the reach of H is .B.
-
- * Otherwise, the reach of H is H.
-
- >>> reach("www.acme.com")
- '.acme.com'
- >>> reach("acme.com")
- 'acme.com'
- >>> reach("acme.local")
- '.local'
-
- """
- i = h.find(".")
- if i >= 0:
- #a = h[:i] # this line is only here to show what a is
- b = h[i+1:]
- i = b.find(".")
- if is_HDN(h) and (i >= 0 or b == "local"):
- return "."+b
- return h
-
-def is_third_party(request):
- """
-
- RFC 2965, section 3.3.6:
-
- An unverifiable transaction is to a third-party host if its request-
- host U does not domain-match the reach R of the request-host O in the
- origin transaction.
-
- """
- req_host = request_host_lc(request)
- # the origin request's request-host was stuffed into request by
- # _urllib2_support.AbstractHTTPHandler
- return not domain_match(req_host, reach(request.origin_req_host))
-
-
-try:
- all
-except NameError:
- # python 2.4
- def all(iterable):
- for x in iterable:
- if not x:
- return False
- return True
-
-
-class Cookie:
- """HTTP Cookie.
-
- This class represents both Netscape and RFC 2965 cookies.
-
- This is deliberately a very simple class. It just holds attributes. It's
- possible to construct Cookie instances that don't comply with the cookie
- standards. CookieJar.make_cookies is the factory function for Cookie
- objects -- it deals with cookie parsing, supplying defaults, and
- normalising to the representation used in this class. CookiePolicy is
- responsible for checking them to see whether they should be accepted from
- and returned to the server.
-
- version: integer;
- name: string;
- value: string (may be None);
- port: string; None indicates no attribute was supplied (e.g. "Port", rather
- than eg. "Port=80"); otherwise, a port string (eg. "80") or a port list
- string (e.g. "80,8080")
- port_specified: boolean; true if a value was supplied with the Port
- cookie-attribute
- domain: string;
- domain_specified: boolean; true if Domain was explicitly set
- domain_initial_dot: boolean; true if Domain as set in HTTP header by server
- started with a dot (yes, this really is necessary!)
- path: string;
- path_specified: boolean; true if Path was explicitly set
- secure: boolean; true if should only be returned over secure connection
- expires: integer; seconds since epoch (RFC 2965 cookies should calculate
- this value from the Max-Age attribute)
- discard: boolean, true if this is a session cookie; (if no expires value,
- this should be true)
- comment: string;
- comment_url: string;
- rfc2109: boolean; true if cookie arrived in a Set-Cookie: (not
- Set-Cookie2:) header, but had a version cookie-attribute of 1
- rest: mapping of other cookie-attributes
-
- Note that the port may be present in the headers, but unspecified ("Port"
- rather than"Port=80", for example); if this is the case, port is None.
-
- """
-
-
- _attrs = ("version", "name", "value",
- "port", "port_specified",
- "domain", "domain_specified", "domain_initial_dot",
- "path", "path_specified",
- "secure", "expires", "discard", "comment", "comment_url",
- "rfc2109", "_rest")
-
- def __init__(self, version, name, value,
- port, port_specified,
- domain, domain_specified, domain_initial_dot,
- path, path_specified,
- secure,
- expires,
- discard,
- comment,
- comment_url,
- rest,
- rfc2109=False,
- ):
-
- if version is not None: version = int(version)
- if expires is not None: expires = int(expires)
- if port is None and port_specified is True:
- raise ValueError("if port is None, port_specified must be false")
-
- self.version = version
- self.name = name
- self.value = value
- self.port = port
- self.port_specified = port_specified
- # normalise case, as per RFC 2965 section 3.3.3
- self.domain = domain.lower()
- self.domain_specified = domain_specified
- # Sigh. We need to know whether the domain given in the
- # cookie-attribute had an initial dot, in order to follow RFC 2965
- # (as clarified in draft errata). Needed for the returned $Domain
- # value.
- self.domain_initial_dot = domain_initial_dot
- self.path = path
- self.path_specified = path_specified
- self.secure = secure
- self.expires = expires
- self.discard = discard
- self.comment = comment
- self.comment_url = comment_url
- self.rfc2109 = rfc2109
-
- self._rest = copy.copy(rest)
-
- def has_nonstandard_attr(self, name):
- return self._rest.has_key(name)
- def get_nonstandard_attr(self, name, default=None):
- return self._rest.get(name, default)
- def set_nonstandard_attr(self, name, value):
- self._rest[name] = value
- def nonstandard_attr_keys(self):
- return self._rest.keys()
-
- def is_expired(self, now=None):
- if now is None: now = time.time()
- return (self.expires is not None) and (self.expires <= now)
-
- def __eq__(self, other):
- return all(getattr(self, a) == getattr(other, a) for a in self._attrs)
-
- def __ne__(self, other):
- return not (self == other)
-
- def __str__(self):
- if self.port is None: p = ""
- else: p = ":"+self.port
- limit = self.domain + p + self.path
- if self.value is not None:
- namevalue = "%s=%s" % (self.name, self.value)
- else:
- namevalue = self.name
- return "" % (namevalue, limit)
-
- def __repr__(self):
- args = []
- for name in ["version", "name", "value",
- "port", "port_specified",
- "domain", "domain_specified", "domain_initial_dot",
- "path", "path_specified",
- "secure", "expires", "discard", "comment", "comment_url",
- ]:
- attr = getattr(self, name)
- args.append("%s=%s" % (name, repr(attr)))
- args.append("rest=%s" % repr(self._rest))
- args.append("rfc2109=%s" % repr(self.rfc2109))
- return "Cookie(%s)" % ", ".join(args)
-
-
-class CookiePolicy:
- """Defines which cookies get accepted from and returned to server.
-
- May also modify cookies.
-
- The subclass DefaultCookiePolicy defines the standard rules for Netscape
- and RFC 2965 cookies -- override that if you want a customised policy.
-
- As well as implementing set_ok and return_ok, implementations of this
- interface must also supply the following attributes, indicating which
- protocols should be used, and how. These can be read and set at any time,
- though whether that makes complete sense from the protocol point of view is
- doubtful.
-
- Public attributes:
-
- netscape: implement netscape protocol
- rfc2965: implement RFC 2965 protocol
- rfc2109_as_netscape:
- WARNING: This argument will change or go away if is not accepted into
- the Python standard library in this form!
- If true, treat RFC 2109 cookies as though they were Netscape cookies. The
- default is for this attribute to be None, which means treat 2109 cookies
- as RFC 2965 cookies unless RFC 2965 handling is switched off (which it is,
- by default), and as Netscape cookies otherwise.
- hide_cookie2: don't add Cookie2 header to requests (the presence of
- this header indicates to the server that we understand RFC 2965
- cookies)
-
- """
- def set_ok(self, cookie, request):
- """Return true if (and only if) cookie should be accepted from server.
-
- Currently, pre-expired cookies never get this far -- the CookieJar
- class deletes such cookies itself.
-
- cookie: mechanize.Cookie object
- request: object implementing the interface defined by
- CookieJar.extract_cookies.__doc__
-
- """
- raise NotImplementedError()
-
- def return_ok(self, cookie, request):
- """Return true if (and only if) cookie should be returned to server.
-
- cookie: mechanize.Cookie object
- request: object implementing the interface defined by
- CookieJar.add_cookie_header.__doc__
-
- """
- raise NotImplementedError()
-
- def domain_return_ok(self, domain, request):
- """Return false if cookies should not be returned, given cookie domain.
-
- This is here as an optimization, to remove the need for checking every
- cookie with a particular domain (which may involve reading many files).
- The default implementations of domain_return_ok and path_return_ok
- (return True) leave all the work to return_ok.
-
- If domain_return_ok returns true for the cookie domain, path_return_ok
- is called for the cookie path. Otherwise, path_return_ok and return_ok
- are never called for that cookie domain. If path_return_ok returns
- true, return_ok is called with the Cookie object itself for a full
- check. Otherwise, return_ok is never called for that cookie path.
-
- Note that domain_return_ok is called for every *cookie* domain, not
- just for the *request* domain. For example, the function might be
- called with both ".acme.com" and "www.acme.com" if the request domain
- is "www.acme.com". The same goes for path_return_ok.
-
- For argument documentation, see the docstring for return_ok.
-
- """
- return True
-
- def path_return_ok(self, path, request):
- """Return false if cookies should not be returned, given cookie path.
-
- See the docstring for domain_return_ok.
-
- """
- return True
-
-
-class DefaultCookiePolicy(CookiePolicy):
- """Implements the standard rules for accepting and returning cookies.
-
- Both RFC 2965 and Netscape cookies are covered. RFC 2965 handling is
- switched off by default.
-
- The easiest way to provide your own policy is to override this class and
- call its methods in your overriden implementations before adding your own
- additional checks.
-
- import mechanize
- class MyCookiePolicy(mechanize.DefaultCookiePolicy):
- def set_ok(self, cookie, request):
- if not mechanize.DefaultCookiePolicy.set_ok(
- self, cookie, request):
- return False
- if i_dont_want_to_store_this_cookie():
- return False
- return True
-
- In addition to the features required to implement the CookiePolicy
- interface, this class allows you to block and allow domains from setting
- and receiving cookies. There are also some strictness switches that allow
- you to tighten up the rather loose Netscape protocol rules a little bit (at
- the cost of blocking some benign cookies).
-
- A domain blacklist and whitelist is provided (both off by default). Only
- domains not in the blacklist and present in the whitelist (if the whitelist
- is active) participate in cookie setting and returning. Use the
- blocked_domains constructor argument, and blocked_domains and
- set_blocked_domains methods (and the corresponding argument and methods for
- allowed_domains). If you set a whitelist, you can turn it off again by
- setting it to None.
-
- Domains in block or allow lists that do not start with a dot must
- string-compare equal. For example, "acme.com" matches a blacklist entry of
- "acme.com", but "www.acme.com" does not. Domains that do start with a dot
- are matched by more specific domains too. For example, both "www.acme.com"
- and "www.munitions.acme.com" match ".acme.com" (but "acme.com" itself does
- not). IP addresses are an exception, and must match exactly. For example,
- if blocked_domains contains "192.168.1.2" and ".168.1.2" 192.168.1.2 is
- blocked, but 193.168.1.2 is not.
-
- Additional Public Attributes:
-
- General strictness switches
-
- strict_domain: don't allow sites to set two-component domains with
- country-code top-level domains like .co.uk, .gov.uk, .co.nz. etc.
- This is far from perfect and isn't guaranteed to work!
-
- RFC 2965 protocol strictness switches
-
- strict_rfc2965_unverifiable: follow RFC 2965 rules on unverifiable
- transactions (usually, an unverifiable transaction is one resulting from
- a redirect or an image hosted on another site); if this is false, cookies
- are NEVER blocked on the basis of verifiability
-
- Netscape protocol strictness switches
-
- strict_ns_unverifiable: apply RFC 2965 rules on unverifiable transactions
- even to Netscape cookies
- strict_ns_domain: flags indicating how strict to be with domain-matching
- rules for Netscape cookies:
- DomainStrictNoDots: when setting cookies, host prefix must not contain a
- dot (e.g. www.foo.bar.com can't set a cookie for .bar.com, because
- www.foo contains a dot)
- DomainStrictNonDomain: cookies that did not explicitly specify a Domain
- cookie-attribute can only be returned to a domain that string-compares
- equal to the domain that set the cookie (e.g. rockets.acme.com won't
- be returned cookies from acme.com that had no Domain cookie-attribute)
- DomainRFC2965Match: when setting cookies, require a full RFC 2965
- domain-match
- DomainLiberal and DomainStrict are the most useful combinations of the
- above flags, for convenience
- strict_ns_set_initial_dollar: ignore cookies in Set-Cookie: headers that
- have names starting with '$'
- strict_ns_set_path: don't allow setting cookies whose path doesn't
- path-match request URI
-
- """
-
- DomainStrictNoDots = 1
- DomainStrictNonDomain = 2
- DomainRFC2965Match = 4
-
- DomainLiberal = 0
- DomainStrict = DomainStrictNoDots|DomainStrictNonDomain
-
- def __init__(self,
- blocked_domains=None, allowed_domains=None,
- netscape=True, rfc2965=False,
- # WARNING: this argument will change or go away if is not
- # accepted into the Python standard library in this form!
- # default, ie. treat 2109 as netscape iff not rfc2965
- rfc2109_as_netscape=None,
- hide_cookie2=False,
- strict_domain=False,
- strict_rfc2965_unverifiable=True,
- strict_ns_unverifiable=False,
- strict_ns_domain=DomainLiberal,
- strict_ns_set_initial_dollar=False,
- strict_ns_set_path=False,
- ):
- """
- Constructor arguments should be used as keyword arguments only.
-
- blocked_domains: sequence of domain names that we never accept cookies
- from, nor return cookies to
- allowed_domains: if not None, this is a sequence of the only domains
- for which we accept and return cookies
-
- For other arguments, see CookiePolicy.__doc__ and
- DefaultCookiePolicy.__doc__..
-
- """
- self.netscape = netscape
- self.rfc2965 = rfc2965
- self.rfc2109_as_netscape = rfc2109_as_netscape
- self.hide_cookie2 = hide_cookie2
- self.strict_domain = strict_domain
- self.strict_rfc2965_unverifiable = strict_rfc2965_unverifiable
- self.strict_ns_unverifiable = strict_ns_unverifiable
- self.strict_ns_domain = strict_ns_domain
- self.strict_ns_set_initial_dollar = strict_ns_set_initial_dollar
- self.strict_ns_set_path = strict_ns_set_path
-
- if blocked_domains is not None:
- self._blocked_domains = tuple(blocked_domains)
- else:
- self._blocked_domains = ()
-
- if allowed_domains is not None:
- allowed_domains = tuple(allowed_domains)
- self._allowed_domains = allowed_domains
-
- def blocked_domains(self):
- """Return the sequence of blocked domains (as a tuple)."""
- return self._blocked_domains
- def set_blocked_domains(self, blocked_domains):
- """Set the sequence of blocked domains."""
- self._blocked_domains = tuple(blocked_domains)
-
- def is_blocked(self, domain):
- for blocked_domain in self._blocked_domains:
- if user_domain_match(domain, blocked_domain):
- return True
- return False
-
- def allowed_domains(self):
- """Return None, or the sequence of allowed domains (as a tuple)."""
- return self._allowed_domains
- def set_allowed_domains(self, allowed_domains):
- """Set the sequence of allowed domains, or None."""
- if allowed_domains is not None:
- allowed_domains = tuple(allowed_domains)
- self._allowed_domains = allowed_domains
-
- def is_not_allowed(self, domain):
- if self._allowed_domains is None:
- return False
- for allowed_domain in self._allowed_domains:
- if user_domain_match(domain, allowed_domain):
- return False
- return True
-
- def set_ok(self, cookie, request):
- """
- If you override set_ok, be sure to call this method. If it returns
- false, so should your subclass (assuming your subclass wants to be more
- strict about which cookies to accept).
-
- """
- debug(" - checking cookie %s", cookie)
-
- assert cookie.name is not None
-
- for n in "version", "verifiability", "name", "path", "domain", "port":
- fn_name = "set_ok_"+n
- fn = getattr(self, fn_name)
- if not fn(cookie, request):
- return False
-
- return True
-
- def set_ok_version(self, cookie, request):
- if cookie.version is None:
- # Version is always set to 0 by parse_ns_headers if it's a Netscape
- # cookie, so this must be an invalid RFC 2965 cookie.
- debug(" Set-Cookie2 without version attribute (%s)", cookie)
- return False
- if cookie.version > 0 and not self.rfc2965:
- debug(" RFC 2965 cookies are switched off")
- return False
- elif cookie.version == 0 and not self.netscape:
- debug(" Netscape cookies are switched off")
- return False
- return True
-
- def set_ok_verifiability(self, cookie, request):
- if request_is_unverifiable(request) and is_third_party(request):
- if cookie.version > 0 and self.strict_rfc2965_unverifiable:
- debug(" third-party RFC 2965 cookie during "
- "unverifiable transaction")
- return False
- elif cookie.version == 0 and self.strict_ns_unverifiable:
- debug(" third-party Netscape cookie during "
- "unverifiable transaction")
- return False
- return True
-
- def set_ok_name(self, cookie, request):
- # Try and stop servers setting V0 cookies designed to hack other
- # servers that know both V0 and V1 protocols.
- if (cookie.version == 0 and self.strict_ns_set_initial_dollar and
- cookie.name.startswith("$")):
- debug(" illegal name (starts with '$'): '%s'", cookie.name)
- return False
- return True
-
- def set_ok_path(self, cookie, request):
- if cookie.path_specified:
- req_path = request_path(request)
- if ((cookie.version > 0 or
- (cookie.version == 0 and self.strict_ns_set_path)) and
- not req_path.startswith(cookie.path)):
- debug(" path attribute %s is not a prefix of request "
- "path %s", cookie.path, req_path)
- return False
- return True
-
- def set_ok_countrycode_domain(self, cookie, request):
- """Return False if explicit cookie domain is not acceptable.
-
- Called by set_ok_domain, for convenience of overriding by
- subclasses.
-
- """
- if cookie.domain_specified and self.strict_domain:
- domain = cookie.domain
- # since domain was specified, we know that:
- assert domain.startswith(".")
- if domain.count(".") == 2:
- # domain like .foo.bar
- i = domain.rfind(".")
- tld = domain[i+1:]
- sld = domain[1:i]
- if (sld.lower() in [
- "co", "ac",
- "com", "edu", "org", "net", "gov", "mil", "int",
- "aero", "biz", "cat", "coop", "info", "jobs", "mobi",
- "museum", "name", "pro", "travel",
- ] and
- len(tld) == 2):
- # domain like .co.uk
- return False
- return True
-
- def set_ok_domain(self, cookie, request):
- if self.is_blocked(cookie.domain):
- debug(" domain %s is in user block-list", cookie.domain)
- return False
- if self.is_not_allowed(cookie.domain):
- debug(" domain %s is not in user allow-list", cookie.domain)
- return False
- if not self.set_ok_countrycode_domain(cookie, request):
- debug(" country-code second level domain %s", cookie.domain)
- return False
- if cookie.domain_specified:
- req_host, erhn = eff_request_host_lc(request)
- domain = cookie.domain
- if domain.startswith("."):
- undotted_domain = domain[1:]
- else:
- undotted_domain = domain
- embedded_dots = (undotted_domain.find(".") >= 0)
- if not embedded_dots and domain != ".local":
- debug(" non-local domain %s contains no embedded dot",
- domain)
- return False
- if cookie.version == 0:
- if (not erhn.endswith(domain) and
- (not erhn.startswith(".") and
- not ("."+erhn).endswith(domain))):
- debug(" effective request-host %s (even with added "
- "initial dot) does not end end with %s",
- erhn, domain)
- return False
- if (cookie.version > 0 or
- (self.strict_ns_domain & self.DomainRFC2965Match)):
- if not domain_match(erhn, domain):
- debug(" effective request-host %s does not domain-match "
- "%s", erhn, domain)
- return False
- if (cookie.version > 0 or
- (self.strict_ns_domain & self.DomainStrictNoDots)):
- host_prefix = req_host[:-len(domain)]
- if (host_prefix.find(".") >= 0 and
- not IPV4_RE.search(req_host)):
- debug(" host prefix %s for domain %s contains a dot",
- host_prefix, domain)
- return False
- return True
-
- def set_ok_port(self, cookie, request):
- if cookie.port_specified:
- req_port = request_port(request)
- if req_port is None:
- req_port = "80"
- else:
- req_port = str(req_port)
- for p in cookie.port.split(","):
- try:
- int(p)
- except ValueError:
- debug(" bad port %s (not numeric)", p)
- return False
- if p == req_port:
- break
- else:
- debug(" request port (%s) not found in %s",
- req_port, cookie.port)
- return False
- return True
-
- def return_ok(self, cookie, request):
- """
- If you override return_ok, be sure to call this method. If it returns
- false, so should your subclass (assuming your subclass wants to be more
- strict about which cookies to return).
-
- """
- # Path has already been checked by path_return_ok, and domain blocking
- # done by domain_return_ok.
- debug(" - checking cookie %s", cookie)
-
- for n in ("version", "verifiability", "secure", "expires", "port",
- "domain"):
- fn_name = "return_ok_"+n
- fn = getattr(self, fn_name)
- if not fn(cookie, request):
- return False
- return True
-
- def return_ok_version(self, cookie, request):
- if cookie.version > 0 and not self.rfc2965:
- debug(" RFC 2965 cookies are switched off")
- return False
- elif cookie.version == 0 and not self.netscape:
- debug(" Netscape cookies are switched off")
- return False
- return True
-
- def return_ok_verifiability(self, cookie, request):
- if request_is_unverifiable(request) and is_third_party(request):
- if cookie.version > 0 and self.strict_rfc2965_unverifiable:
- debug(" third-party RFC 2965 cookie during unverifiable "
- "transaction")
- return False
- elif cookie.version == 0 and self.strict_ns_unverifiable:
- debug(" third-party Netscape cookie during unverifiable "
- "transaction")
- return False
- return True
-
- def return_ok_secure(self, cookie, request):
- if cookie.secure and request.get_type() != "https":
- debug(" secure cookie with non-secure request")
- return False
- return True
-
- def return_ok_expires(self, cookie, request):
- if cookie.is_expired(self._now):
- debug(" cookie expired")
- return False
- return True
-
- def return_ok_port(self, cookie, request):
- if cookie.port:
- req_port = request_port(request)
- if req_port is None:
- req_port = "80"
- for p in cookie.port.split(","):
- if p == req_port:
- break
- else:
- debug(" request port %s does not match cookie port %s",
- req_port, cookie.port)
- return False
- return True
-
- def return_ok_domain(self, cookie, request):
- req_host, erhn = eff_request_host_lc(request)
- domain = cookie.domain
-
- # strict check of non-domain cookies: Mozilla does this, MSIE5 doesn't
- if (cookie.version == 0 and
- (self.strict_ns_domain & self.DomainStrictNonDomain) and
- not cookie.domain_specified and domain != erhn):
- debug(" cookie with unspecified domain does not string-compare "
- "equal to request domain")
- return False
-
- if cookie.version > 0 and not domain_match(erhn, domain):
- debug(" effective request-host name %s does not domain-match "
- "RFC 2965 cookie domain %s", erhn, domain)
- return False
- if cookie.version == 0 and not ("."+erhn).endswith(domain):
- debug(" request-host %s does not match Netscape cookie domain "
- "%s", req_host, domain)
- return False
- return True
-
- def domain_return_ok(self, domain, request):
- # Liberal check of domain. This is here as an optimization to avoid
- # having to load lots of MSIE cookie files unless necessary.
-
- # Munge req_host and erhn to always start with a dot, so as to err on
- # the side of letting cookies through.
- dotted_req_host, dotted_erhn = eff_request_host_lc(request)
- if not dotted_req_host.startswith("."):
- dotted_req_host = "."+dotted_req_host
- if not dotted_erhn.startswith("."):
- dotted_erhn = "."+dotted_erhn
- if not (dotted_req_host.endswith(domain) or
- dotted_erhn.endswith(domain)):
- #debug(" request domain %s does not match cookie domain %s",
- # req_host, domain)
- return False
-
- if self.is_blocked(domain):
- debug(" domain %s is in user block-list", domain)
- return False
- if self.is_not_allowed(domain):
- debug(" domain %s is not in user allow-list", domain)
- return False
-
- return True
-
- def path_return_ok(self, path, request):
- debug("- checking cookie path=%s", path)
- req_path = request_path(request)
- if not req_path.startswith(path):
- debug(" %s does not path-match %s", req_path, path)
- return False
- return True
-
-
-def vals_sorted_by_key(adict):
- keys = adict.keys()
- keys.sort()
- return map(adict.get, keys)
-
-class MappingIterator:
- """Iterates over nested mapping, depth-first, in sorted order by key."""
- def __init__(self, mapping):
- self._s = [(vals_sorted_by_key(mapping), 0, None)] # LIFO stack
-
- def __iter__(self): return self
-
- def next(self):
- # this is hairy because of lack of generators
- while 1:
- try:
- vals, i, prev_item = self._s.pop()
- except IndexError:
- raise StopIteration()
- if i < len(vals):
- item = vals[i]
- i = i + 1
- self._s.append((vals, i, prev_item))
- try:
- item.items
- except AttributeError:
- # non-mapping
- break
- else:
- # mapping
- self._s.append((vals_sorted_by_key(item), 0, item))
- continue
- return item
-
-
-# Used as second parameter to dict.get method, to distinguish absent
-# dict key from one with a None value.
-class Absent: pass
-
-class CookieJar:
- """Collection of HTTP cookies.
-
- You may not need to know about this class: try mechanize.urlopen().
-
- The major methods are extract_cookies and add_cookie_header; these are all
- you are likely to need.
-
- CookieJar supports the iterator protocol:
-
- for cookie in cookiejar:
- # do something with cookie
-
- Methods:
-
- add_cookie_header(request)
- extract_cookies(response, request)
- get_policy()
- set_policy(policy)
- cookies_for_request(request)
- make_cookies(response, request)
- set_cookie_if_ok(cookie, request)
- set_cookie(cookie)
- clear_session_cookies()
- clear_expired_cookies()
- clear(domain=None, path=None, name=None)
-
- Public attributes
-
- policy: CookiePolicy object
-
- """
-
- non_word_re = re.compile(r"\W")
- quote_re = re.compile(r"([\"\\])")
- strict_domain_re = re.compile(r"\.?[^.]*")
- domain_re = re.compile(r"[^.]*")
- dots_re = re.compile(r"^\.+")
-
- def __init__(self, policy=None):
- """
- See CookieJar.__doc__ for argument documentation.
-
- """
- if policy is None:
- policy = DefaultCookiePolicy()
- self._policy = policy
-
- self._cookies = {}
-
- # for __getitem__ iteration in pre-2.2 Pythons
- self._prev_getitem_index = 0
-
- def get_policy(self):
- return self._policy
-
- def set_policy(self, policy):
- self._policy = policy
-
- def _cookies_for_domain(self, domain, request):
- cookies = []
- if not self._policy.domain_return_ok(domain, request):
- return []
- debug("Checking %s for cookies to return", domain)
- cookies_by_path = self._cookies[domain]
- for path in cookies_by_path.keys():
- if not self._policy.path_return_ok(path, request):
- continue
- cookies_by_name = cookies_by_path[path]
- for cookie in cookies_by_name.values():
- if not self._policy.return_ok(cookie, request):
- debug(" not returning cookie")
- continue
- debug(" it's a match")
- cookies.append(cookie)
- return cookies
-
- def cookies_for_request(self, request):
- """Return a list of cookies to be returned to server.
-
- The returned list of cookie instances is sorted in the order they
- should appear in the Cookie: header for return to the server.
-
- See add_cookie_header.__doc__ for the interface required of the
- request argument.
-
- New in version 0.1.10
-
- """
- self._policy._now = self._now = int(time.time())
- cookies = self._cookies_for_request(request)
- # add cookies in order of most specific (i.e. longest) path first
- def decreasing_size(a, b): return cmp(len(b.path), len(a.path))
- cookies.sort(decreasing_size)
- return cookies
-
- def _cookies_for_request(self, request):
- """Return a list of cookies to be returned to server."""
- # this method still exists (alongside cookies_for_request) because it
- # is part of an implied protected interface for subclasses of cookiejar
- # XXX document that implied interface, or provide another way of
- # implementing cookiejars than subclassing
- cookies = []
- for domain in self._cookies.keys():
- cookies.extend(self._cookies_for_domain(domain, request))
- return cookies
-
- def _cookie_attrs(self, cookies):
- """Return a list of cookie-attributes to be returned to server.
-
- The $Version attribute is also added when appropriate (currently only
- once per request).
-
- >>> jar = CookieJar()
- >>> ns_cookie = Cookie(0, "foo", '"bar"', None, False,
- ... "example.com", False, False,
- ... "/", False, False, None, True,
- ... None, None, {})
- >>> jar._cookie_attrs([ns_cookie])
- ['foo="bar"']
- >>> rfc2965_cookie = Cookie(1, "foo", "bar", None, False,
- ... ".example.com", True, False,
- ... "/", False, False, None, True,
- ... None, None, {})
- >>> jar._cookie_attrs([rfc2965_cookie])
- ['$Version=1', 'foo=bar', '$Domain="example.com"']
-
- """
- version_set = False
-
- attrs = []
- for cookie in cookies:
- # set version of Cookie header
- # XXX
- # What should it be if multiple matching Set-Cookie headers have
- # different versions themselves?
- # Answer: there is no answer; was supposed to be settled by
- # RFC 2965 errata, but that may never appear...
- version = cookie.version
- if not version_set:
- version_set = True
- if version > 0:
- attrs.append("$Version=%s" % version)
-
- # quote cookie value if necessary
- # (not for Netscape protocol, which already has any quotes
- # intact, due to the poorly-specified Netscape Cookie: syntax)
- if ((cookie.value is not None) and
- self.non_word_re.search(cookie.value) and version > 0):
- value = self.quote_re.sub(r"\\\1", cookie.value)
- else:
- value = cookie.value
-
- # add cookie-attributes to be returned in Cookie header
- if cookie.value is None:
- attrs.append(cookie.name)
- else:
- attrs.append("%s=%s" % (cookie.name, value))
- if version > 0:
- if cookie.path_specified:
- attrs.append('$Path="%s"' % cookie.path)
- if cookie.domain.startswith("."):
- domain = cookie.domain
- if (not cookie.domain_initial_dot and
- domain.startswith(".")):
- domain = domain[1:]
- attrs.append('$Domain="%s"' % domain)
- if cookie.port is not None:
- p = "$Port"
- if cookie.port_specified:
- p = p + ('="%s"' % cookie.port)
- attrs.append(p)
-
- return attrs
-
- def add_cookie_header(self, request):
- """Add correct Cookie: header to request (mechanize.Request object).
-
- The Cookie2 header is also added unless policy.hide_cookie2 is true.
-
- The request object (usually a mechanize.Request instance) must support
- the methods get_full_url, get_host, is_unverifiable, get_type,
- has_header, get_header, header_items and add_unredirected_header, as
- documented by urllib2.
- """
- debug("add_cookie_header")
- cookies = self.cookies_for_request(request)
-
- attrs = self._cookie_attrs(cookies)
- if attrs:
- if not request.has_header("Cookie"):
- request.add_unredirected_header("Cookie", "; ".join(attrs))
-
- # if necessary, advertise that we know RFC 2965
- if self._policy.rfc2965 and not self._policy.hide_cookie2:
- for cookie in cookies:
- if cookie.version != 1 and not request.has_header("Cookie2"):
- request.add_unredirected_header("Cookie2", '$Version="1"')
- break
-
- self.clear_expired_cookies()
-
- def _normalized_cookie_tuples(self, attrs_set):
- """Return list of tuples containing normalised cookie information.
-
- attrs_set is the list of lists of key,value pairs extracted from
- the Set-Cookie or Set-Cookie2 headers.
-
- Tuples are name, value, standard, rest, where name and value are the
- cookie name and value, standard is a dictionary containing the standard
- cookie-attributes (discard, secure, version, expires or max-age,
- domain, path and port) and rest is a dictionary containing the rest of
- the cookie-attributes.
-
- """
- cookie_tuples = []
-
- boolean_attrs = "discard", "secure"
- value_attrs = ("version",
- "expires", "max-age",
- "domain", "path", "port",
- "comment", "commenturl")
-
- for cookie_attrs in attrs_set:
- name, value = cookie_attrs[0]
-
- # Build dictionary of standard cookie-attributes (standard) and
- # dictionary of other cookie-attributes (rest).
-
- # Note: expiry time is normalised to seconds since epoch. V0
- # cookies should have the Expires cookie-attribute, and V1 cookies
- # should have Max-Age, but since V1 includes RFC 2109 cookies (and
- # since V0 cookies may be a mish-mash of Netscape and RFC 2109), we
- # accept either (but prefer Max-Age).
- max_age_set = False
-
- bad_cookie = False
-
- standard = {}
- rest = {}
- for k, v in cookie_attrs[1:]:
- lc = k.lower()
- # don't lose case distinction for unknown fields
- if lc in value_attrs or lc in boolean_attrs:
- k = lc
- if k in boolean_attrs and v is None:
- # boolean cookie-attribute is present, but has no value
- # (like "discard", rather than "port=80")
- v = True
- if standard.has_key(k):
- # only first value is significant
- continue
- if k == "domain":
- if v is None:
- debug(" missing value for domain attribute")
- bad_cookie = True
- break
- # RFC 2965 section 3.3.3
- v = v.lower()
- if k == "expires":
- if max_age_set:
- # Prefer max-age to expires (like Mozilla)
- continue
- if v is None:
- debug(" missing or invalid value for expires "
- "attribute: treating as session cookie")
- continue
- if k == "max-age":
- max_age_set = True
- if v is None:
- debug(" missing value for max-age attribute")
- bad_cookie = True
- break
- try:
- v = int(v)
- except ValueError:
- debug(" missing or invalid (non-numeric) value for "
- "max-age attribute")
- bad_cookie = True
- break
- # convert RFC 2965 Max-Age to seconds since epoch
- # XXX Strictly you're supposed to follow RFC 2616
- # age-calculation rules. Remember that zero Max-Age is a
- # is a request to discard (old and new) cookie, though.
- k = "expires"
- v = self._now + v
- if (k in value_attrs) or (k in boolean_attrs):
- if (v is None and
- k not in ["port", "comment", "commenturl"]):
- debug(" missing value for %s attribute" % k)
- bad_cookie = True
- break
- standard[k] = v
- else:
- rest[k] = v
-
- if bad_cookie:
- continue
-
- cookie_tuples.append((name, value, standard, rest))
-
- return cookie_tuples
-
- def _cookie_from_cookie_tuple(self, tup, request):
- # standard is dict of standard cookie-attributes, rest is dict of the
- # rest of them
- name, value, standard, rest = tup
-
- domain = standard.get("domain", Absent)
- path = standard.get("path", Absent)
- port = standard.get("port", Absent)
- expires = standard.get("expires", Absent)
-
- # set the easy defaults
- version = standard.get("version", None)
- if version is not None:
- try:
- version = int(version)
- except ValueError:
- return None # invalid version, ignore cookie
- secure = standard.get("secure", False)
- # (discard is also set if expires is Absent)
- discard = standard.get("discard", False)
- comment = standard.get("comment", None)
- comment_url = standard.get("commenturl", None)
-
- # set default path
- if path is not Absent and path != "":
- path_specified = True
- path = escape_path(path)
- else:
- path_specified = False
- path = request_path(request)
- i = path.rfind("/")
- if i != -1:
- if version == 0:
- # Netscape spec parts company from reality here
- path = path[:i]
- else:
- path = path[:i+1]
- if len(path) == 0: path = "/"
-
- # set default domain
- domain_specified = domain is not Absent
- # but first we have to remember whether it starts with a dot
- domain_initial_dot = False
- if domain_specified:
- domain_initial_dot = bool(domain.startswith("."))
- if domain is Absent:
- req_host, erhn = eff_request_host_lc(request)
- domain = erhn
- elif not domain.startswith("."):
- domain = "."+domain
-
- # set default port
- port_specified = False
- if port is not Absent:
- if port is None:
- # Port attr present, but has no value: default to request port.
- # Cookie should then only be sent back on that port.
- port = request_port(request)
- else:
- port_specified = True
- port = re.sub(r"\s+", "", port)
- else:
- # No port attr present. Cookie can be sent back on any port.
- port = None
-
- # set default expires and discard
- if expires is Absent:
- expires = None
- discard = True
-
- return Cookie(version,
- name, value,
- port, port_specified,
- domain, domain_specified, domain_initial_dot,
- path, path_specified,
- secure,
- expires,
- discard,
- comment,
- comment_url,
- rest)
-
- def _cookies_from_attrs_set(self, attrs_set, request):
- cookie_tuples = self._normalized_cookie_tuples(attrs_set)
-
- cookies = []
- for tup in cookie_tuples:
- cookie = self._cookie_from_cookie_tuple(tup, request)
- if cookie: cookies.append(cookie)
- return cookies
-
- def _process_rfc2109_cookies(self, cookies):
- if self._policy.rfc2109_as_netscape is None:
- rfc2109_as_netscape = not self._policy.rfc2965
- else:
- rfc2109_as_netscape = self._policy.rfc2109_as_netscape
- for cookie in cookies:
- if cookie.version == 1:
- cookie.rfc2109 = True
- if rfc2109_as_netscape:
- # treat 2109 cookies as Netscape cookies rather than
- # as RFC2965 cookies
- cookie.version = 0
-
- def _make_cookies(self, response, request):
- # get cookie-attributes for RFC 2965 and Netscape protocols
- headers = response.info()
- rfc2965_hdrs = headers.getheaders("Set-Cookie2")
- ns_hdrs = headers.getheaders("Set-Cookie")
-
- rfc2965 = self._policy.rfc2965
- netscape = self._policy.netscape
-
- if ((not rfc2965_hdrs and not ns_hdrs) or
- (not ns_hdrs and not rfc2965) or
- (not rfc2965_hdrs and not netscape) or
- (not netscape and not rfc2965)):
- return [] # no relevant cookie headers: quick exit
-
- try:
- cookies = self._cookies_from_attrs_set(
- split_header_words(rfc2965_hdrs), request)
- except:
- reraise_unmasked_exceptions()
- cookies = []
-
- if ns_hdrs and netscape:
- try:
- # RFC 2109 and Netscape cookies
- ns_cookies = self._cookies_from_attrs_set(
- parse_ns_headers(ns_hdrs), request)
- except:
- reraise_unmasked_exceptions()
- ns_cookies = []
- self._process_rfc2109_cookies(ns_cookies)
-
- # Look for Netscape cookies (from Set-Cookie headers) that match
- # corresponding RFC 2965 cookies (from Set-Cookie2 headers).
- # For each match, keep the RFC 2965 cookie and ignore the Netscape
- # cookie (RFC 2965 section 9.1). Actually, RFC 2109 cookies are
- # bundled in with the Netscape cookies for this purpose, which is
- # reasonable behaviour.
- if rfc2965:
- lookup = {}
- for cookie in cookies:
- lookup[(cookie.domain, cookie.path, cookie.name)] = None
-
- def no_matching_rfc2965(ns_cookie, lookup=lookup):
- key = ns_cookie.domain, ns_cookie.path, ns_cookie.name
- return not lookup.has_key(key)
- ns_cookies = filter(no_matching_rfc2965, ns_cookies)
-
- if ns_cookies:
- cookies.extend(ns_cookies)
-
- return cookies
-
- def make_cookies(self, response, request):
- """Return sequence of Cookie objects extracted from response object.
-
- See extract_cookies.__doc__ for the interface required of the
- response and request arguments.
-
- """
- self._policy._now = self._now = int(time.time())
- return [cookie for cookie in self._make_cookies(response, request)
- if cookie.expires is None or not cookie.expires <= self._now]
-
- def set_cookie_if_ok(self, cookie, request):
- """Set a cookie if policy says it's OK to do so.
-
- cookie: mechanize.Cookie instance
- request: see extract_cookies.__doc__ for the required interface
-
- """
- self._policy._now = self._now = int(time.time())
-
- if self._policy.set_ok(cookie, request):
- self.set_cookie(cookie)
-
- def set_cookie(self, cookie):
- """Set a cookie, without checking whether or not it should be set.
-
- cookie: mechanize.Cookie instance
- """
- c = self._cookies
- if not c.has_key(cookie.domain): c[cookie.domain] = {}
- c2 = c[cookie.domain]
- if not c2.has_key(cookie.path): c2[cookie.path] = {}
- c3 = c2[cookie.path]
- c3[cookie.name] = cookie
-
- def extract_cookies(self, response, request):
- """Extract cookies from response, where allowable given the request.
-
- Look for allowable Set-Cookie: and Set-Cookie2: headers in the response
- object passed as argument. Any of these headers that are found are
- used to update the state of the object (subject to the policy.set_ok
- method's approval).
-
- The response object (usually be the result of a call to
- mechanize.urlopen, or similar) should support an info method, which
- returns a mimetools.Message object (in fact, the 'mimetools.Message
- object' may be any object that provides a getheaders method).
-
- The request object (usually a mechanize.Request instance) must support
- the methods get_full_url, get_type, get_host, and is_unverifiable, as
- documented by mechanize, and the port attribute (the port number). The
- request is used to set default values for cookie-attributes as well as
- for checking that the cookie is OK to be set.
-
- """
- debug("extract_cookies: %s", response.info())
- self._policy._now = self._now = int(time.time())
-
- for cookie in self._make_cookies(response, request):
- if cookie.expires is not None and cookie.expires <= self._now:
- # Expiry date in past is request to delete cookie. This can't be
- # in DefaultCookiePolicy, because can't delete cookies there.
- try:
- self.clear(cookie.domain, cookie.path, cookie.name)
- except KeyError:
- pass
- debug("Expiring cookie, domain='%s', path='%s', name='%s'",
- cookie.domain, cookie.path, cookie.name)
- elif self._policy.set_ok(cookie, request):
- debug(" setting cookie: %s", cookie)
- self.set_cookie(cookie)
-
- def clear(self, domain=None, path=None, name=None):
- """Clear some cookies.
-
- Invoking this method without arguments will clear all cookies. If
- given a single argument, only cookies belonging to that domain will be
- removed. If given two arguments, cookies belonging to the specified
- path within that domain are removed. If given three arguments, then
- the cookie with the specified name, path and domain is removed.
-
- Raises KeyError if no matching cookie exists.
-
- """
- if name is not None:
- if (domain is None) or (path is None):
- raise ValueError(
- "domain and path must be given to remove a cookie by name")
- del self._cookies[domain][path][name]
- elif path is not None:
- if domain is None:
- raise ValueError(
- "domain must be given to remove cookies by path")
- del self._cookies[domain][path]
- elif domain is not None:
- del self._cookies[domain]
- else:
- self._cookies = {}
-
- def clear_session_cookies(self):
- """Discard all session cookies.
-
- Discards all cookies held by object which had either no Max-Age or
- Expires cookie-attribute or an explicit Discard cookie-attribute, or
- which otherwise have ended up with a true discard attribute. For
- interactive browsers, the end of a session usually corresponds to
- closing the browser window.
-
- Note that the save method won't save session cookies anyway, unless you
- ask otherwise by passing a true ignore_discard argument.
-
- """
- for cookie in self:
- if cookie.discard:
- self.clear(cookie.domain, cookie.path, cookie.name)
-
- def clear_expired_cookies(self):
- """Discard all expired cookies.
-
- You probably don't need to call this method: expired cookies are never
- sent back to the server (provided you're using DefaultCookiePolicy),
- this method is called by CookieJar itself every so often, and the save
- method won't save expired cookies anyway (unless you ask otherwise by
- passing a true ignore_expires argument).
-
- """
- now = time.time()
- for cookie in self:
- if cookie.is_expired(now):
- self.clear(cookie.domain, cookie.path, cookie.name)
-
- def __getitem__(self, i):
- if i == 0:
- self._getitem_iterator = self.__iter__()
- elif self._prev_getitem_index != i-1: raise IndexError(
- "CookieJar.__getitem__ only supports sequential iteration")
- self._prev_getitem_index = i
- try:
- return self._getitem_iterator.next()
- except StopIteration:
- raise IndexError()
-
- def __iter__(self):
- return MappingIterator(self._cookies)
-
- def __len__(self):
- """Return number of contained cookies."""
- i = 0
- for cookie in self: i = i + 1
- return i
-
- def __repr__(self):
- r = []
- for cookie in self: r.append(repr(cookie))
- return "<%s[%s]>" % (self.__class__, ", ".join(r))
-
- def __str__(self):
- r = []
- for cookie in self: r.append(str(cookie))
- return "<%s[%s]>" % (self.__class__, ", ".join(r))
-
-
-class LoadError(Exception): pass
-
-class FileCookieJar(CookieJar):
- """CookieJar that can be loaded from and saved to a file.
-
- Additional methods
-
- save(filename=None, ignore_discard=False, ignore_expires=False)
- load(filename=None, ignore_discard=False, ignore_expires=False)
- revert(filename=None, ignore_discard=False, ignore_expires=False)
-
- Additional public attributes
-
- filename: filename for loading and saving cookies
-
- Additional public readable attributes
-
- delayload: request that cookies are lazily loaded from disk; this is only
- a hint since this only affects performance, not behaviour (unless the
- cookies on disk are changing); a CookieJar object may ignore it (in fact,
- only MSIECookieJar lazily loads cookies at the moment)
-
- """
-
- def __init__(self, filename=None, delayload=False, policy=None):
- """
- See FileCookieJar.__doc__ for argument documentation.
-
- Cookies are NOT loaded from the named file until either the load or
- revert method is called.
-
- """
- CookieJar.__init__(self, policy)
- if filename is not None and not isstringlike(filename):
- raise ValueError("filename must be string-like")
- self.filename = filename
- self.delayload = bool(delayload)
-
- def save(self, filename=None, ignore_discard=False, ignore_expires=False):
- """Save cookies to a file.
-
- filename: name of file in which to save cookies
- ignore_discard: save even cookies set to be discarded
- ignore_expires: save even cookies that have expired
-
- The file is overwritten if it already exists, thus wiping all its
- cookies. Saved cookies can be restored later using the load or revert
- methods. If filename is not specified, self.filename is used; if
- self.filename is None, ValueError is raised.
-
- """
- raise NotImplementedError()
-
- def load(self, filename=None, ignore_discard=False, ignore_expires=False):
- """Load cookies from a file.
-
- Old cookies are kept unless overwritten by newly loaded ones.
-
- Arguments are as for .save().
-
- If filename is not specified, self.filename is used; if self.filename
- is None, ValueError is raised. The named file must be in the format
- understood by the class, or LoadError will be raised. This format will
- be identical to that written by the save method, unless the load format
- is not sufficiently well understood (as is the case for MSIECookieJar).
-
- """
- if filename is None:
- if self.filename is not None: filename = self.filename
- else: raise ValueError(MISSING_FILENAME_TEXT)
-
- f = open(filename)
- try:
- self._really_load(f, filename, ignore_discard, ignore_expires)
- finally:
- f.close()
-
- def revert(self, filename=None,
- ignore_discard=False, ignore_expires=False):
- """Clear all cookies and reload cookies from a saved file.
-
- Raises LoadError (or IOError) if reversion is not successful; the
- object's state will not be altered if this happens.
-
- """
- if filename is None:
- if self.filename is not None: filename = self.filename
- else: raise ValueError(MISSING_FILENAME_TEXT)
-
- old_state = copy.deepcopy(self._cookies)
- self._cookies = {}
- try:
- self.load(filename, ignore_discard, ignore_expires)
- except (LoadError, IOError):
- self._cookies = old_state
- raise
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_debug.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_debug.py
deleted file mode 100644
index 8243969990ddf98865bbcf8bcd910819cc18dfb4..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_debug.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import logging
-
-from _response import response_seek_wrapper
-from _urllib2_fork import BaseHandler
-
-
-class HTTPResponseDebugProcessor(BaseHandler):
- handler_order = 900 # before redirections, after everything else
-
- def http_response(self, request, response):
- if not hasattr(response, "seek"):
- response = response_seek_wrapper(response)
- info = logging.getLogger("mechanize.http_responses").info
- try:
- info(response.read())
- finally:
- response.seek(0)
- info("*****************************************************")
- return response
-
- https_response = http_response
-
-class HTTPRedirectDebugProcessor(BaseHandler):
- def http_request(self, request):
- if hasattr(request, "redirect_dict"):
- info = logging.getLogger("mechanize.http_redirects").info
- info("redirecting to %s", request.get_full_url())
- return request
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_firefox3cookiejar.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_firefox3cookiejar.py
deleted file mode 100644
index a64d70f35d43af4492db93174f55fb74a104fa92..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_firefox3cookiejar.py
+++ /dev/null
@@ -1,248 +0,0 @@
-"""Firefox 3 "cookies.sqlite" cookie persistence.
-
-Copyright 2008 John J Lee
-
-This code is free software; you can redistribute it and/or modify it
-under the terms of the BSD or ZPL 2.1 licenses (see the file
-COPYING.txt included with the distribution).
-
-"""
-
-import logging
-import time
-
-from _clientcookie import CookieJar, Cookie, MappingIterator
-from _util import isstringlike, experimental
-debug = logging.getLogger("mechanize.cookies").debug
-
-
-class Firefox3CookieJar(CookieJar):
-
- """Firefox 3 cookie jar.
-
- The cookies are stored in Firefox 3's "cookies.sqlite" format.
-
- Constructor arguments:
-
- filename: filename of cookies.sqlite (typically found at the top level
- of a firefox profile directory)
- autoconnect: as a convenience, connect to the SQLite cookies database at
- Firefox3CookieJar construction time (default True)
- policy: an object satisfying the mechanize.CookiePolicy interface
-
- Note that this is NOT a FileCookieJar, and there are no .load(),
- .save() or .restore() methods. The database is in sync with the
- cookiejar object's state after each public method call.
-
- Following Firefox's own behaviour, session cookies are never saved to
- the database.
-
- The file is created, and an sqlite database written to it, if it does
- not already exist. The moz_cookies database table is created if it does
- not already exist.
- """
-
- # XXX
- # handle DatabaseError exceptions
- # add a FileCookieJar (explicit .save() / .revert() / .load() methods)
-
- def __init__(self, filename, autoconnect=True, policy=None):
- experimental("Firefox3CookieJar is experimental code")
- CookieJar.__init__(self, policy)
- if filename is not None and not isstringlike(filename):
- raise ValueError("filename must be string-like")
- self.filename = filename
- self._conn = None
- if autoconnect:
- self.connect()
-
- def connect(self):
- import sqlite3 # not available in Python 2.4 stdlib
- self._conn = sqlite3.connect(self.filename)
- self._conn.isolation_level = "DEFERRED"
- self._create_table_if_necessary()
-
- def close(self):
- self._conn.close()
-
- def _transaction(self, func):
- try:
- cur = self._conn.cursor()
- try:
- result = func(cur)
- finally:
- cur.close()
- except:
- self._conn.rollback()
- raise
- else:
- self._conn.commit()
- return result
-
- def _execute(self, query, params=()):
- return self._transaction(lambda cur: cur.execute(query, params))
-
- def _query(self, query, params=()):
- # XXX should we bother with a transaction?
- cur = self._conn.cursor()
- try:
- cur.execute(query, params)
- return cur.fetchall()
- finally:
- cur.close()
-
- def _create_table_if_necessary(self):
- self._execute("""\
-CREATE TABLE IF NOT EXISTS moz_cookies (id INTEGER PRIMARY KEY, name TEXT,
- value TEXT, host TEXT, path TEXT,expiry INTEGER,
- lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER)""")
-
- def _cookie_from_row(self, row):
- (pk, name, value, domain, path, expires,
- last_accessed, secure, http_only) = row
-
- version = 0
- domain = domain.encode("ascii", "ignore")
- path = path.encode("ascii", "ignore")
- name = name.encode("ascii", "ignore")
- value = value.encode("ascii", "ignore")
- secure = bool(secure)
-
- # last_accessed isn't a cookie attribute, so isn't added to rest
- rest = {}
- if http_only:
- rest["HttpOnly"] = None
-
- if name == "":
- name = value
- value = None
-
- initial_dot = domain.startswith(".")
- domain_specified = initial_dot
-
- discard = False
- if expires == "":
- expires = None
- discard = True
-
- return Cookie(version, name, value,
- None, False,
- domain, domain_specified, initial_dot,
- path, False,
- secure,
- expires,
- discard,
- None,
- None,
- rest)
-
- def clear(self, domain=None, path=None, name=None):
- CookieJar.clear(self, domain, path, name)
- where_parts = []
- sql_params = []
- if domain is not None:
- where_parts.append("host = ?")
- sql_params.append(domain)
- if path is not None:
- where_parts.append("path = ?")
- sql_params.append(path)
- if name is not None:
- where_parts.append("name = ?")
- sql_params.append(name)
- where = " AND ".join(where_parts)
- if where:
- where = " WHERE " + where
- def clear(cur):
- cur.execute("DELETE FROM moz_cookies%s" % where,
- tuple(sql_params))
- self._transaction(clear)
-
- def _row_from_cookie(self, cookie, cur):
- expires = cookie.expires
- if cookie.discard:
- expires = ""
-
- domain = unicode(cookie.domain)
- path = unicode(cookie.path)
- name = unicode(cookie.name)
- value = unicode(cookie.value)
- secure = bool(int(cookie.secure))
-
- if value is None:
- value = name
- name = ""
-
- last_accessed = int(time.time())
- http_only = cookie.has_nonstandard_attr("HttpOnly")
-
- query = cur.execute("""SELECT MAX(id) + 1 from moz_cookies""")
- pk = query.fetchone()[0]
- if pk is None:
- pk = 1
-
- return (pk, name, value, domain, path, expires,
- last_accessed, secure, http_only)
-
- def set_cookie(self, cookie):
- if cookie.discard:
- CookieJar.set_cookie(self, cookie)
- return
-
- def set_cookie(cur):
- # XXX
- # is this RFC 2965-correct?
- # could this do an UPDATE instead?
- row = self._row_from_cookie(cookie, cur)
- name, unused, domain, path = row[1:5]
- cur.execute("""\
-DELETE FROM moz_cookies WHERE host = ? AND path = ? AND name = ?""",
- (domain, path, name))
- cur.execute("""\
-INSERT INTO moz_cookies VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-""", row)
- self._transaction(set_cookie)
-
- def __iter__(self):
- # session (non-persistent) cookies
- for cookie in MappingIterator(self._cookies):
- yield cookie
- # persistent cookies
- for row in self._query("""\
-SELECT * FROM moz_cookies ORDER BY name, path, host"""):
- yield self._cookie_from_row(row)
-
- def _cookies_for_request(self, request):
- session_cookies = CookieJar._cookies_for_request(self, request)
- def get_cookies(cur):
- query = cur.execute("SELECT host from moz_cookies")
- domains = [row[0] for row in query.fetchall()]
- cookies = []
- for domain in domains:
- cookies += self._persistent_cookies_for_domain(domain,
- request, cur)
- return cookies
- persistent_coookies = self._transaction(get_cookies)
- return session_cookies + persistent_coookies
-
- def _persistent_cookies_for_domain(self, domain, request, cur):
- cookies = []
- if not self._policy.domain_return_ok(domain, request):
- return []
- debug("Checking %s for cookies to return", domain)
- query = cur.execute("""\
-SELECT * from moz_cookies WHERE host = ? ORDER BY path""",
- (domain,))
- cookies = [self._cookie_from_row(row) for row in query.fetchall()]
- last_path = None
- r = []
- for cookie in cookies:
- if (cookie.path != last_path and
- not self._policy.path_return_ok(cookie.path, request)):
- last_path = cookie.path
- continue
- if not self._policy.return_ok(cookie, request):
- debug(" not returning cookie")
- continue
- debug(" it's a match")
- r.append(cookie)
- return r
diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_form.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_form.py
deleted file mode 100644
index d45bdfc395e266f14912d0934326dbbdf7a5a832..0000000000000000000000000000000000000000
--- a/packages/mediacenter/kodi/config/base-addons/plugin.video.vevo/mechanize/_form.py
+++ /dev/null
@@ -1,3280 +0,0 @@
-"""HTML form handling for web clients.
-
-HTML form handling for web clients: useful for parsing HTML forms, filling them
-in and returning the completed forms to the server. This code developed from a
-port of Gisle Aas' Perl module HTML::Form, from the libwww-perl library, but
-the interface is not the same.
-
-The most useful docstring is the one for HTMLForm.
-
-RFC 1866: HTML 2.0
-RFC 1867: Form-based File Upload in HTML
-RFC 2388: Returning Values from Forms: multipart/form-data
-HTML 3.2 Specification, W3C Recommendation 14 January 1997 (for ISINDEX)
-HTML 4.01 Specification, W3C Recommendation 24 December 1999
-
-
-Copyright 2002-2007 John J. Lee
-Copyright 2005 Gary Poster
-Copyright 2005 Zope Corporation
-Copyright 1998-2000 Gisle Aas.
-
-This code is free software; you can redistribute it and/or modify it
-under the terms of the BSD or ZPL 2.1 licenses (see the file
-COPYING.txt included with the distribution).
-
-"""
-
-# TODO:
-# Clean up post the merge into mechanize
-# * Remove code that was duplicated in ClientForm and mechanize
-# * Remove weird import stuff
-# * Remove pre-Python 2.4 compatibility cruft
-# * Clean up tests
-# * Later release: Remove the ClientForm 0.1 backwards-compatibility switch
-# Remove parser testing hack
-# Clean action URI
-# Switch to unicode throughout
-# See Wichert Akkerman's 2004-01-22 message to c.l.py.
-# Apply recommendations from google code project CURLIES
-# Apply recommendations from HTML 5 spec
-# Add charset parameter to Content-type headers? How to find value??
-# Functional tests to add:
-# Single and multiple file upload
-# File upload with missing name (check standards)
-# mailto: submission & enctype text/plain??
-
-# Replace by_label etc. with moniker / selector concept. Allows, e.g., a
-# choice between selection by value / id / label / element contents. Or
-# choice between matching labels exactly or by substring. etc.
-
-
-__all__ = ['AmbiguityError', 'CheckboxControl', 'Control',
- 'ControlNotFoundError', 'FileControl', 'FormParser', 'HTMLForm',
- 'HiddenControl', 'IgnoreControl', 'ImageControl', 'IsindexControl',
- 'Item', 'ItemCountError', 'ItemNotFoundError', 'Label',
- 'ListControl', 'LocateError', 'Missing', 'ParseError', 'ParseFile',
- 'ParseFileEx', 'ParseResponse', 'ParseResponseEx','PasswordControl',
- 'RadioControl', 'ScalarControl', 'SelectControl',
- 'SubmitButtonControl', 'SubmitControl', 'TextControl',
- 'TextareaControl', 'XHTMLCompatibleFormParser']
-
-import HTMLParser
-from cStringIO import StringIO
-import inspect
-import logging
-import random
-import re
-import sys
-import urllib
-import urlparse
-import warnings
-
-import _beautifulsoup
-import _request
-
-# from Python itself, for backwards compatibility of raised exceptions
-import sgmllib
-# bundled copy of sgmllib
-import _sgmllib_copy
-
-
-VERSION = "0.2.11"
-
-CHUNK = 1024 # size of chunks fed to parser, in bytes
-
-DEFAULT_ENCODING = "latin-1"
-
-_logger = logging.getLogger("mechanize.forms")
-OPTIMIZATION_HACK = True
-
-def debug(msg, *args, **kwds):
- if OPTIMIZATION_HACK:
- return
-
- caller_name = inspect.stack()[1][3]
- extended_msg = '%%s %s' % msg
- extended_args = (caller_name,)+args
- _logger.debug(extended_msg, *extended_args, **kwds)
-
-def _show_debug_messages():
- global OPTIMIZATION_HACK
- OPTIMIZATION_HACK = False
- _logger.setLevel(logging.DEBUG)
- handler = logging.StreamHandler(sys.stdout)
- handler.setLevel(logging.DEBUG)
- _logger.addHandler(handler)
-
-
-def deprecation(message, stack_offset=0):
- warnings.warn(message, DeprecationWarning, stacklevel=3+stack_offset)
-
-
-class Missing: pass
-
-_compress_re = re.compile(r"\s+")
-def compress_text(text): return _compress_re.sub(" ", text.strip())
-
-def normalize_line_endings(text):
- return re.sub(r"(?:(?
- w = MimeWriter(f)
- ...call w.addheader(key, value) 0 or more times...
-
- followed by either:
-
- f = w.startbody(content_type)
- ...call f.write(data) for body data...
-
- or:
-
- w.startmultipartbody(subtype)
- for each part:
- subwriter = w.nextpart()
- ...use the subwriter's methods to create the subpart...
- w.lastpart()
-
- The subwriter is another MimeWriter instance, and should be
- treated in the same way as the toplevel MimeWriter. This way,
- writing recursive body parts is easy.
-
- Warning: don't forget to call lastpart()!
-
- XXX There should be more state so calls made in the wrong order
- are detected.
-
- Some special cases:
-
- - startbody() just returns the file passed to the constructor;
- but don't use this knowledge, as it may be changed.
-
- - startmultipartbody() actually returns a file as well;
- this can be used to write the initial 'if you can read this your
- mailer is not MIME-aware' message.
-
- - If you call flushheaders(), the headers accumulated so far are
- written out (and forgotten); this is useful if you don't need a
- body part at all, e.g. for a subpart of type message/rfc822
- that's (mis)used to store some header-like information.
-
- - Passing a keyword argument 'prefix=' to addheader(),
- start*body() affects where the header is inserted; 0 means
- append at the end, 1 means insert at the start; default is
- append for addheader(), but insert for start*body(), which use
- it to determine where the Content-type header goes.
-
- """
-
- def __init__(self, fp, http_hdrs=None):
- self._http_hdrs = http_hdrs
- self._fp = fp
- self._headers = []
- self._boundary = []
- self._first_part = True
-
- def addheader(self, key, value, prefix=0,
- add_to_http_hdrs=0):
- """
- prefix is ignored if add_to_http_hdrs is true.
- """
- lines = value.split("\r\n")
- while lines and not lines[-1]: del lines[-1]
- while lines and not lines[0]: del lines[0]
- if add_to_http_hdrs:
- value = "".join(lines)
- # 2.2 urllib2 doesn't normalize header case
- self._http_hdrs.append((key.capitalize(), value))
- else:
- for i in range(1, len(lines)):
- lines[i] = " " + lines[i].strip()
- value = "\r\n".join(lines) + "\r\n"
- line = key.title() + ": " + value
- if prefix:
- self._headers.insert(0, line)
- else:
- self._headers.append(line)
-
- def flushheaders(self):
- self._fp.writelines(self._headers)
- self._headers = []
-
- def startbody(self, ctype=None, plist=[], prefix=1,
- add_to_http_hdrs=0, content_type=1):
- """
- prefix is ignored if add_to_http_hdrs is true.
- """
- if content_type and ctype:
- for name, value in plist:
- ctype = ctype + ';\r\n %s=%s' % (name, value)
- self.addheader("Content-Type", ctype, prefix=prefix,
- add_to_http_hdrs=add_to_http_hdrs)
- self.flushheaders()
- if not add_to_http_hdrs: self._fp.write("\r\n")
- self._first_part = True
- return self._fp
-
- def startmultipartbody(self, subtype, boundary=None, plist=[], prefix=1,
- add_to_http_hdrs=0, content_type=1):
- boundary = boundary or choose_boundary()
- self._boundary.append(boundary)
- return self.startbody("multipart/" + subtype,
- [("boundary", boundary)] + plist,
- prefix=prefix,
- add_to_http_hdrs=add_to_http_hdrs,
- content_type=content_type)
-
- def nextpart(self):
- boundary = self._boundary[-1]
- if self._first_part:
- self._first_part = False
- else:
- self._fp.write("\r\n")
- self._fp.write("--" + boundary + "\r\n")
- return self.__class__(self._fp)
-
- def lastpart(self):
- if self._first_part:
- self.nextpart()
- boundary = self._boundary.pop()
- self._fp.write("\r\n--" + boundary + "--\r\n")
-
-
-class LocateError(ValueError): pass
-class AmbiguityError(LocateError): pass
-class ControlNotFoundError(LocateError): pass
-class ItemNotFoundError(LocateError): pass
-
-class ItemCountError(ValueError): pass
-
-# for backwards compatibility, ParseError derives from exceptions that were
-# raised by versions of ClientForm <= 0.2.5
-# TODO: move to _html
-class ParseError(sgmllib.SGMLParseError,
- HTMLParser.HTMLParseError):
-
- def __init__(self, *args, **kwds):
- Exception.__init__(self, *args, **kwds)
-
- def __str__(self):
- return Exception.__str__(self)
-
-
-class _AbstractFormParser:
- """forms attribute contains HTMLForm instances on completion."""
- # thanks to Moshe Zadka for an example of sgmllib/htmllib usage
- def __init__(self, entitydefs=None, encoding=DEFAULT_ENCODING):
- if entitydefs is None:
- entitydefs = get_entitydefs()
- self._entitydefs = entitydefs
- self._encoding = encoding
-
- self.base = None
- self.forms = []
- self.labels = []
- self._current_label = None
- self._current_form = None
- self._select = None
- self._optgroup = None
- self._option = None
- self._textarea = None
-
- # forms[0] will contain all controls that are outside of any form
- # self._global_form is an alias for self.forms[0]
- self._global_form = None
- self.start_form([])
- self.end_form()
- self._current_form = self._global_form = self.forms[0]
-
- def do_base(self, attrs):
- debug("%s", attrs)
- for key, value in attrs:
- if key == "href":
- self.base = self.unescape_attr_if_required(value)
-
- def end_body(self):
- debug("")
- if self._current_label is not None:
- self.end_label()
- if self._current_form is not self._global_form:
- self.end_form()
-
- def start_form(self, attrs):
- debug("%s", attrs)
- if self._current_form is not self._global_form:
- raise ParseError("nested FORMs")
- name = None
- action = None
- enctype = "application/x-www-form-urlencoded"
- method = "GET"
- d = {}
- for key, value in attrs:
- if key == "name":
- name = self.unescape_attr_if_required(value)
- elif key == "action":
- action = self.unescape_attr_if_required(value)
- elif key == "method":
- method = self.unescape_attr_if_required(value.upper())
- elif key == "enctype":
- enctype = self.unescape_attr_if_required(value.lower())
- d[key] = self.unescape_attr_if_required(value)
- controls = []
- self._current_form = (name, action, method, enctype), d, controls
-
- def end_form(self):
- debug("")
- if self._current_label is not None:
- self.end_label()
- if self._current_form is self._global_form:
- raise ParseError("end of FORM before start")
- self.forms.append(self._current_form)
- self._current_form = self._global_form
-
- def start_select(self, attrs):
- debug("%s", attrs)
- if self._select is not None:
- raise ParseError("nested SELECTs")
- if self._textarea is not None:
- raise ParseError("SELECT inside TEXTAREA")
- d = {}
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
-
- self._select = d
- self._add_label(d)
-
- self._append_select_control({"__select": d})
-
- def end_select(self):
- debug("")
- if self._select is None:
- raise ParseError("end of SELECT before start")
-
- if self._option is not None:
- self._end_option()
-
- self._select = None
-
- def start_optgroup(self, attrs):
- debug("%s", attrs)
- if self._select is None:
- raise ParseError("OPTGROUP outside of SELECT")
- d = {}
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
-
- self._optgroup = d
-
- def end_optgroup(self):
- debug("")
- if self._optgroup is None:
- raise ParseError("end of OPTGROUP before start")
- self._optgroup = None
-
- def _start_option(self, attrs):
- debug("%s", attrs)
- if self._select is None:
- raise ParseError("OPTION outside of SELECT")
- if self._option is not None:
- self._end_option()
-
- d = {}
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
-
- self._option = {}
- self._option.update(d)
- if (self._optgroup and self._optgroup.has_key("disabled") and
- not self._option.has_key("disabled")):
- self._option["disabled"] = None
-
- def _end_option(self):
- debug("")
- if self._option is None:
- raise ParseError("end of OPTION before start")
-
- contents = self._option.get("contents", "").strip()
- self._option["contents"] = contents
- if not self._option.has_key("value"):
- self._option["value"] = contents
- if not self._option.has_key("label"):
- self._option["label"] = contents
- # stuff dict of SELECT HTML attrs into a special private key
- # (gets deleted again later)
- self._option["__select"] = self._select
- self._append_select_control(self._option)
- self._option = None
-
- def _append_select_control(self, attrs):
- debug("%s", attrs)
- controls = self._current_form[2]
- name = self._select.get("name")
- controls.append(("select", name, attrs))
-
- def start_textarea(self, attrs):
- debug("%s", attrs)
- if self._textarea is not None:
- raise ParseError("nested TEXTAREAs")
- if self._select is not None:
- raise ParseError("TEXTAREA inside SELECT")
- d = {}
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
- self._add_label(d)
-
- self._textarea = d
-
- def end_textarea(self):
- debug("")
- if self._textarea is None:
- raise ParseError("end of TEXTAREA before start")
- controls = self._current_form[2]
- name = self._textarea.get("name")
- controls.append(("textarea", name, self._textarea))
- self._textarea = None
-
- def start_label(self, attrs):
- debug("%s", attrs)
- if self._current_label:
- self.end_label()
- d = {}
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
- taken = bool(d.get("for")) # empty id is invalid
- d["__text"] = ""
- d["__taken"] = taken
- if taken:
- self.labels.append(d)
- self._current_label = d
-
- def end_label(self):
- debug("")
- label = self._current_label
- if label is None:
- # something is ugly in the HTML, but we're ignoring it
- return
- self._current_label = None
- # if it is staying around, it is True in all cases
- del label["__taken"]
-
- def _add_label(self, d):
- #debug("%s", d)
- if self._current_label is not None:
- if not self._current_label["__taken"]:
- self._current_label["__taken"] = True
- d["__label"] = self._current_label
-
- def handle_data(self, data):
- debug("%s", data)
-
- if self._option is not None:
- # self._option is a dictionary of the OPTION element's HTML
- # attributes, but it has two special keys, one of which is the
- # special "contents" key contains text between OPTION tags (the
- # other is the "__select" key: see the end_option method)
- map = self._option
- key = "contents"
- elif self._textarea is not None:
- map = self._textarea
- key = "value"
- data = normalize_line_endings(data)
- # not if within option or textarea
- elif self._current_label is not None:
- map = self._current_label
- key = "__text"
- else:
- return
-
- if data and not map.has_key(key):
- # according to
- # http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.1 line break
- # immediately after start tags or immediately before end tags must
- # be ignored, but real browsers only ignore a line break after a
- # start tag, so we'll do that.
- if data[0:2] == "\r\n":
- data = data[2:]
- elif data[0:1] in ["\n", "\r"]:
- data = data[1:]
- map[key] = data
- else:
- map[key] = map[key] + data
-
- def do_button(self, attrs):
- debug("%s", attrs)
- d = {}
- d["type"] = "submit" # default
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
- controls = self._current_form[2]
-
- type = d["type"]
- name = d.get("name")
- # we don't want to lose information, so use a type string that
- # doesn't clash with INPUT TYPE={SUBMIT,RESET,BUTTON}
- # e.g. type for BUTTON/RESET is "resetbutton"
- # (type for INPUT/RESET is "reset")
- type = type+"button"
- self._add_label(d)
- controls.append((type, name, d))
-
- def do_input(self, attrs):
- debug("%s", attrs)
- d = {}
- d["type"] = "text" # default
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
- controls = self._current_form[2]
-
- type = d["type"]
- name = d.get("name")
- self._add_label(d)
- controls.append((type, name, d))
-
- def do_isindex(self, attrs):
- debug("%s", attrs)
- d = {}
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
- controls = self._current_form[2]
-
- self._add_label(d)
- # isindex doesn't have type or name HTML attributes
- controls.append(("isindex", None, d))
-
- def handle_entityref(self, name):
- #debug("%s", name)
- self.handle_data(unescape(
- '&%s;' % name, self._entitydefs, self._encoding))
-
- def handle_charref(self, name):
- #debug("%s", name)
- self.handle_data(unescape_charref(name, self._encoding))
-
- def unescape_attr(self, name):
- #debug("%s", name)
- return unescape(name, self._entitydefs, self._encoding)
-
- def unescape_attrs(self, attrs):
- #debug("%s", attrs)
- escaped_attrs = {}
- for key, val in attrs.items():
- try:
- val.items
- except AttributeError:
- escaped_attrs[key] = self.unescape_attr(val)
- else:
- # e.g. "__select" -- yuck!
- escaped_attrs[key] = self.unescape_attrs(val)
- return escaped_attrs
-
- def unknown_entityref(self, ref): self.handle_data("&%s;" % ref)
- def unknown_charref(self, ref): self.handle_data("%s;" % ref)
-
-
-class XHTMLCompatibleFormParser(_AbstractFormParser, HTMLParser.HTMLParser):
- """Good for XHTML, bad for tolerance of incorrect HTML."""
- # thanks to Michael Howitz for this!
- def __init__(self, entitydefs=None, encoding=DEFAULT_ENCODING):
- HTMLParser.HTMLParser.__init__(self)
- _AbstractFormParser.__init__(self, entitydefs, encoding)
-
- def feed(self, data):
- try:
- HTMLParser.HTMLParser.feed(self, data)
- except HTMLParser.HTMLParseError, exc:
- raise ParseError(exc)
-
- def start_option(self, attrs):
- _AbstractFormParser._start_option(self, attrs)
-
- def end_option(self):
- _AbstractFormParser._end_option(self)
-
- def handle_starttag(self, tag, attrs):
- try:
- method = getattr(self, "start_" + tag)
- except AttributeError:
- try:
- method = getattr(self, "do_" + tag)
- except AttributeError:
- pass # unknown tag
- else:
- method(attrs)
- else:
- method(attrs)
-
- def handle_endtag(self, tag):
- try:
- method = getattr(self, "end_" + tag)
- except AttributeError:
- pass # unknown tag
- else:
- method()
-
- def unescape(self, name):
- # Use the entitydefs passed into constructor, not
- # HTMLParser.HTMLParser's entitydefs.
- return self.unescape_attr(name)
-
- def unescape_attr_if_required(self, name):
- return name # HTMLParser.HTMLParser already did it
- def unescape_attrs_if_required(self, attrs):
- return attrs # ditto
-
- def close(self):
- HTMLParser.HTMLParser.close(self)
- self.end_body()
-
-
-class _AbstractSgmllibParser(_AbstractFormParser):
-
- def do_option(self, attrs):
- _AbstractFormParser._start_option(self, attrs)
-
- # we override this attr to decode hex charrefs
- entity_or_charref = re.compile(
- '&(?:([a-zA-Z][-.a-zA-Z0-9]*)|#(x?[0-9a-fA-F]+))(;?)')
- def convert_entityref(self, name):
- return unescape("&%s;" % name, self._entitydefs, self._encoding)
- def convert_charref(self, name):
- return unescape_charref("%s" % name, self._encoding)
- def unescape_attr_if_required(self, name):
- return name # sgmllib already did it
- def unescape_attrs_if_required(self, attrs):
- return attrs # ditto
-
-
-class FormParser(_AbstractSgmllibParser, _sgmllib_copy.SGMLParser):
- """Good for tolerance of incorrect HTML, bad for XHTML."""
- def __init__(self, entitydefs=None, encoding=DEFAULT_ENCODING):
- _sgmllib_copy.SGMLParser.__init__(self)
- _AbstractFormParser.__init__(self, entitydefs, encoding)
-
- def feed(self, data):
- try:
- _sgmllib_copy.SGMLParser.feed(self, data)
- except _sgmllib_copy.SGMLParseError, exc:
- raise ParseError(exc)
-
- def close(self):
- _sgmllib_copy.SGMLParser.close(self)
- self.end_body()
-
-
-class _AbstractBSFormParser(_AbstractSgmllibParser):
-
- bs_base_class = None
-
- def __init__(self, entitydefs=None, encoding=DEFAULT_ENCODING):
- _AbstractFormParser.__init__(self, entitydefs, encoding)
- self.bs_base_class.__init__(self)
-
- def handle_data(self, data):
- _AbstractFormParser.handle_data(self, data)
- self.bs_base_class.handle_data(self, data)
-
- def feed(self, data):
- try:
- self.bs_base_class.feed(self, data)
- except _sgmllib_copy.SGMLParseError, exc:
- raise ParseError(exc)
-
- def close(self):
- self.bs_base_class.close(self)
- self.end_body()
-
-
-class RobustFormParser(_AbstractBSFormParser, _beautifulsoup.BeautifulSoup):
-
- """Tries to be highly tolerant of incorrect HTML."""
-
- bs_base_class = _beautifulsoup.BeautifulSoup
-
-
-class NestingRobustFormParser(_AbstractBSFormParser,
- _beautifulsoup.ICantBelieveItsBeautifulSoup):
-
- """Tries to be highly tolerant of incorrect HTML.
-
- Different from RobustFormParser in that it more often guesses nesting
- above missing end tags (see BeautifulSoup docs).
- """
-
- bs_base_class = _beautifulsoup.ICantBelieveItsBeautifulSoup
-
-
-#FormParser = XHTMLCompatibleFormParser # testing hack
-#FormParser = RobustFormParser # testing hack
-
-
-def ParseResponseEx(response,
- select_default=False,
- form_parser_class=FormParser,
- request_class=_request.Request,
- entitydefs=None,
- encoding=DEFAULT_ENCODING,
-
- # private
- _urljoin=urlparse.urljoin,
- _urlparse=urlparse.urlparse,
- _urlunparse=urlparse.urlunparse,
- ):
- """Identical to ParseResponse, except that:
-
- 1. The returned list contains an extra item. The first form in the list
- contains all controls not contained in any FORM element.
-
- 2. The arguments ignore_errors and backwards_compat have been removed.
-
- 3. Backwards-compatibility mode (backwards_compat=True) is not available.
- """
- return _ParseFileEx(response, response.geturl(),
- select_default,
- False,
- form_parser_class,
- request_class,
- entitydefs,
- False,
- encoding,
- _urljoin=_urljoin,
- _urlparse=_urlparse,
- _urlunparse=_urlunparse,
- )
-
-def ParseFileEx(file, base_uri,
- select_default=False,
- form_parser_class=FormParser,
- request_class=_request.Request,
- entitydefs=None,
- encoding=DEFAULT_ENCODING,
-
- # private
- _urljoin=urlparse.urljoin,
- _urlparse=urlparse.urlparse,
- _urlunparse=urlparse.urlunparse,
- ):
- """Identical to ParseFile, except that:
-
- 1. The returned list contains an extra item. The first form in the list
- contains all controls not contained in any FORM element.
-
- 2. The arguments ignore_errors and backwards_compat have been removed.
-
- 3. Backwards-compatibility mode (backwards_compat=True) is not available.
- """
- return _ParseFileEx(file, base_uri,
- select_default,
- False,
- form_parser_class,
- request_class,
- entitydefs,
- False,
- encoding,
- _urljoin=_urljoin,
- _urlparse=_urlparse,
- _urlunparse=_urlunparse,
- )
-
-def ParseString(text, base_uri, *args, **kwds):
- fh = StringIO(text)
- return ParseFileEx(fh, base_uri, *args, **kwds)
-
-def ParseResponse(response, *args, **kwds):
- """Parse HTTP response and return a list of HTMLForm instances.
-
- The return value of mechanize.urlopen can be conveniently passed to this
- function as the response parameter.
-
- mechanize.ParseError is raised on parse errors.
-
- response: file-like object (supporting read() method) with a method
- geturl(), returning the URI of the HTTP response
- select_default: for multiple-selection SELECT controls and RADIO controls,
- pick the first item as the default if none are selected in the HTML
- form_parser_class: class to instantiate and use to pass
- request_class: class to return from .click() method (default is
- mechanize.Request)
- entitydefs: mapping like {"&": "&", ...} containing HTML entity
- definitions (a sensible default is used)
- encoding: character encoding used for encoding numeric character references
- when matching link text. mechanize does not attempt to find the encoding
- in a META HTTP-EQUIV attribute in the document itself (mechanize, for
- example, does do that and will pass the correct value to mechanize using
- this parameter).
-
- backwards_compat: boolean that determines whether the returned HTMLForm
- objects are backwards-compatible with old code. If backwards_compat is
- true:
-
- - ClientForm 0.1 code will continue to work as before.
-
- - Label searches that do not specify a nr (number or count) will always
- get the first match, even if other controls match. If
- backwards_compat is False, label searches that have ambiguous results
- will raise an AmbiguityError.
-
- - Item label matching is done by strict string comparison rather than
- substring matching.
-
- - De-selecting individual list items is allowed even if the Item is
- disabled.
-
- The backwards_compat argument will be removed in a future release.
-
- Pass a true value for select_default if you want the behaviour specified by
- RFC 1866 (the HTML 2.0 standard), which is to select the first item in a
- RADIO or multiple-selection SELECT control if none were selected in the
- HTML. Most browsers (including Microsoft Internet Explorer (IE) and
- Netscape Navigator) instead leave all items unselected in these cases. The
- W3C HTML 4.0 standard leaves this behaviour undefined in the case of
- multiple-selection SELECT controls, but insists that at least one RADIO
- button should be checked at all times, in contradiction to browser
- behaviour.
-
- There is a choice of parsers. mechanize.XHTMLCompatibleFormParser (uses
- HTMLParser.HTMLParser) works best for XHTML, mechanize.FormParser (uses
- bundled copy of sgmllib.SGMLParser) (the default) works better for ordinary
- grubby HTML. Note that HTMLParser is only available in Python 2.2 and
- later. You can pass your own class in here as a hack to work around bad
- HTML, but at your own risk: there is no well-defined interface.
-
- """
- return _ParseFileEx(response, response.geturl(), *args, **kwds)[1:]
-
-def ParseFile(file, base_uri, *args, **kwds):
- """Parse HTML and return a list of HTMLForm instances.
-
- mechanize.ParseError is raised on parse errors.
-
- file: file-like object (supporting read() method) containing HTML with zero
- or more forms to be parsed
- base_uri: the URI of the document (note that the base URI used to submit
- the form will be that given in the BASE element if present, not that of
- the document)
-
- For the other arguments and further details, see ParseResponse.__doc__.
-
- """
- return _ParseFileEx(file, base_uri, *args, **kwds)[1:]
-
-def _ParseFileEx(file, base_uri,
- select_default=False,
- ignore_errors=False,
- form_parser_class=FormParser,
- request_class=_request.Request,
- entitydefs=None,
- backwards_compat=True,
- encoding=DEFAULT_ENCODING,
- _urljoin=urlparse.urljoin,
- _urlparse=urlparse.urlparse,
- _urlunparse=urlparse.urlunparse,
- ):
- if backwards_compat:
- deprecation("operating in backwards-compatibility mode", 1)
- fp = form_parser_class(entitydefs, encoding)
- while 1:
- data = file.read(CHUNK)
- try:
- fp.feed(data)
- except ParseError, e:
- e.base_uri = base_uri
- raise
- if len(data) != CHUNK: break
- fp.close()
- if fp.base is not None:
- # HTML BASE element takes precedence over document URI
- base_uri = fp.base
- labels = [] # Label(label) for label in fp.labels]
- id_to_labels = {}
- for l in fp.labels:
- label = Label(l)
- labels.append(label)
- for_id = l["for"]
- coll = id_to_labels.get(for_id)
- if coll is None:
- id_to_labels[for_id] = [label]
- else:
- coll.append(label)
- forms = []
- for (name, action, method, enctype), attrs, controls in fp.forms:
- if action is None:
- action = base_uri
- else:
- action = _urljoin(base_uri, action)
- # would be nice to make HTMLForm class (form builder) pluggable
- form = HTMLForm(
- action, method, enctype, name, attrs, request_class,
- forms, labels, id_to_labels, backwards_compat)
- form._urlparse = _urlparse
- form._urlunparse = _urlunparse
- for ii in range(len(controls)):
- type, name, attrs = controls[ii]
- # index=ii*10 allows ImageControl to return multiple ordered pairs
- form.new_control(
- type, name, attrs, select_default=select_default, index=ii*10)
- forms.append(form)
- for form in forms:
- form.fixup()
- return forms
-
-
-class Label:
- def __init__(self, attrs):
- self.id = attrs.get("for")
- self._text = attrs.get("__text").strip()
- self._ctext = compress_text(self._text)
- self.attrs = attrs
- self._backwards_compat = False # maintained by HTMLForm
-
- def __getattr__(self, name):
- if name == "text":
- if self._backwards_compat:
- return self._text
- else:
- return self._ctext
- return getattr(Label, name)
-
- def __setattr__(self, name, value):
- if name == "text":
- # don't see any need for this, so make it read-only
- raise AttributeError("text attribute is read-only")
- self.__dict__[name] = value
-
- def __str__(self):
- return "
")
+
+ def test_namespaces_are_preserved(self):
+ markup = 'This tag is in the a namespaceThis tag is in the b namespace'
+ soup = self.soup(markup)
+ root = soup.root
+ self.assertEqual("http://example.com/", root['xmlns:a'])
+ self.assertEqual("http://example.net/", root['xmlns:b'])
+
+ def test_closing_namespaced_tag(self):
+ markup = '
'
+ self.assertEqual(self.soup(markup).div.encode("utf8"), markup.encode("utf8"))
+
+class TestUnicodeDammit(unittest.TestCase):
+ """Standalone tests of UnicodeDammit."""
+
+ def test_unicode_input(self):
+ markup = u"I'm already Unicode! \N{SNOWMAN}"
+ dammit = UnicodeDammit(markup)
+ self.assertEqual(dammit.unicode_markup, markup)
+
+ def test_smart_quotes_to_unicode(self):
+ markup = b"\x91\x92\x93\x94"
+ dammit = UnicodeDammit(markup)
+ self.assertEqual(
+ dammit.unicode_markup, u"\u2018\u2019\u201c\u201d")
+
+ def test_smart_quotes_to_xml_entities(self):
+ markup = b"\x91\x92\x93\x94"
+ dammit = UnicodeDammit(markup, smart_quotes_to="xml")
+ self.assertEqual(
+ dammit.unicode_markup, "‘’“”")
+
+ def test_smart_quotes_to_html_entities(self):
+ markup = b"\x91\x92\x93\x94"
+ dammit = UnicodeDammit(markup, smart_quotes_to="html")
+ self.assertEqual(
+ dammit.unicode_markup, "‘’“”")
+
+ def test_smart_quotes_to_ascii(self):
+ markup = b"\x91\x92\x93\x94"
+ dammit = UnicodeDammit(markup, smart_quotes_to="ascii")
+ self.assertEqual(
+ dammit.unicode_markup, """''""""")
+
+ def test_detect_utf8(self):
+ utf8 = b"\xc3\xa9"
+ dammit = UnicodeDammit(utf8)
+ self.assertEqual(dammit.unicode_markup, u'\xe9')
+ self.assertEqual(dammit.original_encoding.lower(), 'utf-8')
+
+ def test_convert_hebrew(self):
+ hebrew = b"\xed\xe5\xec\xf9"
+ dammit = UnicodeDammit(hebrew, ["iso-8859-8"])
+ self.assertEqual(dammit.original_encoding.lower(), 'iso-8859-8')
+ self.assertEqual(dammit.unicode_markup, u'\u05dd\u05d5\u05dc\u05e9')
+
+ def test_dont_see_smart_quotes_where_there_are_none(self):
+ utf_8 = b"\343\202\261\343\203\274\343\202\277\343\202\244 Watch"
+ dammit = UnicodeDammit(utf_8)
+ self.assertEqual(dammit.original_encoding.lower(), 'utf-8')
+ self.assertEqual(dammit.unicode_markup.encode("utf-8"), utf_8)
+
+ def test_ignore_inappropriate_codecs(self):
+ utf8_data = u"Räksmörgås".encode("utf-8")
+ dammit = UnicodeDammit(utf8_data, ["iso-8859-8"])
+ self.assertEqual(dammit.original_encoding.lower(), 'utf-8')
+
+ def test_ignore_invalid_codecs(self):
+ utf8_data = u"Räksmörgås".encode("utf-8")
+ for bad_encoding in ['.utf8', '...', 'utF---16.!']:
+ dammit = UnicodeDammit(utf8_data, [bad_encoding])
+ self.assertEqual(dammit.original_encoding.lower(), 'utf-8')
+
+ def test_detect_html5_style_meta_tag(self):
+
+ for data in (
+ b'',
+ b"",
+ b"",
+ b""):
+ dammit = UnicodeDammit(data, is_html=True)
+ self.assertEqual(
+ "euc-jp", dammit.original_encoding)
+
+ def test_last_ditch_entity_replacement(self):
+ # This is a UTF-8 document that contains bytestrings
+ # completely incompatible with UTF-8 (ie. encoded with some other
+ # encoding).
+ #
+ # Since there is no consistent encoding for the document,
+ # Unicode, Dammit will eventually encode the document as UTF-8
+ # and encode the incompatible characters as REPLACEMENT
+ # CHARACTER.
+ #
+ # If chardet is installed, it will detect that the document
+ # can be converted into ISO-8859-1 without errors. This happens
+ # to be the wrong encoding, but it is a consistent encoding, so the
+ # code we're testing here won't run.
+ #
+ # So we temporarily disable chardet if it's present.
+ doc = b"""\357\273\277
+\330\250\330\252\330\261
+\310\322\321\220\312\321\355\344"""
+ chardet = bs4.dammit.chardet_dammit
+ logging.disable(logging.WARNING)
+ try:
+ def noop(str):
+ return None
+ bs4.dammit.chardet_dammit = noop
+ dammit = UnicodeDammit(doc)
+ self.assertEqual(True, dammit.contains_replacement_characters)
+ self.assertTrue(u"\ufffd" in dammit.unicode_markup)
+
+ soup = BeautifulSoup(doc, "html.parser")
+ self.assertTrue(soup.contains_replacement_characters)
+ finally:
+ logging.disable(logging.NOTSET)
+ bs4.dammit.chardet_dammit = chardet
+
+ def test_byte_order_mark_removed(self):
+ # A document written in UTF-16LE will have its byte order marker stripped.
+ data = b'\xff\xfe<\x00a\x00>\x00\xe1\x00\xe9\x00<\x00/\x00a\x00>\x00'
+ dammit = UnicodeDammit(data)
+ self.assertEqual(u"áé", dammit.unicode_markup)
+ self.assertEqual("utf-16le", dammit.original_encoding)
+
+ def test_detwingle(self):
+ # Here's a UTF8 document.
+ utf8 = (u"\N{SNOWMAN}" * 3).encode("utf8")
+
+ # Here's a Windows-1252 document.
+ windows_1252 = (
+ u"\N{LEFT DOUBLE QUOTATION MARK}Hi, I like Windows!"
+ u"\N{RIGHT DOUBLE QUOTATION MARK}").encode("windows_1252")
+
+ # Through some unholy alchemy, they've been stuck together.
+ doc = utf8 + windows_1252 + utf8
+
+ # The document can't be turned into UTF-8:
+ self.assertRaises(UnicodeDecodeError, doc.decode, "utf8")
+
+ # Unicode, Dammit thinks the whole document is Windows-1252,
+ # and decodes it into "☃☃☃“Hi, I like Windows!”☃☃☃"
+
+ # But if we run it through fix_embedded_windows_1252, it's fixed:
+
+ fixed = UnicodeDammit.detwingle(doc)
+ self.assertEqual(
+ u"☃☃☃“Hi, I like Windows!”☃☃☃", fixed.decode("utf8"))
+
+ def test_detwingle_ignores_multibyte_characters(self):
+ # Each of these characters has a UTF-8 representation ending
+ # in \x93. \x93 is a smart quote if interpreted as
+ # Windows-1252. But our code knows to skip over multibyte
+ # UTF-8 characters, so they'll survive the process unscathed.
+ for tricky_unicode_char in (
+ u"\N{LATIN SMALL LIGATURE OE}", # 2-byte char '\xc5\x93'
+ u"\N{LATIN SUBSCRIPT SMALL LETTER X}", # 3-byte char '\xe2\x82\x93'
+ u"\xf0\x90\x90\x93", # This is a CJK character, not sure which one.
+ ):
+ input = tricky_unicode_char.encode("utf8")
+ self.assertTrue(input.endswith(b'\x93'))
+ output = UnicodeDammit.detwingle(input)
+ self.assertEqual(output, input)
+
+class TestNamedspacedAttribute(SoupTest):
+
+ def test_name_may_be_none(self):
+ a = NamespacedAttribute("xmlns", None)
+ self.assertEqual(a, "xmlns")
+
+ def test_attribute_is_equivalent_to_colon_separated_string(self):
+ a = NamespacedAttribute("a", "b")
+ self.assertEqual("a:b", a)
+
+ def test_attributes_are_equivalent_if_prefix_and_name_identical(self):
+ a = NamespacedAttribute("a", "b", "c")
+ b = NamespacedAttribute("a", "b", "c")
+ self.assertEqual(a, b)
+
+ # The actual namespace is not considered.
+ c = NamespacedAttribute("a", "b", None)
+ self.assertEqual(a, c)
+
+ # But name and prefix are important.
+ d = NamespacedAttribute("a", "z", "c")
+ self.assertNotEqual(a, d)
+
+ e = NamespacedAttribute("z", "b", "c")
+ self.assertNotEqual(a, e)
+
+
+class TestAttributeValueWithCharsetSubstitution(unittest.TestCase):
+
+ def test_content_meta_attribute_value(self):
+ value = CharsetMetaAttributeValue("euc-jp")
+ self.assertEqual("euc-jp", value)
+ self.assertEqual("euc-jp", value.original_value)
+ self.assertEqual("utf8", value.encode("utf8"))
+
+
+ def test_content_meta_attribute_value(self):
+ value = ContentMetaAttributeValue("text/html; charset=euc-jp")
+ self.assertEqual("text/html; charset=euc-jp", value)
+ self.assertEqual("text/html; charset=euc-jp", value.original_value)
+ self.assertEqual("text/html; charset=utf8", value.encode("utf8"))
diff --git a/packages/mediacenter/kodi/config/base-addons/script.module.beautifulsoup4/lib/bs4/tests/test_tree.py b/packages/mediacenter/kodi/config/base-addons/script.module.beautifulsoup4/lib/bs4/tests/test_tree.py
new file mode 100644
index 0000000000000000000000000000000000000000..f8515c0ea1c06056471949c1fdf5a2dbb5dd12fd
--- /dev/null
+++ b/packages/mediacenter/kodi/config/base-addons/script.module.beautifulsoup4/lib/bs4/tests/test_tree.py
@@ -0,0 +1,1829 @@
+# -*- coding: utf-8 -*-
+"""Tests for Beautiful Soup's tree traversal methods.
+
+The tree traversal methods are the main advantage of using Beautiful
+Soup over just using a parser.
+
+Different parsers will build different Beautiful Soup trees given the
+same markup, but all Beautiful Soup trees can be traversed with the
+methods tested here.
+"""
+
+import copy
+import pickle
+import re
+import warnings
+from bs4 import BeautifulSoup
+from bs4.builder import (
+ builder_registry,
+ HTMLParserTreeBuilder,
+)
+from bs4.element import (
+ CData,
+ Comment,
+ Doctype,
+ NavigableString,
+ SoupStrainer,
+ Tag,
+)
+from bs4.testing import (
+ SoupTest,
+ skipIf,
+)
+
+XML_BUILDER_PRESENT = (builder_registry.lookup("xml") is not None)
+LXML_PRESENT = (builder_registry.lookup("lxml") is not None)
+
+class TreeTest(SoupTest):
+
+ def assertSelects(self, tags, should_match):
+ """Make sure that the given tags have the correct text.
+
+ This is used in tests that define a bunch of tags, each
+ containing a single string, and then select certain strings by
+ some mechanism.
+ """
+ self.assertEqual([tag.string for tag in tags], should_match)
+
+ def assertSelectsIDs(self, tags, should_match):
+ """Make sure that the given tags have the correct IDs.
+
+ This is used in tests that define a bunch of tags, each
+ containing a single string, and then select certain strings by
+ some mechanism.
+ """
+ self.assertEqual([tag['id'] for tag in tags], should_match)
+
+
+class TestFind(TreeTest):
+ """Basic tests of the find() method.
+
+ find() just calls find_all() with limit=1, so it's not tested all
+ that thouroughly here.
+ """
+
+ def test_find_tag(self):
+ soup = self.soup("1234")
+ self.assertEqual(soup.find("b").string, "2")
+
+ def test_unicode_text_find(self):
+ soup = self.soup(u'
Räksmörgås
')
+ self.assertEqual(soup.find(text=u'Räksmörgås'), u'Räksmörgås')
+
+ def test_find_everything(self):
+ """Test an optimization that finds all tags."""
+ soup = self.soup("foobar")
+ self.assertEqual(2, len(soup.find_all()))
+
+ def test_find_everything_with_name(self):
+ """Test an optimization that finds all tags with a given name."""
+ soup = self.soup("foobarbaz")
+ self.assertEqual(2, len(soup.find_all('a')))
+
+class TestFindAll(TreeTest):
+ """Basic tests of the find_all() method."""
+
+ def test_find_all_text_nodes(self):
+ """You can search the tree for text nodes."""
+ soup = self.soup("Foobar\xbb")
+ # Exact match.
+ self.assertEqual(soup.find_all(text="bar"), [u"bar"])
+ # Match any of a number of strings.
+ self.assertEqual(
+ soup.find_all(text=["Foo", "bar"]), [u"Foo", u"bar"])
+ # Match a regular expression.
+ self.assertEqual(soup.find_all(text=re.compile('.*')),
+ [u"Foo", u"bar", u'\xbb'])
+ # Match anything.
+ self.assertEqual(soup.find_all(text=True),
+ [u"Foo", u"bar", u'\xbb'])
+
+ def test_find_all_limit(self):
+ """You can limit the number of items returned by find_all."""
+ soup = self.soup("12345")
+ self.assertSelects(soup.find_all('a', limit=3), ["1", "2", "3"])
+ self.assertSelects(soup.find_all('a', limit=1), ["1"])
+ self.assertSelects(
+ soup.find_all('a', limit=10), ["1", "2", "3", "4", "5"])
+
+ # A limit of 0 means no limit.
+ self.assertSelects(
+ soup.find_all('a', limit=0), ["1", "2", "3", "4", "5"])
+
+ def test_calling_a_tag_is_calling_findall(self):
+ soup = self.soup("123")
+ self.assertSelects(soup('a', limit=1), ["1"])
+ self.assertSelects(soup.b(id="foo"), ["3"])
+
+ def test_find_all_with_self_referential_data_structure_does_not_cause_infinite_recursion(self):
+ soup = self.soup("")
+ # Create a self-referential list.
+ l = []
+ l.append(l)
+
+ # Without special code in _normalize_search_value, this would cause infinite
+ # recursion.
+ self.assertEqual([], soup.find_all(l))
+
+ def test_find_all_resultset(self):
+ """All find_all calls return a ResultSet"""
+ soup = self.soup("")
+ result = soup.find_all("a")
+ self.assertTrue(hasattr(result, "source"))
+
+ result = soup.find_all(True)
+ self.assertTrue(hasattr(result, "source"))
+
+ result = soup.find_all(text="foo")
+ self.assertTrue(hasattr(result, "source"))
+
+
+class TestFindAllBasicNamespaces(TreeTest):
+
+ def test_find_by_namespaced_name(self):
+ soup = self.soup('4')
+ self.assertEqual("4", soup.find("mathml:msqrt").string)
+ self.assertEqual("a", soup.find(attrs= { "svg:fill" : "red" }).name)
+
+
+class TestFindAllByName(TreeTest):
+ """Test ways of finding tags by tag name."""
+
+ def setUp(self):
+ super(TreeTest, self).setUp()
+ self.tree = self.soup("""First tag.
+ Second tag.
+ Third Nested tag. tag.""")
+
+ def test_find_all_by_tag_name(self):
+ # Find all the tags.
+ self.assertSelects(
+ self.tree.find_all('a'), ['First tag.', 'Nested tag.'])
+
+ def test_find_all_by_name_and_text(self):
+ self.assertSelects(
+ self.tree.find_all('a', text='First tag.'), ['First tag.'])
+
+ self.assertSelects(
+ self.tree.find_all('a', text=True), ['First tag.', 'Nested tag.'])
+
+ self.assertSelects(
+ self.tree.find_all('a', text=re.compile("tag")),
+ ['First tag.', 'Nested tag.'])
+
+
+ def test_find_all_on_non_root_element(self):
+ # You can call find_all on any node, not just the root.
+ self.assertSelects(self.tree.c.find_all('a'), ['Nested tag.'])
+
+ def test_calling_element_invokes_find_all(self):
+ self.assertSelects(self.tree('a'), ['First tag.', 'Nested tag.'])
+
+ def test_find_all_by_tag_strainer(self):
+ self.assertSelects(
+ self.tree.find_all(SoupStrainer('a')),
+ ['First tag.', 'Nested tag.'])
+
+ def test_find_all_by_tag_names(self):
+ self.assertSelects(
+ self.tree.find_all(['a', 'b']),
+ ['First tag.', 'Second tag.', 'Nested tag.'])
+
+ def test_find_all_by_tag_dict(self):
+ self.assertSelects(
+ self.tree.find_all({'a' : True, 'b' : True}),
+ ['First tag.', 'Second tag.', 'Nested tag.'])
+
+ def test_find_all_by_tag_re(self):
+ self.assertSelects(
+ self.tree.find_all(re.compile('^[ab]$')),
+ ['First tag.', 'Second tag.', 'Nested tag.'])
+
+ def test_find_all_with_tags_matching_method(self):
+ # You can define an oracle method that determines whether
+ # a tag matches the search.
+ def id_matches_name(tag):
+ return tag.name == tag.get('id')
+
+ tree = self.soup("""Match 1.
+ Does not match.
+ Match 2.""")
+
+ self.assertSelects(
+ tree.find_all(id_matches_name), ["Match 1.", "Match 2."])
+
+
+class TestFindAllByAttribute(TreeTest):
+
+ def test_find_all_by_attribute_name(self):
+ # You can pass in keyword arguments to find_all to search by
+ # attribute.
+ tree = self.soup("""
+ Matching a.
+
+ Non-matching Matching b.a.
+ """)
+ self.assertSelects(tree.find_all(id='first'),
+ ["Matching a.", "Matching b."])
+
+ def test_find_all_by_utf8_attribute_value(self):
+ peace = u"םולש".encode("utf8")
+ data = u''.encode("utf8")
+ soup = self.soup(data)
+ self.assertEqual([soup.a], soup.find_all(title=peace))
+ self.assertEqual([soup.a], soup.find_all(title=peace.decode("utf8")))
+ self.assertEqual([soup.a], soup.find_all(title=[peace, "something else"]))
+
+ def test_find_all_by_attribute_dict(self):
+ # You can pass in a dictionary as the argument 'attrs'. This
+ # lets you search for attributes like 'name' (a fixed argument
+ # to find_all) and 'class' (a reserved word in Python.)
+ tree = self.soup("""
+ Name match.
+ Class match.
+ Non-match.
+ A tag called 'name1'.
+ """)
+
+ # This doesn't do what you want.
+ self.assertSelects(tree.find_all(name='name1'),
+ ["A tag called 'name1'."])
+ # This does what you want.
+ self.assertSelects(tree.find_all(attrs={'name' : 'name1'}),
+ ["Name match."])
+
+ self.assertSelects(tree.find_all(attrs={'class' : 'class2'}),
+ ["Class match."])
+
+ def test_find_all_by_class(self):
+ tree = self.soup("""
+ Class 1.
+ Class 2.
+ Class 1.
+ Class 3 and 4.
+ """)
+
+ # Passing in the class_ keyword argument will search against
+ # the 'class' attribute.
+ self.assertSelects(tree.find_all('a', class_='1'), ['Class 1.'])
+ self.assertSelects(tree.find_all('c', class_='3'), ['Class 3 and 4.'])
+ self.assertSelects(tree.find_all('c', class_='4'), ['Class 3 and 4.'])
+
+ # Passing in a string to 'attrs' will also search the CSS class.
+ self.assertSelects(tree.find_all('a', '1'), ['Class 1.'])
+ self.assertSelects(tree.find_all(attrs='1'), ['Class 1.', 'Class 1.'])
+ self.assertSelects(tree.find_all('c', '3'), ['Class 3 and 4.'])
+ self.assertSelects(tree.find_all('c', '4'), ['Class 3 and 4.'])
+
+ def test_find_by_class_when_multiple_classes_present(self):
+ tree = self.soup("Found it")
+
+ f = tree.find_all("gar", class_=re.compile("o"))
+ self.assertSelects(f, ["Found it"])
+
+ f = tree.find_all("gar", class_=re.compile("a"))
+ self.assertSelects(f, ["Found it"])
+
+ # Since the class is not the string "foo bar", but the two
+ # strings "foo" and "bar", this will not find anything.
+ f = tree.find_all("gar", class_=re.compile("o b"))
+ self.assertSelects(f, [])
+
+ def test_find_all_with_non_dictionary_for_attrs_finds_by_class(self):
+ soup = self.soup("Found it")
+
+ self.assertSelects(soup.find_all("a", re.compile("ba")), ["Found it"])
+
+ def big_attribute_value(value):
+ return len(value) > 3
+
+ self.assertSelects(soup.find_all("a", big_attribute_value), [])
+
+ def small_attribute_value(value):
+ return len(value) <= 3
+
+ self.assertSelects(
+ soup.find_all("a", small_attribute_value), ["Found it"])
+
+ def test_find_all_with_string_for_attrs_finds_multiple_classes(self):
+ soup = self.soup('')
+ a, a2 = soup.find_all("a")
+ self.assertEqual([a, a2], soup.find_all("a", "foo"))
+ self.assertEqual([a], soup.find_all("a", "bar"))
+
+ # If you specify the class as a string that contains a
+ # space, only that specific value will be found.
+ self.assertEqual([a], soup.find_all("a", class_="foo bar"))
+ self.assertEqual([a], soup.find_all("a", "foo bar"))
+ self.assertEqual([], soup.find_all("a", "bar foo"))
+
+ def test_find_all_by_attribute_soupstrainer(self):
+ tree = self.soup("""
+ Match.
+ Non-match.""")
+
+ strainer = SoupStrainer(attrs={'id' : 'first'})
+ self.assertSelects(tree.find_all(strainer), ['Match.'])
+
+ def test_find_all_with_missing_atribute(self):
+ # You can pass in None as the value of an attribute to find_all.
+ # This will match tags that do not have that attribute set.
+ tree = self.soup("""ID present.
+ No ID present.
+ ID is empty.""")
+ self.assertSelects(tree.find_all('a', id=None), ["No ID present."])
+
+ def test_find_all_with_defined_attribute(self):
+ # You can pass in None as the value of an attribute to find_all.
+ # This will match tags that have that attribute set to any value.
+ tree = self.soup("""ID present.
+ No ID present.
+ ID is empty.""")
+ self.assertSelects(
+ tree.find_all(id=True), ["ID present.", "ID is empty."])
+
+ def test_find_all_with_numeric_attribute(self):
+ # If you search for a number, it's treated as a string.
+ tree = self.soup("""Unquoted attribute.
+ Quoted attribute.""")
+
+ expected = ["Unquoted attribute.", "Quoted attribute."]
+ self.assertSelects(tree.find_all(id=1), expected)
+ self.assertSelects(tree.find_all(id="1"), expected)
+
+ def test_find_all_with_list_attribute_values(self):
+ # You can pass a list of attribute values instead of just one,
+ # and you'll get tags that match any of the values.
+ tree = self.soup("""1
+ 2
+ 3
+ No ID.""")
+ self.assertSelects(tree.find_all(id=["1", "3", "4"]),
+ ["1", "3"])
+
+ def test_find_all_with_regular_expression_attribute_value(self):
+ # You can pass a regular expression as an attribute value, and
+ # you'll get tags whose values for that attribute match the
+ # regular expression.
+ tree = self.soup("""One a.
+ Two as.
+ Mixed as and bs.
+ One b.
+ No ID.""")
+
+ self.assertSelects(tree.find_all(id=re.compile("^a+$")),
+ ["One a.", "Two as."])
+
+ def test_find_by_name_and_containing_string(self):
+ soup = self.soup("foobarfoo")
+ a = soup.a
+
+ self.assertEqual([a], soup.find_all("a", text="foo"))
+ self.assertEqual([], soup.find_all("a", text="bar"))
+ self.assertEqual([], soup.find_all("a", text="bar"))
+
+ def test_find_by_name_and_containing_string_when_string_is_buried(self):
+ soup = self.soup("foofoo")
+ self.assertEqual(soup.find_all("a"), soup.find_all("a", text="foo"))
+
+ def test_find_by_attribute_and_containing_string(self):
+ soup = self.soup('foofoo')
+ a = soup.a
+
+ self.assertEqual([a], soup.find_all(id=2, text="foo"))
+ self.assertEqual([], soup.find_all(id=1, text="bar"))
+
+
+
+
+class TestIndex(TreeTest):
+ """Test Tag.index"""
+ def test_index(self):
+ tree = self.soup("""
+ Identical
+ Not identical
+ Identical
+
+ Identical with child
+ Also not identical
+ Identical with child
+
""")
+ div = tree.div
+ for i, element in enumerate(div.contents):
+ self.assertEqual(i, div.index(element))
+ self.assertRaises(ValueError, tree.index, 1)
+
+
+class TestParentOperations(TreeTest):
+ """Test navigation and searching through an element's parents."""
+
+ def setUp(self):
+ super(TestParentOperations, self).setUp()
+ self.tree = self.soup('''
"""
+ soup = self.soup(doc)
+ second_para = soup.find(id='2')
+ bold = soup.b
+
+ # Move the tag to the end of the second paragraph.
+ soup.find(id='2').append(soup.b)
+
+ # The tag is now a child of the second paragraph.
+ self.assertEqual(bold.parent, second_para)
+
+ self.assertEqual(
+ soup.decode(), self.document_for(
+ '