diff --git a/packages/mediacenter/kodi/config/Database/Addons19.db b/packages/mediacenter/kodi/config/Database/Addons19.db new file mode 100644 index 0000000000000000000000000000000000000000..7fb27edacef3d1008085c4d1ba2b4370613a9918 Binary files /dev/null and b/packages/mediacenter/kodi/config/Database/Addons19.db differ diff --git a/packages/mediacenter/kodi/config/Database/Epg10.db b/packages/mediacenter/kodi/config/Database/Epg10.db new file mode 100644 index 0000000000000000000000000000000000000000..1ed749cece638ccfac4219669f76ea08dddc5e1c Binary files /dev/null and b/packages/mediacenter/kodi/config/Database/Epg10.db differ diff --git a/packages/mediacenter/kodi/config/Database/MyMusic52.db b/packages/mediacenter/kodi/config/Database/MyMusic52.db new file mode 100644 index 0000000000000000000000000000000000000000..165886ca8947ac642d1902867d8a19b5a1a4a5ac Binary files /dev/null and b/packages/mediacenter/kodi/config/Database/MyMusic52.db differ diff --git a/packages/mediacenter/kodi/config/Database/MyVideos93.db b/packages/mediacenter/kodi/config/Database/MyVideos93.db new file mode 100644 index 0000000000000000000000000000000000000000..f060bf3b0599586a8df5bcd6e425c82f1ddd5611 Binary files /dev/null and b/packages/mediacenter/kodi/config/Database/MyVideos93.db differ diff --git a/packages/mediacenter/kodi/config/Database/TV29.db b/packages/mediacenter/kodi/config/Database/TV29.db new file mode 100644 index 0000000000000000000000000000000000000000..0baf59e1a66976da41e0403b302f25bbbf70a4ad Binary files /dev/null and b/packages/mediacenter/kodi/config/Database/TV29.db differ diff --git a/packages/mediacenter/kodi/config/Database/Textures13.db b/packages/mediacenter/kodi/config/Database/Textures13.db new file mode 100644 index 0000000000000000000000000000000000000000..e21814929c9a0e5099071068c4b21e78444f0a1f Binary files /dev/null and b/packages/mediacenter/kodi/config/Database/Textures13.db differ diff --git a/packages/mediacenter/kodi/config/Database/ViewModes6.db b/packages/mediacenter/kodi/config/Database/ViewModes6.db new file mode 100644 index 0000000000000000000000000000000000000000..40a30a01fdfe0f8ece66d00ea978b61107e20adf Binary files /dev/null and b/packages/mediacenter/kodi/config/Database/ViewModes6.db differ diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.SportsDevil/favourites/favourites.cfg b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.SportsDevil/favourites/favourites.cfg new file mode 100644 index 0000000000000000000000000000000000000000..fc4a68b748098b9e442ab866f8d192590cc99033 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.SportsDevil/favourites/favourites.cfg @@ -0,0 +1,18 @@ +######################################################## +# FAVOURITES # +######################################################## +######################################################## +title=RojaDirecta.me +type=rss +icon=/storage/.kodi/addons/plugin.video.SportsDevil/resources/images/roja.jpg +url=livesports/rojadirecta.me.cfg +######################################################## +title=livesportstreams.tv +type=rss +icon=/storage/.kodi/addons/plugin.video.SportsDevil/resources/images/livesports.png +url=livesports/livesportstreams.tv.cfg +######################################################## +title=LiveTV.ru +type=rss +icon=/storage/.kodi/addons/plugin.video.SportsDevil/resources/images/livetv_ru.png +url=livesports/livetv.ru.cfg \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.SportsDevil/settings.xml b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.SportsDevil/settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..5ba5c297ce47cbcf47826eaf7da2471181e3502c --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.SportsDevil/settings.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.adryanlist/settings.xml b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.adryanlist/settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..fe80d29c5cd4c67cde6ed5cd75d1f5ebe68bdf19 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.adryanlist/settings.xml @@ -0,0 +1,3 @@ + + + diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.jtv.archives/settings.xml b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.jtv.archives/settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..baa2bff09971c3951e53fa946a39dd615c56d6ba --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.jtv.archives/settings.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.live.streamspro/settings.xml b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.live.streamspro/settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..fbadb5d5fde76dfe178a7f30ac5fbfdb935a4a39 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.live.streamspro/settings.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.live.streamspro/source_file b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.live.streamspro/source_file new file mode 100644 index 0000000000000000000000000000000000000000..504b629d09a9c63010c73d6d5eac310218364b1b --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.live.streamspro/source_file @@ -0,0 +1 @@ +[{"url": "http://pastebin.com/raw.php?i=ZJFiNyz2", "fanart": "/storage/.kodi/addons/plugin.video.live.streamspro/fanart.jpg", "title": "US Channels"}, {"date": "13.02.2015", "description": ": Lista de Canales para el Livestreamspro :", "title": "Adryan List ", "url": "http://adryanlist.info", "fanart": "http://i.imgur.com/7izulmv.jpg", "genre": "Tv Live", "credits": "adryan", "thumbnail": "http://i.imgur.com/MWSXNtp.png"}] \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/history.txt b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/history.txt new file mode 100644 index 0000000000000000000000000000000000000000..77084a24a4aba06abd7f72014d32eb99b8f78a54 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/history.txt @@ -0,0 +1 @@ +Sopcast|sop://broker.sopcast.com:3912/258927|2|/storage/.kodi/addons/plugin.video.p2p-streams/resources/art/sopcast_logo.jpg diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/arenavision.tar.gz b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/arenavision.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..376a6ecb7edba013e1fadc9046b81f211c2e026b Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/arenavision.tar.gz differ diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/livefootballvideo.tar.gz b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/livefootballvideo.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..ea3875778e6f9d32f8ea6ef2280d0ff062b04146 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/livefootballvideo.tar.gz differ diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/livefootballws.tar.gz b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/livefootballws.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..8f55da4fcec969897cb3888b7ae24ab2d804c0a8 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/livefootballws.tar.gz differ diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/rojadirecta.tar.gz b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/rojadirecta.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..59e172eaae60e54da4bc9b7c845818522d808bf7 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/rojadirecta.tar.gz differ diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/sopcastucoz.tar.gz b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/sopcastucoz.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..b41a0070dbae0075fe6be4a358362d1dfdcb807a Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/sopcastucoz.tar.gz differ diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/torrenttvruall.tar.gz b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/torrenttvruall.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..946b6f542a98edfd304bcdff9d6727bb3b01418c Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/torrenttvruall.tar.gz differ diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/torrenttvrusports.tar.gz b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/torrenttvrusports.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..46a3be82db455c505e2c4ada5b7bccacf911a824 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser-packages/torrenttvrusports.tar.gz differ diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/arenavision.txt b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/arenavision.txt new file mode 100644 index 0000000000000000000000000000000000000000..c9a43b9c6c76efe33d844e649ba59f992d0e0241 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/arenavision.txt @@ -0,0 +1 @@ +{'url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/arenavision.tar.gz', 'md5_url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/arenavision.md5', 'md5': '775c9c7ab967c949d60cad65a93397d6 arenavision.tar.gz\n'} \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/livefootballvideo.txt b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/livefootballvideo.txt new file mode 100644 index 0000000000000000000000000000000000000000..3ff499b2ec1b26c868a885bf720435a9fda775e7 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/livefootballvideo.txt @@ -0,0 +1 @@ +{'url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/livefootballvideo.tar.gz', 'md5_url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/livefootballvideo.md5', 'md5': '2e8b4ec2a248fa7ae36b401cff50852a livefootballvideo.tar.gz\n'} \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/livefootballws.txt b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/livefootballws.txt new file mode 100644 index 0000000000000000000000000000000000000000..36672ea882e65b7cf457dc92cc617760a70bb963 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/livefootballws.txt @@ -0,0 +1 @@ +{'url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/livefootballws.tar.gz', 'md5_url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/livefootballws.md5', 'md5': '40dd61ca718ab2b39cd6a56d52a42f37 livefootballws.tar.gz\n\n'} \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/rojadirecta.txt b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/rojadirecta.txt new file mode 100644 index 0000000000000000000000000000000000000000..a788d9bbf5ec94eda186cbe7e16a5a629a3aed2e --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/rojadirecta.txt @@ -0,0 +1 @@ +{'url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/rojadirecta.tar.gz', 'md5_url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/rojadirecta.md5', 'md5': 'ccfaf7c2cfd9cc4384bc16126e5dce62 \t\trojadirecta.tar.gz\n'} \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/sopcastucoz.txt b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/sopcastucoz.txt new file mode 100644 index 0000000000000000000000000000000000000000..cd4bad82a14882fb84e26639cb262a6c45116c0a --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/sopcastucoz.txt @@ -0,0 +1 @@ +{'url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/sopcastucoz.tar.gz', 'md5_url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/sopcastucoz.md5', 'md5': '244d6ef17459243b8fc2cf14d7157867 sopcastucoz.tar.gz\n\n'} \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/torrenttvruall.txt b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/torrenttvruall.txt new file mode 100644 index 0000000000000000000000000000000000000000..5f06f155dcf46c471486694a61e43cf3d41e9001 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/torrenttvruall.txt @@ -0,0 +1 @@ +{'url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/torrenttvruall.tar.gz', 'md5_url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/torrenttvruall.md5', 'md5': 'ac40d6325eb7c139c9ce82c30ba3f3fd torrenttvruall.tar.gz\n'} \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/torrenttvrusports.txt b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/torrenttvrusports.txt new file mode 100644 index 0000000000000000000000000000000000000000..0d2437fc67608064ffe0f8c03810513240920cb4 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/parser/torrenttvrusports.txt @@ -0,0 +1 @@ +{'url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/torrenttvrusports.tar.gz', 'md5_url': 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/torrenttvrusports.md5', 'md5': 'c3e611a595403224c6e9623220f8aac5 torrenttvrusports.tar.gz\n'} \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/rscript.py b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/rscript.py new file mode 100644 index 0000000000000000000000000000000000000000..6000adb3f8dd51a1374ceeb1fef2db29b7a9db21 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/rscript.py @@ -0,0 +1,10 @@ + # -*- coding: utf-8 -*- +import xbmc,urllib + +all_modules = [ 'http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/arenavision.tar.gz','http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/livefootballvideo.tar.gz','http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/livefootballws.tar.gz','http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/rojadirecta.tar.gz','http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/sopcastucoz.tar.gz','http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/torrenttvruall.tar.gz','http://parsersforp2pstreams.googlecode.com/svn/trunk/%20parsersforp2pstreams/torrenttvrusports.tar.gz'] + +for parser in all_modules: + xbmc.executebuiltin('XBMC.RunPlugin("plugin://plugin.video.p2p-streams/?mode=405&name=p2p&url=' + urllib.quote(parser) + '")') + xbmc.sleep(1000) + +xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % ('P2P-Streams', "All parsers imported",1,'')) \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/settings.xml b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..e819b635631a79b7e1236fbf0342953653684bea --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.p2p-streams/settings.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.pelisalacarta/settings.xml b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.pelisalacarta/settings.xml index d51ea271791cfafd5ad3148b7e5dfca61f61c70d..430538e038ed52f5b8719d3c9133c9b37793780f 100644 --- a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.pelisalacarta/settings.xml +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.pelisalacarta/settings.xml @@ -98,7 +98,7 @@ - + diff --git a/packages/mediacenter/kodi/config/base-addon_data/plugin.video.veetle/settings.xml b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.veetle/settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..30a56fe427dd299c53147c4f018bddab5a86afa4 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/plugin.video.veetle/settings.xml @@ -0,0 +1,3 @@ + + + diff --git a/packages/mediacenter/kodi/config/base-addon_data/script.module.torrent.ts/settings.xml b/packages/mediacenter/kodi/config/base-addon_data/script.module.torrent.ts/settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..28968e9cef3c8a2663f5d9f810c132292eac366b --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addon_data/script.module.torrent.ts/settings.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/addons.DATA.xml b/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/deportesonline.DATA.xml similarity index 100% rename from packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/addons.DATA.xml rename to packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/deportesonline.DATA.xml diff --git a/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/mainmenu.DATA.xml b/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/mainmenu.DATA.xml index e22d737038777e746bb022cb6227a403118059b3..47ae77e49bd678a22932526abb6b53b507d948f1 100644 --- a/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/mainmenu.DATA.xml +++ b/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/mainmenu.DATA.xml @@ -237,18 +237,18 @@ movies - Filmes + $VAR[MoviesButtonThumb] - $VAR[RecentMoviesButtonThumb] + ActivateWindow(10025,videodb://movies/titles/,return) - - - Complemento de Vídeo + plugin.video.adryanlist + + Complemento de video DefaultShortcut.png - image://%2froot%2f.kodi%2faddons%2fplugin.video.tvalacarta%2fresources%2fimages%2fsquares%2fa3media.png/ - ActivateWindow(10025,"plugin://plugin.video.tvalacarta/?channel=a3media&action=mainlist&category=a3media",return) + special://skin/extras/hometiles/livetv.png + ActivateWindow(10025,"plugin://plugin.video.adryanlist",return) tvshows @@ -275,12 +275,12 @@ ActivateWindow(Music,musicdb://,return) - videos - - Custom shortcut - special://skin/extras/hometiles/videos.png - - ActivateWindow(10025,library://video_flat/files.xml/,return) + + + Complemento de video + DefaultShortcut.png + /storage/.kodi/addons/plugin.video.SportsDevil/fanart.jpg + ActivateWindow(10025,"plugin://plugin.video.SportsDevil/?mode=1&item=url%3D%252Fstorage%252F.kodi%252Fuserdata%252Faddon_data%252Fplugin.video.SportsDevil%252Ffavourites%252Ffavourites.cfg%26title%3DFavourites%26type%3Drss%26icon%3D%252Fstorage%252F.kodi%252Faddons%252Fplugin.video.SportsDevil%252Fresources%252Fimages%252Fbookmark.png",return) plugin.video.youtube @@ -291,12 +291,12 @@ ActivateWindow(10025,plugin://plugin.video.youtube,return) - 10040 - - Acceso directo personalizado - special://skin/extras/hometiles/addons.png + videos + + Custom shortcut + special://skin/extras/hometiles/videos.png - ActivateWindow(Programs,Addons,return) + ActivateWindow(10025,library://video_flat/files.xml/,return) weather diff --git a/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/movies.DATA.xml b/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/movies.DATA.xml index d2a832f27af5ff95a59e052c0b56657f8e134a3b..4faa4014ea33eed594efb2458a02d9f04bc29f5e 100644 --- a/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/movies.DATA.xml +++ b/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/movies.DATA.xml @@ -1,12 +1,2 @@ - - - 135 - - Movies - $VAR[MB3FavoritesThumb] - - $INFO[Window(Home).Property(MediaBrowser.std.movies.3.path)] - Skin.HasSetting(HomeMenuUseMBforMovies) - - + \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/atresplayer.DATA.xml b/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/plugin-video-adryanlist.DATA.xml similarity index 100% rename from packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/atresplayer.DATA.xml rename to packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/plugin-video-adryanlist.DATA.xml diff --git a/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/settings.DATA.xml b/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/settings.DATA.xml index 80695c95e21ac0a50775c4b9cbf8b36005f33343..975c2c382962ef3168f913611e8c4ffc9c9d6854 100644 --- a/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/settings.DATA.xml +++ b/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/settings.DATA.xml @@ -16,6 +16,14 @@ image://%2fusr%2fshare%2fkodi%2faddons%2fservice.openelec.settings%2ficon.png/ RunAddOn(service.openelec.settings) + + 24001 + + Configuración + DefaultShortcut.png + + ActivateWindow(AddonBrowser) + 7 diff --git a/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/skin.titan.hash b/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/skin.titan.hash index 18cb68946a83120be25df1b9f6841710fa3aea3e..1b443494789d4d207c7159bbd4ec46841bcbb245 100644 --- a/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/skin.titan.hash +++ b/packages/mediacenter/kodi/config/base-addon_data/script.skinshortcuts/skin.titan.hash @@ -1 +1 @@ -[['::PROFILELIST::', [[u'/storage/.kodi/userdata/', u'StringCompare(System.ProfileName,Master user)']]], ['::SCRIPTVER::', '0.4.5'], ['::XBMCVER::', '15'], [u'/usr/share/kodi/addons/skin.titan/shortcuts/overrides.xml', '465ea28fd6e82e082aa2ab5a92ddfcea'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/mainmenu.DATA.xml', '4715fcfdbe936ab17bf099a597665b8f'], ['/storage/.kodi/userdata/overrides.xml', None], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-0-title.DATA.xml', '69428aa0536ad9762421399c7bd3f21a'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-1-title.DATA.xml', '180802814d37c51a382f0ccb86750e1a'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-2-title.DATA.xml', '1e6a769af9d07d0c5c103a2010e69853'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-3-title.DATA.xml', 'b569d619f133ac24b24068965b1ab7fc'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-4-title.DATA.xml', '5544b71d5d10156ac2a910e694e3abf7'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-5-title.DATA.xml', '73b5b1ae5074fe9c39d73e29f81e2db2'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-6-title.DATA.xml', '9c44c512ce7ed646b46071a48892782f'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-7-title.DATA.xml', 'ebb074626e5b4b3152aa407b4baf9774'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-8-title.DATA.xml', '0202316105c5a914cbb04f31d91af48d'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-9-title.DATA.xml', 'ac5275368ddc3c712394c3ebe3c0e9d6'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-10-title.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-11-title.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-12-title.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-13-title.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-14-title.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-0-title.DATA.xml', '3e4d56d6687e5718497859fe19a222e8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-1-title.DATA.xml', 'bfb3d9ddcaeeb77992b6ccdc44300817'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-2-title.DATA.xml', 'e418381649c58d5316906d904a3e57d5'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-3-title.DATA.xml', '11079b838171264381658dd5bb500937'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-4-title.DATA.xml', '6cf32dbc4fb7d7c16fb803641bf164d2'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-5-title.DATA.xml', 'd7df9d7f48b1fe14691d7906006a26dd'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-6-title.DATA.xml', '80c3e527460ab3521e9a706b026da4c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-7-title.DATA.xml', '8b6b67a463f9f75c9aa00f466bcdad64'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-8-title.DATA.xml', '0161b3294b09e0f0608a472163c11a80'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-9-title.DATA.xml', 'e8b8579b97702dba94435eb5d99826bb'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/livetv.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/movies.DATA.xml', '6d3940e5f8514fae70475c472bd2c271'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/atresplayer.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/tvshows.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/plugin-video-pulsar.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/music.DATA.xml', '54e44701c5ccd3c2caad92bb0ae492dc'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/videos.DATA.xml', '379c0cb0f0c8c3963235d19fe6e1308b'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/plugin-video-youtube.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/addons.DATA.xml', 'd34c41d398b778cf8b4eba20c7678fe5'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/weather.DATA.xml', '379c0cb0f0c8c3963235d19fe6e1308b'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/settings.DATA.xml', '1acc2859b4e5c0e5b63b1b0ababec2e7'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/powermenu.DATA.xml', '0da67b4acb6d3e2c630f62b300be5659'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/usr/share/kodi/addons/skin.titan/1080i/script-skinshortcuts-includes.xml', '9460f2d60ceeb7da0ebccd507b327f24'], [u'/usr/share/kodi/addons/skin.titan/1080i/script-skinshortcuts-includes.xml', '9460f2d60ceeb7da0ebccd507b327f24'], ['::SKINVER::', '3.4.1']] \ No newline at end of file +[['::PROFILELIST::', [[u'/storage/.kodi/userdata/', u'StringCompare(System.ProfileName,Master user)']]], ['::SCRIPTVER::', '0.4.5'], ['::XBMCVER::', '15'], [u'/storage/.kodi/addons/skin.titan/shortcuts/overrides.xml', '465ea28fd6e82e082aa2ab5a92ddfcea'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/mainmenu.DATA.xml', '713e483da6e6b36e87b798debc1f1edc'], ['/storage/.kodi/userdata/overrides.xml', None], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-0-title.DATA.xml', '69428aa0536ad9762421399c7bd3f21a'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-1-title.DATA.xml', '180802814d37c51a382f0ccb86750e1a'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-2-title.DATA.xml', '1e6a769af9d07d0c5c103a2010e69853'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-3-title.DATA.xml', 'b569d619f133ac24b24068965b1ab7fc'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-4-title.DATA.xml', '5544b71d5d10156ac2a910e694e3abf7'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-5-title.DATA.xml', '73b5b1ae5074fe9c39d73e29f81e2db2'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-6-title.DATA.xml', '9c44c512ce7ed646b46071a48892782f'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-7-title.DATA.xml', 'ebb074626e5b4b3152aa407b4baf9774'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-8-title.DATA.xml', '0202316105c5a914cbb04f31d91af48d'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-9-title.DATA.xml', 'ac5275368ddc3c712394c3ebe3c0e9d6'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-10-title.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-11-title.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-12-title.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-13-title.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-mediabrowser-usr-14-title.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-0-title.DATA.xml', '3e4d56d6687e5718497859fe19a222e8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-1-title.DATA.xml', 'bfb3d9ddcaeeb77992b6ccdc44300817'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-2-title.DATA.xml', 'e418381649c58d5316906d904a3e57d5'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-3-title.DATA.xml', '11079b838171264381658dd5bb500937'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-4-title.DATA.xml', '6cf32dbc4fb7d7c16fb803641bf164d2'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-5-title.DATA.xml', 'd7df9d7f48b1fe14691d7906006a26dd'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-6-title.DATA.xml', '80c3e527460ab3521e9a706b026da4c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-7-title.DATA.xml', '8b6b67a463f9f75c9aa00f466bcdad64'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-8-title.DATA.xml', '0161b3294b09e0f0608a472163c11a80'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/info-window-home-property-plexbmc-9-title.DATA.xml', 'e8b8579b97702dba94435eb5d99826bb'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/livetv.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/movies.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/plugin-video-adryanlist.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/tvshows.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/plugin-video-pulsar.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/music.DATA.xml', '54e44701c5ccd3c2caad92bb0ae492dc'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/deportesonline.DATA.xml', 'd34c41d398b778cf8b4eba20c7678fe5'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/plugin-video-youtube.DATA.xml', '3ef7dded684b0cbf90c477b1af4ac0c8'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/videos.DATA.xml', '379c0cb0f0c8c3963235d19fe6e1308b'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/weather.DATA.xml', '379c0cb0f0c8c3963235d19fe6e1308b'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/settings.DATA.xml', 'cfc9c3bf21be0a9e3da02fdbdf5fa3b3'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/powermenu.DATA.xml', '0da67b4acb6d3e2c630f62b300be5659'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/userdata/addon_data/script.skinshortcuts/skin.titan.properties', 'd751713988987e9331980363e24189ce'], [u'/storage/.kodi/addons/skin.titan/1080i/script-skinshortcuts-includes.xml', '178695a01adfe60a3a20adbb829a8adc'], [u'/storage/.kodi/addons/skin.titan/1080i/script-skinshortcuts-includes.xml', '178695a01adfe60a3a20adbb829a8adc'], ['::SKINVER::', '3.4.1']] \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addon_data/script.trakt/queue.db b/packages/mediacenter/kodi/config/base-addon_data/script.trakt/queue.db index d75b6e1dc79c799c853ca725dfeaae04c3f53c8d..0b1bad25c454b8a50000a69104bac3868e87e5c6 100644 Binary files a/packages/mediacenter/kodi/config/base-addon_data/script.trakt/queue.db and b/packages/mediacenter/kodi/config/base-addon_data/script.trakt/queue.db differ diff --git a/packages/mediacenter/kodi/config/base-addon_data/script.tv.show.next.aired/country.db b/packages/mediacenter/kodi/config/base-addon_data/script.tv.show.next.aired/country.db index fa668ab839f4d5635afb5b3723559960bb25ff9d..aa3d7a083000b7da5328968481b0f012c8ce08bb 100644 --- a/packages/mediacenter/kodi/config/base-addon_data/script.tv.show.next.aired/country.db +++ b/packages/mediacenter/kodi/config/base-addon_data/script.tv.show.next.aired/country.db @@ -1 +1 @@ -[{'': 'Unknown', 'TVP SA': 'Poland', 'ESPN': 'USA', 'Fox (IT)': 'Italy', 'FOX Sports 2': 'USA', 'V': 'Canada', 'W Network': 'Canada', 'Syfy': 'USA', 'Cuatro': 'Spain', 'ARY One World': 'Pakistan', '\xc4\x8ceskoslovensk\xc3\xa1 televize': 'Czech Republic', 'Golf Channel': 'USA', 'Rai 1': 'Italy', 'laSexta': 'Spain', 'Rai 3': 'Italy', 'Rai 2': 'Italy', 'TV3 (SE)': 'Sweden', '\xd0\x9f\xd0\xb5\xd1\x80\xd0\xb2\xd1\x8b\xd0\xb9 \xd0\xba\xd0\xb0\xd0\xbd\xd0\xb0\xd0\xbb': 'Russia', 'Anime Network': 'USA', 'Playhouse Disney': 'USA', 'Bravo (UK)': 'United Kingdom', 'Chorus Sports': 'Ireland', 'SBS (AU)': 'Australia', 'Watch': 'United Kingdom', '\xd0\x94\xd0\xbe\xd0\xb6\xd0\xb4\xd1\x8c': 'Russia', 'DRAMAcube': 'South Korea', 'FOX Sports 1': 'USA', 'Nelonen': 'Finland', 'ORTF': 'France', '\xd7\xa7\xd7\xa9\xd7\xaa': 'Israel', 'Mnet': 'South Korea', 'STAR Sports Asia': 'Hong Kong', 'Steel': 'Italy', 'The WB': 'USA', 'Swarnawahini': 'Sri Lanka', 'Community Channel': 'United Kingdom', 'Super!': 'Italy', 'Teletoon': 'Canada', 'BBC Prime': 'United Kingdom', 'LifeStyle HOME': 'Australia', '1+1': 'Ukraine', 'Destination America': 'USA', 'KIKA': 'Germany', 'El Rey Network': 'USA', 'AHC': 'USA', 'SBT': 'Brazil', 'SIC': 'Portugal', 'DIY Network': 'USA', 'BBC America': 'USA', 'RLTV': 'USA', 'Global': 'Canada', 'Tele 5': 'Germany', 'RTL Klub': 'Hungary', 'Polsat': 'Poland', 'TV5 Monde': 'France', 'CBC (CA)': 'Canada', 'Sanskar': 'India', 'DD-Gujarati': 'India', 'Doordarshan Sports': 'India', 'La Trois': 'Belgium', 'VIER': 'Belgium', 'SuoimiTV': 'Finland', 'Sky Box Office': 'United Kingdom', 'TRT Arabic': 'Turkey', '\xd0\x94\xd0\xbe\xd0\xbc\xd0\xb0\xd1\x88\xd0\xbd\xd0\xb8\xd0\xb9': 'Russia', 'TSN': 'Canada', 'NTR': 'Netherlands', 'SET Metro': 'Taiwan', 'Bounce TV': 'USA', 'BBC HD': 'United Kingdom', 'M6': 'France', 'TV Asahi': 'Japan', 'TV Tokyo': 'Japan', 'CW Seed': 'USA', 'CMT': 'USA', 'Cinemax': 'USA', 'BET': 'USA', 'Hakka TV': 'Taiwan', 'ICTV': 'Ukraine', 'AAG TV': 'Pakistan', 'TWiT': 'USA', 'CNNI': 'USA', 'NAVER tvcast': 'South Korea', 'RTBF': 'Belgium', 'Superstation WGN': 'USA', 'Amazon': 'USA', 'ARY Digital': 'Pakistan', 'Doordarshan News': 'India', 'KBS': 'South Korea', 'TVNorge': 'Norway', 'TEN Sports': 'India', 'PowNed': 'Netherlands', 'BBC Three': 'United Kingdom', 'Arena': 'Australia', 'HGTV Canada': 'Canada', 'DR2': 'Denmark', 'STAR Chinese Channel': 'Taiwan', 'Setanta Ireland': 'Ireland', 'FTV': 'Taiwan', 'CCTV': 'China', 'NFL Network': 'USA', 'G4': 'USA', 'Veronica': 'Netherlands', 'Swearnet': 'Canada', 'Zee Gujarati': 'India', 'Canal 9 (AR)': 'Argentina', 'MavTV': 'USA', 'Sixx': 'Germany', 'Bravo (CA)': 'Canada', 'TVS China': 'China', 'PTV Global': 'USA', 'DMAX (IT)': 'Italy', '3+': 'Switzerland', 'HLN': 'USA', 'rmusic TV': 'United Kingdom', 'Fox Life': 'Italy', 'TV Net': 'Turkey', 'here!': 'USA', 'ABC (AU)': 'Australia', 'CBC': 'Canada', 'TLC': 'USA', 'NOS': 'Netherlands', 'Animax': 'Japan', 'Oprah Winfrey Network': 'USA', 'CTS': 'Taiwan', 'FX': 'USA', 'TV Nova': 'Czech Republic', 'B92': 'Serbia', 'Indus News': 'Pakistan', 'MoonTV': 'Finland', 'Telemundo': 'USA', 'Slice': 'Canada', 'B4U Movies': 'United Kingdom', 'CTC': 'Japan', 'Dawn News': 'Pakistan', 'The Hub': 'USA', 'ZDF.Kultur': 'Germany', 'FOX SPORTS': 'Australia', 'MTV Brazil': 'Brazil', 'TVQ (Japan)': 'Japan', 'Dailymotion': 'USA', 'National Geographic (UK)': 'United Kingdom', 'ARTV': 'Canada', 'Anhui TV': 'China', 'Volksmusik TV': 'Germany', 'June': 'France', 'Mondo TV': 'Italy', 'CBBC': 'United Kingdom', 'Comedy Channel': 'USA', 'RCTV': 'Venezuela', 'MDR': 'Germany', 'SIC Sempre Gold': 'Portugal', 'ICI Tou.tv': 'Canada', 'BBC Parliament': 'United Kingdom', 'ABC (JA)': 'Japan', 'ORF 1': 'Austria', 'Show TV': 'Turkey', 'Jiangsu TV': 'China', 'Playboy TV': 'USA', 'RTP N': 'Portugal', 'TVBS Entertainment Channel': 'Taiwan', 'WE tv': 'USA', 'La Une': 'Belgium', 'UK Entertainment Channel': 'United Kingdom', 'Discovery Science': 'USA', 'H\xc3\xadr TV': 'Hungary', 'FEARnet': 'USA', 'Oasis HD': 'Canada', 'S4C2': 'United Kingdom', '\xd0\xa2\xd0\x92 \xd0\xa6\xd0\xb5\xd0\xbd\xd1\x82\xd1\x80': 'Russia', 'SBS': 'Australia', 'element14': 'USA', 'Discovery Family': 'USA', 'Sky Arts': 'United Kingdom', 'Comedy Central (US)': 'USA', 'SR': 'Germany', 'ABS-CBN Broadcasting Company': 'Philippines', '\xc3\xa9\xc3\xa9n': 'Belgium', 'NTV': 'Japan', 'PlayJam': 'United Kingdom', 'LMN': 'USA', 'NTA': 'Nigeria', 'ITVBe': 'United Kingdom', 'Zt\xc3\xa9l\xc3\xa9': 'Canada', 'ERT': 'Greece', 'Nick Jr.': 'USA', 'BBC Four': 'United Kingdom', 'Velocity': 'USA', 'Tokyo MX': 'Japan', 'RTP1': 'Portugal', 'TV11': 'Sweden', 'Geo TV': 'Pakistan', 'HBO Latin America': 'Brazil', 'TF1': 'France', 'UKTV Drama': 'United Kingdom', 'Com\xc3\xa9die+': 'France', 'Discovery Channel (Asia)': 'Singapore', 'Jeuxvideo.com': 'France', 'Phoenix': 'Germany', 'TV One (US)': 'USA', 'NCRV': 'Netherlands', 'Discovery Shed': 'United Kingdom', 'STV (TW)': 'Taiwan', 'ANT1': 'Greece', 'ESPN India': 'India', 'NHK': 'Japan', 'Family (CA)': 'Canada', 'Nick GAS': 'USA', 'LaSexta': 'Italy', 'ABC News 24': 'Australia', 'Cartoon Network Australia': 'Australia', 'TVA (JP)': 'Japan', 'JIM': 'Finland', 'FXX': 'USA', 'TVS Sydney': 'Australia', 'HGTV': 'USA', 'TV 2 Filmkanalen': 'Norway', 'STAR Sports Malaysia': 'Malaysia', 'Canal 10 Saeta': 'Uruguay', 'TV Cultura': 'Brazil', 'KTN': 'Pakistan', 'TV 2 Zulu': 'Denmark', 'SIC Radical': 'Portugal', 'T\xc3\xa9l\xc3\xa9toon': 'France', '\xd0\xa1\xd0\xa2\xd0\xa1': 'Russia', '\xd7\xa2\xd7\xa8\xd7\x95\xd7\xa5 \xd7\x94\xd7\x99\xd7\x9c\xd7\x93\xd7\x99\xd7\x9d\xe2\x80\x8e': 'Israel', 'TV3 (IE)': 'Ireland', 'TV3+': 'Denmark', 'PRO TV': 'Romania', 'Discovery Turbo UK': 'United Kingdom', 'TFO': 'Canada', 'VPRO': 'Netherlands', 'Star TV': 'Turkey', 'NET 5': 'Netherlands', 'VijfTV': 'Belgium', 'Sky News Ireland': 'Ireland', 'Fox Business': 'USA', 'Classic Arts Showcase': 'USA', 'NTV (TW)': 'Taiwan', 'Canal 4 Montecarlo': 'Uruguay', 'addikTV': 'Canada', 'Vimeo': 'USA', 'BBC World News': 'United Kingdom', 'Voyage': 'France', 'Yahoo! Screen': 'USA', 'Fashion TV': 'France', 'Eurosport': 'United Kingdom', 'Zee Cinema': 'India', 'HBO Europe': 'Hungary', 'RT\xc3\x89 Two': 'Ireland', 'Canadian Learning Television': 'Canada', 'Revelation TV': 'United Kingdom', 'C31': 'Australia', 'ETTV': 'Taiwan', 'Televisi\xc3\xb3n de Galicia': 'Spain', '24': 'Turkey', 'Comedy (CA)': 'Canada', 'Pakapaka': 'Argentina', 'AOL': 'USA', 'CBeebies': 'United Kingdom', 'RAI': 'Italy', 'TV3 (NZ)': 'New Zealand', 'Kids Station': 'Japan', 'Fred TV': 'USA', 'Doordarshan National': 'India', 'STAR Plus': 'India', 'TV Cabo': 'Portugal', 'RTL Televizija': 'Croatia', 'Carlton Television': 'United Kingdom', 'Jupiter Broadcasting ': 'USA', 'Royal News': 'Pakistan', 'RTP Madeira': 'Portugal', 'Russia Today': 'Russia', 'T\xc3\xa9l\xc3\xa9-Qu\xc3\xa9bec': 'Canada', 'Challenge': 'United Kingdom', 'AVRO': 'Netherlands', 'SKY PerfecTV!': 'Japan', 'Nickelodeon': 'USA', 'L\xc3\xa2leg\xc3\xbcl TV': 'Turkey', 'Ch\xc3\xa9rie 25': 'France', 'Deutsche Welle TV': 'Germany', 'Sky Living': 'United Kingdom', 'AT-X': 'Japan', 'ETTV Yoyo': 'Taiwan', 'NRK1': 'Norway', 'NRK3': 'Norway', 'NRK2': 'Norway', 'Network Ten': 'Australia', '\xd0\x9d\xd0\xa2\xd0\x92': 'Russia', 'UKTV Food': 'United Kingdom', 'ESPN Hong Kong': 'Hong Kong', 'MTV Base': 'United Kingdom', 'A&E': 'USA', 'SOAPnet': 'USA', 'Rooster Teeth': 'USA', 'Crackle': 'USA', 'A Haber': 'Turkey', 'Sky Deutschland': 'Germany', 'Military Channel': 'USA', 'Skai': 'Greece', 'TVOne Global': 'Pakistan', 'Sirasa': 'Sri Lanka', 'eqhd': 'Canada', '\xd0\xa2\xd0\x92\xd0\xa1': 'Russia', 'RTL TVI': 'Belgium', 'Al Alam': 'Iran', 'ABC (US)': 'USA', 'Sky Uno': 'Italy', 'TRT Avaz': 'Turkey', 'Showcase (CA)': 'Canada', 'Plug RTL': 'Belgium', 'OCN': 'South Korea', 'ZDFneo': 'Germany', 'France 3': 'France', 'France 2': 'France', 'France 5': 'France', 'France 4': 'France', 'SUN news': 'India', 'Radio Bremen': 'Germany', 'ABC': 'USA', 'Arte': 'France', 'Kashish TV': 'Pakistan', 'IFC': 'USA', 'SRF 1': 'Switzerland', 'OCS': 'France', 'VARA': 'Netherlands', 'UKTV Gold': 'United Kingdom', 'MTV3': 'Finland', 'Channel [V]': 'China', 'Discovery': 'USA', 'Ion Television': 'USA', 'AXS TV': 'USA', 'Spektrum': 'Hungary', 'RTL': 'Luxembourg', 'E!': 'USA', 'NBCSN': 'USA', 'TITV': 'Taiwan', 'BBC Canada': 'Canada', 'E4': 'United Kingdom', 'ORF III': 'Austria', 'The Family Channel': 'USA', 'BBC One': 'United Kingdom', 'EO': 'Netherlands', 'Discovery HD World': 'Singapore', 'Filles TV': 'France', 'SBS 6': 'Netherlands', 'YTV': 'Canada', 'TVRI': 'Indonesia', 'MTV (US)': 'USA', 'Record': 'Brazil', 'Bubble Hits': 'Ireland', 'W': 'Australia', 'TV 2 Science Fiction': 'Norway', 'SIC Mulher': 'Portugal', 'TV 2 Nyhetskanalen': 'Norway', 'BTV': 'China', 'LifeStyle': 'Australia', 'Abu Dhabi TV': 'United Arab Emirates', 'TV Chile': 'Chile', 'TBS': 'USA', 'TRT T\xc3\xbcrk': 'Turkey', 'TV S\xc3\xa3o Carlos': 'Brazil', 'STV': 'United Kingdom', 'MTV Dance': 'United Kingdom', 'Kyoto Broadcasting System': 'Japan', 'UTV': 'Ireland', 'C-Span': 'USA', 'TRT Diyanet': 'Turkey', 'CTV (JP)': 'Japan', 'CNBC': 'USA', 'UKTV Style': 'United Kingdom', 'Alpha TV PUNJABI': 'India', 'Prime (NZ)': 'New Zealand', 'STV (UK)': 'United Kingdom', 'RTP \xc3\x81frica': 'Portugal', 'SVTB': 'Sweden', 'ATV': 'Austria', 'TNT Serie': 'Germany', 'Sahara ONE': 'India', 'Discovery MAX': 'Spain', 'iQiyi': 'China', 'MSNBC': 'USA', 'MTV2': 'USA', 'Das Erste': 'Germany', 'RT\xc3\x89 One': 'Ireland', 'TRT 1': 'Turkey', 'Animal Planet': 'USA', 'vtmKzoom': 'Belgium', 'WOWOW': 'Japan', 'Sony Entertainment Television': 'USA', 'STAR Vijay': 'India', 'VT4': 'Belgium', 'TV Land': 'USA', 'KCET': 'USA', 'PTS HD': 'Taiwan', 'Aizo TV': 'Taiwan', 'SciFi': 'USA', 'BNN (NL)': 'Netherlands', 'TV Osaka': 'Japan', '\xd0\xa0\xd0\x95\xd0\x9d': 'Russia', 'TV7 (SE)': 'Sweden', 'Treehouse TV': 'Canada', 'Venevision': 'Venezuela', 'Magyar Telev\xc3\xadzi\xc3\xb3': 'Hungary', 'ART TV': 'Greece', 'SundanceTV': 'USA', 'USA Network': 'USA', 'GTV': 'Taiwan', 'NickToons': 'USA', 'Boomerang': 'USA', 'CSTV': 'South Korea', 'Esquire Network': 'USA', 'Five Life': 'United Kingdom', 'SVT24': 'Sweden', 'GEO Super': 'Pakistan', 'Ora TV': 'USA', 'Fox Channel': 'Germany', 'Current TV': 'USA', 'Televisa': 'Mexico', 'Showcase (AU)': 'Australia', 'TV4 Plus': 'Sweden', 'ITV': 'United Kingdom', 'SAT.1': 'Germany', 'TVP1': 'Poland', 'SVT2': 'Sweden', 'SVT1': 'Sweden', 'Smash Hits': 'United Kingdom', 'Cielo': 'Italy', 'SABC3': 'South Africa', 'Mega Channel': 'Greece', 'CTV (CN)': 'China', 'UKTV History': 'United Kingdom', 'Puls 4': 'Austria', 'TheBlaze': 'USA', 'Travel Channel (UK)': 'United Kingdom', 'TeleZ\xc3\xbcri': 'Switzerland', 'SWR': 'Germany', 'The Weather Channel': 'USA', 'Servus TV': 'Austria', 'UNTV 37': 'Philippines', 'Nagoya Broadcasting Network': 'Japan', 'Thames Television': 'United Kingdom', 'FYI': 'USA', 'TV 2': 'Norway', 'TV 3': 'Denmark', 'Fox Crime': 'Italy', 'Beyaz TV': 'Turkey', 'Kiss': 'United Kingdom', 'Discovery Turbo': 'USA', '2BE': 'Belgium', 'radX': 'Canada', 'TV 2 Sport': 'Norway', 'Toon Disney': 'USA', 'Viasat 4': 'Norway', 'Ovation TV': 'USA', 'FEM': 'United Kingdom', '\xd0\x9f\xd1\x8f\xd1\x82\xd1\x8b\xd0\xb9 \xd0\xba\xd0\xb0\xd0\xbd\xd0\xb0\xd0\xbb': 'Russia', 'ITV Wales': 'United Kingdom', 'TG4': 'Ireland', 'truTV': 'USA', 'VTM': 'Belgium', 'Discovery Kids': 'USA', 'Hunan TV': 'China', 'TVNZ': 'New Zealand', 'PBS Kids Sprout': 'USA', 'VH1 Classics': 'USA', 'RCN TV': 'Colombia', 'Radio Canada': 'Canada', 'RBB': 'Germany', 'Encore': 'USA', 'Caracol TV': 'Colombia', 'MCM': 'France', 'TV Guide Channel': 'USA', 'E! (CA)': 'Canada', 'Starz!': 'USA', 'Dost TV': 'Turkey', 'ESPN Asia': 'Hong Kong', 'CITV': 'United Kingdom', 'TV4 Fakta': 'Sweden', 'Fuji TV': 'Japan', 'Classic FM TV': 'United Kingdom', 'Epsilon TV': 'Greece', 'TV4 Guld': 'Sweden', 'D8': 'France', 'Dish TV': 'USA', 'Kunskapskanalen': 'Sweden', 'Sab TV': 'India', '\xd0\x97\xd0\xb2\xd0\xb5\xd0\xb7\xd0\xb4\xd0\xb0': 'Russia', 'Speed': 'USA', 'TRT Kurd\xc3\xae': 'Turkey', 'Australian Christian Channel': 'Australia', 'E-Channel': 'South Korea', 'Turner South': 'USA', 'MTV Mandarin': 'Taiwan', 'Smithsonian Channel': 'USA', 'STAR Sports Hong Kong': 'Hong Kong', 'TTV': 'Taiwan', 'Canal Off': 'Brazil', 'HIFI': 'Canada', 'YLE': 'Finland', 'STAR News': 'India', 'Rede Globo': 'Brazil', '\xd0\xa2\xd0\x923': 'Russia', 'TQS': 'Canada', 'SUN TV': 'India', 'AXN': 'USA', 'Nine Network': 'Australia', 'Kamp\xc3\xbcs TV': 'Turkey', 'Kids and Teens TV': 'USA', 'Sky Cinema (IT)': 'Italy', 'SET MAX': 'India', 'Hulu': 'USA', 'TRT Belgesel': 'Turkey', 'RTP Internacional': 'Portugal', 'BS11': 'Japan', 'Sky Movies': 'United Kingdom', 'Revision3': 'USA', 'La Cinq': 'France', 'Magic': 'United Kingdom', 'Antenne 2': 'France', 'Pub Channel': 'United Kingdom', 'Phoenix TV': 'China', 'FOX T\xc3\xbcrkiye': 'Turkey', 'Omroep Brabant': 'Netherlands', 'BNN': 'Canada', 'Sky Cinema': 'United Kingdom', 'The Den': 'Ireland', 'Fox Family': 'USA', 'KanaalTwee': 'Belgium', 'Much TV': 'Taiwan', 'Adult Channel': 'United Kingdom', 'Alpha TV': 'Greece', 'Television Osaka': 'Japan', 'National Geographic': 'USA', '\xd0\xa0\xd0\xbe\xd1\x81\xd1\x81\xd0\xb8\xd1\x8f 1': 'Russia', 'WDR': 'Germany', 'TV3 Puls': 'Denmark', 'Varsity TV': 'USA', 'MBC Plus Media': 'South Korea', 'FUNimation Channel': 'USA', 'TV Aichi': 'Japan', 'NRK Super': 'Norway', 'Super Channel': 'Canada', 'W9': 'France', 'Hallmark Channel': 'USA', 'TV One (NZ)': 'New Zealand', 'Seven Network': 'Australia', 'TV 2 Zebra': 'Norway', 'TBN (Trinity Broadcasting Network)': 'USA', 'MTV (UK)': 'United Kingdom', 'TV3 (NO)': 'Norway', 'M-Net': 'South Africa', 'La Siete': 'Spain', 'La Deux': 'Belgium', 'Q TV': 'United Kingdom', 'Paramount Comedy': 'United Kingdom', 'TV4 Science Fiction': 'Sweden', 'Spike TV': 'USA', 'yes': 'Israel', 'NDTV India': 'India', 'More4': 'United Kingdom', 'dk4': 'Denmark', 'Life OK': 'India', 'Univision': 'USA', 'WNL': 'Netherlands', '\xd7\x94\xd7\xa2\xd7\xa8\xd7\x95\xd7\xa5 \xd7\x94\xd7\xa8\xd7\x90\xd7\xa9\xd7\x95\xd7\x9f': 'Israel', 'ETV Gujarati': 'India', 'TCM': 'United Kingdom', 'Sky News': 'United Kingdom', '360': 'Turkey', 'RT': 'Russia', 'ITV Granada': 'United Kingdom', 'FOX': 'USA', 'APTN': 'Canada', '\xd7\xa8\xd7\xa9\xd7\xaa': 'Israel', 'CBC (JP)': 'Japan', 'MusiquePlus': 'Canada', 'Five US': 'United Kingdom', 'NECO': 'Japan', 'BBC Two': 'United Kingdom', 'DaAi TV': 'Taiwan', 'City Channel': 'Ireland', 'Much (CA)': 'Canada', "6'eren": 'Denmark', 'Fox Reality': 'USA', 'Omroep MAX': 'Netherlands', 'MTV Italia': 'Italy', 'CNBC TV18': 'India', 'Crime & Investigation Network': 'USA', 'Logo': 'USA', 'Sony TV': 'India', 'Sky Sports': 'United Kingdom', 'LCI': 'France', 'bTV': 'Bulgaria', 'ETV': 'Estonia', 'The Sportsman Channel': 'USA', '\xc3\x89vasion': 'Canada', 'YouTube': 'USA', 'SIC Com\xc3\xa9dia': 'Portugal', 'Science Channel': 'USA', 'STAR Sports Taiwan': 'Taiwan', 'Press TV': 'Iran', 'BBC Kids': 'Canada', 'TMC': 'Monaco', 'XY TV': 'USA', 'TMF': 'Netherlands', 'Planet Green': 'USA', 'Channel 101': 'USA', 'Gaiam TV ': 'USA', 'Channel U': 'Singapore', 'RTS Un': 'Switzerland', 'Teledoce': 'Uruguay', 'America One Television Network': 'USA', 'STAR Sports India': 'India', 'RTL Television': 'Germany', 'Great American Country': 'USA', '+Globosat': 'Brazil', 'OLN': 'Canada', 'TVM': 'Malta', 'Kanal 4': 'Denmark', 'MTV Hits': 'USA', 'TVI': 'Portugal', 'DMAX (DE)': 'Germany', 'IKON': 'Netherlands', 'TVE': 'Spain', 'Noggin': 'USA', 'STAR Movies': 'Hong Kong', 'Canal 5': 'Mexico', 'Canal J': 'France', 'CI': 'Australia', 'TV8': 'Sweden', 'TSR': 'Switzerland', 'TeenNick': 'USA', 'TV6': 'Sweden', 'El Trece': 'Argentina', 'Canal D': 'Canada', 'TV2': 'New Zealand', 'Kanal 5': 'Sweden', 'TRT Okul': 'Turkey', 'KRO': 'Netherlands', 'Action': 'Canada', 'TestTube': 'USA', 'NDR': 'Germany', 'Semerkand TV': 'Turkey', 'QTV': 'Pakistan', 'RTP A\xc3\xa7ores': 'Portugal', '\xd0\x94\xd0\xa2\xd0\x92': 'Russia', 'DR Ramasjang': 'Denmark', 'Zhejiang TV': 'China', 'RMC D\xc3\xa9couverte': 'France', 'Bandai Channel': 'Japan', 'Com\xc3\xa9die !': 'France', 'WPIX': 'USA', 'TRT \xc3\x87ocuk': 'Turkey', 'Channel 8': 'Singapore', 'Colors': 'India', '\xd0\xa2\xd0\x9d\xd0\xa2': 'Russia', 'ZDF': 'Germany', 'ABC1': 'Australia', 'ABC2': 'Australia', 'ABC3': 'Australia', 'SoHo': 'Australia', 'Channel 2': 'Israel', 'Channel 3': 'Thailand', 'Channel 4': 'United Kingdom', 'Channel 5': 'United Kingdom', 'Channel 6': 'Ireland', 'Channel 7': 'Thailand', 'City': 'Canada', 'History': 'USA', 'DDR1': 'Germany', 'Disney Channel (Germany)': 'Germany', 'GNT': 'Brazil', 'The Africa Channel': 'United Kingdom', 'SIC Not\xc3\xadcias': 'Portugal', 'EinsPlus': 'Germany', 'ABC (PH)': 'Philippines', 'HBO Magyarorsz\xc3\xa1g': 'Hungary', 'S\xc3\xa9ries+': 'Canada', 'PTV Home': 'Pakistan', 'This TV': 'USA', 'DR K': 'Denmark', 'MBN': 'South Korea', 'OWN': 'USA', 'CBS': 'USA', 'ProSieben': 'Germany', 'UP TV': 'USA', 'TeleG': 'United Kingdom', 'MBC': 'South Korea', 'Liberty TV': 'United Kingdom', 'ESPN Taiwan': 'Taiwan', 'MBS': 'Japan', 'Rete 4': 'Italy', 'Discovery Life': 'USA', 'YTV (UK)': 'United Kingdom', 'Oxygen': 'USA', 'WealthTV': 'USA', 'Style': 'USA', 'Trend E': 'South Korea', 'MTV': 'USA', 'The Box': 'United Kingdom', 'Al Arabiyya': 'United Arab Emirates', 'TV Azteca': 'Mexico', 'fuse': 'USA', 'MUTV': 'United Kingdom', 'Sky Cinema (UK)': 'United Kingdom', 'Pivot': 'USA', 'Sky1': 'United Kingdom', 'Sky3': 'United Kingdom', 'Sky2': 'United Kingdom', 'UKTV Yesterday': 'United Kingdom', 'Zee Muzic': 'India', 'Indus Music': 'Pakistan', 'PTV Bolan': 'Pakistan', 'TVQ (Australia)': 'Australia', 'History (CA)': 'Canada', 'TV3 (ES)': 'Spain', 'Movie Central': 'Canada', 'Blip': 'USA', 'Gulli': 'France', 'Canal Sur': 'Spain', 'EBS': 'South Korea', 'Italia 1': 'Italy', 'TV 4': 'Poland', 'TVN Style': 'Poland', 'Living': 'United Kingdom', 'HBO': 'USA', 'Vrak.TV': 'Canada', 'Star World': 'Hong Kong', 'Joi': 'Italy', 'ABC Family': 'USA', 'Travel Channel': 'USA', 'The CW': 'USA', 'CTV': 'Canada', 'FOX Traveller': 'India', 'Nolife': 'France', 'Outdoor Channel': 'USA', 'BR': 'Germany', 'Teletama': 'Japan', 'Aaj TV': 'Pakistan', 'SBS Plus': 'South Korea', 'Food Network Canada': 'Canada', 'BYU Television': 'USA', 'GSN': 'USA', 'HBO Nordic': 'Sweden', 'Nat Geo Wild': 'USA', 'Canale 5': 'Italy', 'TV4 Komedi': 'Sweden', 'G4 Canada': 'Canada', 'Duna TV': 'Hungary', 'KBS TV2': 'South Korea', 'KBS TV1': 'South Korea', '\xd7\xa2\xd7\xa8\xd7\x95\xd7\xa5 10': 'Israel', 'RVU': 'Netherlands', 'Liberty Channel': 'USA', 'Olive': 'South Korea', 'Antena 3': 'Spain', 'NTV (JP)': 'Japan', 'Nick at Nite': 'USA', 'PTV News': 'Pakistan', 'Xbox Video': 'USA', 'BabyFirstTV': 'USA', 'B4U Music': 'United Kingdom', 'Prima televize': 'Czech Republic', 'SVT': 'Sweden', 'ESPN Philippines': 'Philippines', 'Scuzz': 'United Kingdom', 'BR-alpha': 'Germany', 'Canal+': 'France', 'TV P\xc3\xbablica': 'Argentina', 'M\xc4\x81ori Television': 'New Zealand', 'DR1': 'Denmark', 'Bravo': 'USA', 'DR3': 'Denmark', 'Al Jazeera America': 'USA', '3sat': 'Germany', 'Disney Junior': 'USA', 'PBS': 'USA', 'TrueVisions': 'Thailand', 'ICI Explora': 'Canada', 'Mya': 'Italy', 'FOX (FI)': 'Finland', 'TV 2 Charlie': 'Denmark', 'Zee TV': 'India', 'Bravo (US)': 'USA', 'Sub': 'Finland', 'VH1': 'USA', 'Cooking Channel': 'USA', 'ReelzChannel': 'USA', 'Pick TV': 'United Kingdom', 'Telecinco': 'Spain', 'Canal 13': 'Chile', 'Toei Channel': 'Japan', 'ARY Zouq': 'Pakistan', 'Sky Travel': 'United Kingdom', 'tvk': 'Japan', '\xd7\x98\xd7\x9c\xd7\xa2\xd7\x93': 'Israel', 'STAR One': 'India', 'Multishow': 'Brazil', 'TVG Network': 'USA', 'The Movie Network': 'Canada', 'Centric': 'USA', 'NHNZ': 'New Zealand', 'RTL 8': 'Netherlands', 'RTL 7': 'Netherlands', 'AMC': 'USA', 'RTL 4': 'Netherlands', 'QVC': 'USA', 'Dave': 'United Kingdom', 'tvN': 'South Korea', 'CTi TV': 'Taiwan', 'MNN': 'USA', 'Tev\xc3\xa9Ciudad': 'Uruguay', 'PTS': 'Taiwan', 'NT1': 'France', 'UPN': 'USA', 'Sportsman Channel': 'USA', 'Eden': 'United Kingdom', 'Al Jazeera': 'Qatar', 'Schweizer Fernsehen': 'Switzerland', 'Syndication': 'USA', 'NBA TV': 'USA', 'Nou Televisi\xc3\xb3': 'Spain', '\xd0\xa0\xd0\xbe\xd1\x81\xd1\x81\xd0\xb8\xd1\x8f \xd0\x9a': 'Russia', 'CPAC': 'Canada', 'National Geographic Adventure': 'USA', 'The Verge': 'USA', 'MATV': 'United Kingdom', 'Sleuth': 'USA', 'Kerrang! TV': 'United Kingdom', 'TVBS': 'China', 'H2': 'USA', 'DuMont Television Network': 'USA', 'KBS World': 'South Korea', 'Niconico': 'Japan', 'Indus Vision': 'Pakistan', 'Chart Show TV': 'United Kingdom', 'Dragon TV': 'China', 'Canal Famille': 'Canada', 'Lifetime': 'USA', 'VOX': 'Germany', 'ITV4': 'United Kingdom', 'ITV1': 'United Kingdom', 'Kanal 7': 'Turkey', 'ITV3': 'United Kingdom', 'ITV2': 'United Kingdom', 'Audience Network': 'USA', 'RCTI': 'Indonesia', 'Studio 23': 'Philippines', 'NovaTV': 'Bulgaria', 'ZOOM': 'India', 'TROS': 'Netherlands', 'PlayStation Network': 'USA', 'MBC Drama': 'South Korea', 'ABC4Kids': 'Australia', 'STAR Sports Southeast Asia': 'Hong Kong', 'BBC ALBA': 'United Kingdom', 'Prime (BE)': 'Belgium', 'TVN': 'Poland', 'TVO': 'Canada', 'WGN America': 'USA', 'HDNet': 'USA', 'jTBC': 'South Korea', 'Disney Cinemagic': 'United Kingdom', 'Rede Bandeirantes': 'Brazil', 'Cartoon Network': 'USA', 'NBC': 'USA', 'Super \xc3\x89cran': 'Canada', 'TVP2': 'Poland', 'CGV': 'South Korea', 'SABC2': 'South Africa', 'Discovery Channel (Australia)': 'Australia', 'SABC1': 'South Africa', 'Warner Channel': 'USA', 'TVN Turbo': 'Poland', 'Televen': 'Venezuela', 'GMA': 'Philippines', 'France \xc3\x94': 'France', '2\xc3\x972': 'Russia', 'HBO Canada': 'Canada', 'ATN Aastha Channel': 'India', 'Fox8': 'Australia', 'MBC Every1': 'South Korea', 'New Tang Dynasty TV': 'USA', 'DIY Network Canada': 'Canada', 'Disney Channel (US)': 'USA', 't\xc3\xa9va': 'France', 'RDI': 'Canada', 'Videoland Television Network': 'Taiwan', 'Canal de las Estrellas': 'Mexico', 'Lifetime UK': 'United Kingdom', 'TGRT Haber': 'Turkey', 'TVA': 'Canada', 'SUN music': 'India', 'National Geographic (US)': 'USA', 'Disney XD': 'USA', 'TV7 (BG)': 'Bulgaria', 'Kanal D': 'Turkey', 'Cine 5': 'Turkey', 'Court TV': 'USA', 'TVB': 'China', 'BBC News': 'United Kingdom', 'Canal Once': 'Mexico', 'STAR Gold': 'India', '\xc3\x9clke TV': 'Turkey', 'Space': 'Canada', 'NDTV 24x7': 'India', 'SET TV': 'Taiwan', 'Einsfestival': 'Germany', 'Club RTL': 'Belgium', 'Pop': 'USA', 'ORF 2': 'Austria', 'NRJ 12': 'France', 'Guardian Television Network': 'USA', 'Comedy Central (UK)': 'United Kingdom', 'TVGN': 'USA', 'AlloCin\xc3\xa9': 'France', 'ARY Shopping Channel': 'Pakistan', 'CN8': 'USA', 'Investigation Discovery': 'USA', 'The Amp': 'United Kingdom', 'Ustream': 'USA', 'Five': 'United Kingdom', 'Adult Swim': 'USA', 'TV4': 'Sweden', 'S4/C': 'United Kingdom', 'News One': 'Pakistan', 'TNU': 'Uruguay', 'TNT': 'USA', 'MBC Queen': 'South Korea', 'Casa': 'Canada', 'Netflix': 'USA', 'Fuel TV': 'USA', 'Kanal A (Turkey)': 'Turkey', '\xc4\x8cesk\xc3\xa1 televize': 'Czech Republic', 'FOX (US)': 'USA', 'BNT1': 'Bulgaria', 'HOT': 'Israel', 'Red Hot TV': 'United Kingdom', 'Alpha TV GUJARATI': 'India', 'MyNetworkTV': 'USA', 'CNN': 'USA', 'Food Network': 'USA', 'TRT Haber': 'Turkey', 'Nou 24': 'Spain', '\xd0\x86\xd0\xbd\xd1\x82\xd0\xb5\xd1\x80': 'Ukraine', 'Omni': 'Canada', 'Showtime': 'USA', 'Tokyo Broadcasting System': 'Japan', 'ATV T\xc3\xbcrkiye': 'Turkey', 'Universal Channel': 'Brazil', 'Encuentro': 'Argentina', 'LifeStyle FOOD': 'Australia', 'TRT World': 'Turkey', 'TRT HD': 'Turkey', 'Canvas/Ketnet': 'Belgium', 'YTV (CA)': 'Canada', 'Hrvatska radiotelevizija': 'Croatia', 'Sky Atlantic': 'United Kingdom', 'BBC iPlayer': 'United Kingdom', 'La7': 'Italy', 'YTV (JP)': 'Japan', 'RTL 5': 'Netherlands'}, 1, 1440962589.943218] \ No newline at end of file +[{'': 'Unknown', 'TVP SA': 'Poland', 'ESPN': 'USA', 'Fox (IT)': 'Italy', 'FOX Sports 2': 'USA', 'V': 'Canada', 'W Network': 'Canada', 'Syfy': 'USA', 'Cuatro': 'Spain', 'ARY One World': 'Pakistan', '\xc4\x8ceskoslovensk\xc3\xa1 televize': 'Czech Republic', 'Golf Channel': 'USA', 'Rai 1': 'Italy', 'laSexta': 'Spain', 'Rai 3': 'Italy', 'Rai 2': 'Italy', 'TV3 (SE)': 'Sweden', '\xd0\x9f\xd0\xb5\xd1\x80\xd0\xb2\xd1\x8b\xd0\xb9 \xd0\xba\xd0\xb0\xd0\xbd\xd0\xb0\xd0\xbb': 'Russia', 'Anime Network': 'USA', 'Playhouse Disney': 'USA', 'Bravo (UK)': 'United Kingdom', 'Chorus Sports': 'Ireland', 'SBS (AU)': 'Australia', 'Watch': 'United Kingdom', '\xd0\x94\xd0\xbe\xd0\xb6\xd0\xb4\xd1\x8c': 'Russia', 'DRAMAcube': 'South Korea', 'FOX Sports 1': 'USA', 'Nelonen': 'Finland', 'ORTF': 'France', '\xd7\xa7\xd7\xa9\xd7\xaa': 'Israel', 'Mnet': 'South Korea', 'STAR Sports Asia': 'Hong Kong', 'Steel': 'Italy', 'The WB': 'USA', 'Swarnawahini': 'Sri Lanka', 'Community Channel': 'United Kingdom', 'Super!': 'Italy', 'Teletoon': 'Canada', 'BBC Prime': 'United Kingdom', 'LifeStyle HOME': 'Australia', '1+1': 'Ukraine', 'Destination America': 'USA', 'KIKA': 'Germany', 'El Rey Network': 'USA', 'AHC': 'USA', 'SBT': 'Brazil', 'SIC': 'Portugal', 'DIY Network': 'USA', 'BBC America': 'USA', 'RLTV': 'USA', 'Global': 'Canada', 'Tele 5': 'Germany', 'RTL Klub': 'Hungary', 'Polsat': 'Poland', 'TV5 Monde': 'France', 'CBC (CA)': 'Canada', 'Sanskar': 'India', 'DD-Gujarati': 'India', 'Doordarshan Sports': 'India', 'La Trois': 'Belgium', 'VIER': 'Belgium', 'SuoimiTV': 'Finland', 'Sky Box Office': 'United Kingdom', 'TRT Arabic': 'Turkey', '\xd0\x94\xd0\xbe\xd0\xbc\xd0\xb0\xd1\x88\xd0\xbd\xd0\xb8\xd0\xb9': 'Russia', 'TSN': 'Canada', 'NTR': 'Netherlands', 'SET Metro': 'Taiwan', 'Bounce TV': 'USA', 'BBC HD': 'United Kingdom', 'M6': 'France', 'TV Asahi': 'Japan', 'TV Tokyo': 'Japan', 'CW Seed': 'USA', 'CMT': 'USA', 'Cinemax': 'USA', 'BET': 'USA', 'Hakka TV': 'Taiwan', 'ICTV': 'Ukraine', 'AAG TV': 'Pakistan', 'TWiT': 'USA', 'CNNI': 'USA', 'NAVER tvcast': 'South Korea', 'RTBF': 'Belgium', 'Superstation WGN': 'USA', 'Amazon': 'USA', 'ARY Digital': 'Pakistan', 'Doordarshan News': 'India', 'KBS': 'South Korea', 'TVNorge': 'Norway', 'TEN Sports': 'India', 'PowNed': 'Netherlands', 'BBC Three': 'United Kingdom', 'Arena': 'Australia', 'HGTV Canada': 'Canada', 'DR2': 'Denmark', 'STAR Chinese Channel': 'Taiwan', 'Setanta Ireland': 'Ireland', 'FTV': 'Taiwan', 'CCTV': 'China', 'NFL Network': 'USA', 'G4': 'USA', 'Veronica': 'Netherlands', 'Swearnet': 'Canada', 'Zee Gujarati': 'India', 'Canal 9 (AR)': 'Argentina', 'MavTV': 'USA', 'Sixx': 'Germany', 'Bravo (CA)': 'Canada', 'TVS China': 'China', 'PTV Global': 'USA', 'DMAX (IT)': 'Italy', '3+': 'Switzerland', 'HLN': 'USA', 'rmusic TV': 'United Kingdom', 'Fox Life': 'Italy', 'TV Net': 'Turkey', 'here!': 'USA', 'ABC (AU)': 'Australia', 'CBC': 'Canada', 'TLC': 'USA', 'NOS': 'Netherlands', 'Animax': 'Japan', 'Oprah Winfrey Network': 'USA', 'CTS': 'Taiwan', 'FX': 'USA', 'TV Nova': 'Czech Republic', 'B92': 'Serbia', 'Indus News': 'Pakistan', 'MoonTV': 'Finland', 'Telemundo': 'USA', 'Slice': 'Canada', 'CTC': 'Japan', 'Dawn News': 'Pakistan', 'The Hub': 'USA', 'ZDF.Kultur': 'Germany', 'FOX SPORTS': 'Australia', 'MTV Brazil': 'Brazil', 'TVQ (Japan)': 'Japan', 'Dailymotion': 'USA', 'National Geographic (UK)': 'United Kingdom', 'ARTV': 'Canada', 'Anhui TV': 'China', 'Volksmusik TV': 'Germany', 'June': 'France', 'Mondo TV': 'Italy', 'CBBC': 'United Kingdom', 'Comedy Channel': 'USA', 'RCTV': 'Venezuela', 'MDR': 'Germany', 'SIC Sempre Gold': 'Portugal', 'ICI Tou.tv': 'Canada', 'BBC Parliament': 'United Kingdom', 'ABC (JA)': 'Japan', 'ORF 1': 'Austria', 'Show TV': 'Turkey', 'Jiangsu TV': 'China', 'Playboy TV': 'USA', 'RTP N': 'Portugal', 'TVBS Entertainment Channel': 'Taiwan', 'WE tv': 'USA', 'La Une': 'Belgium', 'UK Entertainment Channel': 'United Kingdom', 'Discovery Science': 'USA', 'H\xc3\xadr TV': 'Hungary', 'FEARnet': 'USA', 'Oasis HD': 'Canada', 'S4C2': 'United Kingdom', '\xd0\xa2\xd0\x92 \xd0\xa6\xd0\xb5\xd0\xbd\xd1\x82\xd1\x80': 'Russia', 'SBS': 'Australia', 'element14': 'USA', 'Discovery Family': 'USA', 'Sky Arts': 'United Kingdom', 'Comedy Central (US)': 'USA', 'SR': 'Germany', 'ABS-CBN Broadcasting Company': 'Philippines', '\xc3\xa9\xc3\xa9n': 'Belgium', 'NTV': 'Japan', 'PlayJam': 'United Kingdom', 'LMN': 'USA', 'NTA': 'Nigeria', 'ITVBe': 'United Kingdom', 'Zt\xc3\xa9l\xc3\xa9': 'Canada', 'ERT': 'Greece', 'Nick Jr.': 'USA', 'FOX (UK)': 'United Kingdom', 'BBC Four': 'United Kingdom', 'Velocity': 'USA', 'Tokyo MX': 'Japan', 'RTP1': 'Portugal', 'TV11': 'Sweden', 'Geo TV': 'Pakistan', 'HBO Latin America': 'Brazil', 'TF1': 'France', 'UKTV Drama': 'United Kingdom', 'Com\xc3\xa9die+': 'France', 'Discovery Channel (Asia)': 'Singapore', 'Jeuxvideo.com': 'France', 'Phoenix': 'Germany', 'TV One (US)': 'USA', 'NCRV': 'Netherlands', 'Discovery Shed': 'United Kingdom', 'STV (TW)': 'Taiwan', 'ANT1': 'Greece', 'ESPN India': 'India', 'NHK': 'Japan', 'Family (CA)': 'Canada', 'Nick GAS': 'USA', 'LaSexta': 'Italy', 'ABC News 24': 'Australia', 'Cartoon Network Australia': 'Australia', 'TVA (JP)': 'Japan', 'JIM': 'Finland', 'FXX': 'USA', 'TVS Sydney': 'Australia', 'HGTV': 'USA', 'TV 2 Filmkanalen': 'Norway', 'STAR Sports Malaysia': 'Malaysia', 'Canal 10 Saeta': 'Uruguay', 'TV Cultura': 'Brazil', 'KTN': 'Pakistan', 'TV 2 Zulu': 'Denmark', 'SIC Radical': 'Portugal', 'T\xc3\xa9l\xc3\xa9toon': 'France', '\xd0\xa1\xd0\xa2\xd0\xa1': 'Russia', '\xd7\xa2\xd7\xa8\xd7\x95\xd7\xa5 \xd7\x94\xd7\x99\xd7\x9c\xd7\x93\xd7\x99\xd7\x9d\xe2\x80\x8e': 'Israel', 'TV3 (IE)': 'Ireland', 'TV3+': 'Denmark', 'PRO TV': 'Romania', 'Discovery Turbo UK': 'United Kingdom', 'TFO': 'Canada', 'VPRO': 'Netherlands', 'Star TV': 'Turkey', 'NET 5': 'Netherlands', 'VijfTV': 'Belgium', 'Sky News Ireland': 'Ireland', 'Fox Business': 'USA', 'Classic Arts Showcase': 'USA', 'NTV (TW)': 'Taiwan', 'Canal 4 Montecarlo': 'Uruguay', 'addikTV': 'Canada', 'Vimeo': 'USA', 'BBC World News': 'United Kingdom', 'Voyage': 'France', 'Yahoo! Screen': 'USA', 'Fashion TV': 'France', 'Eurosport': 'United Kingdom', 'Zee Cinema': 'India', 'HBO Europe': 'Hungary', 'RT\xc3\x89 Two': 'Ireland', 'Canadian Learning Television': 'Canada', 'Revelation TV': 'United Kingdom', 'C31': 'Australia', 'ETTV': 'Taiwan', 'Televisi\xc3\xb3n de Galicia': 'Spain', '24': 'Turkey', 'Comedy (CA)': 'Canada', 'Pakapaka': 'Argentina', 'AOL': 'USA', 'CBeebies': 'United Kingdom', 'RAI': 'Italy', 'TV3 (NZ)': 'New Zealand', 'Kids Station': 'Japan', 'Fred TV': 'USA', 'Doordarshan National': 'India', 'STAR Plus': 'India', 'TV Cabo': 'Portugal', 'RTL Televizija': 'Croatia', 'Carlton Television': 'United Kingdom', 'Jupiter Broadcasting ': 'USA', 'Royal News': 'Pakistan', 'RTP Madeira': 'Portugal', 'Russia Today': 'Russia', 'T\xc3\xa9l\xc3\xa9-Qu\xc3\xa9bec': 'Canada', 'Challenge': 'United Kingdom', 'AVRO': 'Netherlands', 'SKY PerfecTV!': 'Japan', 'Nickelodeon': 'USA', 'L\xc3\xa2leg\xc3\xbcl TV': 'Turkey', 'Ch\xc3\xa9rie 25': 'France', 'Deutsche Welle TV': 'Germany', 'Sky Living': 'United Kingdom', 'AT-X': 'Japan', 'ETTV Yoyo': 'Taiwan', 'NRK1': 'Norway', 'NRK3': 'Norway', 'NRK2': 'Norway', 'Network Ten': 'Australia', '\xd0\x9d\xd0\xa2\xd0\x92': 'Russia', 'UKTV Food': 'United Kingdom', 'ESPN Hong Kong': 'Hong Kong', 'MTV Base': 'United Kingdom', 'A&E': 'USA', 'SOAPnet': 'USA', 'Rooster Teeth': 'USA', 'Crackle': 'USA', 'A Haber': 'Turkey', 'Sky Deutschland': 'Germany', 'Military Channel': 'USA', 'Skai': 'Greece', 'TVOne Global': 'Pakistan', 'Sirasa': 'Sri Lanka', 'eqhd': 'Canada', '\xd0\xa2\xd0\x92\xd0\xa1': 'Russia', 'RTL TVI': 'Belgium', 'Al Alam': 'Iran', 'ABC (US)': 'USA', 'Sky Uno': 'Italy', 'TRT Avaz': 'Turkey', 'Showcase (CA)': 'Canada', 'Plug RTL': 'Belgium', 'OCN': 'South Korea', 'ZDFneo': 'Germany', 'France 3': 'France', 'France 2': 'France', 'France 5': 'France', 'France 4': 'France', 'SUN news': 'India', 'Radio Bremen': 'Germany', 'ABC': 'USA', 'Arte': 'France', 'Kashish TV': 'Pakistan', 'IFC': 'USA', 'SRF 1': 'Switzerland', 'OCS': 'France', 'VARA': 'Netherlands', 'UKTV Gold': 'United Kingdom', 'MTV3': 'Finland', 'Channel [V]': 'China', 'Discovery': 'USA', 'Ion Television': 'USA', 'AXS TV': 'USA', 'Spektrum': 'Hungary', 'RTL': 'Luxembourg', 'E!': 'USA', 'NBCSN': 'USA', 'TITV': 'Taiwan', 'BBC Canada': 'Canada', 'E4': 'United Kingdom', 'ORF III': 'Austria', 'The Family Channel': 'USA', 'BBC One': 'United Kingdom', 'EO': 'Netherlands', 'Discovery HD World': 'Singapore', 'Filles TV': 'France', 'SBS 6': 'Netherlands', 'YTV': 'Canada', 'TVRI': 'Indonesia', 'MTV (US)': 'USA', 'Record': 'Brazil', 'Bubble Hits': 'Ireland', 'W': 'Australia', 'TV 2 Science Fiction': 'Norway', 'SIC Mulher': 'Portugal', 'TV 2 Nyhetskanalen': 'Norway', 'BTV': 'China', 'LifeStyle': 'Australia', 'Abu Dhabi TV': 'United Arab Emirates', 'TV Chile': 'Chile', 'TBS': 'USA', 'TRT T\xc3\xbcrk': 'Turkey', 'TV S\xc3\xa3o Carlos': 'Brazil', 'STV': 'United Kingdom', 'MTV Dance': 'United Kingdom', 'Kyoto Broadcasting System': 'Japan', 'UTV': 'Ireland', 'C-Span': 'USA', 'TRT Diyanet': 'Turkey', 'CTV (JP)': 'Japan', 'CNBC': 'USA', 'UKTV Style': 'United Kingdom', 'Alpha TV PUNJABI': 'India', 'Prime (NZ)': 'New Zealand', 'STV (UK)': 'United Kingdom', 'RTP \xc3\x81frica': 'Portugal', 'SVTB': 'Sweden', 'ATV': 'Austria', 'TNT Serie': 'Germany', 'Sahara ONE': 'India', 'Discovery MAX': 'Spain', 'iQiyi': 'China', 'MSNBC': 'USA', 'MTV2': 'USA', 'Das Erste': 'Germany', 'RT\xc3\x89 One': 'Ireland', 'TRT 1': 'Turkey', 'Animal Planet': 'USA', 'vtmKzoom': 'Belgium', 'WOWOW': 'Japan', 'Sony Entertainment Television': 'USA', 'STAR Vijay': 'India', 'VT4': 'Belgium', 'TV Land': 'USA', 'KCET': 'USA', 'PTS HD': 'Taiwan', 'Aizo TV': 'Taiwan', 'SciFi': 'USA', 'BNN (NL)': 'Netherlands', 'TV Osaka': 'Japan', '\xd0\xa0\xd0\x95\xd0\x9d': 'Russia', 'TV7 (SE)': 'Sweden', 'Treehouse TV': 'Canada', 'Venevision': 'Venezuela', 'Magyar Telev\xc3\xadzi\xc3\xb3': 'Hungary', 'ART TV': 'Greece', 'SundanceTV': 'USA', 'USA Network': 'USA', 'GTV': 'Taiwan', 'NickToons': 'USA', 'Boomerang': 'USA', 'CSTV': 'South Korea', 'Esquire Network': 'USA', 'Five Life': 'United Kingdom', 'SVT24': 'Sweden', 'GEO Super': 'Pakistan', 'Ora TV': 'USA', 'Fox Channel': 'Germany', 'Current TV': 'USA', 'Televisa': 'Mexico', 'Showcase (AU)': 'Australia', 'TV4 Plus': 'Sweden', 'ITV': 'United Kingdom', 'SAT.1': 'Germany', 'TVP1': 'Poland', 'SVT2': 'Sweden', 'SVT1': 'Sweden', 'Smash Hits': 'United Kingdom', 'Cielo': 'Italy', 'SABC3': 'South Africa', 'Mega Channel': 'Greece', 'CTV (CN)': 'China', 'UKTV History': 'United Kingdom', 'Puls 4': 'Austria', 'TheBlaze': 'USA', 'Travel Channel (UK)': 'United Kingdom', 'TeleZ\xc3\xbcri': 'Switzerland', 'SWR': 'Germany', 'The Weather Channel': 'USA', 'Servus TV': 'Austria', 'UNTV 37': 'Philippines', 'Nagoya Broadcasting Network': 'Japan', 'Thames Television': 'United Kingdom', 'FYI': 'USA', 'TV 2': 'Norway', 'TV 3': 'Denmark', 'Hrvatska radiotelevizija': 'Croatia', 'Fox Crime': 'Italy', 'Beyaz TV': 'Turkey', 'Kiss': 'United Kingdom', 'Discovery Turbo': 'USA', '2BE': 'Belgium', 'radX': 'Canada', 'TV 2 Sport': 'Norway', 'Toon Disney': 'USA', 'Viasat 4': 'Norway', 'Ovation TV': 'USA', 'FEM': 'United Kingdom', '\xd0\x9f\xd1\x8f\xd1\x82\xd1\x8b\xd0\xb9 \xd0\xba\xd0\xb0\xd0\xbd\xd0\xb0\xd0\xbb': 'Russia', 'ITV Wales': 'United Kingdom', 'TG4': 'Ireland', 'truTV': 'USA', 'VTM': 'Belgium', 'Discovery Kids': 'USA', 'Hunan TV': 'China', 'TVNZ': 'New Zealand', 'PBS Kids Sprout': 'USA', 'VH1 Classics': 'USA', 'RCN TV': 'Colombia', 'Radio Canada': 'Canada', 'RBB': 'Germany', 'Encore': 'USA', 'Caracol TV': 'Colombia', 'MCM': 'France', 'TV Guide Channel': 'USA', 'E! (CA)': 'Canada', 'Starz!': 'USA', 'Dost TV': 'Turkey', 'ESPN Asia': 'Hong Kong', 'CITV': 'United Kingdom', 'TV4 Fakta': 'Sweden', 'Fuji TV': 'Japan', 'Classic FM TV': 'United Kingdom', 'Epsilon TV': 'Greece', 'TV4 Guld': 'Sweden', 'D8': 'France', 'Dish TV': 'USA', 'Kunskapskanalen': 'Sweden', 'Sab TV': 'India', '\xd0\x97\xd0\xb2\xd0\xb5\xd0\xb7\xd0\xb4\xd0\xb0': 'Russia', 'Speed': 'USA', 'TRT Kurd\xc3\xae': 'Turkey', 'Australian Christian Channel': 'Australia', 'E-Channel': 'South Korea', 'Turner South': 'USA', 'MTV Mandarin': 'Taiwan', 'Smithsonian Channel': 'USA', 'STAR Sports Hong Kong': 'Hong Kong', 'TTV': 'Taiwan', 'Canal Off': 'Brazil', 'HIFI': 'Canada', 'YLE': 'Finland', 'STAR News': 'India', 'Rede Globo': 'Brazil', '\xd0\xa2\xd0\x923': 'Russia', 'TQS': 'Canada', 'SUN TV': 'India', 'AXN': 'USA', 'Nine Network': 'Australia', 'Kamp\xc3\xbcs TV': 'Turkey', 'Kids and Teens TV': 'USA', 'Sky Cinema (IT)': 'Italy', 'SET MAX': 'India', 'Hulu': 'USA', 'TRT Belgesel': 'Turkey', 'RTP Internacional': 'Portugal', 'BS11': 'Japan', 'Sky Movies': 'United Kingdom', 'Revision3': 'USA', 'La Cinq': 'France', 'Magic': 'United Kingdom', 'Antenne 2': 'France', 'Pub Channel': 'United Kingdom', 'Phoenix TV': 'China', 'FOX T\xc3\xbcrkiye': 'Turkey', 'Omroep Brabant': 'Netherlands', 'BNN': 'Canada', 'Sky Cinema': 'United Kingdom', 'The Den': 'Ireland', 'Fox Family': 'USA', 'KanaalTwee': 'Belgium', 'Much TV': 'Taiwan', 'Adult Channel': 'United Kingdom', 'Alpha TV': 'Greece', 'Television Osaka': 'Japan', 'National Geographic': 'USA', '\xd0\xa0\xd0\xbe\xd1\x81\xd1\x81\xd0\xb8\xd1\x8f 1': 'Russia', 'WDR': 'Germany', 'TV3 Puls': 'Denmark', 'Varsity TV': 'USA', 'MBC Plus Media': 'South Korea', 'FUNimation Channel': 'USA', 'TV Aichi': 'Japan', 'NRK Super': 'Norway', 'Super Channel': 'Canada', 'W9': 'France', 'Hallmark Channel': 'USA', 'TV One (NZ)': 'New Zealand', 'Seven Network': 'Australia', 'TV 2 Zebra': 'Norway', 'TBN (Trinity Broadcasting Network)': 'USA', 'MTV (UK)': 'United Kingdom', 'TV3 (NO)': 'Norway', 'M-Net': 'South Africa', 'La Siete': 'Spain', 'La Deux': 'Belgium', 'Q TV': 'United Kingdom', 'Paramount Comedy': 'United Kingdom', 'TV4 Science Fiction': 'Sweden', 'Spike TV': 'USA', 'yes': 'Israel', 'NDTV India': 'India', 'More4': 'United Kingdom', 'dk4': 'Denmark', 'Life OK': 'India', 'Univision': 'USA', 'WNL': 'Netherlands', '\xd7\x94\xd7\xa2\xd7\xa8\xd7\x95\xd7\xa5 \xd7\x94\xd7\xa8\xd7\x90\xd7\xa9\xd7\x95\xd7\x9f': 'Israel', 'ETV Gujarati': 'India', 'TCM': 'United Kingdom', 'Sky News': 'United Kingdom', '360': 'Turkey', 'RT': 'Russia', 'ITV Granada': 'United Kingdom', 'FOX': 'USA', 'APTN': 'Canada', '\xd7\xa8\xd7\xa9\xd7\xaa': 'Israel', 'CBC (JP)': 'Japan', 'MusiquePlus': 'Canada', 'Five US': 'United Kingdom', 'NECO': 'Japan', 'BBC Two': 'United Kingdom', 'DaAi TV': 'Taiwan', 'City Channel': 'Ireland', 'Much (CA)': 'Canada', "6'eren": 'Denmark', 'Fox Reality': 'USA', 'Omroep MAX': 'Netherlands', 'MTV Italia': 'Italy', 'CNBC TV18': 'India', 'Crime & Investigation Network': 'USA', 'Logo': 'USA', 'Sony TV': 'India', 'Sky Sports': 'United Kingdom', 'LCI': 'France', 'bTV': 'Bulgaria', 'ETV': 'Estonia', 'The Sportsman Channel': 'USA', '\xc3\x89vasion': 'Canada', 'YouTube': 'USA', 'SIC Com\xc3\xa9dia': 'Portugal', 'Science Channel': 'USA', 'STAR Sports Taiwan': 'Taiwan', 'Press TV': 'Iran', 'BBC Kids': 'Canada', 'TMC': 'Monaco', 'XY TV': 'USA', 'TMF': 'Netherlands', 'Planet Green': 'USA', 'Channel 101': 'USA', 'Gaiam TV ': 'USA', 'Channel U': 'Singapore', 'RTS Un': 'Switzerland', 'Teledoce': 'Uruguay', 'America One Television Network': 'USA', 'STAR Sports India': 'India', 'RTL Television': 'Germany', 'Great American Country': 'USA', '+Globosat': 'Brazil', 'OLN': 'Canada', 'TVM': 'Malta', 'Kanal 4': 'Denmark', 'MTV Hits': 'USA', 'TVI': 'Portugal', 'DMAX (DE)': 'Germany', 'IKON': 'Netherlands', 'TVE': 'Spain', 'Noggin': 'USA', 'STAR Movies': 'Hong Kong', 'Canal 5': 'Mexico', 'Canal J': 'France', 'CI': 'Australia', 'TV8': 'Sweden', 'TSR': 'Switzerland', 'TeenNick': 'USA', 'TV6': 'Sweden', 'El Trece': 'Argentina', 'Canal D': 'Canada', 'TV2': 'New Zealand', 'Kanal 5': 'Sweden', 'TRT Okul': 'Turkey', 'KRO': 'Netherlands', 'Action': 'Canada', 'TestTube': 'USA', 'NDR': 'Germany', 'Semerkand TV': 'Turkey', 'QTV': 'Pakistan', 'RTP A\xc3\xa7ores': 'Portugal', '\xd0\x94\xd0\xa2\xd0\x92': 'Russia', 'DR Ramasjang': 'Denmark', 'Zhejiang TV': 'China', 'RMC D\xc3\xa9couverte': 'France', 'Bandai Channel': 'Japan', 'Com\xc3\xa9die !': 'France', 'WPIX': 'USA', 'TRT \xc3\x87ocuk': 'Turkey', 'Channel 8': 'Singapore', 'Colors': 'India', '\xd0\xa2\xd0\x9d\xd0\xa2': 'Russia', 'ZDF': 'Germany', 'ABC1': 'Australia', 'ABC2': 'Australia', 'ABC3': 'Australia', 'SoHo': 'Australia', 'Channel 2': 'Israel', 'Channel 3': 'Thailand', 'Channel 4': 'United Kingdom', 'Channel 5': 'United Kingdom', 'Channel 6': 'Ireland', 'Channel 7': 'Thailand', 'City': 'Canada', 'History': 'USA', 'DDR1': 'Germany', 'Disney Channel (Germany)': 'Germany', 'GNT': 'Brazil', 'The Africa Channel': 'United Kingdom', 'SIC Not\xc3\xadcias': 'Portugal', 'EinsPlus': 'Germany', 'ABC (PH)': 'Philippines', 'HBO Magyarorsz\xc3\xa1g': 'Hungary', 'S\xc3\xa9ries+': 'Canada', 'PTV Home': 'Pakistan', 'This TV': 'USA', 'DR K': 'Denmark', 'MBN': 'South Korea', 'OWN': 'USA', 'CBS': 'USA', 'ProSieben': 'Germany', 'UP TV': 'USA', 'TeleG': 'United Kingdom', 'MBC': 'South Korea', 'Liberty TV': 'United Kingdom', 'ESPN Taiwan': 'Taiwan', 'MBS': 'Japan', 'Rete 4': 'Italy', 'Discovery Life': 'USA', 'YTV (UK)': 'United Kingdom', 'Oxygen': 'USA', 'WealthTV': 'USA', 'Style': 'USA', 'Trend E': 'South Korea', 'MTV': 'USA', 'The Box': 'United Kingdom', 'Al Arabiyya': 'United Arab Emirates', 'TV Azteca': 'Mexico', 'fuse': 'USA', 'MUTV': 'United Kingdom', 'Sky Cinema (UK)': 'United Kingdom', 'Pivot': 'USA', 'Sky1': 'United Kingdom', 'Sky3': 'United Kingdom', 'Sky2': 'United Kingdom', 'UKTV Yesterday': 'United Kingdom', 'Zee Muzic': 'India', 'Indus Music': 'Pakistan', 'PTV Bolan': 'Pakistan', 'TVQ (Australia)': 'Australia', 'History (CA)': 'Canada', 'TV3 (ES)': 'Spain', 'Movie Central': 'Canada', 'Blip': 'USA', 'Gulli': 'France', 'Canal Sur': 'Spain', 'EBS': 'South Korea', 'Italia 1': 'Italy', 'TV 4': 'Poland', 'TVN Style': 'Poland', 'Living': 'United Kingdom', 'HBO': 'USA', 'Vrak.TV': 'Canada', 'Star World': 'Hong Kong', 'Joi': 'Italy', 'ABC Family': 'USA', 'Travel Channel': 'USA', 'The CW': 'USA', 'CTV': 'Canada', 'FOX Traveller': 'India', 'Nolife': 'France', 'Outdoor Channel': 'USA', 'BR': 'Germany', 'Teletama': 'Japan', 'Aaj TV': 'Pakistan', 'SBS Plus': 'South Korea', 'Food Network Canada': 'Canada', 'BYU Television': 'USA', 'GSN': 'USA', 'HBO Nordic': 'Sweden', 'Nat Geo Wild': 'USA', 'Canale 5': 'Italy', 'TV4 Komedi': 'Sweden', 'G4 Canada': 'Canada', 'Duna TV': 'Hungary', 'KBS TV2': 'South Korea', 'KBS TV1': 'South Korea', '\xd7\xa2\xd7\xa8\xd7\x95\xd7\xa5 10': 'Israel', 'RVU': 'Netherlands', 'Liberty Channel': 'USA', 'Olive': 'South Korea', 'Antena 3': 'Spain', 'NTV (JP)': 'Japan', 'Nick at Nite': 'USA', 'PTV News': 'Pakistan', 'Xbox Video': 'USA', 'BabyFirstTV': 'USA', 'B4U Music': 'United Kingdom', 'Prima televize': 'Czech Republic', 'SVT': 'Sweden', 'ESPN Philippines': 'Philippines', 'Scuzz': 'United Kingdom', 'BR-alpha': 'Germany', 'Canal+': 'France', 'TV P\xc3\xbablica': 'Argentina', 'M\xc4\x81ori Television': 'New Zealand', 'DR1': 'Denmark', 'Bravo': 'USA', 'DR3': 'Denmark', 'Al Jazeera America': 'USA', '3sat': 'Germany', 'Disney Junior': 'USA', 'PBS': 'USA', 'TrueVisions': 'Thailand', 'ICI Explora': 'Canada', 'Mya': 'Italy', 'FOX (FI)': 'Finland', 'TV 2 Charlie': 'Denmark', 'Zee TV': 'India', 'Bravo (US)': 'USA', 'Sub': 'Finland', 'VH1': 'USA', 'Cooking Channel': 'USA', 'ReelzChannel': 'USA', 'Pick TV': 'United Kingdom', 'Telecinco': 'Spain', 'Canal 13': 'Chile', 'Toei Channel': 'Japan', 'ARY Zouq': 'Pakistan', 'Sky Travel': 'United Kingdom', 'tvk': 'Japan', '\xd7\x98\xd7\x9c\xd7\xa2\xd7\x93': 'Israel', 'STAR One': 'India', 'Multishow': 'Brazil', 'TVG Network': 'USA', 'The Movie Network': 'Canada', 'Centric': 'USA', 'NHNZ': 'New Zealand', 'RTL 8': 'Netherlands', 'RTL 7': 'Netherlands', 'AMC': 'USA', 'RTL 4': 'Netherlands', 'QVC': 'USA', 'Dave': 'United Kingdom', 'tvN': 'South Korea', 'CTi TV': 'Taiwan', 'MNN': 'USA', 'Tev\xc3\xa9Ciudad': 'Uruguay', 'PTS': 'Taiwan', 'NT1': 'France', 'UPN': 'USA', 'Sportsman Channel': 'USA', 'Eden': 'United Kingdom', 'Al Jazeera': 'Qatar', 'Schweizer Fernsehen': 'Switzerland', 'Syndication': 'USA', 'NBA TV': 'USA', 'Nou Televisi\xc3\xb3': 'Spain', '\xd0\xa0\xd0\xbe\xd1\x81\xd1\x81\xd0\xb8\xd1\x8f \xd0\x9a': 'Russia', 'CPAC': 'Canada', 'National Geographic Adventure': 'USA', 'The Verge': 'USA', 'MATV': 'United Kingdom', 'Sleuth': 'USA', 'Kerrang! TV': 'United Kingdom', 'TVBS': 'China', 'H2': 'USA', 'DuMont Television Network': 'USA', 'KBS World': 'South Korea', 'Niconico': 'Japan', 'Indus Vision': 'Pakistan', 'Chart Show TV': 'United Kingdom', 'Dragon TV': 'China', 'Canal Famille': 'Canada', 'Lifetime': 'USA', 'VOX': 'Germany', 'ITV4': 'United Kingdom', 'ITV1': 'United Kingdom', 'Kanal 7': 'Turkey', 'ITV3': 'United Kingdom', 'ITV2': 'United Kingdom', 'Audience Network': 'USA', 'RCTI': 'Indonesia', 'Studio 23': 'Philippines', 'NovaTV': 'Bulgaria', 'ZOOM': 'India', 'TROS': 'Netherlands', 'PlayStation Network': 'USA', 'MBC Drama': 'South Korea', 'ABC4Kids': 'Australia', 'STAR Sports Southeast Asia': 'Hong Kong', 'BBC ALBA': 'United Kingdom', 'Prime (BE)': 'Belgium', 'TVN': 'Poland', 'TVO': 'Canada', 'WGN America': 'USA', 'HDNet': 'USA', 'jTBC': 'South Korea', 'Disney Cinemagic': 'United Kingdom', 'Rede Bandeirantes': 'Brazil', 'Cartoon Network': 'USA', 'NBC': 'USA', 'Super \xc3\x89cran': 'Canada', 'TVP2': 'Poland', 'CGV': 'South Korea', 'SABC2': 'South Africa', 'Discovery Channel (Australia)': 'Australia', 'SABC1': 'South Africa', 'Warner Channel': 'USA', 'TVN Turbo': 'Poland', 'Televen': 'Venezuela', 'GMA': 'Philippines', 'France \xc3\x94': 'France', '2\xc3\x972': 'Russia', 'HBO Canada': 'Canada', 'ATN Aastha Channel': 'India', 'Fox8': 'Australia', 'MBC Every1': 'South Korea', 'New Tang Dynasty TV': 'USA', 'DIY Network Canada': 'Canada', 'Disney Channel (US)': 'USA', 't\xc3\xa9va': 'France', 'RDI': 'Canada', 'Videoland Television Network': 'Taiwan', 'Canal de las Estrellas': 'Mexico', 'Lifetime UK': 'United Kingdom', 'TGRT Haber': 'Turkey', 'TVA': 'Canada', 'SUN music': 'India', 'National Geographic (US)': 'USA', 'Disney XD': 'USA', 'TV7 (BG)': 'Bulgaria', 'Kanal D': 'Turkey', 'Cine 5': 'Turkey', 'Court TV': 'USA', 'TVB': 'China', 'BBC News': 'United Kingdom', 'Canal Once': 'Mexico', 'STAR Gold': 'India', '\xc3\x9clke TV': 'Turkey', 'Space': 'Canada', 'NDTV 24x7': 'India', 'SET TV': 'Taiwan', 'Einsfestival': 'Germany', 'Club RTL': 'Belgium', 'Pop': 'USA', 'ORF 2': 'Austria', 'NRJ 12': 'France', 'Guardian Television Network': 'USA', 'Comedy Central (UK)': 'United Kingdom', 'TVGN': 'USA', 'AlloCin\xc3\xa9': 'France', 'ARY Shopping Channel': 'Pakistan', 'CN8': 'USA', 'Investigation Discovery': 'USA', 'The Amp': 'United Kingdom', 'Ustream': 'USA', 'Five': 'United Kingdom', 'Adult Swim': 'USA', 'TV4': 'Sweden', 'S4/C': 'United Kingdom', 'News One': 'Pakistan', 'TNU': 'Uruguay', 'TNT': 'USA', 'MBC Queen': 'South Korea', 'Casa': 'Canada', 'Netflix': 'USA', 'Fuel TV': 'USA', 'Kanal A (Turkey)': 'Turkey', '\xc4\x8cesk\xc3\xa1 televize': 'Czech Republic', 'FOX (US)': 'USA', 'BNT1': 'Bulgaria', 'HOT': 'Israel', 'Red Hot TV': 'United Kingdom', 'Alpha TV GUJARATI': 'India', 'MyNetworkTV': 'USA', 'CNN': 'USA', 'Food Network': 'USA', 'TRT Haber': 'Turkey', 'Nou 24': 'Spain', '\xd0\x86\xd0\xbd\xd1\x82\xd0\xb5\xd1\x80': 'Ukraine', 'Omni': 'Canada', 'Showtime': 'USA', 'Tokyo Broadcasting System': 'Japan', 'ATV T\xc3\xbcrkiye': 'Turkey', 'Universal Channel': 'Brazil', 'Encuentro': 'Argentina', 'LifeStyle FOOD': 'Australia', 'TRT World': 'Turkey', 'TRT HD': 'Turkey', 'Canvas/Ketnet': 'Belgium', 'YTV (CA)': 'Canada', 'B4U Movies': 'United Kingdom', 'Sky Atlantic': 'United Kingdom', 'BBC iPlayer': 'United Kingdom', 'La7': 'Italy', 'YTV (JP)': 'Japan', 'RTL 5': 'Netherlands'}, 1, 1441581753.109535] \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addons/metadata.themoviedb.org/addon.xml b/packages/mediacenter/kodi/config/base-addons/metadata.themoviedb.org/addon.xml index 0ba464c889e4bd845b254a82b3611b77fb7c7236..b9fd5a92f7c112e62e055940e9ccc18682248eaa 100644 --- a/packages/mediacenter/kodi/config/base-addons/metadata.themoviedb.org/addon.xml +++ b/packages/mediacenter/kodi/config/base-addons/metadata.themoviedb.org/addon.xml @@ -1,7 +1,7 @@ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/LICENSE.txt b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..4f8e8eb30cc7571be180a7061524b5b3d7a85beb --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/LICENSE.txt @@ -0,0 +1,282 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS +------------------------------------------------------------------------- diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/addon.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/addon.xml new file mode 100644 index 0000000000000000000000000000000000000000..7c2d524ee6e64b92c8dcb49db28b7af8bad36d95 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/addon.xml @@ -0,0 +1,24 @@ + + + + + + + + + video + + + Justin.tv + Watch live and archived videos from justin.tv + all + + GNU GENERAL PUBLIC LICENSE. Version 2, June 1991 + + http://forum.xbmc.org/showthread.php?tid=51981 + http://justin.tv + + \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/changelog.txt b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/changelog.txt new file mode 100644 index 0000000000000000000000000000000000000000..d2f004b4ea0d94fb78c658406ab7d59b96a9a48c --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/changelog.txt @@ -0,0 +1,47 @@ +Version 0.4.1 +fix archives playback + +Version 0.4.0 +code overhaul + +Version 0.3.9 +added initial support for hls streams +update python version for Gotham compatibility + +Version 0.3.8 +added support for IrcChat add-on +added support for including a password when starting a stream from a plugin:// url +fix ChineseTW language code + +Version 0.3.7.1 +fix encode error in logging +fix prompt for password + +Version 0.3.7 +fix search, no longer available from the API, we now scrape the website function +fix watch status for archives +other bug fixes and code improvements + +Version 0.3.6 +fix error when selecting "All" catagory with XBMC-Frodo + +Version 0.3.5 +fix error when selecting "All" catagory +added view mode setting for "Media Info 3" +added setting to only show live "Justin.tv User Favorites / Follows" + +Version 0.3.4 +fix archived videos page-nation + +Version 0.3.3 +added "Blacklist Channel" to the context menu +added "Bad Password" notification +other bug fixes and error handling + +Version 0.3.2 +small change/fix for stream selection + +Version 0.3.1 +added page-nation to archived videos +added setting "Set default stream quality", most channels only have "Live, iPhone High, and iPhone Low", + setting "720p - 240p" will result in "Live" if not listed, if you need a lower bitrate stream use an iPhone setting \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/default.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/default.py new file mode 100644 index 0000000000000000000000000000000000000000..ff485ab75d43c80dd6e5fde359891ba438a38c2e --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/default.py @@ -0,0 +1,770 @@ +## Credit to Stacked for the original plugin. +## Thanks to toastcutter for save passwords patch + +import urllib +import urllib2 +import os +from urlparse import urlparse, parse_qs + +import StorageServer +import json + +import xbmcplugin +import xbmcgui +import xbmcaddon +import xbmcvfs + +addon = xbmcaddon.Addon() +addon_id = addon.getAddonInfo('id') +addon_version = addon.getAddonInfo('version') +addon_profile = xbmc.translatePath(addon.getAddonInfo('profile')).encode('utf-8') +addon_path = xbmc.translatePath(addon.getAddonInfo('path')).encode('utf-8') +addon_icon = addon.getAddonInfo('icon') +addon_fanart = addon.getAddonInfo('fanart') +j_nick = addon.getSetting('nickname') +j_pass = addon.getSetting('password') +cache = StorageServer.StorageServer("Jtv_Archives", 24) +search_queries = os.path.join(addon_profile, 'search_queries') +passwords_file = os.path.join(addon_profile, 'passwords') +blacklist_file = os.path.join(addon_profile, 'blacklist') +favorites_file = os.path.join(addon_profile, 'favorites') +api_url = 'http://api.justin.tv/api' + +languages = { + 'Swedish': 'sv', + 'Icelandic': 'is', + 'Estonian': 'et', + 'Vietnamese': 'vi', + 'Romanian': 'ro', + 'Slovenian': 'sl', + 'Hindi': 'hi', + 'Dutch': 'nl', + 'Korean': 'ko', + 'Danish': 'da', + 'Indonesian': 'id', + 'Hungarian': 'hu', + 'Ukrainian': 'uk', + 'Lithuanian': 'lt', + 'French': 'fr', + 'Catalan': 'ca', + 'Russian': 'ru', + 'Thai': 'th', + 'Croatian': 'hr', + '简体中文': 'zh-cn', + 'Finnish': 'fi', + 'Hebrew': 'he', + 'Bulgarian': 'bg', + 'Turkish': 'tr', + 'Greek': 'el', + 'Latvian': 'lv', + 'English': 'en', + 'PortugueseBrazil': 'pt-br', + 'Italian': 'it', + 'Portuguese': 'pt', + 'ChineseTW': 'zh-tw', + 'German': 'de', + 'Japanese': 'ja', + 'Norsk (BokmÃ¥l)': 'nb', + 'Czech': 'cs', + 'Slovak': 'sk', + 'Spanish': 'es', + 'Polish': 'pl', + 'Arabic': 'ar', + 'Tagalog': 'tl' + } + +def addon_log(string): + try: + log_message = string.encode('utf-8', 'ignore') + except: + log_message = 'addonException: addon_log: %s' %format_exc() + xbmc.log("[%s-%s]: %s" %(addon_id, addon_version, log_message), level=xbmc.LOGNOTICE) + + +def make_request(url, headers=None, get_url=False): + addon_log('Request: '+url) + if headers is None: + headers = { + 'User-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0', + 'Referer' : 'http://www.justin.tv/' + } + try: + req = urllib2.Request(url,None,headers) + response = urllib2.urlopen(req) + if get_url: + data = response.geturl() + else: + data = response.read() + # addon_log(str(response.info())) + response.close() + return data + except urllib2.URLError, e: + data = None + errorStr = str(e.read()) + addon_log('We failed to open "%s".' %url) + if hasattr(e, 'reason'): + addon_log('We failed to reach a server.') + addon_log('Reason: %s' %e.reason) + if hasattr(e, 'code'): + addon_log('We failed with error code - %s.' %e.code) + + +def get_lang_code(language): + for i in LANGUAGES.items(): + if i[1] == language: + lang_code = i[0] + return lang_code + + +def get_category_list(): + return make_request(api_url + '/category/list.json') + + +def display_main_dir(): + all_icon = os.path.join(addon_path, 'resources', 'icons','all.png') + fav_icon = os.path.join(addon_path, 'resources', 'icons','fav.png') + jfav_icon = os.path.join(addon_path, 'resources', 'icons','jfav.png') + search_icon = os.path.join(addon_path, 'resources', 'icons', 'search.png') + if xbmcvfs.exists(favorites_file): + favorites_list = open(favorites_file).read() + if favorites_list: + add_dir('Favorites', 'get_favorites', fav_icon, 'get_favorites') + justin_user_name = addon.getSetting('j_user') + if justin_user_name: + add_dir('%s Favorites / Follows' %justin_user_name, justin_user_name, jfav_icon, 'get_justin_favorites') + add_dir('All', '', all_icon, 'get_all') + data = json.loads(cache.cacheFunction(get_category_list)) + for i in data.keys(): + if data[i]['name'] in ['Creativity', 'Poker']: + item_icon = all_icon + else: + item_icon = os.path.join(addon_path, 'resources', 'icons', data[i]['icon'].split('/')[-1]) + add_dir(data[i]['name'], 'subcategory', item_icon, 'get_subcategories', {'category_id': i}) + add_dir('Enter Channel Name', 'get_channel', all_icon,'get_channel') + add_dir('Search', 'get_search', search_icon, 'get_search') + return end_of_dir() + + +def display_subcategories(category_id, iconimage): + data = json.loads(cache.cacheFunction(get_category_list)) + if len(data[category_id]['subcategories'].keys()) == 1: + sub_category = data[category_id]['subcategories'].keys()[0] + return get_channels(sub_category, category_id) + if len(data[category_id]['subcategories'].keys()) > 1: + add_dir('All', '', iconimage, 'get_channels', {'category_id': category_id}) + items = data[category_id]['subcategories'] + for i in items.keys(): + info = {'category_id': category_id, 'sub_category': i} + add_dir(items[i]['name'], 'display_channels', iconimage, 'get_channels', info) + return end_of_dir() + return get_channels(None, category_id) + + +def get_channels(sub_category, category_id, page=None): + url = api_url + '/stream/list.json?' + if category_id: + url += 'category=%s' %category_id + if sub_category: + url +='&subcategory=%s' %sub_category + if not addon.getSetting('lang') == "None": + url += '&language=%s' %languages[addon.getSetting('lang')] + if not addon.getSetting('lang1') == "None": + url += ',%s' %languages[addon.getSetting('lang1')] + if page is None: + page = 1 + else: + page = int(page) + url += '&limit=20&offset=%s' %((page -1) * 20) + addon_log('LiveData URL: %s' %url) + data = make_request(url) + if data: + return display_channels(data, sub_category, category_id, page) + + +def display_channels(data, sub_category, category_id, page): + data = json.loads(data) + if not isinstance(data, list): + addon_log('data type: %s' %type(data)) + data = [data] + addon_log('json data: %s' %data) + addon_log('Len Data: %s' %str(len(data))) + addon_log('page: %s' %str(page)) + try: + blacklist = json.loads(open(blacklist_file).read()) + except: + blacklist = None + desc_keys = [ + 'video_bitrate', + 'video_codec', + 'audio_codec', + 'video_height', + 'video_width', + 'category', + 'subcategory', + 'up_time', + 'geo', + 'meta_game', + 'language', + 'stream_count', + 'channel_view_count', + 'featured', + 'broadcast_part', + 'name', + 'stream_type' + ] + for i in data: + if not i.has_key('channel'): + addon_log('No channel data: %s' %i) + info = {} + + desc = ' | '.join(['%s: %s' %(k.replace('_', ' ').title(), i[k]) for + k in desc_keys if i.has_key(k) and i[k]]) + if desc: + info['plot'] = desc + if i.has_key('channel'): + if i['channel'].has_key('login') and i['channel']['login']: + name = i['channel']['login'] + elif i.has_key('login') and i['login']: + name = i['login'] + elif i.has_key('name') and i['name']: + name = i['name'].split('user_')[-1] + else: + try: + name = str(i['image_url_medium']).split('/')[-1].split('-')[0] + except: + addon_log('Name not found: %s' %i) + continue + if blacklist and name in blacklist: + addon_log('Channel: %s - Blacklisted' %name) + continue + if i.has_key('channel'): + if (i['channel'].has_key('status') and i['channel']['status'] and + i['channel']['status'] != 'Broadcasting LIVE on Justin.tv'): + info['title'] = i['channel']['status'] + elif i['channel'].has_key('title') and i['channel']['title']: + info['title'] = i['channel']['title'] + elif i.has_key('title') and i['title']: + info['title'] = i['title'] + else: + info['title'] = name + + thumb = None + fanart = None + if addon.getSetting('fanart') == "true": + if i.has_key('channel'): + if i['channel'].has_key('image_url_huge') and i['channel']['image_url_huge']: + fanart = i['channel']['image_url_huge'] + elif i.has_key('image_url_huge') and i['image_url_huge']: + fanart = i['image_url_huge'] + info['fanart'] = fanart + if addon.getSetting('use_channel_icon') == "0" and fanart: + thumb = fanart + if not thumb: + if i.has_key('channel'): + if i['channel'].has_key('screen_cap_url_large') and i['channel']['screen_cap_url_large']: + thumb = i['channel']['screen_cap_url_large'] + elif i['channel'].has_key('image_url_large') and i['channel']['image_url_large']: + thumb = i['channel']['image_url_large'] + elif i.has_key('image_url_large') and i['image_url_large']: + thumb = i['image_url_large'] + if not thumb: + addon_log('No Thumb') + thumb = addon_icon + if not fanart: + addon_log('No Fanart') + fanart = addon_fanart + add_dir(name, 'play_stream', thumb, 'set_resolved_url', info, get_stream_info(i)) + + if not category_id == 'search': + page_num = None + if len(data) == 20: + if page: + page_num = page + 1 + else: + page_num = 1 + if page_num: + info = {'category_id': category_id, 'sub_category': sub_category, 'page': page_num} + next_png = os.path.join(addon_path, 'resources', 'icons','next.png') + add_dir('Next Page', 'load_more_channels', next_png, 'get_channels', info) + return end_of_dir(True) + + +def get_stream_info(item_dict): + stream_info = {'video_info': {}, 'audio_info': {}} + if item_dict.has_key('video_codec') and item_dict['video_codec']: + stream_info['video_info']['codec'] = item_dict['video_codec'] + if item_dict.has_key('video_height') and item_dict['video_height']: + stream_info['video_info']['height'] = item_dict['video_height'] + if item_dict.has_key('video_width') and item_dict['video_width']: + stream_info['video_info']['width'] = item_dict['video_width'] + if (item_dict.has_key('audio_codec') and + item_dict['audio_codec'] and item_dict['audio_codec'] != '???'): + stream_info['audio_info']['codec'] = item_dict['audio_codec'] + return stream_info + + +def get_user_data(user_name): + url = api_url + '/user/show/%s.json' %user_name + data = make_request(url) + if data and not data == '[]': + addon_log('User Data: %s' %data) + return data + + +def get_user_favorites(justin_user_name): + url = api_url + '/user/favorites/%s.json?limit=100' %justin_user_name + if addon.getSetting('live_only') == "true": + url += '&live=true' + data = make_request(url) + if data: + return display_channels(data, '', '', None) + + +def display_channel_archives(name, url=None): + if url is None: + url = api_url + '/channel/archives/%s.json' %name + responce = make_request(url) + next_png = os.path.join(addon_path, 'resources', 'icons','next.png') + if responce and responce != '[]': + data = json.loads(responce) + for i in data: + info = {} + info['plot'] = ' | '.join(['%s: %s' %(k.replace('_', ' ').title(), i[k]) for + k in i.keys() if i[k]]) + stream_url = i['video_file_url'] + thumb = i['image_url_medium'] + info['title'] = i['title'].encode('utf-8') + if i.has_key('broadcast_part') and i['broadcast_part']: + info['title'] += ' - Part: %s' %i['broadcast_part'].encode('utf-8') + if i.has_key('length') and i['length']: + info['duration'] = int(i['length']) / 60 + add_dir(info['title'], stream_url, thumb, 'set_archive_url', info, get_stream_info(i)) + + if len(data) == 20: + if not 'offset=' in url: + url = url + '?offset=20' + else: + offset = int(url.split('offset=')[1]) + url = url.split('?')[0]+'?offset=%s' %(offset + 20) + add_dir('Next Page', url, next_png, 'get_channel_archives') + return end_of_dir(True) + else: + notify('No archives found for channel: %s' %name) + + +def notify(message): + xbmc.executebuiltin("XBMC.Notification(Addon Notification,%s,5000,%s)" + %(message, addon_icon)) + + +def resolve_url(channel_name, password=None): + url = 'https://api.twitch.tv/api/channels/%s/access_token?as3=t' %channel_name + data = json.loads(make_request(url)) + if not data: + addon_log('No Data: api.twitch.tv') + notify('Channel data not found') + return + token_data = json.loads(data['token']) + for i in token_data: + addon_log('%s: %s' %(i, token_data[i])) + + private_code = 'null' + if not token_data['private']['allowed_to_view']: + if token_data['needed_info']: + addon_log('needed_info: %s' %token_data['needed_info']) + if 'private' in token_data['needed_info']: + if not password: + password = get_password(channel_name) + private_code = urllib2.quote(password) + params = [ + 'nauthsig=%s' %data['sig'], + 'player=jtvweb', + 'private_code=%s' %private_code, + 'type=any', + 'nauth=%s' %urllib2.quote(data['token']), + 'allow_source=true', + ] + stream_url = 'http://usher.twitch.tv/select/%s.json?' %channel_name + '&'.join(params) + return stream_url + + +def set_resolved_url(resolved_url): + success = False + if resolved_url: + success = True + else: + resolved_url = '' + item = xbmcgui.ListItem(path=resolved_url) + xbmcplugin.setResolvedUrl(int(sys.argv[1]), success, item) + + +def loadPasswords(): + passwords = {} + if addon.getSetting('save_passwords') == 'true': + if xbmcvfs.exists(passwords_file): + passwords = json.loads(open(passwords_file).read()) + return passwords + + +def savePasswords(passwords): + if addon.getSetting('save_passwords') == 'true': + f = open(passwords_file, "w") + f.write(json.dumps(passwords)) + f.close() + + +def get_password(name): + passwords = loadPasswords() + password = '' + if name in passwords: + password = passwords[name] + keyboard = xbmc.Keyboard(password,'Enter Password') + keyboard.doModal() + if (keyboard.isConfirmed() == False): + return + password = keyboard.getText() + passwords[name] = password + savePasswords(passwords) + if len(password) == 0: + return None + else: + return password + + +def add_dir(name, url, iconimage, mode, info={}, stream_info={}): + isfolder = True + fanart = addon_fanart + params = {'name': name, 'url': url, 'mode': mode, 'iconimage': iconimage} + if info.has_key('category_id') and info['category_id']: + params['category_id'] = info['category_id'] + if info.has_key('sub_category') and info['sub_category']: + params['sub_category'] = info['sub_category'] + if info.has_key('page'): + params['page'] = info['page'] + url = '%s?%s' %(sys.argv[0], urllib.urlencode(params)) + if info.has_key('title'): + title = info['title'] + else: + title = name + listitem = xbmcgui.ListItem(title, iconImage=iconimage, thumbnailImage=iconimage) + if stream_info: + if stream_info['video_info'].keys(): + listitem.addStreamInfo('video', stream_info['video_info']) + if stream_info['audio_info'].keys(): + listitem.addStreamInfo('audio', stream_info['audio_info']) + if info.has_key('fanart') and info['fanart']: + fanart = info['fanart'] + listitem.setProperty("Fanart_Image", fanart) + context_menu = [] + if info.has_key('fav'): + context_menu.append( + ('Remove from Jtv Favorites', + 'XBMC.RunPlugin(%s?mode=remove_fav&name=%s)' + %(sys.argv[0], urllib.quote(name)))) + else: + context_menu.append( + ('Add to Jtv Favorites', + 'XBMC.RunPlugin(%s?mode=add_favorite¶ms=%s&info=%s)' + %(sys.argv[0], urllib.quote(json.dumps(params)), + urllib.quote(json.dumps(info))))) + if mode in ['resolve_url', 'set_resolved_url', 'set_archive_url']: + isfolder = False + listitem.setProperty('IsPlayable', 'true') + listitem.setInfo('video', infoLabels=info) + context_menu.append( + ('Get Channel Archives', + 'XBMC.Container.Update(%s?mode=get_channel_archives&name=%s)' + %(sys.argv[0], urllib.quote(name)))) + context_menu.append( + ('Run IrcChat', + "RunScript(script.ircchat," + "run_irc=True&nickname=%s&username=%s&password=%s&host=%s&channel=%s)" + %(j_nick, j_nick, j_pass, 'irc.twitch.tv', name))) + context_menu.append( + ('Blacklist Channel','XBMC.RunPlugin(%s?mode=blacklist_channel&name=%s)' + %(sys.argv[0], urllib.quote(name)))) + if mode == 'search' and name == 'Previous Search Queries': + context_menu.append( + ('Remove', + 'XBMC.Container.Update(%s?mode=remove_query&name=%s)' + %(sys.argv[0], urllib.quote(name)))) + listitem.addContextMenuItems(context_menu) + xbmcplugin.addDirectoryItem(int(sys.argv[1]), url, listitem, isfolder) + + +def search(search_q, url=None): + if search_q == 'Previous Search Queries': + search_icon = os.path.join(addon_path, 'resources', 'icons', 'search.png') + search_list = json.loads(open(search_queries).read()) + for i in search_list: + addon_log('search type: %s' %type(i)) + if isinstance(i, list): + # prior to 4.0 will return a list + title = i[0] + else: + title = i + add_dir(title, 'saved_search_query', search_icon, 'search') + return end_of_dir() + + elif search_q == 'New Search': + keyboard = xbmc.Keyboard('','Search') + keyboard.doModal() + if (keyboard.isConfirmed() == False): + return + search_q = keyboard.getText() + if len(search_q) == 0: + return + if addon.getSetting('save_search') == 'true': + search_file = xbmcvfs.exists(search_queries) + if not search_file: + search_list = [] + else: + search_list = json.loads(open(search_queries).read()) + search_list.append(search_q) + a = open(search_queries, "w") + a.write(json.dumps(search_list)) + a.close() + + url = 'http://api.justin.tv/api/stream/search/%s.json' %urllib.quote(search_q) + addon_log('Search URL: '+url) + data = make_request(url) + if data: + return display_channels(data, sub_category, category_id, None) + else: + return notify('No Results for: %s' %search_q) + + +def remove_search(name): + search_list = json.loads(open(search_queries).read()) + for i in range(len(search_list)): + if name in search_list[i]: + del search_list[i] + a = open(search_queries, "w") + a.write(json.dumps(search_list)) + a.close() + return xbmc.executebuiltin('Container.Refresh') + + +def get_search(): + if addon.getSetting('save_search') == 'true': + search_file = xbmcvfs.exists(search_queries) + if search_file: + search_icon = os.path.join(addon_path, 'resources', 'icons', 'search.png') + add_dir('New Search', 'new_search', search_icon, 'search') + add_dir('Previous Search Queries', 'previous_search', search_icon, 'search') + return end_of_dir() + else: + return search('New Search') + + +def get_channel(channel_name, play=False, password=None): + if channel_name == 'Enter Channel Name': + keyboard = xbmc.Keyboard('','Channel Name') + keyboard.doModal() + if (keyboard.isConfirmed() == False): + return + channel_name = keyboard.getText() + if len(channel_name) == 0: + return + + user_data = get_user_data(channel_name) + if not user_data: + return notify('Did not find channel: %s' %channel_name) + + url = api_url + '/stream/list.json?channel=%s' %channel_name + data = make_request(url) + if not data or data == '[]': + display_channels(user_data, None, 'channel', None) + dialog = xbmcgui.Dialog() + ret = dialog.yesno('%s is a valid channel' %channel_name, + 'The channel does not seem to be live\n', + 'Do you want to check for archives?') + if ret: + return display_channel_archives(channel_name, password) + else: + if play == 'player': + return xbmc.Player().play(resolve_url(channel_name, password)) + elif play: + return set_resolved_url(resolve_url(channel_name, password)) + return display_channels(data, None, 'channel', None) + + +def display_favorites(): + favorites_list = open(favorites_file).read() + for i in json.loads(favorites_list): + if isinstance(i[0], dict): + i[1]['fav'] = True + add_dir(i[0]['name'], i[0]['url'], i[0]['iconimage'], i[0]['mode'], i[1]) + else: + # pre version 0.4 favorite + info = {'title': i[2].encode('utf-8'), 'fav': True} + add_dir(i[0], 'get_channel', i[1], 'get_channel', info) + return end_of_dir(True) + + +def add_favorite(params, info): + info = json.loads(info) + params = json.loads(params) + if info.has_key('title'): + title = info['title'] + else: + title = params['name'] + keyboard = xbmc.Keyboard(title, 'Rename?') + keyboard.doModal() + if (keyboard.isConfirmed() == False): + return + title = keyboard.getText() + if len(title) == 0: + return + info['title'] = title + if xbmcvfs.exists(favorites_file): + favorites_list = open(favorites_file).read() + if favorites_list: + fav_list = json.loads(favorites_list) + else: + fav_list = [] + else: + fav_list = [] + fav_list.append((params, info)) + a = open(favorites_file, "w") + a.write(json.dumps(fav_list)) + a.close() + + +def remove_favorite(name): + data = json.loads(favorites_list) + for i in range(len(data)): + if isinstance(data[i][0], dict): + if name in data[i][0]['name']: + del data[i] + break + elif name in data[i]: + del data[i] + break + a = open(favorites_file, "w") + a.write(json.dumps(data)) + a.close() + return xbmc.executebuiltin('Container.Refresh') + + +def blacklist_channel(name): + blacklist_ = xbmcvfs.exists(blacklist_file) + if not blacklist_: + black_list = [] + else: + black_list = json.loads(open(blacklist_file, "r").read()) + black_list.append(name) + f = open(blacklist_file, "w") + f.write(json.dumps(black_list)) + f.close + return xbmc.executebuiltin('Container.Refresh') + + +def get_params(): + p = parse_qs(sys.argv[2][1:]) + for i in p.keys(): + p[i] = p[i][0] + return p + + +def set_view_mode(): + view_modes = { + '0': '502', # List + '1': '51', # Big List + '2': '500', # Thumbnails + '3': '501', # Poster Wrap + '4': '508', # Fanart + '5': '504', # Media info + '6': '503', # Media info 2 + '7': '515' # Media info 3 + } + view_mode = addon.getSetting('view_mode') + if view_mode == '8': + return + xbmc.executebuiltin('Container.SetViewMode(%s)' %view_modes[view_mode]) + + +def end_of_dir(set_content=False): + xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_UNSORTED) + xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_LABEL) + if set_content: + xbmcplugin.setContent(int(sys.argv[1]), 'movies') + set_view_mode() + xbmcplugin.endOfDirectory(int(sys.argv[1])) + + +params = get_params() +addon_log("params: %s" %params) +try: + mode = params['mode'] +except: + mode = None + +if mode == None: + display_main_dir() + +elif mode == 'get_all': + get_channels(None, None) + +elif mode == 'get_subcategories': + display_subcategories(params['category_id'], params['iconimage']) + +elif mode == 'get_channels': + page = None + sub_category = None + if params.has_key('page'): + page = params['page'] + if params.has_key('sub_category'): + sub_category = params['sub_category'] + get_channels(sub_category, params['category_id'], page) + +elif mode == 'set_resolved_url': + set_resolved_url(resolve_url(params['name'])) + xbmc.sleep(3000) + if addon.getSetting('run_chat') == 'true': + xbmc.executebuiltin( + "RunScript(script.ircchat," + "run_irc=True&nickname=%s&username=%s&password=%s&host=%s&channel=%s)" + %(j_nick, j_nick, j_pass, 'irc.twitch.tv', params['name'])) + +elif mode == 'get_search': + get_search() + +elif mode == 'get_channel': + play = False + if params.has_key('play') and params['play']: + play = params['play'] + password = False + if params.has_key('password') and params['password']: + password = params['password'] + get_channel(params['name'], play, password) + +elif mode == 'get_favorites': + display_favorites() + +elif mode == 'get_channel_archives': + url = None + if params.has_key('url'): + url = params['url'] + display_channel_archives(params['name'], url) + +elif mode == 'add_favorite': + add_favorite(params['params'], params['info']) + +elif mode == 'remove_fav': + remove_favorite(params['name']) + +elif mode == 'set_archive_url': + set_resolved_url(params['url']) + +elif mode == 'get_justin_favorites': + get_user_favorites(params['url']) + +elif mode == 'search': + search(params['name'], params['url']) + +elif mode == 'remove_query': + remove_search(params['name']) + +elif mode == 'blacklist_channel': + blacklist_channel(params['name']) diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/fanart.jpg b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/fanart.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3cb5c052270a1e50c5d2b3c0b3d37e5cfe73c7c8 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/fanart.jpg differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/icon.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..45593fde497cdce76f77dcd3bc66675ae76f23bf Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/icon.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/all.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/all.png new file mode 100644 index 0000000000000000000000000000000000000000..bd23e698f57ea0e8e90103ca18ec567aa11df769 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/all.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/animals.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/animals.png new file mode 100644 index 0000000000000000000000000000000000000000..e73ccc3c2a2bdac6ee742c96f21d0594af8352e1 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/animals.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/entertainment.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/entertainment.png new file mode 100644 index 0000000000000000000000000000000000000000..4dc083c8261c587ba2a33feb639cc9c75d1d9663 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/entertainment.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/fav.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/fav.png new file mode 100644 index 0000000000000000000000000000000000000000..5305f470e311db41fdf913b94184d86cefe5491d Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/fav.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/gaming.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/gaming.png new file mode 100644 index 0000000000000000000000000000000000000000..d70d74d02c6526c54cc4142d78ad988d261e7440 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/gaming.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/jfav.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/jfav.png new file mode 100644 index 0000000000000000000000000000000000000000..f8b995ff49cbcf11ee95026d83560ab8d93fc960 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/jfav.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/news.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/news.png new file mode 100644 index 0000000000000000000000000000000000000000..85ff610a2ed20a833edad36145b9ccffacc3e4fc Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/news.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/next.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/next.png new file mode 100644 index 0000000000000000000000000000000000000000..cde975995273df8b0861d4368a702ce7a4b676b2 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/next.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/other.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/other.png new file mode 100644 index 0000000000000000000000000000000000000000..a7421a31f4080cb49d0c603b9439112e13d28793 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/other.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/science_tech.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/science_tech.png new file mode 100644 index 0000000000000000000000000000000000000000..c7bfbc51d4742d434f6c995ef441916618b2c890 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/science_tech.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/search.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/search.png new file mode 100644 index 0000000000000000000000000000000000000000..0e554ca1572c874449cfbba8ce4ffd6bb1273231 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/search.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/social.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/social.png new file mode 100644 index 0000000000000000000000000000000000000000..abfdcc677f91d205ae905d4a82636ae5032ac0fc Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/social.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/sports.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/sports.png new file mode 100644 index 0000000000000000000000000000000000000000..67fd84ecf0f78cd18615b40eee4f26f854b65932 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/icons/sports.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/settings.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..eece91d03e2c59e45ff6a206ac9eb6449adcee21 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.jtv.archives/resources/settings.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/addon.xml b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/addon.xml new file mode 100644 index 0000000000000000000000000000000000000000..7b8f6c610696659ffa473a1171aac55c507efac6 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/addon.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + video + + + SopCast and AceStream + AceStream and Sopcast in your favourite media center! Watch peer-to-peer streams in Kodi without the need for external players. Project page: https://github.com/enen92/P2P-Streams-Kodi + AceStream e Sopcast no seu Media-Center de eleição! Assista a streams peer-to-peer no Kodi sem a necessidade de players externos. Página do projecto: https://github.com/enen92/P2P-Streams-Kodi + Acestream en Sopcast in jouw favoriete media center. Kijk peer-to-peer streams in Kodi zonder de noodzaak voor externe spelers. Project pagina: https://github.com/enen92/P2P-Streams-Kodi/ + AceStream e SopCast nel tuo Media Center preferito! Guarda i canali peer-to-peer in Kodi senza la necessità di player esterni. Pagina del progetto: https://github.com/enen92/P2P-Streams-Kodi/ + The authors does not host nor distribute any of the content you may watch using this addon. The authors have no affiliation with any of the content providers. This addon does not track its users. + Os autores não alojam nem distribuem nenhum do conteúdo acessível a partir deste addon. Os autores não têm qualquer afiliação com nenhum dos sites utilizados por este addon. O addon não contem nenhuma ferramenta de tracking. + De auteurs houden of delen niets van de inhoud die u kunt bekijken met behulp van deze addon. De auteurs hebben geen banden met welke leverancier van inhoud dan ook. Deze addon houdt geen gegevens bij van zijn gebruikers. + L'autore non detiene o distribuisce alcun contenuto fruibile tramite l'utilizzo di questo addon. L'autore non è affiliato con nessun fornitore dei contenuti. Questo addon non traccia i suoi utenti. + http://forum.kodi.tv/showthread.php?tid=201894 + https://github.com/enen92/P2P-Streams-Kodi | https://github.com/enen92/P2P-Streams-Kodi--Modules- + https://code.google.com/p/p2p-strm/ + all + + diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/changelog.txt b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/changelog.txt new file mode 100644 index 0000000000000000000000000000000000000000..bb8bfe15835cd208bcbb8dd27221cf09947c09bc --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/changelog.txt @@ -0,0 +1,155 @@ +===== Stable Versions ======== +[B]v1.2.0 (20/12/2014)[/B] +-Fixed sopcast-type lists (added a few exceptions) + +[B]v1.1.9 (13/12/2014)[/B] +-Updated Android internal acestreamengine (and external apps) to v3.0.6 (Android L compatible) +-Updated Linux x64 ace engine to v.3.0.5.1 +-Fixed Openelec x86 ace package to be compatible with OE RC/Kodi +-Updated Openelec x64 ace package to v.3.0.5.1 and compatibility with OE RC/kodi +-Removed fixed views in xml lists +-Fixed a minor bug in one of the sopcast settings (thanks alesnav) + +[B]v1.1.8 (10/12/2014)[/B] +-Updated android acestreamengine to version 3.0.3 +-Added option to change port for the internal engine (8621,8622,8623 only) for android +-Added cache allocation option for android (memory vs disk) +-Fixed stop function in android +-Fixed auto-conf in android +-Renamed all utils entries to peertopeerutils to avoid script errors +-Parser sync & disclaimer bump +-Xbmc references 2 Kodi +-Several other bug fixes + +[B]v1.1.7 (6/12/2014)[/B] +-Updated acestreamengine for general linux x64 distros to version 3.0.5 +-Updated acestreamengine for openelec x64 to version 3.0.5 + +[B]v1.1.6 (5/12/2014)[/B] +-Updated windows acestream engine to version 3.0.4 +-Updated general linux x86 acestream engine to version 3.0.3 +-Updated general linux x64 acestream engine to version 3.0.3 +-Updated Openelec x86 acestream engine to version 3.0.3 +-Updated Openelec x64 acestream engine to version 3.0.3 + +[B]v1.1.5 (17/11/2014)[/B] +-Fix listings for Kodi Helix +-Fix dropbox hosted lists + +[B]v1.1.4 (29/10/2014)[/B] +-Acestreamengine bundle for Linux x86 was re-packaged (based on debian to avoid debian errors) +-Fixed OSX curl errors with sopcast (file is downloaded locally by a thread and forwarded to the player) +-New settings for sopcast in osx (timer used for example) +-New configuration for acestreams under osx (using the windows wine emulated version of the acestreamengine 3.0.2 by july ighor) +-New behaviour for Acestreams in OSX +-Changes to the wiki + +[B]v1.1.3 (23/10/2014)[/B] +-Updated windows acestream engine to version 3.0.2 +-Updated Linux x64 acestream engine to version 3.0.2 +-Updated Linux x86 acestream engine to version 3.0.2 +-Updated OpenELEC x64 acestream engine to version 3.0.2 +-Updated OpenELEC i386 acestream engine to version 3.0.2 +-Updated Android Arm acestream engine bundle to version 3.0.2 +-Updated Acestreamengine.apk and AcePlayer.apk in google code repo/mirror +-Fixed action-type settings for Kodi/Helix +-Improved italian translation (tks axlt2002) + +[B]v1.1.2 (4/10/2014)[/B] +-Fix manually add to favourites option not showing +-Fix non-existent acestreamcachefolder on linux +-Added addon history (can be disabed in the addon settings). Every ace or sop link you watch gets saved +-It's now possible to change acestreamengine settings through the addon gui in windows +-Added option to enter the list of parsers on addon startup +-Updated italian translation (tks axlt2002) + +[B]v1.1.1 (29/9/2014)[/B] +-Fix changing acestream settings from the addon for recent linux/android acestreamengine versions +-Add possibility to call torrentstream controller proxy and use any media player (in android) +-Fixed bug with costum fanart not showing in parsers +-Added option to have a costum fanart for costum lists +-Added option to mannually add channels to favourites +-Added a costum stop function to replace the one used by the skin or the remote (credits of the remote option goes to takoi - keymap editor addon). This new function basically checks if the playing media matches the acestream url format and, if that's the case, it kills the engine and clears cache before stopping the stream. +-Updated italian translation (thanks axlt2002) + +[B]v1.1.0 (20/9/2014)[/B] +-Fix acestream window for any skin rather than confluence + +[B]v1.0.9 (19/9/2014)[/B] +-Updated linux x64 Acestreamengine to version 3.0.0-b2 +-Updated Openelec x64 Acestreamengine to version 3.0.0-b2 +-Updated Android internal Acestreamengine to version 2.3.1 +-Updated Android Apks in repository to match latest version of the engine and player +-Added support for android x86 (Acestream only) + +[B]v1.0.8 (17/9/2014)[/B] +-Updated acestreamengine for Windows (version 2.3.0-Next) +-Updated acestreamengine for Linux x64 and Openelec x64 (version 3.0.0 b1) +-Plenty of new options for Android devices: + -The addon now includes its own engine like in other platforms (default option -> All addon). This allows you to change the acestreamengine settings from within the addon plus stop/killing the engine after you watch a stream. + -You can still use xbmc player + external acestream engine as before (xbmc player + external acestreamengine.apk) + -You can now use an external player (aceplayer.apk) (option external player) +-Fixed bug in m3u lists not being properly scrapped +-Added support for private parsers (hosted in dropbox) +-Fixed timezones due to the pytz dependency being missing in addon.xml +-In android rooted devices you can now kill the processes if for some reason xbmc crashed leaving the process running on the background (hence assigned to a different username) +-It's now possibile to define the cache folder from within the addon +-Bump parser disclaimer + +[B]v1.0.7 (8/9/2014)[/B] +-Fix download modules on boot on arm + +[B]v1.0.6 (5/9/2014)[/B] +-Fixed issue with mobile networks +-Updated italian strings (tks axlt2002) +-Fix download modules on boot (acestream) android +-Fix local lists +-Added support for Jynxbox Pure linux custom firmware (added to the list of supported OS's) + + +[B]v1.0.5 (1/9/2014)[/B] +-Fix download modules on boot function +-Fixed script error in advancedsettings.xml +-Fixed "An error has occured" notification after sys.exit +-Bug fixes in the configuration function to avoid the download of wrong modules +-Fixed change port function for platforms using the tarasian666 acestreamengine +-Minor fix regarding disk cache determination in tarasian666 acestreamengine +-Updated acestream bundle for openelec i386 +-Updated acestream bundle for openelec x86_64 +-Fixed acestream bundle for linux i386 +-Bump acestreamengine md5 to force transfer the new acestreambundles for linux_i386, linux_armv6, linux_armv7, osx_i386, osx_x86_64,openeleci386,openelecx86_64 + + +[B]v1.0.4 (29/8/2014)[/B] +-Configuration has been written "from scratch". It's now possible for us to force the user to push module updates between versions. +-It is now possible to change acestreamengine settings from the advanced tools menu for linux +-Fixed non-existing folder if the first thing a user does after instalation is to clear the parser traces or run a remote python script +-Added sleep before sopcast "channel initialization failed" notification +-Minor bug fixes +-Wiki updated + +[B]v1.0.3 (23/8/2014)[/B] +-Updated acestreamengine for windows + android + +B]v1.0.2 (22/8/2014)[/B] +-Updated acestreamengine for linux i386/x64_86 +-Simplified configuration for linux i386/x64_86 +-Updated engines for openelec i386/x64_86 +-Updated sopclient for android +-Improvements in the parser engine (requested by al101) +-Fixed xbmc favourites if parser folder is empty +-Wiki updated + +[B]v1.0.1 (17/8/2014)[/B] +-Fixed handshake for acestreamengine api versions > 2.x +-Added new android acestreamengine (addon configuration) + +[B]v1.0.0 (11/8/2014)[/B] +-First stable release + + +===== Devlopment versions ======= + +[B]v0.1.0 (13-01-2014) - v0.5.0 (11/8/2014)[/B] +-Development and previous alpha,beta releases of the addon + diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/default.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/default.py new file mode 100644 index 0000000000000000000000000000000000000000..22752d1654288dc17c2516668595d15f1be8fb44 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/default.py @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- + +""" p2p-streams (c) 2014 enen92 fightnight + + This file contains the main menu and the addon directory tree. + All the necessary modules are present in ~/resources/core directory + Parsers are in ~/resources/core/parsers + +""" + +import xbmc,xbmcaddon,xbmcgui,xbmcplugin,urllib,urllib2,os,re,sys,datetime,time,subprocess,xbmcvfs,socket +from resources.core.peertopeerutils.pluginxbmc import * +from resources.core import acestream as ace +from resources.core import sopcast as sop +from resources.core.autoconf import * +from resources.core.peertopeerutils.directoryhandle import addLink,addDir +from resources.core.favourites import * +from resources.core.advancedfunctions import * +from resources.core.livestreams import * +from resources.core.parsers import parsers +from resources.core.resolver import go_to_id +from resources.core.acecore import stop_aceengine +from resources.core.history import * + +def main_menu(): + addDir(translate(40114),MainURL,400,addonpath + art + 'web-parsers-menu.png',2,True) + addDir(translate(40115),MainURL,100,addonpath + art + 'xml_lists.png',2,True) + addDir(translate(40144),MainURL,200,addonpath + art + 'Favorites-menu.png',2,True) + if settings.getSetting('addon_history') == "true": + addDir(translate(70036),MainURL,8,addonpath + art + 'history.png',2,True) + if "confluence" in xbmc.getSkinDir(): addLink('','','p2p') + if xbmc.getCondVisibility('system.platform.windows') or xbmc.getCondVisibility('system.platform.linux') or xbmc.getCondVisibility('System.Platform.OSX') or xbmc.getCondVisibility('System.Platform.Android'): + addDir('[COLOR orange]AceStream: [/COLOR]' + translate(40004),MainURL,4,addonpath + art + 'acestream-menu-item.png',1,False) + addDir('[COLOR orange]AceStream: [/COLOR]' + translate(600029),MainURL,6,addonpath + art + 'acestream-menu-item.png',1,False) + if xbmc.getCondVisibility('system.platform.windows') or xbmc.getCondVisibility('system.platform.linux') or xbmc.getCondVisibility('System.Platform.OSX') or xbmc.getCondVisibility('System.Platform.Android'): + addDir('[COLOR orange]SopCast: [/COLOR]' + translate(40005),MainURL,3,addonpath + art + 'sopcast-menu-item.png',1,False) + addDir('[COLOR orange]SopCast: [/COLOR]' + translate(40006),MainURL,5,addonpath + art + 'sopcast-menu-item.png',1,False) + if xbmc.getCondVisibility('System.Platform.IOS') or xbmc.getCondVisibility('System.Platform.ATV2'): + addLink(translate(40056),'',addonpath + art + 'processwarning.png') + if "confluence" in xbmc.getSkinDir(): addLink('','','p2p') + addDir('[B]' + translate(40057) + '[/B]',MainURL,300,addonpath + art + 'settings_menu.png',2,True) + xbmc.executebuiltin("Container.SetViewMode(50)") + #break_sopcast is a function used in windows to intentionally break the sopcast.exe setup by renaming one of its codec files. It's ran here to rename the file again in case it failed when played before + sop.break_sopcast() + + +""" +Addon tree is below +""" + +def get_params(): + param=[] + paramstring=sys.argv[2] + if len(paramstring)>=2: + params=sys.argv[2] + cleanedparams=params.replace('?','') + if (params[len(params)-1]=='/'): + params=params[0:len(params)-2] + pairsofparams=cleanedparams.split('&') + param={} + for i in range(len(pairsofparams)): + splitparams={} + splitparams=pairsofparams[i].split('=') + if (len(splitparams))==2: + param[splitparams[0]]=splitparams[1] + return param + +params=get_params() +url=None +name=None +mode=None +iconimage=None +parser=None +parserfunction=None + +try: url=urllib.unquote_plus(params["url"]) +except: pass +try: name=urllib.unquote_plus(params["name"]) +except: pass +try: mode=int(params["mode"]) +except: pass +try: regexs=params["regexs"] +except:pass +try: iconimage=urllib.unquote_plus(params["iconimage"]) +except: pass +try: parser=urllib.unquote_plus(params["parser"]) +except: pass +try:parserfunction=params["parserfunction"] +except: pass + + +print("Mode: "+str(mode)) +print("URL: "+str(url)) +print("Name: "+str(name)) +print("Iconimage: "+str(iconimage)) +print("Parser: "+str(parser)) +print("Parserfunction: "+str(parserfunction)) + +#from 1-99 functions related to the addon menu functions +if mode==None: + print("Installed version: v" + versao) + if settings.getSetting('autoconfig') == "true": first_conf() + else: + if settings.getSetting('last_version_check') != versao: + try:check_for_updates() + except: pass + if settings.getSetting('enter_channel_list') == "false": + main_menu() + else: + parsers.addon_parsers_menu() +elif mode==1: ace.acestreams(name,iconimage,url) +elif mode==2: sop.sopstreams(name,iconimage,url) +elif mode==3: go_to_id('sop_id') +elif mode==4: go_to_id('ace') +elif mode==5: go_to_id('sop_url') +elif mode==6: ace.load_local_torrent() +elif mode==7: stop_aceengine() +elif mode==8: list_history() +elif mode==9: remove_history() +#from 100-199 functions related to xml lists +elif mode==100: xml_lists_menu() +elif mode==101: list_type(url) +elif mode==102: get_channels(name,url) +elif mode==103: getChannelItems(name,url,"fanart") +elif mode==104: getRegexParsed(regexs, url) +elif mode==105: item = xbmcgui.ListItem(path=url); xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, item) +elif mode==106: xbmc.executebuiltin(url.replace(';','')) +elif mode==107: addlista() +elif mode==108: remove_list(name) +elif mode==109: get_groups(url) +#from 200-299 Favourites +elif mode==200: addon_favourites() +elif mode==201: add_to_addon_favourites(name,url,iconimage) +elif mode==202: remove_addon_favourites(url) +elif mode==203: manual_add_to_favourites() +#from 300-399 Advanced functions +elif mode==300: advanced_menu() +elif mode==301: import_advancedxml() +elif mode==302: recoverbackup_advancedxml() +elif mode==303: backup_advancedxml() +elif mode==304: delete_advancedxml() +elif mode==305: set_engine_setting(url) +elif mode==306: remove_lock() +elif mode==307: clear_cache(url) +elif mode==308: set_linux_engine_setting(url) +elif mode==309: set_acestream_engine_cache_folder(url) +elif mode==310: shutdown_hooks() +elif mode==311: set_android_port() +elif mode==312: set_android_cache_aloc() +#from 400-499 Site parsers +elif mode==400: parsers.addon_parsers_menu() +elif mode==401: + parsers.parser_check() + package = 'resources.core.parsers.' + parser + tree = "main" + parser_module = getattr(__import__(package, fromlist=[tree]), tree) + parser_module.module_tree(name,url,iconimage,mode,parser,parserfunction) +elif mode==402: parsers.add_new_parser(url='') +elif mode==403: parsers.remove_parser(iconimage) +elif mode==404: parsers.runscript() +elif mode==405: parsers.add_new_parser(url) +elif mode==406: parsers.sync_parser() +elif mode==407: parsers.sync_single_parser(parser) +elif mode==408: parsers.clear_parser_trace() + +xbmcplugin.endOfDirectory(int(sys.argv[1])) diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/fanart.jpg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/fanart.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2adf02bff88106cdb477bac6c4e0cfc8504ae3cb Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/fanart.jpg differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/icon.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9d13dbef990dc36450e53e8b1410f4d78b7eae32 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/icon.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.xstream/resources/lib/handler/__init__.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/__init__.py similarity index 100% rename from packages/mediacenter/kodi/config/base-addons/plugin.video.xstream/resources/lib/handler/__init__.py rename to packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/__init__.py diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..4ec4428fbc0875ea8656ddbf406e19c74b09e2b8 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/__init__.pyo differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Baseball.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Baseball.png new file mode 100644 index 0000000000000000000000000000000000000000..a7c756bfe784247e04dbb609a1584e36b6727163 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Baseball.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Basketball.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Basketball.png new file mode 100644 index 0000000000000000000000000000000000000000..ee2082154bb7e01d3efc2fe00aafedb3ebb9e3a5 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Basketball.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Cricket.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Cricket.png new file mode 100644 index 0000000000000000000000000000000000000000..cb3ad6333a49e960df75537bccc57f0ed6d66008 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Cricket.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Cycling.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Cycling.png new file mode 100644 index 0000000000000000000000000000000000000000..ed2cfaf3ca73ce9c87c4e22147d1559dd0923c3c Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Cycling.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Favorites-menu.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Favorites-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..d9fd2fd31416328e314eacb78e1eaf5349c136f3 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Favorites-menu.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Golf.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Golf.png new file mode 100644 index 0000000000000000000000000000000000000000..a2cf7590a68686043c94b20275acb1e8cc4ea236 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Golf.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/IceHockey.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/IceHockey.png new file mode 100644 index 0000000000000000000000000000000000000000..9fa20f81f7886a5212f1caeecf6475777bc2d8f6 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/IceHockey.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Other.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Other.png new file mode 100644 index 0000000000000000000000000000000000000000..5653b96ee8113be7a54b6a4601762f4031b357a0 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Other.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Other_white.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Other_white.png new file mode 100644 index 0000000000000000000000000000000000000000..0b146c62d9e8ce1f623259329b04330a393a4082 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Other_white.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Racing.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Racing.png new file mode 100644 index 0000000000000000000000000000000000000000..66aa50cc3553751011587ae73926956f523b60b2 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Racing.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Rugby.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Rugby.png new file mode 100644 index 0000000000000000000000000000000000000000..3b507967af5fc58979a22a3eb36c5360f8a15c90 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Rugby.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Tennis.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Tennis.png new file mode 100644 index 0000000000000000000000000000000000000000..aa39121f5814c47c54d35c40f38dbdc4f0c54102 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/Tennis.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/acelogofull.jpg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/acelogofull.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5dd034991efe78ed39d5b5ce63622470b89e0c3a Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/acelogofull.jpg differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/acestream-menu-item.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/acestream-menu-item.png new file mode 100644 index 0000000000000000000000000000000000000000..7786f4476e824148443b2b9c8b6adb0faee82736 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/acestream-menu-item.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/acestreamlogo.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/acestreamlogo.png new file mode 100644 index 0000000000000000000000000000000000000000..af4e363455648e3a59c53f4ec37ffad97aaddbd4 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/acestreamlogo.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/americanfootball.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/americanfootball.png new file mode 100644 index 0000000000000000000000000000000000000000..a3ad3c41feb8b9aa87be6fcf2f34fc1fa8b925b1 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/americanfootball.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/cloud.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/cloud.png new file mode 100644 index 0000000000000000000000000000000000000000..b9848e1e265688420facf558f64d46a1b98b1463 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/cloud.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/football.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/football.png new file mode 100644 index 0000000000000000000000000000000000000000..7f88fc23e769edc99712c0a57237c79cd1e0d362 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/football.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/history.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/history.png new file mode 100644 index 0000000000000000000000000000000000000000..c9a52f2cffc52739b6364c9a2382dd6b737cbb8f Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/history.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/lateral-fundo.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/lateral-fundo.png new file mode 100644 index 0000000000000000000000000000000000000000..4b7488955671869f14be21a940536aa338a814bc Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/lateral-fundo.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/lateral-separador.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/lateral-separador.png new file mode 100644 index 0000000000000000000000000000000000000000..5b7212a95fae3dbec5deebb6c1f190732ecfb3f6 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/lateral-separador.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/plus-menu.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/plus-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..40df3fe1393fc2d801bc15e8da1b7a65b670d0f7 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/plus-menu.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/processwarning.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/processwarning.png new file mode 100644 index 0000000000000000000000000000000000000000..37b0ac5063436131f3cd9caa89b89d38e52829d7 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/processwarning.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/settings_menu.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/settings_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..45293af5fd74d3ea9817dfa093cf03847d0a2f1c Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/settings_menu.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/sopcast-menu-item.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/sopcast-menu-item.png new file mode 100644 index 0000000000000000000000000000000000000000..170e1f36f28ce20db8ccec6b4f989ce65403c8c4 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/sopcast-menu-item.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/sopcast_link.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/sopcast_link.png new file mode 100644 index 0000000000000000000000000000000000000000..7120eff5c6858627b58475ca1466f97f4509f1bc Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/sopcast_link.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/sopcast_logo.jpg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/sopcast_logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1b7eb1af7ce17f51d74e976f2fd0142908585ddc Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/sopcast_logo.jpg differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/web-parsers-menu.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/web-parsers-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..ecbbe839f528126aedbbcb8c307b3903263ac229 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/web-parsers-menu.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/xml_list_sopcast.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/xml_list_sopcast.png new file mode 100644 index 0000000000000000000000000000000000000000..30eb68f654a4249e97d27298b3d10b053d30278f Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/xml_list_sopcast.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/xml_lists.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/xml_lists.png new file mode 100644 index 0000000000000000000000000000000000000000..aed31dda499b621a85d75aba193b2f44145480e3 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/art/xml_lists.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/binaries/sopclient b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/binaries/sopclient new file mode 100644 index 0000000000000000000000000000000000000000..39b8281a585829a64685ed32d77649a327b59007 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/binaries/sopclient differ diff --git a/packages/mediacenter/kodi/config/base-addons/skin.titan/extras/openelec/openelec_logo.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/__init__.py similarity index 100% rename from packages/mediacenter/kodi/config/base-addons/skin.titan/extras/openelec/openelec_logo.png rename to packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/__init__.py diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..266fba3a59efc855951b0b4d2065b8a3b28bc95b Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/__init__.pyo differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/acecore.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/acecore.py new file mode 100644 index 0000000000000000000000000000000000000000..b753c95b4f43963e6e22487f261cd363170ce135 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/acecore.py @@ -0,0 +1,1038 @@ +# -*- coding: utf-8 -*- + +""" p2p-streams (c) 2014 enen92 fightnight + + This file contains the acestream console of the addon. Initial versions were coded by Nouismons and so, this file is based on his work. + + Classes: + + Logger() -> Log class + _TSPlayer(xbmc.Player) -> Inheritance of the xbmc.Player class for acestreams + TSengine() -> Acestreamengine class, start functions, etc + TSServ(threading.Thread) -> Acestreamengine service class + OverlayText(object) -> Overlaytext displayed on player + + +""" + +import httplib,urllib,urllib2,re,sys,subprocess,os,socket,threading,time,random,json,xbmcplugin,xbmcgui,xbmc,xbmcaddon,xbmcvfs +from peertopeerutils.pluginxbmc import * + +""" Fixed variables """ + +aceport=int(settings.getSetting('aceporta')) +server_ip=settings.getSetting('ip_addr') +if settings.getSetting('save')=='true': save=False +else: save=False +if settings.getSetting('ace-debug')=='true': alog=True +else: alog=False +if (sys.platform == 'win32') or (sys.platform == 'win64'): pwin=True +else: pwin=False +if xbmc.getCondVisibility('System.Platform.OSX'): posx=True +else: posx=False + + +""" Function and class list """ + + +def show_Msg(heading, message, times = 3000, pics = addon_icon): + try: xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s, "%s")' % (heading.encode('utf-8'), message.encode('utf-8'), times, pics.encode('utf-8'))) + except Exception, e: + print( '[%s]: ShowMessage: Transcoding UTF-8 failed [%s]' % (addon_id, e), 2 ) + try: xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s, "%s")' % (heading, message, times, pics)) + except Exception, e: + print( '[%s]: ShowMessage: exec failed [%s]' % (addon_id, e), 3 ) + +class Logger(): + def __init__(self,Name): + self.started=False + self.name=Name + self.link=None + def out(self,txt): + if alog: + print "%s:%s"%(self.name,txt) + + +class _TSPlayer(xbmc.Player): + + def __init__( self): + self.started=False + self.log=Logger("TSPlayer") + self.log.out('init') + self.active=True + self.link=None + self.vod=True + self.duration=None + self.coms=[] + if settings.getSetting('force_dvplayer') == 'true': xbmc.Player(xbmc.PLAYER_CORE_DVDPLAYER) + def onPlayBackPaused( self ): + self.log.out('paused') + + def onPlayBackStarted( self ): + xbmc.executebuiltin('XBMC.ActivateWindow("fullscreenvideo")') + self.started=True + self.log.out('started') + if self.vod: + try: + self.duration= int(xbmc.Player().getTotalTime()*1000) + comm='DUR '+self.link.replace('\r','').replace('\n','')+' '+str(self.duration) + self.coms.append(comm) + except: pass + + comm='PLAYBACK '+self.link.replace('\r','').replace('\n','')+' 0' + self.coms.append(comm) + xbmc.sleep(2500) + + def onPlayBackResumed(self): + self.log.out("play resume") + + def onPlayBackEnded(self): + self.log.out("play ended") + self.active=False + comm='PLAYBACK '+self.link.replace('\r','').replace('\n','')+' 100' + self.coms.append(comm) + + def onPlayBackStopped(self): + self.log.out("play stop") + self.active=False + if settings.getSetting('engine-status') == "true": + try:lat123._close() + except:pass + + def __del__(self): + self.log.out('delete') + + + +class TSengine(): + + def __init__(self): + xbmc.Player().stop() + self.log=Logger("TSEngine") + self.push=Logger('OUT') + self.alive=True + self.progress = xbmcgui.DialogProgress() + self.player=None + self.files={} + self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._sock.settimeout(3) + self.progress.create(translate(40000),translate(40052)) + self.tsserv =None + self.conn=False + self.title=None + self.filename=None + self.mode=None + self.url=None + self.local=False + self.saved=False + self.pos=[25,50,75,100] + l=False + while xbmc.Player().isPlaying(): + l=True + if xbmc.abortRequested: + self.log.out("XBMC asked to abort request") + return False + if self.progress.iscanceled(): + return False + xbmc.sleep(300) + + settings.setSetting('active','1') + if l: xbmc.sleep(500) + + def ts_init(self): + self.tsserv = TSServ(self._sock) + self.tsserv.start() + comm="HELLOBG" + self.TSpush(comm) + self.progress.update(0,translate(1104)," ") + while not self.tsserv.version: + if xbmc.abortRequested: + self.log.out("XBMC asked to abort request") + return False + if self.progress.iscanceled(): + return False + time.sleep(1) + ready='READY' + if self.tsserv.key: + import hashlib + sha1 = hashlib.sha1() + pkey=self.tsserv.pkey + sha1.update(self.tsserv.key+pkey) + key=sha1.hexdigest() + pk=pkey.split('-')[0] + key="%s-%s"%(pk,key) + ready='READY key=%s'% key + if self.progress.iscanceled(): + self.err=1 + return False + self.TSpush(ready) + return True + + def sm(self,msg): + show_Msg('AceStream',msg) + + def connect(self): + server_ip='127.0.0.1' + servip=settings.getSetting('ip_addr') + aceport=int(settings.getSetting('aceporta')) + self.log.out('Trying to connect') + self.progress.update(0,translate(1001),' ') + if pwin: + res=self.startWin() + aceport=self.getWinPort() + if not aceport: + res=self.startWin() + if not res: return False + elif posx: + res=self.startosx() + aceport=self.getosxPort() + if not aceport: + res=self.startosx() + if not res: return False + else: + self.log.out('try to connect to Linux engine') + self.log.out('Connecting to %s:%s'%(servip,aceport)) + try: + self._sock.connect((servip, aceport)) + self.log.out('Connected to %s:%s'%(servip,aceport)) + return True + except: + res=self.startLin() + if not res: return False + i=40 + while (i>1): + self.progress.update(0,translate(40046),translate(40049) + str('%s'%i) + ' ' + translate(40050) ) + try: + if pwin: aceport=self.getWinPort() + elif posx: aceport=self.getosxPort() + self._sock.connect((servip, aceport)) + self.log.out('Connected to %s:%s'%(servip,aceport)) + i=0 + return True + except: + self.log.out('Failed to connect to %s:%s'%(servip,aceport)) + if self.progress.iscanceled(): + return False + break + i=i-1 + xbmc.sleep(1000) + if xbmc.getCondVisibility('system.platform.OSX'): + j = [33,30,27,24,21,18,15,12,9,6,3] + if i in j: + print("another attempt to start osx engine..") + self.startosx() + self._sock.close() + self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + self.sm('Cant connect') + return False + + def getosxPort(self): + try: + path=os.path.join('/Applications','Ace Stream.app','Contents','Resources','wineprefix','drive_c','users','IGHOR','Application Data','ACEStream','engine') + pfile= os.path.join( path,'acestream.port') + gf = open(pfile, 'r') + aceport=int(gf.read()) + except: + return False + self.log.out('get aceport - %s'%aceport) + return aceport + + def startosx(self): + self.log.out('try to start OSX engine') + import subprocess + comd = [os.path.join('/Applications','Ace Stream.app','Contents','Resources','Wine.bundle','Contents','Resources','bin','wine'),os.path.join('/Applications','Ace Stream.app','Contents','Resources','wineprefix','drive_c','users','IGHOR','Application Data','ACEStream','engine','ace_engine.exe')] + print comd + try: + self.proc = subprocess.Popen(comd,shell=False) + except: + self.sm('Not Installed') + self.log.out('Not Installed') + self.progress.update(0,'AceStream not installed','') + return False + self.log.out('Engine starting') + return True + + + def startLin(self): + self.log.out('try to start Lin engine') + import subprocess + if xbmc.getCondVisibility('System.Platform.Android') or settings.getSetting('force_android') == "true": + try: + if settings.getSetting('engine_app') == "1": xbmc.executebuiltin('XBMC.StartAndroidActivity("org.acestream.engine")') + else: + command = ["sh","/data/data/"+settings.getSetting('app_id')+"/files/plugin.video.p2p-streams/org.acestream.engine/files/droidace.sh",settings.getSetting('app_id')] + if settings.getSetting('total_max_download_rate') != "0": + command.append('--download-limit') + command.append(settings.getSetting('total_max_download_rate')) + if settings.getSetting('total_max_upload_rate') != "0": + command.append('--upload-limit') + command.append(settings.getSetting('total_max_upload_rate')) + self.proc = subprocess.Popen(command) + except: + self.sm("Not installed") + self.log.out("Not installed") + self.progress.update(0,"Acestreamengine.apk not installed","") + else: + print("Linux not android..") + if os.uname()[4] == "armv6l" or os.uname()[4] == "armv7l": + try: + self.proc = subprocess.Popen([settings.getSetting('python_cmd'),os.path.join(pastaperfil,'acestream','ace','start.py')]) + except: + self.sm("Not installed") + self.log.out("Not installed") + self.progress.update(0,"Acestream engine not installed") + + elif settings.getSetting('openeleci386') == "true" or settings.getSetting('openelecx86_64') == "true": + try: + command = ["sh",os.path.join(pastaperfil,'acestream','start.sh')] + if settings.getSetting('total_max_download_rate') != "0": + command.append('--download-limit') + command.append(settings.getSetting('total_max_download_rate')) + if settings.getSetting('total_max_upload_rate') != "0": + command.append('--upload-limit') + command.append(settings.getSetting('total_max_upload_rate')) + self.proc = subprocess.Popen(command) + except: + self.sm("Not installed") + self.log.out("Not installed") + self.progress.update(0,"Acestream engine not installed") + else: + print("Not armv7 or armv6") + if settings.getSetting('ace_cmd') == "0": + acefolder = os.path.join(pastaperfil,'acestream') + acebin = os.path.join(pastaperfil,'acestream','acestreamengine') + command = [acebin,'--client-console','--lib-path',acefolder] + if settings.getSetting('total_max_download_rate') != "0": + command.append('--download-limit') + command.append(settings.getSetting('total_max_download_rate')) + if settings.getSetting('total_max_upload_rate') != "0": + command.append('--upload-limit') + command.append(settings.getSetting('total_max_upload_rate')) + print command + elif settings.getSetting('ace_cmd') == "1": command = ["acestreamengine","--client-console"] + elif settings.getSetting('ace_cmd') == "2": command = settings.getSetting('ace_cmd_alternative').split(' ') + try: + self.proc = subprocess.Popen(command) + except: + self.sm('Not Installed') + self.log.out('Not Installed') + self.progress.update(0,'AceStream not installed','') + return False + self.log.out('Engine starting') + return True + + def startWin(self): + try: + needed_value='ace_engine.exe' + path_value=os.path.join(pastaperfil,'acestream',needed_value) + self.log.out("Try to start %s"%needed_value) + self.progress.update(0,'Starting ASEngine','') + os.startfile(path_value) + self.log.out('AceStream Engine starting') + except: + self.sm('Not Installed') + self.log.out('Not Installed') + self.progress.update(0,'AceStream not installed','') + return False + return True + + def getWinPort(self): + try: + path=os.path.join(pastaperfil,'acestream') + pfile= os.path.join( path,'acestream.port') + gf = open(pfile, 'r') + aceport=int(gf.read()) + except: + return False + self.log.out('get aceport - %s'%aceport) + return aceport + + def TSpush(self,command): + self.push.out(command) + try: + self._sock.send(command+'\r\n') + except: + self.push.out("!!!Error!!!") + + def get_link(self, index=0, title='', icon='', thumb=''): + self.title=title + self.log.out("play") + self.tsserv.ind=index + self.progress.update(89,translate(1005),'') + for k,v in self.files.iteritems(): + if v==index: self.filename=urllib.unquote(k).replace('/','_').replace('\\','_') + try: + avail=os.path.exists(self.filename.decode('utf-8')) + except: + try: + avail=os.path.exists(self.filename) + self.filename=self.filename.encode('utf-8') + except: self.filename='temp.avi' + self.log.out('Starting file:%s'%self.filename) + + try: self.filename=settings.getSetting('folder')+self.filename + except: + self.filename=None + save=False + + self.log.out('Get filename to save:%s'%self.filename) + spons='' + if self.mode!='PID': spons=' 0 0 0' + comm='START '+self.mode+ ' ' + self.url + ' '+ str(index) + spons + self.TSpush(comm) + self.progress.update(89,translate(1004),'') + while not self.tsserv.got_url and not self.progress.iscanceled() and not self.tsserv.err: + self.progress.update(int(self.tsserv.proc),self.tsserv.label,self.tsserv.line) + xbmc.sleep(200) + if xbmc.abortRequested: + self.log.out("XBMC is shutting down") + break + if self.tsserv.err: self.sm('Failed to load file') + self.progress.update(100,translate(1005),'') + if settings.getSetting('save')=='true': save=True + else: save=False + + if self.tsserv.event and save: + self.progress.update(0,translate(400006)," ") + comm='SAVE %s path=%s'%(self.tsserv.event[0]+' '+self.tsserv.event[1],urllib.quote(self.filename)) + self.TSpush(comm) + self.tsserv.event=None + succ=True + + while not os.path.exists(self.filename.decode('utf-8')) and not self.progress.iscanceled(): + if xbmc.abortRequested or self.progress.iscanceled(): + self.log.out("XBMC asked to abort request") + succ=False + break + xbmc.sleep(200) + if not succ: return False + self.tsserv.got_url=self.filename.decode('utf-8') + self.local=True + + self.active=True + self.progress.close() + return self.tsserv.got_url + + def play_url_ind(self, index=0, title='', icon='', thumb=''): + self.lnk=self.get_link(index,title,icon,thumb) + if not self.lnk: return False + if settings.getSetting('aceplay_type') == str(1): + if ":6878/" in self.lnk: self.lnk = self.lnk.replace(":6878",":" + settings.getSetting('playerport')) + if self.progress:self.progress.close() + item = xbmcgui.ListItem(title,iconImage="DefaultVideo.png", thumbnailImage=thumb) + item.setPath(path=self.lnk) + if settings.getSetting('engine-status') == "true": + global lat123 + lat123 = OverlayText() + xbmcplugin.setResolvedUrl(int(sys.argv[1]),True,item) + xbmc.sleep(100) + self.player=_TSPlayer() + self.player.vod=True + self.player.link=self.tsserv.got_url + self.log.out('play') + self.player.link=self.lnk + if self.progress:self.progress.close() + if self.local: + if int(sys.argv[1]) < 0: + xbmc.Player().play(self.lnk,item) + else: + xbmc.sleep(50) + if int(sys.argv[1]) < 0: + self.player.play(self.lnk,item) + show_window = False + while self.player.active and not self.local: + if settings.getSetting('engine-status') == "true": + if show_window == False and xbmc.getCondVisibility('Window.IsActive(videoosd)'): + lat123.show() + show_window = True + elif not xbmc.getCondVisibility('Window.IsActive(videoosd)'): + try: + lat123.hide() + except: pass + show_window = False + self.loop() + xbmc.sleep(300) + if xbmc.abortRequested: + self.log.out("XBMC asked to abort request") + break + self.log.out('ended play') + + def loop(self): + pos=self.pos + + if len(self.player.coms)>0: + comm=self.player.coms[0] + self.player.coms.remove(comm) + self.TSpush(comm) + + if self.player.isPlaying(): + if self.player.getTotalTime()>0: cpos= int((1-(self.player.getTotalTime()-self.player.getTime())/self.player.getTotalTime())*100) + else: cpos=0 + if cpos in pos: + pos.remove(cpos) + comm='PLAYBACK '+self.player.link.replace('\r','').replace('\n','')+' %s'%cpos + self.TSpush(comm) + + if self.tsserv.event and save: + self.log.out('Try to save file in loop') + comm='SAVE %s path=%s'%(self.tsserv.event[0]+' '+self.tsserv.event[1],urllib.quote(self.filename)) + self.TSpush(comm) + self.tsserv.event=None + succ=True + self.saved=True + + if self.saved and self.player.started: + self.log.out('saving content') + if self.player.isPlaying() and os.path.exists(self.filename.decode('utf-8')): + xbmc.sleep(10000) + self.log.out('Start local file') + self.tsserv.got_url=self.filename + self.local=True + + self.sm('Start Local File') + try: time1=self.player.getTime() + except: time1=0 + + i = xbmcgui.ListItem("***%s"%self.title) + i.setProperty('StartOffset', str(time1)) + self.log.out('Play local file') + self.local=True + self.player.active=False + + + def load_torrent(self, torrent, mode, host=server_ip, port=aceport ): + self.mode=mode + self.url=torrent + if not self.connect(): + + return False + if not self.ts_init(): + self.sm('Initialization Failed') + return False + self.conn=True + self.progress.update(0,translate(1102),"") + + if mode!='PID': spons=' 0 0 0' + else: spons='' + comm='LOADASYNC '+ str(random.randint(0, 0x7fffffff)) +' '+mode+' ' + torrent + spons + self.TSpush(comm) + + while not self.tsserv.files and not self.progress.iscanceled(): + if xbmc.abortRequested: + self.log.out("XBMC is shutting down") + break + if self.tsserv.err: + self.log.out("Failed to load files") + break + xbmc.sleep(200) + if self.progress.iscanceled(): + return False + if not self.tsserv.files: + self.sm('Failed to load list files') + return False + self.filelist=self.tsserv.files + self.file_count = self.tsserv.count + self.files={} + self.progress.update(89,translate(40043),'') + if self.file_count>1: + flist=json.loads(self.filelist) + for list in flist['files']: + self.files[urllib.unquote_plus(urllib.quote(list[0]))]=list[1] + elif self.file_count==1: + flist=json.loads(self.filelist) + list=flist['files'][0] + self.files[urllib.unquote_plus(urllib.quote(list[0]))]=list[1] + + self.progress.update(100,translate(40051),'') + + return "Ok" + + def end(self): + if settings.getSetting("kill_type") == "1" or xbmc.getCondVisibility('system.platform.windows'): + self.active=False + comm='SHUTDOWN' + if self.conn:self.TSpush(comm) + self.log.out("Ending") + try: self._sock.shutdown(socket.SHUT_WR) + except: pass + if self.tsserv: self.tsserv.active=False + if self.tsserv: self.tsserv.join() + self.log.out("end thread") + self._sock.close() + self.log.out("socket closed") + if self.progress:self.progress.close() + + if settings.getSetting('engine-status') == "true": + try:lat123._close() + except:pass + + if xbmc.getCondVisibility('system.platform.windows'): + if settings.getSetting('shutdown-engine') == "true": + subprocess.Popen('taskkill /F /IM ace_engine.exe /T',shell=True) + else: pass + elif xbmc.getCondVisibility('system.platform.linux') and not xbmc.getCondVisibility('System.Platform.Android'): + if settings.getSetting('shutdown-engine') == "true": + try: + self.proc.kill() + self.proc.wait() + if settings.getSetting('openelecx86_64') == "true" or settings.getSetting('openeleci386') == "true": + os.system("kill $(ps aux | grep '[a]cestream' | awk '{print $1}')") + except: pass + elif xbmc.getCondVisibility('system.platform.OSX'): + if settings.getSetting('shutdown-engine') == "true": + try: + kill_cmd = [os.path.join('/Applications','Ace Stream.app','Contents','Resources','Wine.bundle','Contents','Resources','bin','wine'),os.path.join('/Applications','Ace Stream.app','Contents','Resources','wineprefix','drive_c','windows','system','taskkill.exe'),'/f','/im','ace_engine.exe'] + #print kill_cmd + kill_proc = subprocess.Popen(kill_cmd,shell=False) + except: pass + try: + self.proc.kill() + self.proc.wait() + except: pass + elif xbmc.getCondVisibility('System.Platform.Android') and settings.getSetting("engine_app") == "0": + if settings.getSetting('shutdown-engine') == "true": + try: + self.proc.kill() + self.proc.wait() + except: pass + try: + xbmc_user = os.getlogin() + procshut_ace = subprocess.Popen(['ps','|','grep','python'],shell=False,stdout=subprocess.PIPE) + for line in procshut_ace.stdout: + match = re.findall(r'\S+', line.rstrip()) + if match: + if 'acestream' in match[-1] and len(match)>2: + if xbmc_user == match[0]: + os.system("kill " + match[1]) + else: + os.system("su -c kill " + match[1]) + except: pass + + + if settings.getSetting("kill_type") == "0": + if xbmc.getCondVisibility('system.platform.windows'): + subprocess.Popen('taskkill /F /IM ace_engine.exe /T',shell=True) + #if settings.getSetting('save') != "true": + # try: + # cache_file = self.lnk.split('/')[-2] + # acestream_cachefolder_file = os.path.join(os.getenv("SystemDrive"),'\_acestream_cache_',cache_file) + # xbmcvfs.delete(acestream_cachefolder_file) + # except: pass + + if xbmc.getCondVisibility('system.platform.linux') and not xbmc.getCondVisibility('System.Platform.Android'): + os.system("kill $(ps aux | grep '[a]cestream' | awk '{print $1}')") + os.system("kill $(ps aux | grep '[a]cestream' | awk '{print $2}')") + os.system("kill $(ps aux | grep '[s]tart.py' | awk '{print $2}')") + if settings.getSetting('save') != "true": + try: + cache_file = self.lnk.split('/')[-2] + if 'arm' not in os.uname()[4]: + if settings.getSetting('acestream_cachefolder') == '': acestream_cachefolder_file = os.path.join(os.getenv("HOME"),'.ACEStream','cache','.acestream_cache') + else: acestream_cachefolder_file = settings.getSetting('acestream_cachefolder') + else: + if settings.getSetting('acestream_cachefolder') == '': acestream_cachefolder_file = os.path.join(os.getenv("HOME"),'.ACEStream','cache') + else: acestream_cachefolder_file = settings.getSetting('acestream_cachefolder') + folder,cachefiles = xbmcvfs.listdir(acestream_cachefolder_file) + for cachefile in cachefiles: + if cache_file in cachefile: + xbmcvfs.delete(os.path.join(acestream_cachefolder_file,cachefile)) + except: pass + + elif xbmc.getCondVisibility('system.platform.OSX'): + try: + kill_cmd = [os.path.join('/Applications','Ace Stream.app','Contents','Resources','Wine.bundle','Contents','Resources','bin','wine'),os.path.join('/Applications','Ace Stream.app','Contents','Resources','wineprefix','drive_c','windows','system','taskkill.exe'),'/f','/im','ace_engine.exe'] + #print kill_cmd + kill_proc = subprocess.Popen(kill_cmd,shell=False) + except: pass + + elif xbmc.getCondVisibility('System.Platform.Android'): + try: + procshut_ace = subprocess.Popen(['ps','|','grep','python'],shell=False,stdout=subprocess.PIPE) + for line in procshut_ace.stdout: + match = re.findall(r'\S+', line.rstrip()) + if match: + if 'acestream' in match[-1] and len(match)>2: + os.system("kill " + match[1]) + xbmc.sleep(200) + except: pass + if settings.getSetting('save') != "true": + try: + if settings.getSetting('acestream_cachefolder') != '': + dirs, cache_files = xbmcvfs.listdir(os.path.join(settings.getSetting('acestream_cachefolder'),'.acestream_cache')) + print dirs,cache_files + for cache_file in cache_files: + xbmcvfs.delete(os.path.join(settings.getSetting('acestream_cachefolder'),'.acestream_cache',cache_file)) + else: + acestream_cachefolder_file = os.path.join('/sdcard','.ACEStream','cache','.acestream_cache') + dirs, cache_files = xbmcvfs.listdir(acestream_cachefolder_file) + for cache_file in cache_files: + xbmcvfs.delete(os.path.join(acestream_cachefolder_file,cache_file)) + except: pass + + self.active=False + self.log.out("Force Killing") + try: self._sock.shutdown(socket.SHUT_WR) + except: pass + if self.tsserv: self.tsserv.active=False + if self.tsserv: self.tsserv.join() + self.log.out("end thread") + self._sock.close() + self.log.out("socket closed") + if self.progress:self.progress.close() + + + + def __del__(self): + settings.setSetting('active','0') + +class TSServ(threading.Thread): + + def __init__(self,_socket): + self.pkey='n51LvQoTlJzNGaFxseRK-uvnvX-sD4Vm5Axwmc4UcoD-jruxmKsuJaH0eVgE' + threading.Thread.__init__(self) + self.log=Logger("TSServer") + self.inc=Logger('IN') + self.log.out("init") + self.sock=_socket + self.daemon = True + self.active = True + self.err = False + self.buffer=65020 + self.temp="" + self.msg=None + + self.version=None + + self.fileslist=None + self.files=None + self.key=None + self.count=None + self.ind=None + + self.got_url=None + self.event=None + self.proc=0 + self.label='' + self.line='' + self.pause=False + def run(self): + while self.active and not self.err: + + try: + self.last_received=self.sock.recv(self.buffer) + except: self.last_received='' + + ind=self.last_received.find('\r\n') + cnt=self.last_received.count('\r\n') + + if ind!=-1 and cnt==1: + self.last_received=self.temp+self.last_received[:ind] + self.temp='' + self.exec_com() + elif cnt>1: + fcom=self.last_received + ind=1 + while ind!=-1: + ind=fcom.find('\r\n') + self.last_received=fcom[:ind] + self.exec_com() + fcom=fcom[(ind+2):] + elif ind==-1: + self.temp=self.temp+self.last_received + self.last_received=None + + + + self.log.out('Daemon Dead') + + def exec_com(self): + + self.inc.out(self.last_received) + line=self.last_received + comm=self.last_received.split(' ')[0] + params=self.last_received.split(' ')[1::] + self.msg=line + if settings.getSetting('ace-debug') == "true": + print('Sent command: ' + str(comm)) + if comm=='HELLOTS': + try: self.version=params[0].split('=')[1] + except: self.version='1.0.6' + try: + match = re.compile('key=(.*)').findall(line) + self.key = match[0].split(' ')[0] + except: self.key=None + elif comm=='LOADRESP': + fil = line + ll= fil[fil.find('{'):len(fil)] + self.fileslist=ll + + json_files=json.loads(self.fileslist) + try: + aa=json_files['infohash'] + if json_files['status']==2: + self.count=len(json_files['files']) + if json_files['status']==1: + self.count=1 + if json_files['status']==0: + self.count=None + self.files=self.fileslist.split('\n')[0] + self.fileslist=None + self.log.out("files:%s"%self.files) + except: + self.count=None + self.fileslist=None + self.err=True + elif comm=='EVENT': + if self.last_received.split(' ')[1]=='cansave': + event=self.last_received.split(' ')[2:4] + ind= event[0].split('=')[1] + if int(ind)==int(self.ind): self.event=event + if self.last_received.split(' ')[1]=='getuserdata': + self.sock.send('USERDATA [{"gender": 1}, {"age": 3}]\r\n') + + elif comm=='START' or comm=='PLAY': + servip=settings.getSetting('ip_addr') + self.got_url=self.last_received.split(' ')[1].replace('127.0.0.1',servip) # + self.log.out('Get Link:%s'%self.got_url) + self.params=self.last_received.split(' ')[2:] + if 'stream=1' in self.params: self.log.out('Live Stream') + else: self.log.out('VOD Stream') + elif comm=='RESUME': self.pause=0 + elif comm=='PAUSE': self.pause=1 + if comm=="STATUS": self.showStats(line) + + def showStats(self,params): + params=params.split(' ')[1] + ss=re.compile('main:[a-z]+',re.S) + s1=re.findall(ss, params)[0] + st=s1.split(':')[1] + self.proc=0 + self.label=" " + self.line=" " + + if st=='idle': + self.label=translate(1105) + if settings.getSetting('ace-debug') == "true": + print('Received command Engine idle' ) + + elif st=='starting': + self.label=translate(40055) + if settings.getSetting('ace-debug') == "true": + print('Received command starting TS' ) + + elif st=='err': + self.label=translate(1011) + self.err="dl" + if settings.getSetting('ace-debug') == "true": + print('Received command ERROR!' ) + + elif st=='check': + self.label=translate(1103) + self.proc=int(params.split(';')[1]) + if settings.getSetting('ace-debug') == "true": + print('Received command check' ) + + elif st=='prebuf': + self.proc=int( params.split(';')[1] )+0.1 + self.label=translate(1100) + self.line='Seeds:%s Download:%sKb/s'%(params.split(';')[8],params.split(';')[5]) + engine_data = { "action": str(translate(1100)), "percent": str(params.split(';')[1])+ "%","download":str(params.split(';')[5]) + " Kb/s", "upload":str(params.split(';')[7]) + " Kb/s","seeds":str(params.split(';')[8]),"total_download":str(int(params.split(';')[10])/(1024*1024))+'Mb',"total_upload":str(int(params.split(';')[12])/(1024*1024))+'Mb' } + if settings.getSetting('ace-debug') == "true": + print('Received command: ' + str(engine_data) ) + + elif st=='loading': + self.label=translate(40043) + if settings.getSetting('ace-debug') == "true": + print('Received command loading' ) + + elif st=='dl': + engine_data = { "action": str(translate(50010)), "percent": str(params.split(';')[1])+ "%","download":str(params.split(';')[3]) + " Kb/s", "upload":str(params.split(';')[5]) + " Kb/s","seeds":str(params.split(';')[6]),"total_download":str(int(params.split(';')[8])/(1024*1024))+'Mb',"total_upload":str(int(params.split(';')[10])/(1024*1024))+'Mb' } + if settings.getSetting('engine-status') == "true": + try: + lat123.set_information(engine_data) + except: pass + if settings.getSetting('ace-debug') == "true": + print('Received command: ' + str(engine_data) ) + + elif st=='buf': + engine_data = { "action": str(translate(50008)), "percent": str(params.split(';')[1])+ "%","download":str(params.split(';')[5]) + " Kb/s", "upload":str(params.split(';')[7]) + " Kb/s","seeds":str(params.split(';')[8]),"total_download":str(int(params.split(';')[10])/(1024*1024))+"Mb","total_upload":str(int(params.split(';')[12])/(1024*1024))+"Mb" } + if settings.getSetting('engine-status') == "true": + try: + lat123.set_information(engine_data) + except: pass + if settings.getSetting('ace-debug') == "true": + print('Received command: ' + str(engine_data) ) + + def end(self): + self.active = False + self.daemon = False + self.log.out('Daemon Fully Dead') + + +def stop_aceengine(): + print "coiso a fechar a aceengine" + if xbmc.getCondVisibility('Player.HasMedia'): + if re.findall('http://(\d+).(\d+).(\d+).(\d+):(\d+)/content/(.+?)/(\d+)\.(\d+)',xbmc.Player().getPlayingFile()): + if xbmc.getCondVisibility('system.platform.windows'): + subprocess.Popen('taskkill /F /IM ace_engine.exe /T',shell=True) + #Need to finish this... + #if settings.getSetting('save') != "true": + # try: + # cache_file = self.lnk.split('/')[-2] + # acestream_cachefolder_file = os.path.join(os.getenv("SystemDrive"),'\_acestream_cache_',cache_file) + # xbmcvfs.delete(acestream_cachefolder_file) + # except: pass + + if xbmc.getCondVisibility('system.platform.linux') and not xbmc.getCondVisibility('System.Platform.Android'): + os.system("kill $(ps aux | grep '[a]cestream' | awk '{print $1}')") + os.system("kill $(ps aux | grep '[a]cestream' | awk '{print $2}')") + os.system("kill $(ps aux | grep '[s]tart.py' | awk '{print $2}')") + if settings.getSetting('save') != "true": + try: + cache_file = xbmc.Player().getPlayingFile().split('/')[-2] + if 'arm' not in os.uname()[4]: + if settings.getSetting('acestream_cachefolder') == '': acestream_cachefolder_file = os.path.join(os.getenv("HOME"),'.ACEStream','cache','.acestream_cache') + else: acestream_cachefolder_file = settings.getSetting('acestream_cachefolder') + else: + if settings.getSetting('acestream_cachefolder') == '': acestream_cachefolder_file = os.path.join(os.getenv("HOME"),'.ACEStream','cache') + else: acestream_cachefolder_file = settings.getSetting('acestream_cachefolder') + folder,cachefiles = xbmcvfs.listdir(acestream_cachefolder_file) + for cachefile in cachefiles: + if cache_file in cachefile: + xbmcvfs.delete(os.path.join(acestream_cachefolder_file,cachefile)) + except: pass + + elif xbmc.getCondVisibility('system.platform.OSX'): + try: + kill_cmd = [os.path.join('/Applications','Ace Stream.app','Contents','Resources','Wine.bundle','Contents','Resources','bin','wine'),os.path.join('/Applications','Ace Stream.app','Contents','Resources','wineprefix','drive_c','windows','system','taskkill.exe'),'/f','/im','ace_engine.exe'] + kill_proc = subprocess.Popen(kill_cmd,shell=False) + except: pass + + elif xbmc.getCondVisibility('System.Platform.Android'): + try: + procshut_ace = subprocess.Popen(['ps','|','grep','python'],shell=False,stdout=subprocess.PIPE) + for line in procshut_ace.stdout: + match = re.findall(r'\S+', line.rstrip()) + if match: + if 'acestream' in match[-1] and len(match)>2: + os.system("kill " + match[1]) + xbmc.sleep(200) + except: pass + if settings.getSetting('save') != "true": + try: + if settings.getSetting('acestream_cachefolder') != '': + dirs, cache_files = xbmcvfs.listdir(os.path.join(settings.getSetting('acestream_cachefolder'),'.acestream_cache')) + print dirs,cache_files + for cache_file in cache_files: + xbmcvfs.delete(os.path.join(settings.getSetting('acestream_cachefolder'),'.acestream_cache',cache_file)) + else: + acestream_cachefolder_file = os.path.join('/sdcard','.ACEStream','cache','.acestream_cache') + dirs, cache_files = xbmcvfs.listdir(acestream_cachefolder_file) + for cache_file in cache_files: + xbmcvfs.delete(os.path.join(acestream_cachefolder_file,cache_file)) + except: pass + xbmc.executebuiltin('PlayerControl(Stop)') + + + + +class OverlayText(object): + def __init__(self): + self.showing = False + self.window = xbmcgui.Window(12005) + viewport_w, viewport_h = self._get_skin_resolution() + font_max = 'font13' + font_min = 'font10' + origin_x = int(float(viewport_w)/1.3913) + origin_y = int(float(viewport_h)/8.0) + window_w = int(float(viewport_w)/3.7647) + window_h = int(float(viewport_h)/2.5714) + acelogo_w = int(float(window_w)/8.5) + acelogo_h = int(float(window_w)/11.0) + text_lat = int(float(window_w)/15) + text_w = int(float(window_w)/1.7) + text_h = int(float(window_h)/14) + fst_setting = int(float(window_h)/3.5) + fst_stat_setting = int(float(window_h)/1.4) + + #main window + self._background = xbmcgui.ControlImage(origin_x, origin_y, window_w, window_h, os.path.join(addonpath,"resources","art","lateral-fundo.png")) + self._acestreamlogo = xbmcgui.ControlImage(origin_x + int(float(window_w)/11.3), origin_y + int(float(window_h)/14), acelogo_w, acelogo_h, os.path.join(addonpath,"resources","art","acestreamlogo.png")) + self._supseparator = xbmcgui.ControlImage(origin_x, origin_y + int(float(viewport_h)/12.176), window_w-10, 1, os.path.join(addonpath,"resources","art","lateral-separador.png")) + self._botseparator = xbmcgui.ControlImage(origin_x, origin_y + window_h - 30, window_w-10, 1, os.path.join(addonpath,"resources","art","lateral-separador.png")) + self._title = xbmcgui.ControlLabel(origin_x+int(float(window_w)/3.4), origin_y + text_h, window_w - 140, text_h, str(translate(50000)), font=font_max, textColor='0xFFEB9E17') + self._total_stats_label = xbmcgui.ControlLabel(origin_x+int(float(window_h)/1.72), origin_y + int(float(window_h)/1.6), int(float(window_w)/1.7), 20, str(translate(50005)), font=font_min, textColor='0xFFEB9E17') + #labels + self._action = xbmcgui.ControlLabel(origin_x + text_lat, origin_y + fst_setting, int(float(text_w)*1.6), text_h, str(translate(50001)) + ' N/A', font=font_min) + self._download = xbmcgui.ControlLabel(origin_x + text_lat, origin_y + fst_setting + text_h, int(float(text_w)*1.6), text_h, str(translate(50002)) + ' N/A', font=font_min) + self._upload = xbmcgui.ControlLabel(origin_x + text_lat, origin_y + fst_setting + 2*text_h, text_w, text_h, str(translate(50003)) + ' N/A', font=font_min) + self._seeds = xbmcgui.ControlLabel(origin_x + text_lat, origin_y + fst_setting + 3*text_h, text_w, text_h, str(translate(50004)) + ' N/A', font=font_min) + self._total_download = xbmcgui.ControlLabel(origin_x + text_lat, origin_y + fst_stat_setting, text_w, text_h, str(translate(50006)) + ' N/A', font=font_min) + self._total_upload = xbmcgui.ControlLabel(origin_x + text_lat, origin_y + fst_stat_setting + text_h, text_w, text_h, str(translate(50007)) + ' N/A', font=font_min) + self._percent_value = xbmcgui.ControlLabel(origin_x+int(float(window_h)/1.05), origin_y + fst_setting, text_w, text_h,'N/A', font=font_min) + + def show(self): + self.showing=True + self.window.addControl(self._background) + self.window.addControl(self._acestreamlogo) + self.window.addControl(self._supseparator) + self.window.addControl(self._botseparator) + self.window.addControl(self._title) + self.window.addControl(self._action) + self.window.addControl(self._download) + self.window.addControl(self._upload) + self.window.addControl(self._seeds) + self.window.addControl(self._total_stats_label) + self.window.addControl(self._total_download) + self.window.addControl(self._total_upload) + self.window.addControl(self._percent_value) + + + def hide(self): + self.showing=False + self.window.removeControl(self._total_download) + self.window.removeControl(self._total_upload) + self.window.removeControl(self._percent_value) + self.window.removeControl(self._title) + self.window.removeControl(self._action) + self.window.removeControl(self._download) + self.window.removeControl(self._upload) + self.window.removeControl(self._seeds) + self.window.removeControl(self._total_stats_label) + self.window.removeControl(self._acestreamlogo) + self.window.removeControl(self._supseparator) + self.window.removeControl(self._botseparator) + self.window.removeControl(self._background) + + def set_information(self,engine_data): + if self.showing == True: + self._action.setLabel(str(translate(50001)) + ' ' + engine_data["action"]) + self._percent_value.setLabel(engine_data["percent"]) + self._download.setLabel(str(translate(50002))+ ' ' + engine_data["download"]) + self._upload.setLabel(str(translate(50003)) + ' ' + engine_data["upload"]) + self._seeds.setLabel(str(translate(50004)) + ' ' + engine_data["seeds"]) + self._total_download.setLabel(str(translate(50006)) + ' ' + engine_data["total_download"]) + self._total_upload.setLabel(str(translate(50007)) + ' ' + engine_data["total_upload"]) + else: pass + + def _close(self): + if self.showing: + self.hide() + else: + pass + try: + self.window.clearProperties() + print("OverlayText window closed") + except: pass + + #Taken from xbmctorrent + def _get_skin_resolution(self): + import xml.etree.ElementTree as ET + skin_path = xbmc.translatePath("special://skin/") + tree = ET.parse(os.path.join(skin_path, "addon.xml")) + try: res = tree.findall("./res")[0] + except: res = tree.findall("./extension/res")[0] + return int(res.attrib["width"]), int(res.attrib["height"]) + + diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/acecore.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/acecore.pyo new file mode 100644 index 0000000000000000000000000000000000000000..981e4a98dab7d37330a9a0a8b1089b10a623b923 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/acecore.pyo differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/acestream.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/acestream.py new file mode 100644 index 0000000000000000000000000000000000000000..5e7a0c63f49f88664ed21978f4a1cd895c188768 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/acestream.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- + +""" p2p-streams (c) 2014 enen92 fightnight + + This file contains the function that brigdes the addon to the acecore.py file + + Functions: + + load_local_torrent() -> Load a local .torrent file + acestreams(name,iconimage,chid) -> Function that interprets the received url (acestream://,*.acelive,ts://) and sends it to acestreams_builtin + acestreams_builtin(name,iconimage,chid -> Bridge to acecore.py file + + +""" + +import xbmc,xbmcgui,xbmcplugin,urllib,xbmcvfs,os,subprocess +from peertopeerutils.pluginxbmc import * +from history import * + +aceport=62062 + +def load_local_torrent(): + torrent_file = xbmcgui.Dialog().browse(int(1), translate(600028), 'myprograms','.torrent') + if torrent_file: + if xbmc.getCondVisibility('system.platform.windows'): + acestreams("Local .torrent ("+str("file:\\" + torrent_file) +")","",'file:\\' + torrent_file) + else: + acestreams("Local .torrent ("+str("file://" + torrent_file) +")","",'file://' + torrent_file) + else: pass + +def acestreams(name,iconimage,chid): + if not iconimage: iconimage=os.path.join(addonpath,'resources','art','acelogofull.jpg') + else: iconimage = urllib.unquote(iconimage) + if settings.getSetting('addon_history') == "true": + try: add_to_history(name, str(chid),1, iconimage) + except: pass + if settings.getSetting('engine_app') != '2' and settings.getSetting('engine_app') != '3': + if settings.getSetting('aceplay_type') == "2": + pDialog = xbmcgui.DialogProgress() + ret = pDialog.create(translate(40000), translate(40154),translate(40155),translate(40156)) + pDialog.update(0) + xbmc.sleep(3000) + pDialog.update(100) + pDialog.close() + ip_adress = settings.getSetting('ip_addr') + proxy_port = settings.getSetting('aceporta') + chid=chid.replace('acestream://','').replace('ts://','') + strm = "http://" + ip_adress + ":" + proxy_port + "/pid/" + chid + "/stream.mp4" + listitem = xbmcgui.ListItem(name, iconImage="DefaultVideo.png", thumbnailImage=iconimage) + listitem.setLabel(name + " (" + chid + ")") + listitem.setInfo('video', {'Title': name + " (" + chid + ")"}) + xbmc.Player().play(strm,listitem) + else: acestreams_builtin(name,iconimage,chid) + else: + if '.acelive' in chid: pass + elif '.torrent' in chid: pass + else: + if 'acestream://' in chid: pass + else: chid = 'acestream://' + chid + if settings.getSetting('engine_app') == '2': + xbmc.executebuiltin('XBMC.StartAndroidActivity("org.acestream","android.intent.action.VIEW","","'+chid+'")') + elif settings.getSetting('engine_app') == '3': + xbmc.executebuiltin('XBMC.StartAndroidActivity("ru.vidsoftware.acestreamcontroller.free","android.intent.action.VIEW","","'+chid+'")') + +def acestreams_builtin(name,iconimage,chid): + if xbmc.getCondVisibility('system.platform.windows'): + try: + import _winreg + t = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, 'Software\AceStream') + needed_value = _winreg.QueryValueEx(t , 'EnginePath')[0] + print needed_value.replace('\\','\\\\') + subprocess.Popen("wmic process where ExecutablePath='"+needed_value.replace('\\','\\\\')+"' delete",shell=True) + xbmc.sleep(200) + subprocess.Popen('taskkill /F /IM ace_player.exe /T',shell=True) + xbmc.sleep(200) + except: pass + elif xbmc.getCondVisibility('System.Platform.OSX'): + if settings.getSetting('shutdown-engine') == "true": + os.system("kill $(ps aux | grep '[s]tart.py')") + try:from acecore import TSengine as tsengine + except: + mensagemok(translate(40000),translate(40037)) + return + xbmc.executebuiltin('Action(Stop)') + lock_file = xbmc.translatePath('special://temp/'+ 'ts.lock') + if xbmcvfs.exists(lock_file): + xbmcvfs.delete(lock_file) + if chid != '': + chid=chid.replace('acestream://','').replace('ts://','').replace('st://','') + print("Starting Player Ace hash: " + chid) + TSPlayer = tsengine() + out = None + if chid.find('http://') == -1 and chid.find('.torrent') == -1: + out = TSPlayer.load_torrent(chid,'PID',port=aceport) + elif chid.find('http://') == -1 and chid.find('.torrent') != -1: + out = TSPlayer.load_torrent(chid,'TORRENT',port=aceport) + else: + out = TSPlayer.load_torrent(chid,'TORRENT',port=aceport) + if out == 'Ok': + TSPlayer.play_url_ind(0,name + ' (' + chid + ')',iconimage,iconimage) + TSPlayer.end() + return + else: + mensagemok(translate(40000),translate(40038)) + TSPlayer.end() + return + else: + mensagemprogresso.close() diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/acestream.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/acestream.pyo new file mode 100644 index 0000000000000000000000000000000000000000..8c17f6eef0db2b5876e1ad682d05c17c04d2642a Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/acestream.pyo differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/advancedfunctions.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/advancedfunctions.py new file mode 100644 index 0000000000000000000000000000000000000000..e91eb5a2ff90faee0e94b37109025c8aecbe7264 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/advancedfunctions.py @@ -0,0 +1,431 @@ +# -*- coding: utf-8 -*- + +""" p2p-streams (c) 2014 enen92 fightnight + + This file contains all the function the addon uses in the section "Advanced tools". + + Functions: + + Advancedsettings.xml related functions are below. Advancedsettings.xml are not automatically imported since they are advanced configurations the user should have control of. + + advanced_menu() -> Main menu + import_advancedxml() -> Import recommended advancedsettings.xml + backup_advancedxml() -> When importing an advancedsettings.xml file, if a previous file exists on the same directory the addon will automatically make a backup of the file renaming it to advancedsettingsbackup.xml. This is what this function does + recoverbackup_advancedxml() -> Recover an advancedsettings.xml file resulting from a previous backup + delete_advancedxml() -> Delete the advancedsettings.xml file + + Acestream related functions: + set_engine_setting(file) -> Set an acestreamengine setting to a given value. This is used in macosx and linux arm since the acestreamengine is not officially provided by acestream.org and the user doesn't have any other way to change them. + remove_lock() -> function to remove .lock files created during the acestream loop. + set_acestream_engine_cache_folder(url) -> Change acestreamengine cache folder + set_linux_engine_setting(url) -> change acestreamengine settings from gui for linux/android + clear_cache(url) -> Clear the contents of the acestream cache folder + shutdown_hooks() -> Function to set a costum shutdown hook to the used skin and costum stop shortcuts + set_android_port() -> Import sessionconfig.pickle for android + set_android_cache_aloc() -> Set android cache allocation for the internal engine + + +""" + +import xbmc,xbmcgui,xbmcplugin,xbmcvfs,sys,os,re +from peertopeerutils.pluginxbmc import * +from peertopeerutils.directoryhandle import addLink,addDir +from peertopeerutils.iofile import * +from peertopeerutils.webutils import download_tools +from peertopeerutils.utilities import getDirectorySize + + +def advanced_menu(): + addLink('[COLOR orange]XBMC Advancedsettings.xml:[/COLOR]','',addonpath + art + 'settings_menu.png') + lock_file = xbmc.translatePath('special://temp/'+ 'ts.lock') + if xbmcvfs.exists(lock_file): + addDir(translate(40068),MainURL,306,'',2,False) + userdatapath = xbmc.translatePath(os.path.join('special://home/userdata'.decode('utf-8'),''.decode('utf-8'))) + advancedsettings_var = os.path.join(userdatapath,'advancedsettings.xml') + advancedsettingsbackup_var = os.path.join(userdatapath,'advancedsettingsbackup.xml') + addDir(translate(40058),MainURL,301,'p2p',2,False) + if xbmcvfs.exists(advancedsettings_var): + addDir(translate(40063),MainURL,303,'p2p',2,False) + addDir(translate(40065),MainURL,304,'p2p',2,False) + if xbmcvfs.exists(advancedsettingsbackup_var): + addDir(translate(40061),MainURL,302,'p2p',2,False) + addLink('','','p2p') + if xbmcvfs.exists(advancedsettings_var): + content = readfile(advancedsettings_var) + match = re.compile('(.+?)').findall(content) + if match: + if match[0] != '252420': valuebuff = '[COLOR red]' + match[0] + '[/COLOR]' + else : valuebuff = '[COLOR green]' + match[0] + '[/COLOR]' + addLink(translate(40067) +valuebuff+']','','p2p') + addLink('','','p2p') + #Apply shutdown hooks + addLink('[COLOR orange]'+translate(70025)+'[/COLOR]','',addonpath + art + 'settings_menu.png') + addDir(translate(70026),MainURL,310,'p2p',2,False) + #Change engine settings from xbmc menus + eligible = False + if xbmc.getCondVisibility('system.platform.linux') and settings.getSetting('force_android') != "true": + if os.uname()[4] == "armv6l" or os.uname()[4] == "armv7l": + eligible = True + elif xbmc.getCondVisibility('system.platform.OSX'): eligible = False + elif settings.getSetting('openeleci386') == "true": eligible = False + elif settings.getSetting('force_android') == "true": eligible = False + else: eligible = False + if eligible and os.path.exists(os.path.join(pastaperfil,'acestream','ace','ACEStream','values')): + addLink('[COLOR orange]Acestream engine settings:[/COLOR]','',addonpath + art + 'settings_menu.png') + acestream_cachefolder = os.path.join(os.getenv("HOME"),'.ACEStream','cache') + acestream_cache_size = str(int(getDirectorySize(acestream_cachefolder))/(1024*1024)) + addDir(translate(70003) + '[COLOR orange] [' + acestream_cache_size + ' MB][/COLOR]',acestream_cachefolder,307,'p2p',1,False) + try: + porta = readfile(os.path.join(pastaperfil,"acestream","ace","ACEStream","values","port.txt")) + except: porta = "N/A" + try: + acestream_settings_file = os.path.join(os.getenv("HOME"),'.ACEStream','sessconfig.pickle') + sessconfig = readfile(acestream_settings_file) + portvector = re.compile("S'minport'\np(\d+)\nI(\d+)\n").findall(sessconfig) + maxport = re.compile("S'maxport'\np(\d+)\nI(\d+)\n").findall(sessconfig) + except: portvector = [];maxport=[] + addDir(translate(600015) +"[COLOR orange][ " + str(int(porta))+ " ][/COLOR]",os.path.join(pastaperfil,"acestream","ace","ACEStream","values","port.txt") + '|' + str(portvector)+'|'+str(maxport),305,'p2p',2,False) + try: + vodbuffer = readfile(os.path.join(pastaperfil,"acestream","ace","ACEStream","values","vodbuffer.txt")) + except: vodbuffer = "N/A" + addDir(translate(600016) + "[COLOR orange][ " + str(int(vodbuffer))+ " ][/COLOR]",os.path.join(pastaperfil,"acestream","ace","ACEStream","values","vodbuffer.txt"),305,'p2p',2,False) + try: + livebuffer = readfile(os.path.join(pastaperfil,"acestream","ace","ACEStream","values","livebuffer.txt")) + except: livebuffer = "N/A" + addDir(translate(600017)+"[COLOR orange][ " + str(int(livebuffer))+ " ][/COLOR]",os.path.join(pastaperfil,"acestream","ace","ACEStream","values","livebuffer.txt"),305,'p2p',2,False) + try: + downloadlimit = readfile(os.path.join(pastaperfil,"acestream","ace","ACEStream","values","downloadlimit.txt")) + except: downloadlimit = "N/A" + addDir(translate(600018) +"[COLOR orange][ " + str(int(downloadlimit))+ " ][/COLOR]",os.path.join(pastaperfil,"acestream","ace","ACEStream","values","downloadlimit.txt"),305,'p2p',2,False) + try: + uploadlimit = readfile(os.path.join(pastaperfil,"acestream","ace","ACEStream","values","uploadlimit.txt")) + except: uploadlimit = "N/A" + addDir(translate(600019)+"[COLOR orange][ " + str(int(uploadlimit))+ " ][/COLOR]",os.path.join(pastaperfil,"acestream","ace","ACEStream","values","uploadlimit.txt"),305,'p2p',2,False) + try: + maxconnections = readfile(os.path.join(pastaperfil,"acestream","ace","ACEStream","values","maxconnections.txt")) + except: maxconnections = "N/A" + addDir(translate(600020)+"[COLOR orange][ " + str(int(maxconnections))+ " ][/COLOR]",os.path.join(pastaperfil,"acestream","ace","ACEStream","values","maxconnections.txt"),305,'p2p',2,False) + try: + maxconnectionsstream = readfile(os.path.join(pastaperfil,"acestream","ace","ACEStream","values","maxconnectionsstream.txt")) + except: maxconnectionsstream = "N/A" + addDir(translate(600021)+"[COLOR orange][ " + str(int(maxconnectionsstream))+ " ][/COLOR]",os.path.join(pastaperfil,"acestream","ace","ACEStream","values","maxconnectionsstream.txt"),305,'',2,False) + elif eligible and not os.path.exists(os.path.join(pastaperfil,'acestream','ace','ACEStream','values')): + addLink("[COLOR red][B]"+translate(600027)+"[/COLOR][/B]","",addonpath + art + 'processwarning.png') + else: + pass + if (not eligible and xbmc.getCondVisibility('system.platform.linux') and settings.getSetting('ace_cmd') == "0") or (not eligible and xbmc.getCondVisibility('system.platform.windows')) or (not eligible and xbmc.getCondVisibility('system.platform.Android') and settings.getSetting('engine_app') == "0") or (settings.getSetting('force_android') == "true" and settings.getSetting('engine_app') == "0"): + if xbmc.getCondVisibility('system.platform.linux') and not xbmc.getCondVisibility('system.platform.Android'): + default_acefolder = os.path.join(os.getenv("HOME"),'.ACEStream') + default_cachefolder = os.path.join(os.getenv("HOME"),'.ACEStream','cache','.acestream_cache') + pickle_repo = 'http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/playerconf.pickle' + if settings.getSetting('acestream_cachefolder') == '': acestream_cachefolder = os.path.join(os.getenv("HOME"),'.ACEStream','cache','.acestream_cache') + else: acestream_cachefolder = settings.getSetting('acestream_cachefolder') + acestream_settings_file = os.path.join(os.getenv("HOME"),'.ACEStream','playerconf.pickle') + elif xbmc.getCondVisibility('system.platform.Android'): + default_acefolder = os.path.join('/sdcard','.ACEStream') + default_cachefolder = os.path.join('/sdcard','.ACEStream','.acestream_cache') + pickle_repo = 'http://p2p-strm.googlecode.com/svn/trunk/Modules/Android/playerconf.pickle' + if settings.getSetting('acestream_cachefolder') == '': acestream_cachefolder = os.path.join('/sdcard','.ACEStream','.acestream_cache') + else: + acestream_cachefolder = os.path.join(settings.getSetting('acestream_cachefolder'),'.acestream_cache') + if not os.path.exists(acestream_cachefolder):xbmcvfs.mkdir(acestream_cachefolder) + acestream_settings_file = os.path.join('/sdcard','.ACEStream','playerconf.pickle') + elif xbmc.getCondVisibility('system.platform.windows'): + default_acefolder = os.path.join(os.getenv("APPDATA"),".ACEStream") + pickle_repo = 'http://p2p-strm.googlecode.com/svn/trunk/Modules/Windows/playerconf.pickle' + default_cachefolder = os.path.join(os.getenv("SystemDrive"),'\_acestream_cache_') + acestream_cachefolder = default_cachefolder + acestream_settings_file = os.path.join(os.getenv("APPDATA"),".ACEStream","playerconf.pickle") + #workaround to keep settings file in place if they get deleted + if not os.path.exists(default_acefolder): xbmcvfs.mkdir(default_acefolder) + if not os.path.exists(default_cachefolder): xbmcvfs.mkdir(default_cachefolder) + if not os.path.exists(acestream_settings_file): + local_file = os.path.join(default_acefolder,pickle_repo.split("/")[-1]) + download_tools().Downloader(pickle_repo,local_file,'',translate(40000)) + xbmc.sleep(200) + if xbmcvfs.exists(acestream_settings_file): + settings_text = readfile(acestream_settings_file) + save(acestream_settings_file,settings_text.replace('my_cache_folder',default_cachefolder)) + if xbmcvfs.exists(acestream_settings_file) and os.path.exists(acestream_cachefolder): + addLink('[COLOR orange]Acestream engine settings:[/COLOR]','',addonpath + art + 'settings_menu.png') + xbmc.sleep(200) + #Change default port for Android + if xbmc.getCondVisibility('system.platform.Android'): + android_port = settings.getSetting('android_port') + addDir(translate(600015) +"[COLOR orange] [ " + android_port + " ][/COLOR]",'p2p',311,'p2p',2,False) + # + acestream_cache_size = str(int(getDirectorySize(acestream_cachefolder))/(1024*1024)) + addDir(translate(70003) + '[COLOR orange] [' + acestream_cache_size + ' MB][/COLOR]',acestream_cachefolder,307,'p2p',1,False) + settings_content = readfile(acestream_settings_file) + number_of_settings = re.compile('p(\d+)\n').findall(settings_content) + cachefoldersetting = re.compile("'download_dir'\np\d+\n.+?/(.+?)\n").findall(settings_content) + if not cachefoldersetting: + if xbmc.getCondVisibility('system.platform.linux') and not xbmc.getCondVisibility('system.platform.Android'): + if not 'arm' in os.uname()[4]: + cachefoldersetting = os.path.join(os.getenv("HOME"),'.ACEStream','cache','.acestream_cache') + settings.setSetting('acestream_cachefolder',cachefoldersetting) + else: + cachefoldersetting = os.path.join('/sdcard','.ACEStream','cache') + settings.setSetting('acestream_cachefolder',cachefoldersetting) + elif xbmc.getCondVisibility('system.platform.windows'): + cachefoldersetting = os.path.join(os.getenv("SystemDrive"),'_acestream_cache_') + settings.setSetting('acestream_cachefolder',cachefoldersetting) + else: + cachefoldersetting = os.path.join('/sdcard','.ACEStream','cache') + settings.setSetting('acestream_cachefolder',cachefoldersetting) + else: + if xbmc.getCondVisibility('system.platform.linux') and not xbmc.getCondVisibility('system.platform.Android'): + if not 'arm' in os.uname()[4]: + cachefoldersetting = os.path.join('/',cachefoldersetting[0].replace("'",""),'.acestream_cache') + settings.setSetting('acestream_cachefolder',cachefoldersetting) + else: + cachefoldersetting = cachefoldersetting[0] + if cachefoldersetting: addDir(translate(70013)+"[COLOR orange][ " + cachefoldersetting + " ][/COLOR]",str(cachefoldersetting),309,'p2p',2,False) + else: addDir(translate(70013)+"[COLOR orange][" + cachefoldersetting + "][/COLOR]",cachefoldersetting,309,'p2p',2,False) + buffer_type = re.compile("S'live_cache_type'\np(\d+)\nS(.*)").findall(settings_content) + if xbmc.getCondVisibility('system.platform.Android'): + if buffer_type: + if 'memory' in buffer_type[0][1]: addDir(translate(70041)+"[COLOR orange] [ Memory ][/COLOR]",'p2p',312,'p2p',2,False) + elif 'disk' in buffer_type[0][1]: addDir(translate(70041)+"[COLOR orange] [ Disk ][/COLOR]",'p2p',312,'p2p',2,False) + else: pass + livebuffervalue = re.compile("S'live_buffer_time'\np(\d+)\nI(\d+)").findall(settings_content) + if livebuffervalue: addDir(translate(600017)+"[COLOR orange][ " + livebuffervalue[0][1] + " ][/COLOR]",'live_buffer_time|' + str(livebuffervalue)+'|'+str(len(number_of_settings)),308,'p2p',2,False) + else: addDir(translate(600017)+"[COLOR orange][3][/COLOR]",'live_buffer_time|'+str(len(number_of_settings)),308,'p2p',2,False) + vodbuffervalue = re.compile("S'player_buffer_time'\np(\d+)\nI(\d+)").findall(settings_content) + if vodbuffervalue: addDir(translate(600016)+"[COLOR orange][ " + vodbuffervalue[0][1] + " ][/COLOR]",'player_buffer_time|'+str(vodbuffervalue)+'|'+str(len(number_of_settings)),308,'p2p',2,False) + else: addDir(translate(600016)+"[COLOR orange][10][/COLOR]",'player_buffer_time|'+str(len(number_of_settings)),308,'p2p',2,False) + downloadlimit = re.compile("S'total_max_download_rate'\np(\d+)\nI(\d+)").findall(settings_content) + if downloadlimit: addDir(translate(600018)+"[COLOR orange][ " + downloadlimit[0][1] + " ][/COLOR]",'total_max_download_rate|'+str(downloadlimit)+'|'+str(len(number_of_settings)),308,'p2p',2,False) + else: addDir(translate(600018)+"[COLOR orange][0][/COLOR]",'total_max_download_rate|'+str(len(number_of_settings)),308,'p2p',2,False) + uploadlimit = re.compile("S'total_max_upload_rate'\np(\d+)\nI(\d+)").findall(settings_content) + if uploadlimit: addDir(translate(600019)+"[COLOR orange][ " + uploadlimit[0][1] + " ][/COLOR]",'total_max_upload_rate|'+str(uploadlimit)+'|'+str(len(number_of_settings)),308,'p2p',2,False) + else: addDir(translate(600019)+"[COLOR orange][0][/COLOR]",'total_max_upload_rate|'+str(len(number_of_settings)),308,'p2p',2,False) + maxconnection_per_stream = re.compile("S'max_peers'\np(\d+)\nI(\d+)").findall(settings_content) + if maxconnection_per_stream: addDir(translate(600021)+"[COLOR orange][ " + maxconnection_per_stream[0][1] + " ][/COLOR]",'max_peers|'+str(maxconnection_per_stream)+'|'+str(len(number_of_settings)),308,'p2p',2,False) + else: addDir(translate(600021)+"[COLOR orange][50][/COLOR]",'max_peers|'+str(len(number_of_settings)),308,'p2p',2,False) + + + +""" + +AdvancedSettings.xml Related functions + +""" + +def import_advancedxml(): + userdatapath = xbmc.translatePath(os.path.join('special://home/userdata'.decode('utf-8'),''.decode('utf-8'))) + advancedsettings_var = os.path.join(userdatapath,'advancedsettings.xml') + advancedsettingsbackup_var = os.path.join(userdatapath,'advancedsettingsbackup.xml') + if xbmcvfs.exists(advancedsettings_var): + print("An advanced settings XML file already exists") + if xbmcvfs.exists(advancedsettingsbackup_var): + print("An advanced settings backup already exists") + xbmcvfs.delete(advancedsettingsbackup_var) + xbmcvfs.rename(advancedsettings_var,advancedsettingsbackup_var) + advancedname = ["Cachemembuffer=252420","freememorycachepercent=5"] + advancedurl = ["http://p2p-strm.googlecode.com/svn/trunk/Advancedsettings/advancedsettings.xml","http://p2p-strm.googlecode.com/svn/trunk/Advancedsettings/advancedsettingstonicillo.xml"] + index = xbmcgui.Dialog().select(translate(40185), advancedname) + if index > -1: + download_tools().Downloader(advancedurl[index],advancedsettings_var,translate(40059),translate(40000)) + mensagemok(translate(40000),translate(40060)) + else: + xbmcvfs.rename(advancedsettings_var,advancedsettingsbackup_var) + advancedname = ["Cachemembuffer=252420","freememorycachepercent=5"] + advancedurl = ["http://p2p-strm.googlecode.com/svn/trunk/Advancedsettings/advancedsettings.xml","http://p2p-strm.googlecode.com/svn/trunk/Advancedsettings/advancedsettingstonicillo.xml"] + index = xbmcgui.Dialog().select(translate(40185), advancedname) + if index > -1: + download_tools().Downloader(advancedurl[index],advancedsettings_var,translate(40059),translate(40000)) + mensagemok(translate(40000),translate(40060)) + else: + print("No advancedsettings.xml in the system yet") + advancedname = ["Cachemembuffer=252420","freememorycachepercent=5"] + advancedurl = ["http://p2p-strm.googlecode.com/svn/trunk/Advancedsettings/advancedsettings.xml","http://p2p-strm.googlecode.com/svn/trunk/Advancedsettings/advancedsettingstonicillo.xml"] + index = xbmcgui.Dialog().select(translate(40185), advancedname) + if index > -1: + download_tools().Downloader(advancedurl[index],advancedsettings_var,translate(40059),translate(40000)) + mensagemok(translate(40000),translate(40060)) + xbmc.executebuiltin("Container.Refresh") + + +def backup_advancedxml(): + userdatapath = xbmc.translatePath(os.path.join('special://home/userdata'.decode('utf-8'),''.decode('utf-8'))) + advancedsettings_var = os.path.join(userdatapath,'advancedsettings.xml') + advancedsettingsbackup_var = os.path.join(userdatapath,'advancedsettingsbackup.xml') + if xbmcvfs.exists(advancedsettingsbackup_var): + xbmcvfs.delete(advancedsettingsbackup_var) + xbmcvfs.copy(advancedsettings_var,advancedsettingsbackup_var) + mensagemok(translate(40000),translate(40064)) + xbmc.executebuiltin("Container.Refresh") + + +def recoverbackup_advancedxml(): + userdatapath = xbmc.translatePath(os.path.join('special://home/userdata'.decode('utf-8'),''.decode('utf-8'))) + advancedsettings_var = os.path.join(userdatapath,'advancedsettings.xml') + advancedsettingsbackup_var = os.path.join(userdatapath,'advancedsettingsbackup.xml') + xbmcvfs.delete(advancedsettings_var) + xbmcvfs.rename(advancedsettingsbackup_var,advancedsettings_var) + mensagemok(translate(40000),translate(40062)) + xbmc.executebuiltin("Container.Refresh") + +def delete_advancedxml(): + userdatapath = xbmc.translatePath(os.path.join('special://home/userdata'.decode('utf-8'),''.decode('utf-8'))) + advancedsettings_var = os.path.join(userdatapath,'advancedsettings.xml') + advancedsettingsbackup_var = os.path.join(userdatapath,'advancedsettingsbackup.xml') + xbmcvfs.delete(advancedsettings_var) + mensagemok(translate(40000),translate(40066)) + xbmc.executebuiltin("Container.Refresh") + + + +""" + +Acestream/Sopcast Engine Related functions + +""" + +def set_engine_setting(file): + if 'port.txt' in file: + ficheiro = file.split('|')[0] + else: ficheiro = file + acestream_settings_file = os.path.join(os.getenv("HOME"),'.ACEStream','sessconfig.pickle') + value = readfile(ficheiro) + keyb = xbmc.Keyboard(str(int(value)), translate(600024)) + keyb.doModal() + if (keyb.isConfirmed()): + search = keyb.getText() + try: + int(search) + integer = True + except: integer = False + if integer == True: + save(ficheiro, search) + if 'port.txt' in file: + try: + text = readfile(acestream_settings_file) + minport = eval(file.split('|')[1]) + maxport = eval(file.split('|')[2]) + text = text.replace("S'minport'\np" + minport[0][0] +"\nI" + minport[0][1] +"\n","S'minport'\np" + minport[0][0] +"\nI" + search +"\n").replace("S'maxport'\np" + maxport[0][0] +"\nI" + maxport[0][1] +"\n","S'maxport'\np" + maxport[0][0] +"\nI" + search +"\n") + save(acestream_settings_file,text) + except: pass + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(600026), 1,os.path.join(addonpath,"icon.png"))) + xbmc.executebuiltin("Container.Refresh") + else: + mensagemok(translate(40000),translate(600025)) + sys.exit(0) + +def remove_lock(): + lock_file = xbmc.translatePath('special://temp/'+ 'ts.lock') + xbmcvfs.delete(lock_file) + mensagemok(translate(40000),translate(40069)) + xbmc.executebuiltin("Container.Refresh") + +def clear_cache(url): + dirs, files = xbmcvfs.listdir(url) + for fich in files: + xbmcvfs.delete(os.path.join(url,fich)) + if files: xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(40161), 1,addonpath+"/icon.png")) + xbmc.executebuiltin("Container.Refresh") + +def set_linux_engine_setting(url): + if xbmc.getCondVisibility('system.platform.linux') and not xbmc.getCondVisibility('system.platform.Android'): + acestream_settings_file = os.path.join(os.getenv("HOME"),'.ACEStream','playerconf.pickle') + elif xbmc.getCondVisibility('system.platform.Android'): + acestream_settings_file = os.path.join('/sdcard','.ACEStream','playerconf.pickle') + elif xbmc.getCondVisibility('system.platform.windows'): + acestream_settings_file = os.path.join(os.getenv("APPDATA"),".ACEStream","playerconf.pickle") + settings_content = readfile(acestream_settings_file) + keyb = xbmc.Keyboard('',translate(600024)) + keyb.doModal() + if (keyb.isConfirmed()): + search = keyb.getText() + try: + int(search) + integer = True + except: integer = False + if integer == True: + if len(url.split('|')) == 3: + settings_content = settings_content.replace('p'+str(eval(url.split('|')[1])[0][0])+'\nI'+str(eval(url.split('|')[1])[0][1]),'p'+str(eval(url.split('|')[1])[0][0])+'\nI'+search) + save(acestream_settings_file, settings_content) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(600026), 1,addonpath+"/icon.png")) + xbmc.executebuiltin("Container.Refresh") + else: + settings_content = settings_content.replace('s.',"sS'"+url.split('|')[0]+"'\np"+url.split('|')[1]+"\nI"+search+"\ns.") + save(acestream_settings_file, settings_content) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(600026), 1,addonpath+"/icon.png")) + xbmc.executebuiltin("Container.Refresh") + if 'total_max_download_rate' in url: settings.setSetting('total_max_download_rate',value=search) + if 'total_max_upload_rate' in url: settings.setSetting('total_max_upload_rate',value=search) + else: + mensagemok(translate(40000),translate(600025)) + sys.exit(0) + +def set_android_port(): + ports = ['8621','8622','8623'] + ports_pickle = ['http://p2p-strm.googlecode.com/svn/trunk/Modules/Android/sessconf/8621/sessconfig.pickle','http://p2p-strm.googlecode.com/svn/trunk/Modules/Android/sessconf/8622/sessconfig.pickle','http://p2p-strm.googlecode.com/svn/trunk/Modules/Android/sessconf/8623/sessconfig.pickle'] + choose=xbmcgui.Dialog().select(translate(600015),ports) + if choose > -1: + escolha = ports_pickle[choose] + session_pickle_android = os.path.join('/sdcard','.ACEStream','sessconfig.pickle') + download_tools().Downloader(escolha,session_pickle_android,'',translate(40000)) + settings.setSetting('android_port',ports[choose]) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(600026), 1,addonpath+"/icon.png")) + xbmc.executebuiltin("Container.Refresh") + +def set_android_cache_aloc(): + acestream_settings_file = os.path.join('/sdcard','.ACEStream','playerconf.pickle') + settings_content = readfile(acestream_settings_file) + types = ['Memory','Disk'] + choose=xbmcgui.Dialog().select(translate(70041),types) + if choose > -1: + escolha = types[choose] + if escolha == 'Memory': + settings_content = settings_content.replace("S'disk'","S'memory'") + elif escolha == 'Disk': + settings_content = settings_content.replace("S'memory'","S'disk'") + else:pass + save(acestream_settings_file, settings_content) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(600026), 1,addonpath+"/icon.png")) + xbmc.executebuiltin("Container.Refresh") + + +def set_acestream_engine_cache_folder(url): + if not xbmc.getCondVisibility('system.platform.windows'): + opcao= xbmcgui.Dialog().yesno(translate(40000), translate(70011)) + else: opcao = '' + if opcao: + if not xbmc.getCondVisibility('system.platform.Android'): + acestream_settings_file = os.path.join(os.getenv("HOME"),'.ACEStream','playerconf.pickle') + else: + acestream_settings_file = os.path.join('/sdcard','.ACEStream','playerconf.pickle') + settings_content = readfile(acestream_settings_file) + cachefolder = xbmcgui.Dialog().browse(3, translate(70012) , 'myprograms','') + if cachefolder: + settings_content = settings_content.replace(url,cachefolder) + save(acestream_settings_file, settings_content) + settings.setSetting('acestream_cachefolder',cachefolder) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(600026), 1,addonpath+"/icon.png")) + xbmc.executebuiltin("Container.Refresh") + +def shutdown_hooks(): + opcao= xbmcgui.Dialog().yesno(translate(40000), translate(70027),translate(70028) + str(xbmc.getSkinDir()) ) + if opcao: + mensagemok(translate(40000),translate(70029),translate(70030)) + mensagemok(translate(40000),translate(70031)) + opcao= xbmcgui.Dialog().yesno(translate(40000), translate(70032) ) + if opcao: + import xml.etree.ElementTree as ET + skin_path = xbmc.translatePath("special://skin/") + tree = ET.parse(os.path.join(skin_path, "addon.xml")) + try: res = tree.findall("./res")[0] + except: res = tree.findall("./extension/res")[0] + xml_specific_folder = str(res.attrib["folder"]) + xml_video_osd = os.path.join(xbmc.translatePath("special://skin/"),xml_specific_folder,"VideoOSD.xml") + xml_content = readfile(xml_video_osd).replace('PlayerControl(Stop)','RunPlugin(plugin://plugin.video.p2p-streams/?mode=7)') + try: + save(xml_video_osd,xml_content) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(600026), 1,addonpath+"/icon.png")) + except: mensagemok(translate(40000),'No permissions.') + opcao= xbmcgui.Dialog().yesno(translate(40000), translate(70033) ) + if opcao: + from peertopeerutils.keymapeditor import * + run() diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/advancedfunctions.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/advancedfunctions.pyo new file mode 100644 index 0000000000000000000000000000000000000000..6e52afb177654b6fe9d4e6c2966dda49e4075372 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/advancedfunctions.pyo differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/autoconf.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/autoconf.py new file mode 100644 index 0000000000000000000000000000000000000000..53cf8156bf863569d83a70c8a96c0daedea9de8e --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/autoconf.py @@ -0,0 +1,791 @@ +# -*- coding: utf-8 -*- + +""" p2p-streams (c) 2014 enen92 fightnight + + This file contains a single function. It's a function that will run on the addon first boot to download and configure the system for acestream/sopcast. The platform will be automatically detected and the necessary files downloaded and extracted to the userdata. + This function will run if and only the setting "Download modules" on boot is enabled. + + Functions: + + check_for_updates() -> Look for module updates between versions, force download them + firstconf() -> Configuration function, detects the platform, saves to settings, run configure sopcast/acestream functions + configure_sopcast() -> Configure Sopcast + configure_acestream() -> Configure Acestream + +""" + +import xbmc,xbmcgui,xbmcplugin,xbmcvfs +import tarfile,os,re,sys,subprocess +from peertopeerutils.pluginxbmc import * +from peertopeerutils.webutils import download_tools,get_page_source +from peertopeerutils.utilities import * + +""" Platform dependent files downloaded during the addon configuration""" + +#Linux Armv6 (Raspberry PI) +sopcast_raspberry = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/RaspberryPi/sopcast-raspberry.tar.gz" +acestream_generic_raspberry = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/RaspberryPi/raspberry-acestream.tar.gz" +acestream_openelec_raspberry = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/RaspberryPi/openelec-acestream.tar.gz" +#Linux Armv7 packages +sopcast_jynxbox = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/Armv7/sopcast-jynxbox_purelinux.tar.gz" +acestream_mxlinux = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/Armv7/mxlinux/mxlinux_armv7_acestream.tar.gz" +acestream_armv7_openelec = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/Armv7/openelec/openelec-acestream.tar.gz" +acestream_armv7_xbian = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/Armv7/xbian/xbian_acestream.tar.gz" +#Linux i386 and x86_64 (including openelec) +sopcast_linux_generico = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/Sopcastx86_64i386/sopcast_linux.tar.gz" +openelecx86_64_sopcast = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/x86_64/Openelec/sopcast_openelec64.tar.gz" +openeelcx86_64_acestream = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/x86_64/Openelec/acestream_openelec64_3051.tar.gz" +openelecxi386_sopcast = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/i386/openelec/sopcast_openeleci386.tar.gz" +openeelcxi386_acestream = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/i386/openelec/acestream_openeleci386_303fix.tar.gz" +#gen linux +acestream_linux_x64_generic = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/x86_64/acestream-linux-x86_64_3051.tar.gz" +acestream_linux_i386_generic = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Linux/i386/acestream-linux-i386_303.tar.gz" +#Android +sopcast_apk = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Android/SopCast.apk.tar.gz" +acestreamengine_apk_arm = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Android/AceStream-3.0.6-2in1.apk.tar.gz" +acestreamengine_apk_x86 = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Android/AceStream-3.0.6-2in1.apk.tar.gz" +android_aceengine_arm = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Android/org.acestream.engine-arm-3.0.6.tar.gz" +android_aceengine_x86 = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Android/org.acestream.engine_x86.tar.gz" +android_aceplayer_arm = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Android/AcePlayer-3.0.6-2in1.apk.tar.gz" +android_aceplayer_x86 = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Android/AcePlayer-3.0.6-2in1.apk.tar.gz" +#Mac OSX +osx_i386_sopcast = "http://p2p-strm.googlecode.com/svn/trunk/Modules/MacOsx/i386/sopcast_osxi386.tar.gz" +osx_i386_acestream = "http://p2p-strm.googlecode.com/svn/trunk/Modules/MacOsx/AceStreamWineOSX.zip" +osx_x64_sopcast = "http://p2p-strm.googlecode.com/svn/trunk/Modules/MacOsx/x86_64/sopcast_osx64.tar.gz" +osx_x64_acestream = "http://p2p-strm.googlecode.com/svn/trunk/Modules/MacOsx/AceStreamWineOSX.zip" +#Windows Files +acestream_windows = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Windows/acewindows-aceengine3.0.4.tar.gz" +srvany_executable = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Windows/srvany.tar.gz" +srvany_permissions = "http://p2p-strm.googlecode.com/svn/trunk/Modules/Windows/sopcastp2p-permissions.txt" + +def check_for_updates(): + try: + version_source = get_page_source("http://p2p-strm.googlecode.com/svn/trunk/ModuleVersions/versions.info") + except: version_source = "" + if version_source: + version_source = eval(version_source) + if xbmc.getCondVisibility('system.platform.linux') and not xbmc.getCondVisibility('system.platform.Android') and not settings.getSetting('force_android') == "true": + if os.uname()[4] == "armv6l": + if settings.getSetting('openelecarm6') == "true": platf = "openelec_arm6" + else: platf = "raspberrypi" + elif os.uname()[4] == "armv7l": + if settings.getSetting('openelecarm7') == "true": platf = "openelec_armv7" + elif settings.getSetting('mxlinuxarm7') == "true": platf = "mxlinux_armv7" + elif settings.getSetting('xbianarm7') == "true": platf = "xbian_armv7" + elif settings.getSetting('jynxbox_arm7') == "true": platf = "jynxbox_armv7" + elif os.uname()[4] == "i386" or os.uname()[4] == "i686": + if settings.getSetting('openeleci386') == "true": platf = "openeleci386" + else: platf = "linuxi386" + elif os.uname()[4] == "x86_64": + if settings.getSetting('openelecx86_64') == "true": platf = "openelecx64" + else: platf = "linux_x86_64" + elif xbmc.getCondVisibility('system.platform.windows'): platf = "windows" + elif xbmc.getCondVisibility('system.platform.Android') or settings.getSetting('force_android') == "true": platf = "android" + elif xbmc.getCondVisibility('System.Platform.OSX'): + if os.uname()[4] == "i386" or os.uname()[4] == "i686": platf = "osx32" + elif os.uname()[4] == "x86_64": platf = "osx64" + try: + if version_source["sopcast"][platf] != settings.getSetting('sopcast_version'): configure_sopcast(version_source["sopcast"][platf]) + sopcast_update = True + except: sopcast_update = False + try: + if version_source["acestream"][platf] != settings.getSetting('acestream_version'): configure_acestream(version_source["acestream"][platf]) + acestream_update = True + except: acestream_update = False + if acestream_update and sopcast_update: settings.setSetting('last_version_check',value=versao) + return + + + + +def first_conf(): + settings.setSetting('last_version_check',value='') + settings.setSetting('sopcast_version',value='') + settings.setSetting('acestream_version',value='') + if xbmc.getCondVisibility('system.platform.linux') and not xbmc.getCondVisibility('system.platform.Android') and not settings.getSetting('force_android') == "true": + if os.uname()[4] == "armv6l": + if re.search(os.uname()[1],"openelec",re.IGNORECASE): settings.setSetting('openelecarm6',value='true') + elif re.search(os.uname()[1],"raspbmc",re.IGNORECASE): settings.setSetting('raspberrypi',value='true') + elif os.path.isfile("/etc/xbian_version"): acestream_rpi = settings.setSetting('raspberrypi',value='true') + elif "ARCH" in os.uname()[2]: + settings.setSetting('raspberrypi',value='true') + settings.setSetting('python_cmd',value='python2') + else: + mensagemok(translate(40000),translate(400007),translate(400008)) + OS_list = ["OpenELEC","Raspbmc","Xbian","Pipplware","Arch Linux Arm"] + OS_Rpi_choose = xbmcgui.Dialog().select + choose=OS_Rpi_choose('Select your OS',OS_list) + if choose > -1: + if OS_list[choose] == "OpenELEC": settings.setSetting('openelecarm6',value='true') + elif OS_list[choose] == "Arch Linux Arm": settings.setSetting('raspberrypi',value='true');settings.setSetting('python_cmd',value='python2') + else: settings.setSetting('raspberrypi',value='true') + check_for_updates() + elif os.uname()[4] == "armv7l": + if re.search(os.uname()[1],"openelec",re.IGNORECASE): + settings.setSetting('openelecarm7',value='true') + elif os.path.isfile("/etc/xbian_version"): + settings.setSetting('xbianarm7',value='true') + else: + mensagemok(translate(40000),translate(40109),translate(40110)) + OS_list = ["MXLinux","OpenELEC","Xbian","Jynxbox Pure Linux"] + choose=xbmcgui.Dialog().select('Select your OS',OS_list) + if choose > -1: + OS_Choose= OS_list[choose] + if OS_Choose == "OpenELEC": settings.setSetting('openelecarm7',value='true') + elif OS_Choose == "Xbian": settings.setSetting('xbianarm7',value='true') + elif OS_Choose == "MXLinux": settings.setSetting('mxlinuxarm7',value='true') + elif OS_Choose == "Jynxbox Pure Linux": settings.setSetting('jynxbox_arm7',value='true') + check_for_updates() + else: + #32bit and 64bit + if os.uname()[4] == "x86_64": + if re.search(os.uname()[1],"openelec",re.IGNORECASE): + settings.setSetting('openelecx86_64',value='true') + else: + opcao= xbmcgui.Dialog().yesno(translate(40000), translate(40113)) + if opcao: + settings.setSetting('openelecx86_64',value='true') + elif os.uname()[4] == "i386" or os.uname()[4] == "i686": + if re.search(os.uname()[1],"openelec",re.IGNORECASE): + settings.setSetting('openeleci386',value='true') + else: + opcao= xbmcgui.Dialog().yesno(translate(40000), translate(600023)) + if opcao: + settings.setSetting('openeleci386',value='true') + check_for_updates() + + elif xbmc.getCondVisibility('system.platform.windows'): + check_for_updates() + + elif xbmc.getCondVisibility('system.platform.Android'): + check_for_updates() + + elif xbmc.getCondVisibility('System.Platform.OSX'): + check_for_updates() + + settings.setSetting('autoconfig',value="false") + + + +def configure_sopcast(latest_version): + #Configuration for LINUX + if xbmc.getCondVisibility('system.platform.linux') and not xbmc.getCondVisibility('system.platform.Android') and not settings.getSetting('force_android') == "true": + print("Detected OS: Linux") + #Linux Armv6 + if os.uname()[4] == "armv6l": + print("Detected linux armv6 - possible Raspberry PI") + #Sop + SPSC_KIT = os.path.join(addonpath,sopcast_raspberry.split("/")[-1]) + download_tools().Downloader(sopcast_raspberry,SPSC_KIT,translate(40025),translate(40000)) + import tarfile + if tarfile.is_tarfile(SPSC_KIT): + path_libraries = os.path.join(pastaperfil,"sopcast") + download_tools().extract(SPSC_KIT,path_libraries) + xbmc.sleep(500) + download_tools().remove(SPSC_KIT) + if latest_version: settings.setSetting('sopcast_version',value=latest_version) + return + + elif os.uname()[4] == "armv7l": + if settings.getSetting('jynxbox_arm7') == "true": + SPSC_KIT = os.path.join(addonpath,sopcast_jynxbox.split("/")[-1]) + download_tools().Downloader(sopcast_jynxbox,SPSC_KIT,translate(40025),translate(40000)) + import tarfile + if tarfile.is_tarfile(SPSC_KIT): + path_libraries = os.path.join(pastaperfil) + download_tools().extract(SPSC_KIT,path_libraries) + xbmc.sleep(500) + download_tools().remove(SPSC_KIT) + if latest_version: settings.setSetting('sopcast_version',value=latest_version) + return + else: + SPSC_KIT = os.path.join(addonpath,sopcast_raspberry.split("/")[-1]) + download_tools().Downloader(sopcast_raspberry,SPSC_KIT,translate(40025),translate(40000)) + import tarfile + if tarfile.is_tarfile(SPSC_KIT): + path_libraries = os.path.join(pastaperfil,"sopcast") + download_tools().extract(SPSC_KIT,path_libraries) + xbmc.sleep(500) + download_tools().remove(SPSC_KIT) + if latest_version: settings.setSetting('sopcast_version',value=latest_version) + return + + elif os.uname()[4] == "x86_64": + generic = False + if settings.getSetting('openelecx86_64') == "true": + print("Detected OpenELEC x86_64") + SPSC_KIT = os.path.join(addonpath,openelecx86_64_sopcast.split("/")[-1]) + download_tools().Downloader(openelecx86_64_sopcast,SPSC_KIT,translate(40025),translate(40000)) + import tarfile + if tarfile.is_tarfile(SPSC_KIT): + download_tools().extract(SPSC_KIT,pastaperfil) + xbmc.sleep(500) + download_tools().remove(SPSC_KIT) + if latest_version: settings.setSetting('sopcast_version',value=latest_version) + return + else: generic = True + elif os.uname()[4] == "i386" or os.uname()[4] == "i686": + generic = False + if settings.getSetting('openeleci386') == "true": + SPSC_KIT = os.path.join(addonpath,openelecxi386_sopcast.split("/")[-1]) + download_tools().Downloader(openelecxi386_sopcast,SPSC_KIT,translate(40025),translate(40000)) + import tarfile + if tarfile.is_tarfile(SPSC_KIT): + download_tools().extract(SPSC_KIT,pastaperfil) + xbmc.sleep(500) + download_tools().remove(SPSC_KIT) + if latest_version: settings.setSetting('sopcast_version',value=latest_version) + return + else: generic = True + if generic == True: + SPSC_KIT = os.path.join(addonpath,sopcast_linux_generico.split("/")[-1]) + download_tools().Downloader(sopcast_linux_generico,SPSC_KIT,translate(40025),translate(40000)) + import tarfile + if tarfile.is_tarfile(SPSC_KIT): + path_libraries = os.path.join(pastaperfil,"sopcast") + download_tools().extract(SPSC_KIT,path_libraries) + xbmc.sleep(500) + download_tools().remove(SPSC_KIT) + #set every single file from the bundle as executable + path_libraries = os.path.join(pastaperfil,"sopcast") + dirs, files = xbmcvfs.listdir(path_libraries) + for ficheiro in files: + binary_path = os.path.join(path_libraries,ficheiro) + st = os.stat(binary_path) + import stat + os.chmod(binary_path, st.st_mode | stat.S_IEXEC) + path_libraries = os.path.join(path_libraries,"lib") + dirs, files = xbmcvfs.listdir(path_libraries) + for ficheiro in files: + binary_path = os.path.join(path_libraries,ficheiro) + st = os.stat(binary_path) + import stat + os.chmod(binary_path, st.st_mode | stat.S_IEXEC) + if latest_version: settings.setSetting('sopcast_version',value=latest_version) + return + + + elif xbmc.getCondVisibility('system.platform.windows'): + print("Detected OS: Windows") + if not xbmcvfs.exists(pastaperfil): xbmcvfs.mkdir(pastaperfil) + #Sop + import ctypes + is_admin=ctypes.windll.shell32.IsUserAnAdmin() != 0 + if is_admin == False: + mensagemok(translate(40000),translate(40158),translate(40159)) + else: + import subprocess + cmd = ['sc','delete','sopcastp2p'] + proc = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True) + for line in proc.stdout: + print("cmd out: " + line.rstrip()) + xbmc.sleep(1000) + ret = mensagemprogresso.create(translate(40000),translate(40000)) + mensagemprogresso.update(0,translate(40160)," ") + xbmc.sleep(1000) + 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) + sopcast_executable = value + print("Installation executable of sopcast was found: " + sopcast_executable) + _winreg.CloseKey(aKey) + mensagemprogresso.update(10,translate(40160),translate(40161)) + except: + sopcast_executable = "" + mensagemok(translate(40000),translate(40162),translate(40163)) + if not sopcast_executable: pass + else: + xbmc.sleep(1000) + mensagemprogresso.update(20,translate(40164)," ") + xbmc.sleep(1000) + print ("Getting windows users IDS") + aReg = _winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE) + aKey = _winreg.OpenKey(aReg, r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList') + users = [] + for i in range(1024): + try: + asubkey=_winreg.EnumKey(aKey,i) + print(asubkey) + aKeydois = _winreg.OpenKey(aReg, os.path.join('SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList',asubkey)) + val=_winreg.QueryValueEx(aKeydois, "ProfileImagePath") + try: + print(val[0]) + except: + print("Notice: User with strange characters, print cmd ignored.") + if "Windows" in val[0] or "%systemroot%" in val[0]: + pass + else: + users.append(asubkey) + except: + pass + if not users: + mensagemok(translate(40000),translate(40165)) + else: + mensagemprogresso.update(30,translate(40164),translate(40161)) + xbmc.sleep(200) + mensagemprogresso.update(30,translate(40166)," ") + xbmc.sleep(1000) + print("System Users", users) + srvany_final_location = os.path.join(sopcast_executable.replace("SopCast.exe",""),"srvany.exe") + srvany_download_location = os.path.join(addonpath,"srvany.exe") + srvanytgz_download_location = os.path.join(addonpath,"srvany.tar.gz") + download_tools().Downloader(srvany_executable,srvanytgz_download_location,translate(40167),translate(40000)) + xbmc.sleep(1000) + import tarfile + if tarfile.is_tarfile(srvanytgz_download_location): + path_libraries = addonpath + download_tools().extract(srvanytgz_download_location,path_libraries) + xbmcvfs.copy(srvany_download_location,srvany_final_location) + download_tools().remove(srvanytgz_download_location) + download_tools().remove(srvany_download_location) + xbmc.sleep(1000) + ret = mensagemprogresso.create(translate(40000),translate(40000)) + xbmc.sleep(200) + mensagemprogresso.update(35,translate(40168)," ") + xbmc.sleep(1000) + import subprocess + cmd = ['sc','create','sopcastp2p','binpath=',os.path.join(os.path.join(sopcast_executable.replace("SopCast.exe","")),'srvany.exe')] + proc = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True) + servicecreator = False + for line in proc.stdout: + print ("cmd out: " + line.rstrip()) + servicecreator = True + if servicecreator == False: + mensagemok(translate(40000),translate(40169)) + else: + mensagemprogresso.update(40,translate(40168),translate(40161)) + xbmc.sleep(1000) + mensagemprogresso.update(45,translate(40170)," ") + xbmc.sleep(1000) + print("Trying to modify regedit....") + try: + aReg = _winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE) + key = _winreg.CreateKey(aReg, r'SYSTEM\CurrentControlSet\Services\sopcastp2p\Parameters') + _winreg.SetValueEx(key, 'AppDirectory', 0, _winreg.REG_SZ, os.path.join(sopcast_executable.replace("SopCast.exe",""))) + _winreg.SetValueEx(key, 'Application', 0, _winreg.REG_SZ, os.path.join(os.path.join(sopcast_executable.replace("SopCast.exe","")),"SopCast.exe")) + _winreg.SetValueEx(key, 'AppParameters', 0, _winreg.REG_SZ, "sop://") + mensagemprogresso.update(50,translate(40170), translate(40161)) + regedit = True + except: + mensagemok(translate(40000),translate(40171)) + regedit = False + if regedit == False: pass + else: + xbmc.sleep(1000) + mensagemprogresso.update(50,translate(40172), " ") + cmd = ['sc','sdshow','sopcastp2p'] + proc = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True) + lines = [] + for line in proc.stdout: + print(line.rstrip()) + if line.rstrip() != "" and "(" in line.rstrip(): lines.append(line.rstrip()) + else: pass + if len(lines) != 1: mensagemok(translate(40000),translate(40173)) + else: + linha_arr = [] + for user in users: + linha_arr.append('(A;;RPWPCR;;;' + user + ')') + linha_add = '' + for linha in linha_arr: + linha_add += linha + print("line peace to add: " + linha_add) + linha_final = lines[0].replace("S:(",linha_add + "S:(") + print("Final line: " + linha_final) + permissions = False + xbmc.sleep(500) + mensagemprogresso.update(60,translate(40172), translate(40161)) + xbmc.sleep(500) + mensagemprogresso.update(60,translate(40174), " ") + cmd = ['sc','sdset','sopcastp2p',linha_final] + proc = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True) + for line in proc.stdout: + print(line.rstrip()) + permissions = True + if permissions == False: mensagemok(translate(40000),translate(40175)) + else: + mensagemprogresso.update(70,translate(40174), translate(40161)) + xbmc.sleep(1000) + mensagemprogresso.update(70,translate(40176), " ") + print("Trying to set sopcastp2p service regedit permissions...") + download_tools().Downloader(srvany_permissions,os.path.join(pastaperfil,"sopcastp2p-permissions.txt"),translate(40177),translate(40000)) + xbmc.sleep(500) + ret = mensagemprogresso.create(translate(40000),translate(40000)) + xbmc.sleep(500) + mensagemprogresso.update(80,translate(40178), " ") + xbmc.sleep(1000) + cmd = ['regini',os.path.join(pastaperfil,"sopcastp2p-permissions.txt")] + proc = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True) + for line in proc.stdout: + print(line.rstrip()) + mensagemprogresso.update(90,translate(40178), translate(40178)) + mensagemprogresso.update(100,translate(40179), " ") + xbmc.sleep(2000) + mensagemprogresso.close() + if latest_version: settings.setSetting('sopcast_version',value=latest_version) + return + + elif xbmc.getCondVisibility('System.Platform.OSX'): + print("Detected OS: Mac OSX") + available = False + if os.uname()[-1] == "x86_64": + mac_package = osx_x64_sopcast + available = True + elif os.uname()[-1] == "i386": + mac_package = osx_i386_sopcast + available = True + else: + available = False + if available == True: + if not os.path.exists(pastaperfil): + xbmcvfs.mkdir(pastaperfil) + MAC_KIT = os.path.join(addonpath,mac_package.split("/")[-1]) + download_tools().Downloader(mac_package,MAC_KIT,translate(40025),translate(40000)) + import tarfile + if tarfile.is_tarfile(MAC_KIT): + path_libraries = os.path.join(pastaperfil) + download_tools().extract(MAC_KIT,pastaperfil) + download_tools().remove(MAC_KIT) + sp_sc_auth = os.path.join(pastaperfil,"sopcast","sp-sc-auth") + st = os.stat(sp_sc_auth) + import stat + os.chmod(sp_sc_auth, st.st_mode | stat.S_IEXEC) + if latest_version: settings.setSetting('sopcast_version',value=latest_version) + return + else: + mensagemok(translate(40000),translate(600014)) + return + + elif xbmc.getCondVisibility('System.Platform.Android') or settings.getSetting('force_android') == "true": + + print("Detected OS: Android") + #Sopcast configuration + print("Starting SopCast Configuration") + + #Moving sopclient to ext4 hack - tks steeve from xbmctorrent + + sopclient_builtin_location = os.path.join(addonpath,"resources","binaries","sopclient") + + #Hack to get current xbmc app id + xbmcfolder=xbmc.translatePath(addonpath).split("/") + + i = 0 + found = False + sopcast_installed = False + + for folder in xbmcfolder: + if folder.count('.') >= 2 and folder != addon_id : + found = True + break + else: + i+=1 + + if found == True: + uid = os.getuid() + app_id = xbmcfolder[i] + xbmc_data_path = os.path.join("/data", "data", app_id) + if os.path.exists(xbmc_data_path) and uid == os.stat(xbmc_data_path).st_uid: + android_binary_dir = os.path.join(xbmc_data_path, "files", "plugin.video.p2p-streams") + if not os.path.exists(android_binary_dir): + os.makedirs(android_binary_dir) + android_binary_path = os.path.join(android_binary_dir, "sopclient") + if not os.path.exists(android_binary_path) or os.path.getsize(android_binary_path) != os.path.getsize(sopclient_builtin_location): + import shutil + shutil.copy2(sopclient_builtin_location, android_binary_path) + binary_path = android_binary_path + st = os.stat(binary_path) + import stat + os.chmod(binary_path, st.st_mode | stat.S_IEXEC) + settings.setSetting('android_sopclient',value=binary_path) + opcao= xbmcgui.Dialog().yesno(translate(40000), translate(50011),translate(50012)) + if not opcao: + settings.setSetting('external-sopcast',value='1') + settings.setSetting('force_android',value='true') + sopcast_installed = True + mensagemok(translate(40000),translate(50014)) + else: + mensagemok(translate(40000),translate(50013)) + if os.path.exists(os.path.join("sdcard","Download")): + pasta = os.path.join("sdcard","Download") + sopfile = os.path.join("sdcard","Download",sopcast_apk.split("/")[-1]) + else: + dialog = xbmcgui.Dialog() + pasta = dialog.browse(int(0), translate(40190), 'myprograms') + sopfile = os.path.join(pasta,sopcast_apk.split("/")[-1]) + download_tools().Downloader(sopcast_apk,sopfile,translate(40073),translate(40000)) + import tarfile + if tarfile.is_tarfile(sopfile): + download_tools().extract(sopfile,pasta) + download_tools().remove(sopfile) + mensagemok(translate(40000),translate(50015),pasta,translate(50016)) + sopcast_installed = True + settings.setSetting('external-sopcast',value='0') + mensagemok(translate(40000),translate(50014)) + if latest_version: settings.setSetting('sopcast_version',value=latest_version) + return + + else: + mensagemok(translate(40000),translate(50017)) + return + + + +def configure_acestream(latest_version): + #Configuration for LINUX + if xbmc.getCondVisibility('system.platform.linux') and not xbmc.getCondVisibility('system.platform.Android') and not settings.getSetting('force_android') == "true": + print("Detected OS: Linux") + #Linux Armv6 + if os.uname()[4] == "armv6l": + print("Detected linux armv6 - possible Raspberry PI") + if settings.getSetting('openelecarm6') == "true": acestream_rpi = acestream_openelec_raspberry + else: acestream_rpi = acestream_generic_raspberry + ACE_KIT = os.path.join(addonpath,acestream_rpi.split("/")[-1]) + download_tools().Downloader(acestream_rpi,ACE_KIT,translate(40026),translate(40000)) + import tarfile + if tarfile.is_tarfile(ACE_KIT): + path_libraries = os.path.join(pastaperfil,"acestream") + download_tools().extract(ACE_KIT,path_libraries) + xbmc.sleep(500) + download_tools().remove(ACE_KIT) + if latest_version: settings.setSetting('acestream_version',value=latest_version) + return + #Linux Armv7 + elif os.uname()[4] == "armv7l": + if settings.getSetting('openelecarm7') == "true": acestream_package = acestream_armv7_openelec + elif settings.getSetting('xbianarm7') == "true": acestream_package = acestream_armv7_xbian + elif settings.getSetting('mxlinuxarm7') == "true" or settings.getSetting('jynxbox_arm7') == "true": acestream_package = acestream_mxlinux + + ACE_KIT = os.path.join(addonpath,acestream_package.split("/")[-1]) + download_tools().Downloader(acestream_package,ACE_KIT,translate(40026),translate(40000)) + import tarfile + if tarfile.is_tarfile(ACE_KIT): + path_libraries = os.path.join(pastaperfil,"acestream") + download_tools().extract(ACE_KIT,path_libraries) + xbmc.sleep(500) + download_tools().remove(ACE_KIT) + if latest_version: settings.setSetting('acestream_version',value=latest_version) + return + + elif os.uname()[4] == "x86_64": + if settings.getSetting('openelecx86_64') == "true": + print("OpenELEC x86_64 Acestream configuration") + ACE_KIT = os.path.join(addonpath,openeelcx86_64_acestream.split("/")[-1]) + download_tools().Downloader(openeelcx86_64_acestream ,ACE_KIT,translate(40026),translate(40000)) + import tarfile + if tarfile.is_tarfile(ACE_KIT): + download_tools().extract(ACE_KIT,pastaperfil) + xbmc.sleep(500) + download_tools().remove(ACE_KIT) + if latest_version: settings.setSetting('acestream_version',value=latest_version) + return + + else: + print("64 bit Linux Disto Acestream Configuration") + ACE_KIT = os.path.join(addonpath,acestream_linux_x64_generic.split("/")[-1]) + download_tools().Downloader(acestream_linux_x64_generic,ACE_KIT,translate(40026),translate(40000)) + import tarfile + if tarfile.is_tarfile(ACE_KIT): + download_tools().extract(ACE_KIT,pastaperfil) + xbmc.sleep(500) + download_tools().remove(ACE_KIT) + if latest_version: settings.setSetting('acestream_version',value=latest_version) + return + + elif os.uname()[4] == "i386" or os.uname()[4] == "i686": + if settings.getSetting('openeleci386') == "true": + print("32 bit Openelec Acestream Configuration") + ACE_KIT = os.path.join(addonpath,openeelcxi386_acestream.split("/")[-1]) + download_tools().Downloader(openeelcxi386_acestream,ACE_KIT,translate(40026),translate(40000)) + import tarfile + if tarfile.is_tarfile(ACE_KIT): + download_tools().extract(ACE_KIT,pastaperfil) + xbmc.sleep(500) + download_tools().remove(ACE_KIT) + if latest_version: settings.setSetting('acestream_version',value=latest_version) + return + else: + print("32 bit Linux general distro Acestream Configuration") + ACE_KIT = os.path.join(addonpath,acestream_linux_i386_generic.split("/")[-1]) + download_tools().Downloader(acestream_linux_i386_generic,ACE_KIT,translate(40026),translate(40000)) + import tarfile + if tarfile.is_tarfile(ACE_KIT): + download_tools().extract(ACE_KIT,pastaperfil) + xbmc.sleep(500) + download_tools().remove(ACE_KIT) + if latest_version: settings.setSetting('acestream_version',value=latest_version) + return + + elif xbmc.getCondVisibility('system.platform.windows'): + print("Detected OS: Windows") + if not os.path.exists(pastaperfil): xbmcvfs.mkdir(pastaperfil) + #Ace + SPSC_KIT = os.path.join(addonpath,acestream_windows.split("/")[-1]) + download_tools().Downloader(acestream_windows,SPSC_KIT,translate(40026),translate(40000)) + import shutil + if os.path.exists(os.path.join(pastaperfil,"acestream")): + shutil.rmtree(os.path.join(pastaperfil,"acestream")) + if os.path.exists(os.path.join(pastaperfil,"player")): + shutil.rmtree(os.path.join(pastaperfil,"player")) + import tarfile + if tarfile.is_tarfile(SPSC_KIT): + path_libraries = os.path.join(pastaperfil) + download_tools().extract(SPSC_KIT,path_libraries) + download_tools().remove(SPSC_KIT) + if latest_version: settings.setSetting('acestream_version',value=latest_version) + return + + elif xbmc.getCondVisibility('System.Platform.OSX'): + print("Detected OS: Mac OSX") + available = False + if os.uname()[-1] == "x86_64": + mac_package = osx_x64_acestream + available = True + elif os.uname()[-1] == "i386": + mac_package = osx_i386_acestream + available = True + else: + available = False + if available == True: + MAC_KIT = os.path.join('/Applications',mac_package.split("/")[-1]) + if not xbmcvfs.exists(os.path.join('/Applications','Ace Stream.app')): + download_tools().Downloader(mac_package,MAC_KIT,translate(40026),translate(40000)) + if xbmcvfs.exists(MAC_KIT): + xbmc.sleep(1000) + cmd = 'unzip /Applications/AceStreamWineOSX.zip' + zipa = subprocess.Popen(cmd,shell=True) + cmd = 'chmod -R 755 /Applications/Ace\ Stream.app' + print cmd + chmod = subprocess.Popen(cmd,shell=True) + try: os.remove(MAC_KIT) + except: pass + if latest_version: settings.setSetting('acestream_version',value=latest_version) + return + else: + mensagemok(translate(40000),translate(600014)) + return + + + elif xbmc.getCondVisibility('System.Platform.Android') or settings.getSetting('force_android') == "true": + + print("Detected OS: Android") + print("Starting Acestream Configuration") + #acestream config for android + if not os.path.exists(pastaperfil): xbmcvfs.mkdir(pastaperfil) + #Hack to get xbmc app id + xbmcfolder=xbmc.translatePath(addonpath).split("/") + + i = 0 + found = False + sopcast_installed = False + + for folder in xbmcfolder: + if folder.count('.') >= 2 and folder != addon_id : + found = True + break + else: + i+=1 + + if found == True: + uid = os.getuid() + app_id = xbmcfolder[i] + settings.setSetting('app_id',app_id) + #Acestreamconfiguration for android starts here + if "arm" in os.uname()[4]: + acebundle = os.path.join(pastaperfil,android_aceengine_arm.split("/")[-1]) + download_tools().Downloader(android_aceengine_arm,acebundle,translate(70014),translate(40000)) + else: + acebundle = os.path.join(pastaperfil,android_aceengine_x86.split("/")[-1]) + download_tools().Downloader(android_aceengine_x86,acebundle,translate(70014),translate(40000)) + import tarfile + if tarfile.is_tarfile(acebundle): + download_tools().extract(acebundle,pastaperfil) + download_tools().remove(acebundle) + orgacestreamenginefolder = os.path.join(pastaperfil,"org.acestream.engine") + xbmc_data_path = os.path.join("/data", "data", app_id) + if os.path.exists(xbmc_data_path) and uid == os.stat(xbmc_data_path).st_uid: + android_binary_dir = os.path.join(xbmc_data_path, "files", "plugin.video.p2p-streams") + if not os.path.exists(android_binary_dir): os.makedirs(android_binary_dir) + android_acestream_folder = os.path.join(android_binary_dir,"org.acestream.engine") + if not os.path.exists(android_acestream_folder): os.makedirs(android_acestream_folder) + else: + #clean install for android - delete old folder + print android_acestream_folder + try: + os.system("chmod -R 777 "+android_acestream_folder+"/*") + os.system("rm -r '"+android_acestream_folder+"'") + except: pass + try: os.makedirs(android_acestream_folder) + except: pass + xbmc.sleep(200) + #clean install in android - remove /sdcard/.ACEStream folder if it exists (to be enabled between versions if we need to remove older settings + #if os.path.exists(os.path.join('/sdcard','.ACEStream')): + # try: + # hidden_ace = os.path.join('/sdcard','.ACEStream') + # os.system("chmod -R 777 "+hidden_ace+"/*") + # os.system("rm -r '"+hidden_ace+"'") + # except: pass + recursive_overwrite(orgacestreamenginefolder, android_acestream_folder, ignore=None) + pythonbin = os.path.join(android_acestream_folder,"files","python","bin","python") + st = os.stat(pythonbin) + import stat + os.chmod(pythonbin, st.st_mode | stat.S_IEXEC) + if os.path.exists(orgacestreamenginefolder): + try: + os.system("chmod -R 777 "+orgacestreamenginefolder+"/*") + os.system("rm -r '"+orgacestreamenginefolder+"'") + except: pass + try: xbmcvfs.mkdir(os.path.join('/sdcard','org.acestream.engine')) + except: pass + opcao= xbmcgui.Dialog().yesno(translate(40000), translate(70015),translate(70016)) + if not opcao: + settings.setSetting('engine_app','0') + else: + mensagemok(translate(40000),translate(50018),translate(50019),translate(50020)) + if os.path.exists(os.path.join("sdcard","Download")): + pasta = os.path.join("sdcard","Download") + if "arm" in os.uname()[4]: acefile = os.path.join("sdcard","Download",acestreamengine_apk_arm.split("/")[-1]) + else: acefile = os.path.join("sdcard","Download",acestreamengine_apk_x86.split("/")[-1]) + else: + dialog = xbmcgui.Dialog() + pasta = dialog.browse(int(0), translate(40190), 'myprograms') + if "arm" in os.uname()[4]: acefile = os.path.join(pasta,acestreamengine_apk_arm.split("/")[-1]) + else: acefile = os.path.join(pasta,acestreamengine_apk_x86.split("/")[-1]) + if "arm" in os.uname()[4]: download_tools().Downloader(acestreamengine_apk_arm,acefile,translate(40072),translate(40000)) + else: download_tools().Downloader(acestreamengine_apk_x86,acefile,translate(40072),translate(40000)) + import tarfile + if tarfile.is_tarfile(acefile): + download_tools().extract(acefile,pasta) + download_tools().remove(acefile) + xbmc.sleep(2000) + mensagemok(translate(40000),translate(50021),pasta,translate(50016)) + mensagemok(translate(40000),translate(50023),translate(50024),translate(50025)) + settings.setSetting('engine_app','1') + opcao= xbmcgui.Dialog().yesno(translate(40000), translate(70017),translate(70018)) + if opcao: + if os.path.exists(os.path.join("sdcard","Download")): + pasta = os.path.join("sdcard","Download") + if "arm" in os.uname()[4]: acefile = os.path.join("sdcard","Download",android_aceplayer_arm.split("/")[-1]) + else: os.path.join("sdcard","Download",android_aceplayer_x86.split("/")[-1]) + else: + dialog = xbmcgui.Dialog() + pasta = dialog.browse(int(0), translate(40190), 'myprograms') + if "arm" in os.uname()[4]: acefile = os.path.join(pasta,acestreamengine_apk_arm.split("/")[-1]) + else: acefile = os.path.join(pasta,acestreamengine_apk_x86.split("/")[-1]) + if "arm" in os.uname()[4]: download_tools().Downloader(android_aceplayer_arm,acefile,translate(70019),translate(40000)) + else: download_tools().Downloader(android_aceplayer_x86,acefile,translate(70019),translate(40000)) + import tarfile + if tarfile.is_tarfile(acefile): + download_tools().extract(acefile,pasta) + download_tools().remove(acefile) + xbmc.sleep(2000) + mensagemok(translate(40000),translate(70020),pasta,translate(50016)) + opcao= xbmcgui.Dialog().yesno(translate(40000), translate(70021)) + if opcao: + settings.setSetting('engine_app','2') + if latest_version: settings.setSetting('acestream_version',value=latest_version) + mensagemok(translate(40000),translate(50022)) + return + else: + mensagemok(translate(40000),translate(50017)) + return diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/autoconf.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/autoconf.pyo new file mode 100644 index 0000000000000000000000000000000000000000..0f6d608aae2d0c5b166944c1e141469e09d946a2 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/autoconf.pyo differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/favourites.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/favourites.py new file mode 100644 index 0000000000000000000000000000000000000000..1cf0b5463a0a66861e447b51a24fa2bc42cf232e --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/favourites.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- + +""" p2p-streams (c) 2014 enen92 fightnight + + This file contains the the code for favourites used in the addon + + Functions: + + addon_favourites() -> Main menu. It parses the userdata/Favourites folder for items and lists them + manual_add_to_favourites() -> Add a favourite to list manually + add_to_addon_favourites(name,url,iconimage) -> Add an item to the addon favourites. Receives the name of the channel, the url and the iconimage + remove_addon_favourites(url) -> Remove from addon favourites + + +""" + +import xbmc,xbmcgui,xbmcplugin,xbmcvfs,sys,os +from peertopeerutils.pluginxbmc import * +from peertopeerutils.iofile import * +from peertopeerutils.directoryhandle import addDir +from random import randint + +def addon_favourites(): + if os.path.exists(os.path.join(pastaperfil,"Favourites")): + dirs, files = xbmcvfs.listdir(os.path.join(pastaperfil,"Favourites")) + if files: + for file in files: + string = readfile(os.path.join(pastaperfil,"Favourites",file)) + match = string.split("|") + try: iconimage = match[3] + except: + if 'acestream' in file: iconimage = addonpath + art + 'acelogofull.png' + elif 'sop' in file: iconimage = addonpath + art + 'sopcast_logo.jpg' + else: iconimage = '' + addDir("[B][COLOR orange]" + match[0] + "[/B][/COLOR]",match[2],int(match[1]),iconimage,1,False) + addDir('[B]' + translate(70022) + '[/B]',MainURL,203,addonpath + art + 'plus-menu.png',2,False) + xbmc.executebuiltin("Container.SetViewMode(51)") + +def manual_add_to_favourites(): + keyb = xbmc.Keyboard("", translate(70023)) + keyb.doModal() + if (keyb.isConfirmed()): + favourite_url = keyb.getText() + if ('acestream://' in favourite_url) or ('sop://' in favourite_url) or ('.acelive' in favourite_url) or ('.torrent' in favourite_url): + keyb = xbmc.Keyboard("", translate(70024)) + keyb.doModal() + if (keyb.isConfirmed()): + favourite_name = keyb.getText() + if favourite_name: pass + else: favourite_name = 'p2p-streams ' + str(randint(1,100)) + add_to_addon_favourites(favourite_name,favourite_url,'') + else: + mensagemok(translate(40000),translate(40128)) + +def add_to_addon_favourites(name,url,iconimage): + name = name.replace("[b]","").replace("[/b]","").replace("[color orange]","").replace("[/color]","").replace("[B]","").replace("[/B]","") + if "runplugin" in url: + match = re.compile("url=(.+?)&mode=(.+?)&").findall(url.replace(";","")) + for url,mode in match: + favourite_text = str(name) + " (" + str(url) + ")|" + str(mode) + "|" + str(url) + '|' + str(iconimage) + favouritetxt = os.path.join(pastaperfil,"Favourites",url.replace(":","").replace("/","") + ".txt") + if not xbmcvfs.exists(os.path.join(pastaperfil,"Favourites")): xbmcvfs.mkdir(os.path.join(pastaperfil,"Favourites")) + save(favouritetxt, favourite_text) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(40148), 1,addonpath+"/icon.png")) + else: + if "sop://" in url: + tipo = "sopcast" + if not iconimage: iconimage = os.path.join(addonpath,'resources','art','sopcast_logo.jpg') + elif "acestream://" in url: + tipo = "acestream" + if not iconimage: iconimage = os.path.join(addonpath,'resources','art','acelogofull.jpg') + elif ".torrent" in url: + tipo = "acestream" + if not iconimage: iconimage = os.path.join(addonpath,'resources','art','acelogofull.jpg') + elif ".acelive" in url: + tipo = "acestream" + if not iconimage: iconimage = os.path.join(addonpath,'resources','art','acelogofull.jpg') + else: + if len(url) < 30: tipo = "sopcast" + else: tipo = "acestream" + if tipo == "sopcast": + favourite_text = str(name) + " (" + str(url) + ")|" + str(2) + "|" + str(url) + '|' + str(iconimage) + elif tipo == "acestream": + favourite_text = str(name) + " (" + str(url) + ")|" + str(1) + "|" + str(url) + '|' + str(iconimage) + favouritetxt = os.path.join(pastaperfil,"Favourites",url.replace(":","").replace("/","") + ".txt") + if not xbmcvfs.exists(os.path.join(pastaperfil,"Favourites")): xbmcvfs.mkdir(os.path.join(pastaperfil,"Favourites")) + save(favouritetxt, favourite_text) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(40148), 1,addonpath+"/icon.png")) + xbmc.executebuiltin("Container.Refresh") + +def remove_addon_favourites(url): + if "runplugin" in url: + match = re.compile("url=(.+?)&mode").findall(url.replace(";","")) + if match: ficheiro = os.path.join(pastaperfil,"Favourites",match[0].replace("/","").replace(":","") + ".txt") + else: + ficheiro = os.path.join(pastaperfil,"Favourites",url.replace(":","").replace("/","") + ".txt") + xbmcvfs.delete(ficheiro) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(40147), 1,addonpath+"/icon.png")) + xbmc.executebuiltin("Container.Refresh") + diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/favourites.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/favourites.pyo new file mode 100644 index 0000000000000000000000000000000000000000..5d3fbae1c30e92f9725332970ac1f1abfae25dd0 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/favourites.pyo differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/history.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/history.py new file mode 100644 index 0000000000000000000000000000000000000000..af9cb4fbeffb2be7cb584706cb27b5d26b4b2205 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/history.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- + +""" p2p-streams (c) 2014 enen92 fightnight + + This file manages the history of recent played p2p addon items + + Functions: + + list_history() -> Function list addon history. It grabs the info from history.txt in the userdata + add_to_history(name,url,mode,iconimage) -> Add to addon history. It appends a new line to history.txt + remove_history() -> delete history.txt if the file exists + + +""" +import xbmcvfs,xbmc,os,sys +from peertopeerutils.pluginxbmc import * +from peertopeerutils.iofile import * +from peertopeerutils.directoryhandle import addDir + +history_file = os.path.join(pastaperfil,'history.txt') + +def list_history(): + if xbmcvfs.exists(history_file): + lines = open(history_file).readlines() + i=0 + for line in lines: + info = line.split('|') + if i < int(settings.getSetting('items_per_page')): + try: + addDir(info[0],info[1],int(info[2]),info[3].replace('\n',''),1,False) + except: pass + i+=1 + else: + sys.exit(0) + +def add_to_history(name,url,mode,iconimage): + line = str(name) + '|' + str(url) + '|' +str(mode) +'|' + str(iconimage) + '\n' + if xbmcvfs.exists(history_file): + lines = open(history_file).readlines() + if len(lines) < int(settings.getSetting('items_per_page')): + if name in lines[0]: pass + else: + lines.insert(0,line) + open(history_file, 'w').writelines(lines) + else: + lines = open(history_file).readlines() + newlines = lines[0:-1*int(settings.getSetting('items_per_page'))-1] + newlines.insert(0,line) + open(history_file, 'w').writelines(newlines) + else: + save(history_file,line) + return + +def remove_history(): + if xbmcvfs.exists(history_file): + xbmcvfs.delete(history_file) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(600026), 1,addonpath+"/icon.png")) + diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/history.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/history.pyo new file mode 100644 index 0000000000000000000000000000000000000000..dc018e9cf182375cac39a9853c869b1cc43fec96 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/history.pyo differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/livestreams.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/livestreams.py new file mode 100644 index 0000000000000000000000000000000000000000..beb76b3debe06f273a8ef3ec32c53943cd031a3b --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/livestreams.py @@ -0,0 +1,521 @@ +# -*- coding: utf-8 -*- + +""" p2p-streams (c) 2014 enen92 fightnight + + This file contains the livestream addon engine. It is mostly based on divingmule work on livestreams addon! + + Functions: + + xml_lists_menu() -> main menu for the xml list category + addlista() -> add a new list. It'll ask for local or remote and processes the given input + remove_list(name) -> Remove a list + + get_groups(url) -> First regex function to parse a given list. Sopcast type list + get_channels(name,url) -> Second regex function to parse a given list. Used to general livestreams xml type lists + getData(url,fanart) -> Get the item data such as iconimage, fanart, etc + getChannelItems(name,url,fanart) -> Function to grab the channel items + getItems(items,fanart) -> Function to grab the items from the xml + removeNonAscii(s) -> Function to remove non-ascii characters from the list + getSoup(url) -> uses beautifulsoup to parse a remote xml + addon_log(string) -> Simple log/print function + getRegexParsed(regexs, url) -> parse the regex expression + list_type(url) -> Checks if the list is xml or m3u + parse_m3u(url) -> Parses a m3u type list + + + +""" + +import urllib,urllib2,re,xbmcplugin,xbmcgui,xbmc,xbmcaddon,HTMLParser,time,datetime,os,xbmcvfs,sys +from BeautifulSoup import BeautifulStoneSoup, BeautifulSoup, BeautifulSOAP +from peertopeerutils.pluginxbmc import * +from peertopeerutils.webutils import * +from peertopeerutils.directoryhandle import * +from peertopeerutils.iofile import * + +""" + +Main Menu + +""" + +def xml_lists_menu(): + if settings.getSetting('sopcast-oficial') == "true": + addDir(translate(40116),"http://sopcast.org/chlist.xml",101,addonpath + art + 'xml_list_sopcast.png',2,True) + try: + if os.path.exists(os.path.join(pastaperfil,"Lists")): + dirs, files = xbmcvfs.listdir(os.path.join(pastaperfil,"Lists")) + for file in files: + f = open(os.path.join(pastaperfil,"Lists",file), "r") + string = f.read() + if xbmcvfs.exists(os.path.join(pastaperfil,"Lists-fanart",file.replace('.txt','.jpg'))):addDir("[B][COLOR orange]" + file.replace(".txt","") + "[/B][/COLOR]",string,101,addonpath + art + 'xml_lists.png',2,True,fan_art=os.path.join(pastaperfil,"Lists-fanart",file.replace('.txt','.jpg'))) + else: addDir("[B][COLOR orange]" + file.replace(".txt","") + "[/B][/COLOR]",string,101,addonpath + art + 'xml_lists.png',2,True) + except: pass + addDir(translate(40121),MainURL,107,addonpath + art + 'plus-menu.png',2,False) + #xbmc.executebuiltin("Container.SetViewMode(51)") + +""" + +Add a new list function + +""" + +def addlista(): + opcao= xbmcgui.Dialog().yesno(translate(40000), translate(40123),"","",translate(40124),translate(40125)) + if opcao: + dialog = xbmcgui.Dialog() + lista_xml = dialog.browse(int(1), translate(40186), 'myprograms','.xml|.m3u') + keybdois = xbmc.Keyboard("", translate(40130)) + keybdois.doModal() + if (keybdois.isConfirmed()): + searchname = keybdois.getText() + if searchname=='': sys.exit(0) + encode=urllib.quote(searchname) + if xbmcvfs.exists(os.path.join(pastaperfil,"Lists")): pass + else: xbmcvfs.mkdir(os.path.join(pastaperfil,"Lists")) + txt_name = searchname + ".txt" + save(os.path.join(pastaperfil,"Lists",txt_name),lista_xml) + mensagemok(translate(40000),translate(40129)) + xbmc.executebuiltin("XBMC.Container.Refresh") + else: + keyb = xbmc.Keyboard("", translate(40127)) + keyb.doModal() + if (keyb.isConfirmed()): + search = keyb.getText() + if search=='': sys.exit(0) + if "dropbox" in search and not "?dl=1" in search: search = search + '?dl=1' + if "xml" not in search.split(".")[-1] and "m3u" not in search.split(".")[-1]: mensagemok(translate(40000),translate(40128)); sys.exit(0) + else: + try: + code = get_page_source(search) + except: + mensagemok(translate(40000),translate(40128)) + sys.exit(0) + keybdois = xbmc.Keyboard("", translate(40130)) + keybdois.doModal() + if (keybdois.isConfirmed()): + searchname = keybdois.getText() + if searchname=='': sys.exit(0) + encode=urllib.quote(searchname) + if os.path.exists(os.path.join(pastaperfil,"Lists")): pass + else: xbmcvfs.mkdir(os.path.join(pastaperfil,"Lists")) + txt_name = searchname + ".txt" + save(os.path.join(pastaperfil,"Lists",txt_name),search) + mensagemok(translate(40000),translate(40129)) + xbmc.executebuiltin("XBMC.Container.Refresh") + +""" + +Remove a List + +""" + +def remove_list(name): + xbmcvfs.delete(name) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(40150), 1,addonpath+"/icon.png")) + xbmc.executebuiltin("Container.Refresh") + +""" + +Parsing functions + +""" +def list_type(url): + ltype = url.split('.')[-1] + if 'xml' in ltype: get_groups(url) + elif 'm3u' in ltype: parse_m3u(url) + else: pass + +def parse_m3u(url): + if "http" in url: content = get_page_source(url) + else: content = readfile(url) + match = re.compile('#EXTINF:.+?,(.*?)\n(.*?)(?:\r|\n)').findall(content) + for channel_name,stream_url in match: + if 'plugin://' in stream_url: + stream_url = 'XBMC.RunPlugin('+stream_url+')' + addDir(channel_name,stream_url,106,'',1,False) + elif 'sop://' in stream_url: + addDir(channel_name,stream_url,2,'',1,False) + elif ('acestream://' in stream_url) or ('.acelive' in stream_url) or ('.torrent' in stream_url): + addDir(channel_name,stream_url,1,'',1,False) + else: addLink(channel_name,stream_url,'') + + +def get_groups(url): + from xml.etree import ElementTree + try: + print("Sopcast xml-type list detected") + if "http" in url: + source = get_page_source(url) + save(os.path.join(pastaperfil,"working.xml"),source) + workingxml = os.path.join(pastaperfil,"working.xml") + else: + workingxml = url + groups = ElementTree.parse(workingxml).findall('.//group') + unname_group_index = 1 + LANGUAGE = "en" + for group in groups: + if group.attrib[LANGUAGE] == "": + group.attrib[LANGUAGE] = str(unname_group_index) + unname_group_index = unname_group_index + 1 + if re.sub('c','e',LANGUAGE) == LANGUAGE: + OTHER_LANG = re.sub('e','c',LANGUAGE) + else: + OTHER_LANG = re.sub('c','e',LANGUAGE) + if LANGUAGE == "cn": + try: + if len(group.attrib[OTHER_LANG]) > 0: + group.attrib[LANGUAGE] = group.attrib[OTHER_LANG] + unname_group_index = unname_group_index - 1 + except: + pass + if (group.find('.//channel')==None): continue + group_name=group.attrib[LANGUAGE] + try: + addDir_livestreams_common(group_name,url,102,addonpath + art + 'xml_list_sopcast.png',True) + except: pass + #xbmc.executebuiltin("Container.SetViewMode(51)") + except: + print("Other type of xml list") + getData(url,"") + +def get_channels(name,url): + from xml.etree import ElementTree + if url.startswith('http://'): + source = get_page_source(url) + else: + source = readfile(url) + save(os.path.join(pastaperfil,"working.xml"),source) + chlist_tree = ElementTree.parse(os.path.join(pastaperfil,"working.xml")) + LANGUAGE = "en" + groups = ElementTree.parse(os.path.join(pastaperfil,"working.xml")).findall('.//group') + for group in groups: + if group.attrib[LANGUAGE].encode('utf-8') == name: + channels = group.findall('.//channel') + for channel in channels: + try: + try: + title = channel.find('.//name').attrib['en'].encode('utf-8') + except: title = '' + if not title: + try: title = channel.find('.//name').attrib['cn'].encode('utf-8') + except: title = '' + if not title: + try: title = channel.find('.//name').text + except: title = '' + tipo = channel.find('.//stream_type').text + sop_address = channel.find('.//item').text + if not tipo: tipo = "N/A" + if not title: title = "N/A" + thumbnail = "" + try: + thumbnail = channel.find('.//thumbnail').text + except: pass + if sop_address: + if thumbnail == "": thumbnail = addonpath + art + 'sopcast_link.png' + try: addDir_livestreams_common('[B][COLOR orange]' + title + ' [/B][/COLOR](' + tipo +')',sop_address,2,thumbnail,False) + except:pass + else: pass + except: pass + else: pass + + +def getData(url,fanart): + soup = getSoup(url) + if len(soup('channels')) > 0: + channels = soup('channel') + for channel in channels: + name = channel('name')[0].string + thumbnail = channel('thumbnail')[0].string + if thumbnail == None: + thumbnail = '' + + try: + if not channel('fanart'): + if addon.getSetting('use_thumb') == "true": + fanArt = thumbnail + else: + fanArt = fanart + else: + fanArt = channel('fanart')[0].string + if fanArt == None: + raise + except: + fanArt = fanart + + try: + desc = channel('info')[0].string + if desc == None: + raise + except: + desc = '' + + try: + genre = channel('genre')[0].string + if genre == None: + raise + except: + genre = '' + + try: + date = channel('date')[0].string + if date == None: + raise + except: + date = '' + + try: + credits = channel('credits')[0].string + if credits == None: + raise + except: + credits = '' + + try: + addDir_livestreams(name.encode('utf-8', 'ignore'),url.encode('utf-8'),103,thumbnail,fanArt,desc,genre,date,credits,True) + except: + addon_log('There was a problem adding directory from getData(): '+name.encode('utf-8', 'ignore')) + else: + addon_log('No Channels: getItems') + getItems(soup('item'),fanart) + +def getChannelItems(name,url,fanart): + soup = getSoup(url) + channel_list = soup.find('channel', attrs={'name' : name.decode('utf-8')}) + items = channel_list('item') + try: + fanArt = channel_list('fanart')[0].string + if fanArt == None: + raise + except: + fanArt = fanart + for channel in channel_list('subchannel'): + name = channel('name')[0].string + try: + thumbnail = channel('thumbnail')[0].string + if thumbnail == None: + raise + except: + thumbnail = '' + try: + if not channel('fanart'): + if addon.getSetting('use_thumb') == "true": + fanArt = thumbnail + else: + fanArt = channel('fanart')[0].string + if fanArt == None: + raise + except: + pass + try: + desc = channel('info')[0].string + if desc == None: + raise + except: + desc = '' + + try: + genre = channel('genre')[0].string + if genre == None: + raise + except: + genre = '' + + try: + date = channel('date')[0].string + if date == None: + raise + except: + date = '' + + try: + credits = channel('credits')[0].string + if credits == None: + raise + except: + credits = '' + + try: + addDir_livestreams(name.encode('utf-8', 'ignore'),url.encode('utf-8'),3,thumbnail,fanArt,desc,genre,credits,date) + except: + addon_log('There was a problem adding directory - '+name.encode('utf-8', 'ignore')) + getItems(items,fanArt) + +def getItems(items,fanart): + total = len(items) + addon_log('Total Items: %s' %total) + for item in items: + try: + name = item('title')[0].string + if name is None: + name = 'unknown?' + except: + addon_log('Name Error') + name = '' + try: + if item('epg'): + if item.epg_url: + addon_log('Get EPG Regex') + epg_url = item.epg_url.string + epg_regex = item.epg_regex.string + epg_name = get_epg(epg_url, epg_regex) + if epg_name: + name += ' - ' + epg_name + elif item('epg')[0].string > 1: + name += getepg(item('epg')[0].string) + else: + pass + except: + addon_log('EPG Error') + + try: + url = [] + for i in item('link'): + if not i.string == None: + url.append(i.string) + if len(url) < 1: + raise + except: + addon_log('Error element, Passing:'+name.encode('utf-8', 'ignore')) + continue + + try: + thumbnail = item('thumbnail')[0].string + if thumbnail == None: + raise + except: + thumbnail = '' + try: + if not item('fanart'): + if addon.getSetting('use_thumb') == "true": + fanArt = thumbnail + else: + fanArt = fanart + else: + fanArt = item('fanart')[0].string + if fanArt == None: + raise + except: + fanArt = fanart + try: + desc = item('info')[0].string + if desc == None: + raise + except: + desc = '' + + try: + genre = item('genre')[0].string + if genre == None: + raise + except: + genre = '' + + try: + date = item('date')[0].string + if date == None: + raise + except: + date = '' + + regexs = None + if item('regex'): + try: + regexs = {} + for i in item('regex'): + regexs[i('name')[0].string] = {} + regexs[i('name')[0].string]['expre'] = i('expres')[0].string + regexs[i('name')[0].string]['page'] = i('page')[0].string + try: + regexs[i('name')[0].string]['refer'] = i('referer')[0].string + except: + addon_log("Regex: -- No Referer --") + try: + regexs[i('name')[0].string]['agent'] = i('agent')[0].string + except: + addon_log("Regex: -- No User Agent --") + regexs = urllib.quote(repr(regexs)) + except: + regexs = None + addon_log('regex Error: '+name.encode('utf-8', 'ignore')) + + try: + if "RunPlugin" in url[0]: + try: + addDir_livestreams(name.encode('utf-8', 'ignore'),url[0],106,thumbnail,fanArt,desc,genre,"credits",date) + except: + match = re.compile("&name=(.+?)\)").findall(url[0].replace(";","")) + if match: + try: + addDir_livestreams(name.encode('utf-8', 'ignore'),removeNonAscii(url[0]),106,thumbnail,fanArt,desc,genre,credits,date) + except: + try: + addDir_livestreams(removeNonAscii(name.encode('utf-8', 'ignore')),removeNonAscii(url[0].replace(";","")),106,thumbnail,fanArt,desc,genre,credits,date) + except: + addon_log('There was a problem adding item - '+name.encode('utf-8', 'ignore')) + else: + addon_log('There was a problem adding item - '+name.encode('utf-8', 'ignore')) + + else: + if ('acestream://' in url[0]) or ('.acelive' in url[0]) or ('.torrent' in url[0]): + if 'plugin://' not in url[0]: + addDir_livestreams(name.encode('utf-8', 'ignore'),url[0],1,thumbnail,fanArt,desc,genre,"credits",date) + else: + addLink_livestreams(url[0].replace(';',''),name.encode('utf-8', 'ignore'),thumbnail,fanArt,desc,genre,date,True,None,regexs,total) + elif 'sop://' in url[0]: + if 'plugin://' not in url[0]: + addDir_livestreams(name.encode('utf-8', 'ignore'),url[0],2,thumbnail,fanArt,desc,genre,"credits",date) + else: + addLink_livestreams(url[0].replace(';',''),name.encode('utf-8', 'ignore'),thumbnail,fanArt,desc,genre,date,True,None,regexs,total) + else: addLink_livestreams(url[0].replace(';',''),name.encode('utf-8', 'ignore'),thumbnail,fanArt,desc,genre,date,True,None,regexs,total) + except: + addon_log('There was a problem adding item - '+name.encode('utf-8', 'ignore')) + +def removeNonAscii(s): return "".join(filter(lambda x: ord(x)<128, s)) + +def getSoup(url): + if url.startswith('http://'): + data = makeRequest(url) + else: + if xbmcvfs.exists(url): + if url.startswith("smb://") or url.startswith("nfs://"): + copy = xbmcvfs.copy(url, os.path.join(profile, 'temp', 'sorce_temp.txt')) + if copy: + data = open(os.path.join(profile, 'temp', 'sorce_temp.txt'), "r").read() + xbmcvfs.delete(os.path.join(profile, 'temp', 'sorce_temp.txt')) + else: + addon_log("failed to copy from smb:") + else: + data = open(url, 'r').read() + else: + addon_log("Soup Data not found!") + return + return BeautifulSOAP(data, convertEntities=BeautifulStoneSoup.XML_ENTITIES) + +def addon_log(string): + print(string) + +def getRegexParsed(regexs, url): + regexs = eval(urllib.unquote(regexs)) + cachedPages = {} + doRegexs = re.compile('\$doregex\[([^\]]*)\]').findall(url) + for k in doRegexs: + if k in regexs: + m = regexs[k] + if m['page'] in cachedPages: + link = cachedPages[m['page']] + else: + req = urllib2.Request(m['page']) + req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; rv:14.0) Gecko/20100101 Firefox/14.0.1') + if 'refer' in m: + req.add_header('Referer', m['refer']) + if 'agent' in m: + req.add_header('User-agent', m['agent']) + response = urllib2.urlopen(req) + link = response.read() + response.close() + cachedPages[m['page']] = link + reg = re.compile(m['expre']).search(link) + url = url.replace("$doregex[" + k + "]", reg.group(1).strip()) + item = xbmcgui.ListItem(path=url) + xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, item) diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/livestreams.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/livestreams.pyo new file mode 100644 index 0000000000000000000000000000000000000000..723711b3024002cb5977073e7e967dde1b1eb9b1 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/livestreams.pyo differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/__init__.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1337b40118c9ac14e6044d27a4edd7addc1de5a6 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/__init__.py @@ -0,0 +1,7 @@ +""" p2p-streams + 2014 enen92 fightnight""" + + + + + diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..3ba80e38089c0ffaee9374bde4171536a0d02605 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/__init__.pyo differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/arenavision/__init__.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/arenavision/__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/arenavision/cleaner.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/arenavision/cleaner.py new file mode 100644 index 0000000000000000000000000000000000000000..51efbbd789350472107177db18c30987d619a16e --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/arenavision/cleaner.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + +""" +This plugin is 3rd party and not part of p2p-streams addon + +Arenavision.in + +""" + + +def clean(text): + text = text.replace(u'\xda','U').replace(u'\xc9','E').replace(u'\xd3','O').replace(u'\xd1','N').replace(u'\xcd','I').replace(u'\xc1','A') + return text diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/arenavision/icon.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/arenavision/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e319a8c54719e05d6e15abb66d018f3ca03f0141 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/arenavision/icon.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/arenavision/main.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/arenavision/main.py new file mode 100644 index 0000000000000000000000000000000000000000..64485067beb57347190434e124397cabf7d3c0dd --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/arenavision/main.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- + +""" +This plugin is 3rd party and not part of p2p-streams addon + +Arenavision.in + +""" +import sys,os,requests +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 +from cleaner import * + +base_url = "http://www.arenavision.in" + +def module_tree(name,url,iconimage,mode,parser,parserfunction): + if not parserfunction: arenavision_menu() + elif parserfunction == "arenavision_streams": arenavision_streams(name,url) + elif parserfunction == "arenavision_schedule": arenavision_schedule(url) + elif parserfunction == "arenavision_chooser": arenavision_chooser(url) + + + +def arenavision_menu(): + headers = { + "Cookie" : "beget=begetok; has_js=1;" + } + try: + source = requests.get(base_url,headers=headers).text + except: source="";xbmcgui.Dialog().ok(translate(40000),translate(40128)) + if source: + match = re.compile('leaf">(.+?)', source, re.DOTALL) + for event in match: + eventmatch = re.compile('(\d+)/(\d+)/(\d+) (.+?):(.+?) CET (.+?)<').findall(event) + for dia,mes,year,hour,minute,evento in eventmatch: + try: + import datetime + from peertopeerutils import pytzimp + d = pytzimp.timezone(str(pytzimp.timezone('Europe/Madrid'))).localize(datetime.datetime(2000 + int(year), int(mes), int(dia), hour=int(hour), minute=int(minute))) + timezona= settings.getSetting('timezone_new') + my_location=pytzimp.timezone(pytzimp.all_timezones[int(timezona)]) + convertido=d.astimezone(my_location) + fmt = "%d-%m-%y %H:%M" + time=convertido.strftime(fmt) + except: + time='N/A' + event_array = evento.split('/') + event_name = '' + event_channels = [] + i = 1 + for parc in event_array: + if 'AV' in parc: + event_channels.append(parc) + try: addDir('[B][COLOR red]' + time + '[/B][/COLOR] ' + removeNonAscii(clean(event_array[0])),str(event_channels),401,os.path.join(current_dir,"icon.png"),1,False,parser="arenavision",parserfunction="arenavision_chooser") + except:pass + + + +def arenavision_chooser(url): + dictionary = eval(url) + index = xbmcgui.Dialog().select("On...", dictionary) + if index > -1: + headers = { + "Cookie" : "beget=begetok; has_js=1;" + } + try: + source = requests.get(base_url,headers=headers).text + except: source="";xbmcgui.Dialog().ok(translate(40000),translate(40128)) + if source: + match = re.compile('leaf">(.+?)Gimnasia La PlataGimnasia La Plata +#
vs.
+#
Nueva ChicagoNueva Chicago
+#
+# +#Online + + +def module_tree(name,url,iconimage,mode,parser,parserfunction): + if not parserfunction: livefootballvideo_events() + elif parserfunction == 'sources': livefootballvideo_sources(url) + +def livefootballvideo_events(): + try: + source = get_page_source(base_url) + except: source ="";xbmcgui.Dialog().ok(translate(40000),translate(40128)) + if source: + match = re.compile('(.+?)\n
\n.+?(.+?).+?(.+?)/span>.+?\n
<.+?(.+?)
\n.+?\n.+?class=".+?">(.+?).+?\n.+?\n\n(.+?) ').findall(source) + for comp,timetmp,datetmp,home,away,url,live in match: + mes_dia = re.compile(', (.+?) (.+?)<').findall(datetmp) + for mes,dia in mes_dia: + dia = re.findall('\d+', dia) + month = translate_months(mes) + hora_minuto = re.compile('(\d+):(\d+)').findall(timetmp) + try: + import datetime + from peertopeerutils import pytzimp + d = pytzimp.timezone(str(pytzimp.timezone('Atlantic/Azores'))).localize(datetime.datetime(2014, int(month), int(dia[0]), hour=int(hora_minuto[0][0]), minute=int(hora_minuto[0][1]))) + timezona= settings.getSetting('timezone_new') + my_location=pytzimp.timezone(pytzimp.all_timezones[int(timezona)]) + convertido=d.astimezone(my_location) + fmt = "%d/%m %H:%M" + time=convertido.strftime(fmt) + + if "Online" in live: time = '[B][COLOR green](Online)[/B][/COLOR]' + else: time = '[B][COLOR orange]' + time + '[/B][/COLOR]' + addDir(time + ' - [B]('+comp+')[/B] ' + home + ' vs ' + away,url,401,os.path.join(addonpath,'resources','art','football.png'),len(match),True,parser='livefootballvideo',parserfunction='sources') + except: addDir('[B][COLOR orange]' + timetmp + ' ' + datetmp + '[/B][/COLOR] - [B]('+comp+')[/B] ' + home + ' vs ' + away,url,401,os.path.join(addonpath,'resources','art','football.png'),len(match),True,parser='livefootballvideo',parserfunction='sources') + + +def livefootballvideo_sources(url): + print url + try: + source = get_page_source(url) + except: source = ""; xbmcgui.Dialog().ok(translate(40000),translate(40128)) + if source: + match = re.compile("(.+?)\n(.+?)(.+?)
', source, re.DOTALL) + number_of_items= len(items) + for item in reversed(items): + data = re.compile('
(.+?)
').findall(item) + try: + check = re.compile(">.+? (.+?):(.+?)").findall(data[-1].replace("color:","")) + if not check and "Online" not in data[-1]:pass + else: + data_item = data[-1].replace("","").replace("","").replace('','').replace("","") + url = re.compile('
').findall(item) + teams = re.compile('/.+?-(.+?).html').findall(url[0]) + try: + match = re.compile('(.+?) (.+?) (.+?):(.*)').findall(data_item) + import datetime + from peertopeerutils import pytzimp + timezona= settings.getSetting('timezone_new') + d = pytzimp.timezone(str(pytzimp.timezone('Europe/Moscow'))).localize(datetime.datetime(2014, 6, int(match[0][0]), hour=int(match[0][2]), minute=int(match[0][3]))) + my_place=pytzimp.timezone(pytzimp.all_timezones[int(timezona)]) + convertido=d.astimezone(my_place) + fmt = "%d %H:%M" + time=convertido.strftime(fmt) + addDir("[B][COLOR orange]("+translate(600012)+time+")[/COLOR][/B] "+teams[0],url[0],401,os.path.join(current_dir,'icon.png'),number_of_items,True,parser="livefootballws",parserfunction="streams") + except: + if '' not in data_item: + addDir("[B][COLOR green]("+data_item+")[/COLOR][/B] "+teams[0],url[0],401,os.path.join(current_dir,'icon.png'),number_of_items,True,parser="livefootballws",parserfunction="streams") + else: pass + except: pass + +def livefootballws_streams(url): + try: + source = mechanize_browser(url) + except: source = ""; xbmcgui.Dialog().ok(translate(40000),translate(40128));sys.exit(0) + if source: + items = re.findall('(.*?)', 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').findall(item) + channel_info_arr = re.compile('(.+?)').findall(item) + try: + channel = channel_info_arr[-4].replace('','').replace('','') + except: channel = 'N/A' + if "sop://" in match[-1]: + try: + addDir("[B][COLOR orange][SopCast] [/COLOR] "+channel+"[/B] ("+stream_quality[0]+' Kbs)',match[-1],2,os.path.join(current_dir,'icon.png'),number_of_items,False) + except: pass + elif "acestream://" in match[-1]: + link = re.compile("acestream://(.*)").findall(match[-1]) + try: + addDir("[B][COLOR orange][Acestream] [/COLOR] "+channel.replace('
','')+"[/B] ("+stream_quality[0]+' Kbs)',link[0],1,os.path.join(current_dir,'icon.png'),number_of_items,False) + except: pass + elif "torrentstream" in match[-1]: + link = re.compile("http://torrentstream.org/stream/test.php\?id=(.*)").findall(match[-1]) + try: + addDir("[B][COLOR orange][Acestream] [/COLOR] "+channel.replace('
','')+"[/B] ("+stream_quality[0]+' Kbs)',link[0],1,os.path.join(current_dir,'icon.png'),number_of_items,False) + except: pass + else:pass + else: + xbmcgui.Dialog().ok(translate(40000),translate(40022)) + sys.exit(0) + +def get_page_source_cookie(url,cookie): + import urllib2 + req = urllib2.Request(url) + req.add_header('User-Agent , Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/41.0.2272.76 Chrome/41.0.2272.76 Safari/537.36', user_agent) + req.add_header('Cookie', cookie) + req.add_header('Host','livefootball.ws|cloudflare-nginx') + response = urllib2.urlopen(req) + link=response.read() + if response.headers.get("Content-Encoding", "") == "gzip": + import zlib + data = zlib.decompressobj(16 + zlib.MAX_WBITS).decompress(link) + else: + data = link + response.close() + return data \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/livefootballws/main.pyc b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/livefootballws/main.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1edf701096739dfa3e0ddec32208bd711431e770 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/livefootballws/main.pyc differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/livefootballws/module.cfg b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/livefootballws/module.cfg new file mode 100644 index 0000000000000000000000000000000000000000..f3556a5dc2732199c7c9bbc378eb373be1d04dc5 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/livefootballws/module.cfg @@ -0,0 +1 @@ +{ 'name' : 'Livefootball.ws'} diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/parsers.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/parsers.py new file mode 100644 index 0000000000000000000000000000000000000000..18a48530eb2a1142effdbc8bfe516419b94efa52 --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/parsers.py @@ -0,0 +1,314 @@ +# -*- coding: utf-8 -*- +""" p2p-streams (c) 2014 enen92 fightnight + +This file handles all the website parsers addon engine + +Functions: + + addon_parsers_menu() -> Lists all installed parsers + add_new_parser() -> Function to add a new parser + remove_parser(iconimage) -> Remove a parser + sync_parser() -> Syncs the parser code with remote repository + runscript() -> Executes a remote python script + clear_parser_trace() -> Remove all traces of parsers instalation + parser_check() -> Function to check if parser folder is empty and info is in userdata + +""" + + +import os,sys,xbmc,xbmcgui,xbmcvfs,re,datetime,time,shutil +base_dir = os.path.dirname(os.path.realpath(__file__)) +core_dir = os.path.dirname(os.path.realpath(__file__)).replace('parsers','') +sys.path.append(core_dir) +from peertopeerutils.webutils import * +from peertopeerutils.directoryhandle import addDir,addLink +from peertopeerutils.pluginxbmc import * +from peertopeerutils.iofile import * + +parser_folder = os.path.join(pastaperfil,'parser') +parser_core_folder = os.path.join(addonpath,'resources','core','parsers') +parser_packages_folder = os.path.join(pastaperfil,'parser-packages') + + +def addon_parsers_menu(): + if settings.getSetting('parser_disclaimer_three') == "true": + opcao= xbmcgui.Dialog().yesno(translate(40000),translate(70004),translate(70005),translate(70006)) + if opcao: settings.setSetting('parser_disclaimer_three',"false") + dirs,files = xbmcvfs.listdir(base_dir) + if not dirs: + dirpackages,filespackages = xbmcvfs.listdir(parser_packages_folder) + if filespackages: + for fich in filespackages: + shutil.copyfile(os.path.join(parser_packages_folder,fich), os.path.join(parser_core_folder,fich)) + xbmc.sleep(100) + import tarfile + if tarfile.is_tarfile(os.path.join(parser_core_folder,fich)): + download_tools().extract(os.path.join(parser_core_folder,fich),parser_core_folder) + download_tools().remove(os.path.join(parser_core_folder,fich)) + else: + dirsuserdata,files = xbmcvfs.listdir(parser_folder) + for fich in files: + dictionary_module = eval(readfile(os.path.join(parser_folder,fich))) + if "url" in dictionary_module.keys(): + add_new_parser(dictionary_module["url"]) + else: + xbmcvfs.copy(os.path.join(parser_packages_folder,fich.replace('.txt','.tar.gz')),os.path.join(parser_core_folder,fich.replace('.txt','.tar.gz'))) + import tarfile + if tarfile.is_tarfile(os.path.join(parser_core_folder,fich.replace('.txt','.tar.gz'))): + download_tools().extract(os.path.join(parser_core_folder,fich.replace('.txt','.tar.gz')),parser_core_folder) + download_tools().remove(os.path.join(parser_core_folder,fich.replace('.txt','.tar.gz'))) + dirs,files = xbmcvfs.listdir(base_dir) + parser_dict = {} + for module in dirs: + module_dir = os.path.join(base_dir,module) + module_cfg = os.path.join(module_dir,"module.cfg") + module_icon = os.path.join(module_dir,"icon.png") + module_fanart = os.path.join(module_dir,"fanart.jpg") + if xbmcvfs.exists(module_icon): thumbnail = module_icon + else: thumbnail = 'os.path.join(module_dir,"")' + if xbmcvfs.exists(module_fanart): fanart = module_fanart + else: fanart = "%s/fanart.jpg"%settings.getAddonInfo("path") + if xbmcvfs.exists(module_cfg): + cfg = readfile(module_cfg) + try: + cfg = eval(cfg) + module_name = cfg['name'] + except: module_name = None + if module_name: + parser_dict[module_name] = [module,thumbnail,fanart] + total_parsers = len(parser_dict.keys()) + if settings.getSetting('parser_sync') == "true": + try:t1 = datetime.datetime.strptime(settings.getSetting("parsers_last_sync_two"), "%Y-%m-%d %H:%M:%S.%f") + except:t1 = datetime.datetime.fromtimestamp(time.mktime(time.strptime(settings.getSetting("parsers_last_sync_two"), "%Y-%m-%d %H:%M:%S.%f"))) + t2 = datetime.datetime.now() + hoursList = [10, 15, 20, 24] + interval = int(settings.getSetting("parser_sync_cron")) + update = abs(t2 - t1) > datetime.timedelta(hours=hoursList[interval]) + if update: + sync_parser() + settings.setSetting('parsers_last_sync_two',value=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")) + + for key in sorted(parser_dict.keys()): + addDir(key,MainURL,401,parser_dict[key][1],total_parsers,True,parser=parser_dict[key][0],fan_art=parser_dict[key][2]) + addDir(translate(400011),MainURL,402,addonpath + art + 'plus-menu.png',2,False) + +def add_new_parser(url): + if not url: + opcao= xbmcgui.Dialog().yesno(translate(40000),translate(400012),"","",translate(40124),translate(40125)) + if opcao: + dialog = xbmcgui.Dialog() + parser_tball = dialog.browse(int(1), translate(400013), 'myprograms','.tar.gz') + if '.tar.gz' in parser_tball: + parser_name = parser_tball.split('/') + if len(parser_name) == 1: parser_name = parser_tball.split('\\') + parser_name=parser_name[-1].replace('.tar.gz','') + print("the list is: " + parser_tball,parser_name) + future_parser_tball = os.path.join(parser_folder,parser_name+'.tar.gz') + xbmcvfs.copy(parser_tball,future_parser_tball) + if not xbmcvfs.exists(os.path.join(pastaperfil,"parser-packages")): xbmcvfs.mkdir(os.path.join(pastaperfil,"parser-packages")) + parser_package_directory_file = os.path.join(pastaperfil,"parser-packages",parser_name+'.tar.gz') + xbmcvfs.copy(future_parser_tball,parser_package_directory_file) + import tarfile + if tarfile.is_tarfile(future_parser_tball): + download_tools().extract(future_parser_tball,parser_core_folder) + xbmc.sleep(500) + download_tools().remove(future_parser_tball) + module_file = os.path.join(parser_folder,parser_name + '.txt') + text = str({}) + save(module_file,str(text)) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(400014),1,addonpath+"/icon.png")) + xbmc.executebuiltin("Container.Refresh") + else: + mensagemok(translate(40000),translate(400015)) + sys.exit(0) + else: + keyb = xbmc.Keyboard("", translate(400016)) + keyb.doModal() + if (keyb.isConfirmed()): + search = keyb.getText() + if search=='': sys.exit(0) + if '.tar.gz' not in search: mensagemok(translate(40000),translate(400017)); sys.exit(0) + else: + md5checksum = search.replace('.tar.gz','.md5') + modulename = search.split('/')[-1].replace('.tar.gz','').replace('?raw=true','').replace('?dl=1','') + md5_up=url_isup(md5checksum) + module_up=url_isup(search) + if not xbmcvfs.exists(parser_folder): xbmcvfs.mkdir(parser_folder) + text = {} + if module_up: text['url'] = search + if md5_up: text['md5'] = get_page_source(md5checksum) + if text: + try: + module_file = os.path.join(parser_folder,modulename + '.txt') + module_tar_location = os.path.join(parser_core_folder,modulename+'tar.gz') + save(module_file,str(text)) + download_tools().Downloader(search,module_tar_location,translate(400018),translate(40000)) + import tarfile + if tarfile.is_tarfile(module_tar_location): + download_tools().extract(module_tar_location,parser_core_folder) + xbmc.sleep(500) + download_tools().remove(module_tar_location) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000),translate(400014),1,addonpath+"/icon.png")) + xbmc.executebuiltin("Container.Refresh") + except: mensagemok(translate(40000),translate(400024)) + else: + mensagemok(translate(40000),translate(400015)) + sys.exit(0) + else: + modulename = url.split('/')[-1].replace('.tar.gz','').replace('?raw=true','').replace('?dl=1','') + if not xbmcvfs.exists(parser_folder): xbmcvfs.mkdir(parser_folder) + if not xbmcvfs.exists(parser_packages_folder): xbmcvfs.mkdir(parser_packages_folder) + if xbmcvfs.exists(os.path.join(parser_folder,modulename + '.txt')): + texto = readfile(os.path.join(parser_folder,modulename + '.txt')) + texto = eval(texto) + if type(texto) == dict: + if 'md5_url' in texto.keys(): md5checksum = texto['md5_url'] + else: md5checksum = url.replace('.tar.gz','.md5') + else: md5checksum = url.replace('.tar.gz','.md5') + else: md5checksum = url.replace('.tar.gz','.md5') + md5_up=url_isup(md5checksum) + module_up=url_isup(url) + text = {} + if module_up: text['url'] = url + if md5_up: + text['md5'] = get_page_source(md5checksum) + text['md5_url'] = md5checksum + if text: + module_file = os.path.join(parser_folder,modulename + '.txt') + module_tar_location = os.path.join(parser_core_folder,modulename+'.tar.gz') + module_parser_backup = os.path.join(parser_packages_folder,modulename+'.tar.gz') + save(module_file,str(text)) + download_tools().Downloader(url,module_tar_location,translate(400018),translate(40000)) + import tarfile + if tarfile.is_tarfile(module_tar_location): + download_tools().extract(module_tar_location,parser_core_folder) + shutil.copyfile(module_tar_location, module_parser_backup) + xbmc.sleep(500) + download_tools().remove(module_tar_location) + print(str(modulename) + " : Module installed sucessfully") + return + +def remove_parser(iconimage): + parser_plugin = iconimage.split('/') + if len(parser_plugin) == 1: + parser_plugin=iconimage.split("\\") + parser_plugin = parser_plugin[-2] + xbmcvfs.delete(os.path.join(parser_folder,parser_plugin +'.txt')) + module_folder = os.path.join(parser_core_folder,parser_plugin) + module_package_backup = os.path.join(parser_packages_folder,parser_plugin + '.tar.gz') + dirs, files = xbmcvfs.listdir(module_folder) + for file in files: + xbmcvfs.delete(os.path.join(module_folder,file)) + import shutil + shutil.rmtree(module_folder) + try: xbmcvfs.delete(module_package_backup) + except: pass + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000), translate(400019),1,addonpath+"/icon.png")) + xbmc.executebuiltin("Container.Refresh") + +def sync_parser(): + dirs, files = xbmcvfs.listdir(parser_folder) + if files: + mensagemprogresso.create(translate(40000),translate(400020),"") + mensagemprogresso.update(0,translate(400020),"") + xbmc.sleep(1000) + number_of_files = len(files) + i = 0 + for file in files: + i += 1 + error = False + mensagemprogresso.update(int(float(i)/number_of_files*100),translate(400020),file.replace('.txt',''),translate(400021)) + module_file = os.path.join(parser_folder,file) + text = eval(readfile(module_file)) + if not text: pass + else: + if 'url' and 'md5' in text.keys(): + installed_md5 = text['md5'] + module_url = text['url'] + if 'md5_url' in text.keys(): module_md5 = text['md5_url'] + else: module_md5 = text['url'].replace('.tar.gz','.md5') + try: current_md5 = get_page_source(module_md5) + except: current_md5 = installed_md5; error = True + if current_md5 != installed_md5: + print('Module requires update ' + str(file.replace('.txt','')) + ' ' + str(installed_md5) + ' != ' + str(current_md5)) + mensagemprogresso.update(int(float(i)/number_of_files*100),translate(400020),file.replace('.txt',''),translate(400025)) + add_new_parser(module_url) + mensagemprogresso.create(translate(40000),translate(400020),file.replace('.txt',''),translate(400022)) + else: + print('Module is up to date: ' + str(file.replace('.txt',''))) + if error == False: message = translate(400023) + else: message = translate(400024) + mensagemprogresso.update(int(float(i)/number_of_files*100),translate(400020),file.replace('.txt',''),message) + xbmc.sleep(1000) + try: + mensagemprogresso.update(100,"","") + mensagemprogresso.close() + except: pass + settings.setSetting('parsers_last_sync_two',value=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")) + return + +def sync_single_parser(parser): + parser_file = os.path.join(parser_folder,parser+'.txt') + if xbmcvfs.exists(parser_file): + string = eval(readfile(parser_file)) + if string: + add_new_parser(string['url']) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000),translate(400026),1,addonpath+"/icon.png")) + +def runscript(): + if not xbmcvfs.exists(pastaperfil): xbmcvfs.mkdir(pastaperfil) + keyb = xbmc.Keyboard("", translate(400016)) + keyb.doModal() + if (keyb.isConfirmed()): + search = keyb.getText() + if search=='': sys.exit(0) + else: + try: + download_tools().Downloader(search,os.path.join(pastaperfil,'rscript.py'),translate(400027),translate(40000)) + xbmc.executebuiltin('XBMC.RunScript('+os.path.join(pastaperfil,'rscript.py')+')') + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000),translate(400028),1,addonpath+"/icon.png")) + except: mensagemok(translate(40000),translate(40128)) + +def clear_parser_trace(): + if not xbmcvfs.exists(pastaperfil): xbmcvfs.mkdir(pastaperfil) + if not xbmcvfs.exists(parser_packages_folder): xbmcvfs.mkdir(parser_packages_folder) + if not xbmcvfs.exists(parser_folder): xbmcvfs.mkdir(parser_folder) + dirs,files = xbmcvfs.listdir(parser_core_folder) + import shutil + for directory in dirs: + shutil.rmtree(os.path.join(parser_core_folder,directory)) + dirs,files = xbmcvfs.listdir(parser_packages_folder) + for fich in files: + xbmcvfs.delete(os.path.join(parser_packages_folder,fich)) + dirs,files = xbmcvfs.listdir(parser_folder) + for fich in files: + xbmcvfs.delete(os.path.join(parser_folder,fich)) + xbmc.executebuiltin("Notification(%s,%s,%i,%s)" % (translate(40000),translate(70007),1,addonpath+"/icon.png")) + +def parser_check(): + dirs,files = xbmcvfs.listdir(base_dir) + if not dirs: + dirpackages,filespackages = xbmcvfs.listdir(parser_packages_folder) + if filespackages: + for fich in filespackages: + shutil.copyfile(os.path.join(parser_packages_folder,fich), os.path.join(parser_core_folder,fich)) + xbmc.sleep(100) + import tarfile + if tarfile.is_tarfile(os.path.join(parser_core_folder,fich)): + download_tools().extract(os.path.join(parser_core_folder,fich),parser_core_folder) + download_tools().remove(os.path.join(parser_core_folder,fich)) + else: + dirsuserdata,files = xbmcvfs.listdir(parser_folder) + for fich in files: + dictionary_module = eval(readfile(os.path.join(parser_folder,fich))) + if "url" in dictionary_module.keys(): + add_new_parser(dictionary_module["url"]) + else: + xbmcvfs.copy(os.path.join(parser_packages_folder,fich.replace('.txt','.tar.gz')),os.path.join(parser_core_folder,fich.replace('.txt','.tar.gz'))) + import tarfile + if tarfile.is_tarfile(os.path.join(parser_core_folder,fich.replace('.txt','.tar.gz'))): + download_tools().extract(os.path.join(parser_core_folder,fich.replace('.txt','.tar.gz')),parser_core_folder) + download_tools().remove(os.path.join(parser_core_folder,fich.replace('.txt','.tar.gz'))) + else: pass + return + diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/parsers.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/parsers.pyo new file mode 100644 index 0000000000000000000000000000000000000000..0b34ded59ec82af457c7b4ec28821a6cbc68f6d8 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/parsers.pyo differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/__init__.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/__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/rojadirecta/__init__.pyo b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..079a4e5bc2a2150b1bea5fa0772b90577cad9ef3 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/__init__.pyo differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/icon.png b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fbdd806c5ff244df40aa4b17bad69c299675f845 Binary files /dev/null and b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/icon.png differ diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/main.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/main.py new file mode 100644 index 0000000000000000000000000000000000000000..03a35cea3695929af426df5150a7b190c05d992c --- /dev/null +++ b/packages/mediacenter/kodi/config/base-addons/plugin.video.p2p-streams/resources/core/parsers/rojadirecta/main.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- + +""" +This plugin is 3rd party and not part of p2p-streams addon + +Rojadirecta.me +""" + +import sys,os,requests +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://rojadirecta.my.to/" + +def module_tree(name,url,iconimage,mode,parser,parserfunction): + if not parserfunction: rojadirecta_events() + elif parserfunction == 'resolve_and_play': rojadirecta_resolver(name,url) + +def rojadirecta_events(): + try: + source = get_page_source(base_url) + except: source = "";xbmcgui.Dialog().ok(translate(40000),translate(40128)) + if source: + match = re.findall('([^<]+)(.*?)',source,re.DOTALL) + for id,time,eventtmp in match: + try: + import datetime + from peertopeerutils import pytzimp + d = pytzimp.timezone(str(pytzimp.timezone('Europe/Madrid'))).localize(datetime.datetime(2014, 6, 7, hour=int(time.split(':')[0]), minute=int(time.split(':')[-1]))) + timezona= settings.getSetting('timezone_new') + my_location=pytzimp.timezone(pytzimp.all_timezones[int(timezona)]) + convertido=d.astimezone(my_location) + fmt = "%H:%M" + time=convertido.strftime(fmt) + except:pass + eventnospanish = re.compile('(.+?)').findall(eventtmp) + if eventnospanish: + for spanishtitle in eventnospanish: + eventtmp = eventtmp.replace('' + spanishtitle + '','') + eventclean=eventtmp.replace('','').replace('','').replace(' ()','').replace('','').replace('','') + matchdois = re.compile('(.*)\s*(.*?)\s*').findall(eventclean) + for sport,event in matchdois: + express = '.*?\s*' + streams = re.findall(express,source,re.DOTALL) + for streamdata in streams: + p2pstream = re.compile('P2P\n.+?([^<]*)\n.+?([^<]*)\n.+?([^<]*)\n.+?([^<]*)\n.+?","")+"][/B]-"+canal.replace("<","").replace(">","")+" - ("+language.replace("<","").replace(">","")+") - ("+qualidade.replace("<","").replace(">","")+" Kbs)",urltmp.replace("goto/",""),401,thumbnail,43,False,parser='rojadirecta',parserfunction='resolve_and_play') + p2pdirect = re.compile('P2P(.+?).+?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. - https://github.com/moneymaker365/plugin.video.vevo - - \ 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','DEBU​G_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','cook​ies') - 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','DEBU​G_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 = '' % 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'. -

FooBar

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' - tag should - implicitly close the previous tag within the same
    ** 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 " is not real!" % name - self.handle_data('' % 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("" % 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
    , - but not close a tag in another table. - -
    BlahBlah - should be transformed into: -
    BlahBlah - 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 "" % (self.id, self.text) - - -def _get_label(attrs): - text = attrs.get("__label") - if text is not None: - return Label(text) - else: - return None - -class Control: - """An HTML form control. - - An HTMLForm contains a sequence of Controls. The Controls in an HTMLForm - are accessed using the HTMLForm.find_control method or the - HTMLForm.controls attribute. - - Control instances are usually constructed using the ParseFile / - ParseResponse functions. If you use those functions, you can ignore the - rest of this paragraph. A Control is only properly initialised after the - fixup method has been called. In fact, this is only strictly necessary for - ListControl instances. This is necessary because ListControls are built up - from ListControls each containing only a single item, and their initial - value(s) can only be known after the sequence is complete. - - The types and values that are acceptable for assignment to the value - attribute are defined by subclasses. - - If the disabled attribute is true, this represents the state typically - represented by browsers by 'greying out' a control. If the disabled - attribute is true, the Control will raise AttributeError if an attempt is - made to change its value. In addition, the control will not be considered - 'successful' as defined by the W3C HTML 4 standard -- ie. it will - contribute no data to the return value of the HTMLForm.click* methods. To - enable a control, set the disabled attribute to a false value. - - If the readonly attribute is true, the Control will raise AttributeError if - an attempt is made to change its value. To make a control writable, set - the readonly attribute to a false value. - - All controls have the disabled and readonly attributes, not only those that - may have the HTML attributes of the same names. - - On assignment to the value attribute, the following exceptions are raised: - TypeError, AttributeError (if the value attribute should not be assigned - to, because the control is disabled, for example) and ValueError. - - If the name or value attributes are None, or the value is an empty list, or - if the control is disabled, the control is not successful. - - Public attributes: - - type: string describing type of control (see the keys of the - HTMLForm.type2class dictionary for the allowable values) (readonly) - name: name of control (readonly) - value: current value of control (subclasses may allow a single value, a - sequence of values, or either) - disabled: disabled state - readonly: readonly state - id: value of id HTML attribute - - """ - def __init__(self, type, name, attrs, index=None): - """ - type: string describing type of control (see the keys of the - HTMLForm.type2class dictionary for the allowable values) - name: control name - attrs: HTML attributes of control's HTML element - - """ - raise NotImplementedError() - - def add_to_form(self, form): - self._form = form - form.controls.append(self) - - def fixup(self): - pass - - def is_of_kind(self, kind): - raise NotImplementedError() - - def clear(self): - raise NotImplementedError() - - def __getattr__(self, name): raise NotImplementedError() - def __setattr__(self, name, value): raise NotImplementedError() - - def pairs(self): - """Return list of (key, value) pairs suitable for passing to urlencode. - """ - return [(k, v) for (i, k, v) in self._totally_ordered_pairs()] - - def _totally_ordered_pairs(self): - """Return list of (key, value, index) tuples. - - Like pairs, but allows preserving correct ordering even where several - controls are involved. - - """ - raise NotImplementedError() - - def _write_mime_data(self, mw, name, value): - """Write data for a subitem of this control to a MimeWriter.""" - # called by HTMLForm - mw2 = mw.nextpart() - mw2.addheader("Content-Disposition", - 'form-data; name="%s"' % name, 1) - f = mw2.startbody(prefix=0) - f.write(value) - - def __str__(self): - raise NotImplementedError() - - def get_labels(self): - """Return all labels (Label instances) for this control. - - If the control was surrounded by a ' - #sPattern = 'class="alt1Active".*?([^<]+)<.*?(src="([^"]+)|).*?' #Serien - # request - sHtmlContent = __getHtmlContent(sUrl = siteUrl) - # parse content - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - if (aResult[0] == False): - return - total = len(aResult[1]) - for img, link, hdS, title, yearS in aResult[1]: - sMovieTitle = title.replace('&','&') - sTitle = sMovieTitle - sUrl = URL_SHOW_MOVIE + str(link) - year = '' - aResult = oParser.parse(yearS, ' ([0-9]{4}) -') - if aResult[0]: - year = aResult[1][0] - aResult = oParser.parse(hdS, '(title="HD Quali")') - if aResult[0]: - sTitle = sTitle + ' [HD]' - oGuiElement = cGuiElement(sTitle,SITE_IDENTIFIER,'getHosters') - oGuiElement.setMediaType('movie') - oGuiElement.setYear(year) - oGuiElement.setThumbnail(img) - params.setParam('movieUrl', sUrl) - params.setParam('sMovieTitle', sMovieTitle) - oGui.addFolder(oGuiElement, params, bIsFolder = False, iTotal = total) - - # check for next site - iTotalPages = __getTotalPages(iPage, sHtmlContent) - if (iTotalPages >= int(iPage)+1): - params = ParameterHandler() - params.setParam('iPage', int(iPage)+1) - params.setParam('normalySiteUrl', normalySiteUrl) - params.setParam('siteUrl', normalySiteUrl+str(int(iPage)+1)) - oGui.addNextPage(SITE_IDENTIFIER,'parseMovieResultSite', params, iTotalPages) - - if iTotalPages > 1: - oGuiElement = cGuiElement('Go to page x of '+str(iTotalPages),SITE_IDENTIFIER,'gotoPage') - params = ParameterHandler() - oGui.addFolder(oGuiElement, params) - - oGui.setView('movies') - -def gotoPage(): - oGui = cGui() - pageNum = oGui.showNumpad() - if not pageNum: - return - params = ParameterHandler() - siteUrl = params.getValue('normalySiteUrl')+pageNum - __parseMovieResultSite(oGui, siteUrl, iPage = int(pageNum)) - oGui.setEndOfDirectory() - -def __getTotalPages(iPage, sHtml): - sPattern = '>Seite [0-9]+ von ([0-9]+)<' - oParser = cParser() - aResult = oParser.parse(sHtml, sPattern) - if (aResult[0] == True): - iTotalCount = int(aResult[1][0]) - return iTotalCount - return 0 - - -def __createDisplayStart(iPage): - return (20 * int(iPage)) - 20 - -def __createInfo(oGui, sHtmlContent): - sPattern = ''+\ - '.*?title="([^\"]+)".*?.*?([^<]+).*?>([^<]+)' - - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - - if (aResult[0] == True): - for aEntry in aResult[1]: - sUrl = aEntry[0].strip() - if not (sUrl.startswith('http')): - sUrl = URL_MAIN +'/'+ sUrl - sTitle = aEntry[1] + ' (' + aEntry[2] + ')' - - oGuiElement = cGuiElement() - oGuiElement.setSiteName(SITE_IDENTIFIER) - oGuiElement.setFunction('parseMovieSimpleList') - oGuiElement.setTitle(sTitle) - - oOutputParameterHandler = ParameterHandler() - oOutputParameterHandler.setParam('sUrl', sUrl) - oGui.addFolder(oGuiElement, oOutputParameterHandler) - - oGui.setEndOfDirectory() - -def parseMovieSimpleList(): - oGui = cGui() - params = ParameterHandler() - oParser = cParser() - - if (params.exist('iPage')): - iPage = params.getValue('iPage') - else: - iPage = 1 - - if (params.exist('sUrl')): - sUrl = params.getValue('sUrl') - logger.info(sUrl) - if (sUrl.find('tvshows-season-') != -1): - sPattern = '\s*(.*?)\s*.*?' - if params.exist('sLanguageToken'): - sLanguageToken = params.getValue('sLanguageToken') - oRequest = cRequestHandler(sUrl) - sHtmlContent = oRequest.request() - aResult = oParser.parse(sHtmlContent, sPattern) - if aResult[0] == True: - for aEntry in aResult[1]: - sUrl = str(aEntry[0]).strip() - if not (sUrl.startswith('http')): - sUrl = URL_MAIN +'/'+ sUrl - if aEntry[2] == sLanguageToken: - break - oRequest = cRequestHandler(sUrl) - sHtmlContent = oRequest.request() - aResult = oParser.parse(sHtmlContent, sPattern) - if aResult[0] == True: - for aEntry in aResult[1]: - sUrl = str(aEntry[0]).strip() - if not (sUrl.startswith('http')): - sUrl = URL_MAIN +'/'+ sUrl - if aEntry[2] == sLanguageToken: - break - - else: - oRequest = cRequestHandler(sUrl) - sHtmlContent = oRequest.request() - aResult = oParser.parse(sHtmlContent, sPattern) - if aResult[0] == True: - sUrl = str(aResult[1][0][0]).strip() - if not (sUrl.startswith('http')): - sUrl = URL_MAIN + sUrl - oRequest = cRequestHandler(sUrl) - sHtmlContent = oRequest.request() - aResult = oParser.parse(sHtmlContent, sPattern) - if aResult[0] == True: - sUrl = str(aResult[1][0][0]).strip() - if not (sUrl.startswith('http')): - sUrl = URL_MAIN +'/'+ sUrl - __getAllSeasons(sUrl) - - else: - __parseMovieSimpleList(sUrl, iPage, oGui) - oGui.setView('movies') - oGui.setEndOfDirectory() - -def __parseMovieSimpleList(sUrl, iPage, oGui, sHtmlContent = False): - oParser = cParser() - if not sHtmlContent: - oRequest = cRequestHandler(sUrl) - sHtmlContent = __getHtmlContent(sUrl) - - sPattern = '(.*?)\s*.*?' - aResult = oParser.parse(sHtmlContent, sPattern) - - pattern = "coverPreview([0-9]+)\"\)\.hover.*?

    Image preview\s*(.*?).*?smileys/([0-9])\.gif.*?class="info">.*?
    (.*?)(?:
    |).*?id="xline">') - aResult = cParser().parse(sHtmlContent, sPattern) - if (aResult[0] == True): - oGui = cGui() - total = len(aResult[1]) - for aEntry in aResult[1]: - newUrl = aEntry[0] - if not (newUrl.startswith('http')): - newUrl = URL_MAIN +'/'+ newUrl - - sThumbnail = aEntry[1] - sMovieTitle = cUtil().unescape(aEntry[2].strip().replace('kostenlos', '')) - - oGuiElement = cGuiElement() - oGuiElement.setSiteName(SITE_IDENTIFIER) - oGuiElement.setFunction('showHosters') - oGuiElement.setMediaType('movie') - fRating = float(aEntry[4]) - sDescription = cUtil().unescape(aEntry[6].strip().decode('utf-8')).encode('utf-8') - sDescription = cUtil().removeHtmlTags(sDescription) - oGuiElement.setDescription(sDescription) - oGuiElement.addItemValue('Rating',fRating) - oGuiElement.setThumbnail(sThumbnail.replace('https','http')) - oGuiElement.setTitle(sMovieTitle) - oGuiElement.setLanguage(__getLanguage(aEntry[3])) - oGuiElement._sQuality = aEntry[5] - oOutputParameterHandler = ParameterHandler() - oOutputParameterHandler.setParam('sUrl', newUrl) - oOutputParameterHandler.setParam('sMovieTitle', sMovieTitle) - - oGui.addFolder(oGuiElement, oOutputParameterHandler, bIsFolder=False, iTotal = total) - oGui.setView('movies') - oGui.setEndOfDirectory() - -def showFeaturedSeries(): - params = ParameterHandler() - if (params.exist('sUrl')): - sUrl = params.getValue('sUrl') - - oRequest = cRequestHandler(sUrl) - sHtmlContent = oRequest.request() - - sPattern = '

    (.*?)

    ' - aResult = cParser().parse(sHtmlContent,sPattern) - if aResult[0] == True: - sPattern = '
    .*? 1: - for x in range(2, int(pages) + 1): - sHtmlContentPage = __getHtmlContent('%spage/%s/' % (sUrl, str(x))) - __getMovies(oGui, sHtmlContentPage) - - if bInternGui: - oGui.setView('movies') - oGui.setEndOfDirectory() - - -def __getMovies(oGui, sHtmlContent): - oParams = ParameterHandler() - sBlockPattern = '
    .*?href="(.*?)"(.*?)src="(.*?)".*?alt="(.*?)"' - - # parse content - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sBlockPattern) - unescape = cUtil().unescape - if aResult[0]: - for link, span, img, title in aResult[1]: - title = unescape(title.decode('utf-8')).encode('utf-8') - # TODO: Looking for span isn't the best way, but the only difference I found - if "span" not in span: - if __isSeriesEverAvaiable(): - url = __getSELink(link) - - if url: - guiElement = cGuiElement(title, SERIESEVER_IDENTIFIER, 'showMovie') - guiElement.setMediaType('movie') - guiElement.setThumbnail(img) - oParams.addParams({'sUrl': url}) - oGui.addFolder(guiElement, oParams) - else: - guiElement = cGuiElement(title, SITE_IDENTIFIER, 'showHosters') - guiElement.setMediaType('movie') - guiElement.setThumbnail(img) - oParams.addParams({'sUrl': link, 'Title': title}) - oGui.addFolder(guiElement, oParams, bIsFolder=False) - - -def __decode(text): - text = text.replace('–', '-') - text = text.replace('&', '&') - text = text.replace('’', '\'') - return text - - -def __getSELink(sUrl): - sPattern = '' - - # request - sHtmlContent = __getHtmlContent(sUrl) - # parse content - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - - if aResult[0]: - return aResult[1][0] - - return False - - -def showHosters(): - logger.info('load showHosters') - oParams = ParameterHandler() - sPattern = 'a href="(' + oParams.getValue('sUrl') + '.*?/)"' - - # request - sHtmlContent = __getHtmlContent() - # parse content - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - - hosters = [] - - hosters = getHoster(sHtmlContent, hosters) - - if aResult[0]: - for link in aResult[1]: - sHtmlContentTmp = __getHtmlContent(link) - hosters = getHoster(sHtmlContentTmp, hosters) - - if hosters: - hosters.append('getHosterUrl') - - return hosters - - -def getHoster(sHtmlContent, hosters): - sPattern = '

    Inhalt:(.*?)
    ' - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - - if (aResult[0] == True): - for aEntry in aResult[1]: - sThumbnail = str(aEntry[0]) - sDescription = cUtil().removeHtmlTags(str(aEntry[1])).replace('\t', '').strip() - oGuiElement = cGuiElement() - oGuiElement.setSiteName(SITE_IDENTIFIER) - oGuiElement.setTitle('info (press Info Button)') - oGuiElement.setThumbnail(sThumbnail) - oGuiElement.setFunction('dummyFolder') - oGuiElement.setDescription(sDescription) - oGui.addFolder(oGuiElement) - -def showAdult(): - oConfig = cConfig() - if oConfig.getSetting('showAdult')=='true': - return True - return False - -def dummyFolder(): - oGui = cGui() - oGui.setEndOfDirectory() -#### Hosterhandling -def getHosters(): - hosters = [] - params = ParameterHandler() - if (params.exist('movieUrl') and params.exist('sMovieTitle')): - sSiteUrl = params.getValue('movieUrl') - sMovieTitle = params.getValue('sMovieTitle') - sHtmlContent = __getHtmlContent(sUrl = sSiteUrl) - sPattern = 'id="ame_noshow_post.*?([^<]+)' - aResult = cParser().parse(sHtmlContent, sPattern) - if aResult[0] == True: - for aEntry in aResult[1]: - sUrl = aEntry[0] - # extract hoster domainname - if 'gstream.to/secure/' in sUrl : - sHoster = sUrl.split('secure/')[-1].split('/')[0].split('.')[-2] - else: - sHoster = sUrl.split('//')[-1].split('/')[0].split('.')[-2] - hoster = {} - hoster['link'] = sUrl - hoster['name'] = sHoster - hosters.append(hoster) - hosters.append('getHosterUrl') - return hosters - -def getHosterUrl(sUrl = False): - params = ParameterHandler() - if not sUrl: - sUrl = params.getValue('url') - results = [] - if 'gstream.to/secure/' in sUrl : - sHoster = sUrl.split('secure/')[-1].split('/')[0] - oRequest = cRequestHandler(sUrl, False) - oRequest.addHeaderEntry('Cookie', params.getValue('securityCookie')) - oRequest.addHeaderEntry('Referer', params.getValue('movieUrl')) - oRequest.ignoreDiscard(True) - try: - oRequest.request() - sUrl = oRequest.getRealUrl() - sUrl = 'http://%s%s' % (sHoster, sUrl.split(sHoster)[-1]) - except: - pass - result = {} - result['streamUrl'] = sUrl - result['resolved'] = False - results.append(result) - return results \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.xstream/sites/kinoleak.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.xstream/sites/kinoleak.py deleted file mode 100644 index fcb4018ad9890d3f9b0a1771ad94a1818496493b..0000000000000000000000000000000000000000 --- a/packages/mediacenter/kodi/config/base-addons/plugin.video.xstream/sites/kinoleak.py +++ /dev/null @@ -1,188 +0,0 @@ -# -*- coding: utf-8 -*- -from resources.lib.gui.gui import cGui -from resources.lib.gui.guiElement import cGuiElement -from resources.lib.handler.requestHandler import cRequestHandler -from resources.lib.parser import cParser -from resources.lib import logger -from resources.lib.handler.ParameterHandler import ParameterHandler - - -SITE_IDENTIFIER = 'kinoleak' -SITE_NAME = 'KinoLeak.Tv' -SITE_ICON = 'kinoleak.png' - -URL_MAIN = 'http://kinoleak.tv/' -URL_NEW = 'http://kinoleak.tv/index.php?site=Addons&do=NewMovies' -URL_ALL = 'http://kinoleak.tv/index.php?site=Addons&do=ALLMovies' - -URL_COMEDY = 'http://kinoleak.tv/index.php?site=Addons&do=Genres&S=Komödie' -URL_ACTION = 'http://kinoleak.tv/index.php?site=Addons&do=Genres&S=Action' -URL_HORROR = 'http://kinoleak.tv/index.php?site=Addons&do=Genres&S=Horror' -URL_THRILLER = 'http://kinoleak.tv/index.php?site=Addons&do=Genres&S=Thriller' -URL_DRAMA = 'http://kinoleak.tv/index.php?site=Addons&do=Genres&S=Drama' -URL_FANTASY = 'http://kinoleak.tv/index.php?site=Addons&do=Genres&S=Fantasy' -URL_ADVENTURE = 'http://kinoleak.tv/index.php?site=Addons&do=Genres&S=Abenteuer' -URL_ANIMATION = 'http://kinoleak.tv/index.php?site=Addons&do=Genres&S=Animation' -URL_SCIFI = 'http://kinoleak.tv/index.php?site=Addons&do=Genres&S=Sci-Fi' - - -def load(): - oGui = cGui() - oGui.addFolder(cGuiElement('Neuste Filme', SITE_IDENTIFIER, 'showNewMovies')) - oGui.addFolder(cGuiElement('Suche', SITE_IDENTIFIER, 'showSearch')) - oGui.addFolder(cGuiElement('Alle Filme', SITE_IDENTIFIER, 'showAllMovies')) - oGui.addFolder(cGuiElement('Sci-Fi', SITE_IDENTIFIER, 'showGenreSciFi')) - oGui.addFolder(cGuiElement('Komödie', SITE_IDENTIFIER, 'showGenreKomoedie')) - oGui.addFolder(cGuiElement('Action', SITE_IDENTIFIER, 'showGenreAction')) - oGui.addFolder(cGuiElement('Horror', SITE_IDENTIFIER, 'showGenreHorror')) - oGui.addFolder(cGuiElement('Thriller', SITE_IDENTIFIER, 'showGenreThriller')) - oGui.addFolder(cGuiElement('Drama', SITE_IDENTIFIER, 'showGenreDrama')) - oGui.addFolder(cGuiElement('Fantasy', SITE_IDENTIFIER, 'showGenreFantasy')) - oGui.addFolder(cGuiElement('Abenteuer', SITE_IDENTIFIER, 'showGenreAbenteuer')) - oGui.addFolder(cGuiElement('Animation', SITE_IDENTIFIER, 'showGenreAnimation')) - oGui.setEndOfDirectory() - -def showNewMovies(): - _parseMovieList(URL_NEW) - -def showAllMovies(): - _parseMovieList(URL_ALL) - -def showGenreSciFi(): - _parseMovieList(URL_SCIFI) - -def showGenreKomoedie(): - _parseMovieList(URL_COMEDY) - -def showGenreAction(): - _parseMovieList(URL_ACTION) - -def showGenreHorror(): - _parseMovieList(URL_HORROR) - -def showGenreThriller(): - _parseMovieList(URL_THRILLER) - -def showGenreDrama(): - _parseMovieList(URL_DRAMA) - -def showGenreFantasy(): - _parseMovieList(URL_FANTASY) - -def showGenreAbenteuer(): - _parseMovieList(URL_ADVENTURE) - -def showGenreAnimation(): - _parseMovieList(URL_ANIMATION) - -def showSearch(): - oGui = cGui() - - sSearchText = oGui.showKeyBoard() - if (sSearchText != False and sSearchText != ''): - _search(oGui, sSearchText) - else: - return - oGui.setEndOfDirectory() - - -def _search(oGui, sSearchString): - searchUrl = URL_MAIN + 'livesearch.php?q=' - - oRequest = cRequestHandler(searchUrl + sSearchString) - content = oRequest.request() - searchPattern = "([^<>']+)" - oParser = cParser() - aResult = oParser.parse(content, searchPattern) - if not aResult[0]: - return - ###### parse entries - params = ParameterHandler() - function = 'getHosters' - iTotal = len(aResult[1]) - for link, img, title in aResult[1]: - sLabel = title.split('(') - sTitle = sLabel[0].strip() - sNextUrl = link - params.setParam('siteUrl',sNextUrl) - oGuiElement = cGuiElement(sTitle, SITE_IDENTIFIER, function) - oGuiElement.setThumbnail(img) - #oGuiElement.setMediaType('movie') - if len(sLabel)>1: - year = sLabel[-1].replace(')','') - oGuiElement.setYear(year) - if 'site=Movies' in link: - oGuiElement.setMediaType('movie') - oGui.addFolder(oGuiElement, params, bIsFolder = False, iTotal = iTotal) - else: - continue - - -def _parseMovieList(url): - oGui = cGui() - params = ParameterHandler() - oRequestHandler = cRequestHandler(url) - sHtmlContent = oRequestHandler.request() - # parse movie entries - pattern = 'class="tabel-topasd".*?([^<>]+).*?title="([^"]+)"/>' - oParser = cParser() - aResult = oParser.parse(sHtmlContent, pattern) - if not aResult[0]: - return - total = len(aResult[1]) # Anzahl der Treffer - for link, img, title, plot, qual in aResult[1]: - titleParts = title.split('(') # Titel von Jahr trennen - movieTitle = titleParts[0].strip().decode('iso-8859-1').encode('utf-8') # encoding anpassen wegen Umlauten - - guiElement = cGuiElement(movieTitle, SITE_IDENTIFIER, 'getHosters') - guiElement.setThumbnail(img) #Cover als Thumbnail setzen - guiElement.setDescription(plot.decode('iso-8859-1')) # Filmbeschreibung setzen, decode wegen Umlauten - if len(titleParts)>1: - tag = titleParts[-1].replace(')','') - if tag.isdigit() and len(tag)==4: - guiElement.setYear(tag) - guiElement.setMediaType('movie') - if '720p' in qual: # erst mal unwichtig - guiElement._sQuality = 720 - elif '1080p' in qual: - guiElement._sQuality = 1080 - - params.setParam('siteUrl',link) - oGui.addFolder(guiElement, params, bIsFolder = False, iTotal = total) - oGui.setView('movies') #diese Liste unterliegt den automatisch ViewSettings für Filmlisten - oGui.setEndOfDirectory() - -#--------------------------------------------------------------------- - -def getHosters(): - oParams = ParameterHandler() #Parameter laden - sUrl = oParams.getValue('siteUrl') # Weitergegebenen Urlteil aus den Parametern holen - - oRequestHandler = cRequestHandler(URL_MAIN+sUrl) # gesamte Url zusammesetzen - sHtmlContent = oRequestHandler.request() # Seite abrufen - - sPattern = 'iframe src="(http[^"]+)"' - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern, ignoreCase = True) - hosters = [] # hosterliste initialisieren - sFunction='getHosterUrl' # folgeFunktion festlegen - if (aResult[0] == True): - for aEntry in aResult[1]: - hoster = {} - hoster['link'] = aEntry - # extract domain name - hoster['name'] = aEntry.split('//')[-1].split('/')[0].split('.')[-2] - hosters.append(hoster) - hosters.append(sFunction) - return hosters - -def getHosterUrl(sStreamUrl = False): - if not sStreamUrl: - params = ParameterHandler() - sStreamUrl = oParams.getValue('url') - results = [] - result = {} - result['streamUrl'] = sStreamUrl - result['resolved'] = False - results.append(result) - return results \ No newline at end of file diff --git a/packages/mediacenter/kodi/config/base-addons/plugin.video.xstream/sites/kinox_to.py b/packages/mediacenter/kodi/config/base-addons/plugin.video.xstream/sites/kinox_to.py deleted file mode 100644 index 66f5f565ee7edc69cf77aed1f9b71400cedbf227..0000000000000000000000000000000000000000 --- a/packages/mediacenter/kodi/config/base-addons/plugin.video.xstream/sites/kinox_to.py +++ /dev/null @@ -1,896 +0,0 @@ -# -*- coding: utf-8 -*- -import urllib -from resources.lib.gui.gui import cGui -from resources.lib.gui.guiElement import cGuiElement -from resources.lib.handler.requestHandler import cRequestHandler -from resources.lib.parser import cParser -from resources.lib.util import cUtil -from resources.lib.config import cConfig -from resources.lib import logger -from json import loads -import re -from resources.lib.handler.ParameterHandler import ParameterHandler -from resources.lib import jsunprotect - -SITE_IDENTIFIER = 'kinox_to' -SITE_NAME = 'Kinox.to' -SITE_ICON = 'kinox.png' -oConfig = cConfig() -domain = oConfig.getSetting('kinox_to-domain') -#### -URL_MAIN = 'http://' + domain -URL_NEWS = URL_MAIN + '/index.php' -URL_CINEMA_PAGE = URL_MAIN + '/Cine-Films.html' -URL_GENRE_PAGE = URL_MAIN +'/Genre.html' -URL_MOVIE_PAGE = URL_MAIN + '/Movies.html' -URL_SERIE_PAGE = URL_MAIN + '/Series.html' -URL_DOCU_PAGE = URL_MAIN + '/Documentations.html' - -URL_FAVOURITE_MOVIE_PAGE = URL_MAIN + '/Popular-Movies.html' -URL_FAVOURITE_SERIE_PAGE = URL_MAIN + '/Popular-Series.html' -URL_FAVOURITE_DOCU_PAGE = URL_MAIN + '/Popular-Documentations.html' - -URL_LATEST_SERIE_PAGE = URL_MAIN + '/Latest-Series.html' -URL_LATEST_DOCU_PAGE = URL_MAIN + '/Latest-Documentations.html' - -URL_SEARCH = URL_MAIN + '/Search.html' -URL_MIRROR = URL_MAIN + '/aGET/Mirror/' -URL_EPISODE_URL = URL_MAIN + '/aGET/MirrorByEpisode/' -URL_AJAX = URL_MAIN + '/aGET/List/' -URL_LANGUAGE = URL_MAIN + '/aSET/PageLang/1' - - -def load(): - logger.info("Load %s" % SITE_NAME) - - sSecurityValue = __getSecurityCookieValue() - if sSecurityValue == '': - pass - elif sSecurityValue == False: - return - oParams = ParameterHandler() - oParams.setParam('securityCookie', sSecurityValue) - ## Create all main menu entries - oGui = cGui() - - oParams.setParam('sUrl', URL_NEWS) - oParams.setParam('page', 1) - oParams.setParam('mediaType', 'news') - oGui.addFolder(cGuiElement('Neues von Heute',SITE_IDENTIFIER,'showNews'),oParams) - oParams.setParam('sUrl', URL_MOVIE_PAGE) - oParams.setParam('mediaType', 'movie') - oGui.addFolder(cGuiElement('Filme',SITE_IDENTIFIER,'showMovieMenu'),oParams) - oParams.setParam('sUrl', URL_SERIE_PAGE) - oParams.setParam('mediaType', 'series') - oGui.addFolder(cGuiElement('Serien',SITE_IDENTIFIER,'showSeriesMenu'),oParams) - oParams.setParam('sUrl', URL_DOCU_PAGE) - oParams.setParam('mediaType', 'documentation') - oGui.addFolder(cGuiElement('Dokumentationen',SITE_IDENTIFIER,'showDocuMenu'),oParams) - oParams.setParam('sUrl', URL_SEARCH) - oParams.setParam('mediaType', '') - oGui.addFolder(cGuiElement('Suche',SITE_IDENTIFIER,'showSearch'),oParams) - oGui.setEndOfDirectory() - -######## Allgemeines -def __createMenuEntry(oGui, sFunction, sLabel, dOutputParameter): - oParams = ParameterHandler() - - # Create all paramters out of lOuputParameter - try: - for param,value in dOutputParameter.items(): - oParams.setParam(param, value) - except Exception, e: - logger.error("Can't add parameter to menu entry with label: %s: %s" % (sLabel, e)) - #oParams = "" - - # Create the gui element - oGuiElement = cGuiElement() - oGuiElement.setSiteName(SITE_IDENTIFIER) - oGuiElement.setFunction(sFunction) - oGuiElement.setTitle(sLabel) - oGui.addFolder(oGuiElement, oParams) - -######## Seitenspezifisch -def showMovieMenu(): - oGui = cGui() - oParams = ParameterHandler() - - oGui.addFolder(cGuiElement('Kinofilme',SITE_IDENTIFIER,'showCinemaMovies'),oParams) - oGui.addFolder(cGuiElement('A-Z',SITE_IDENTIFIER,'showCharacters'),oParams) - oGui.addFolder(cGuiElement('Genres',SITE_IDENTIFIER,'showGenres'),oParams) - oParams.setParam('sUrl', URL_FAVOURITE_MOVIE_PAGE) - oGui.addFolder(cGuiElement('Beliebteste Filme', SITE_IDENTIFIER, 'showFavItems'),oParams) - oGui.setEndOfDirectory() - -def showSeriesMenu(): - oGui = cGui() - oParams = ParameterHandler() - - oGui.addFolder(cGuiElement('A-Z',SITE_IDENTIFIER,'showCharacters'),oParams) - #oGui.addFolder(cGuiElement('Genres',SITE_IDENTIFIER,'showGenres'),oParams) - oParams.setParam('sUrl', URL_FAVOURITE_SERIE_PAGE) - oGui.addFolder(cGuiElement('Beliebteste Serien',SITE_IDENTIFIER,'showFavItems'),oParams) - oParams.setParam('sUrl', URL_LATEST_SERIE_PAGE) - oGui.addFolder(cGuiElement('Neuste Serien',SITE_IDENTIFIER,'showFavItems'),oParams) - oGui.setEndOfDirectory() - -def showDocuMenu(): - oGui = cGui() - oParams = ParameterHandler() - - oGui.addFolder(cGuiElement('A-Z',SITE_IDENTIFIER,'showCharacters'),oParams) - #oGui.addFolder(cGuiElement('Genres',SITE_IDENTIFIER,'showGenres'),oParams) - oParams.setParam('sUrl', URL_FAVOURITE_DOCU_PAGE) - oGui.addFolder(cGuiElement('Beliebteste Dokumentationen',SITE_IDENTIFIER,'showFavItems'),oParams) - oParams.setParam('sUrl', URL_LATEST_DOCU_PAGE) - oGui.addFolder(cGuiElement('Neuste Dokumentationen',SITE_IDENTIFIER,'showFavItems'),oParams) - oGui.setEndOfDirectory() - -def __createLanguage(sLangID): - if sLangID == "1": - return 'de' - elif sLangID == "2" or sLangID == "15": - return 'en' - elif sLangID == "7": - return 'tu' - elif sLangID == "4": - return 'ch' - elif sLangID == "5": - return 'sp' - elif sLangID == "6": - return 'fr' - elif sLangID == "8": - return 'jp' - elif sLangID == '11': - return 'it' - elif sLangID == "16": - return 'nl' - elif sLangID == "25": - return 'ru' - return sLangID - -def __checkSubLanguage(sTitle): - if not ' subbed*' in sTitle: - return [sTitle, ''] - temp = sTitle.split(' *') - subLang = temp[-1].split('subbed*')[0].strip() - title = ' '.join(temp[0:-1]).strip() - if subLang == 'german': - return [title, 'de'] - else: - return [title, subLang] - - -def __getHtmlContent(sUrl = None, sSecurityValue = None): - oParams = ParameterHandler() - # Test if a url is available and set it - if sUrl is None and not oParams.exist('sUrl'): - logger.error("There is no url we can request.") - return False - else: - if sUrl is None: - sUrl = oParams.getValue('sUrl') - # Test if a security value is available - if sSecurityValue is None: - if oParams.exist("securityCookie"): - sSecurityValue = oParams.getValue("securityCookie") - if not sSecurityValue: - sSecurityValue = '' - # preferred language - sPrefLang = __getPreferredLanguage() - # Make the request - oRequest = cRequestHandler(sUrl) - oRequest.addHeaderEntry('Cookie', sPrefLang+sSecurityValue+'ListDisplayYears=Always;') - oRequest.addHeaderEntry('Referer', URL_MAIN) - oRequest.addHeaderEntry('Accept', '*/*') - oRequest.addHeaderEntry('Host', domain) - - return oRequest.request() - -def __getPreferredLanguage(): - sLanguage = oConfig.getSetting('prefLanguage') - if sLanguage == '0': - sPrefLang = 'ListNeededLanguage=25%2C24%2C26%2C2%2C5%2C6%2C7%2C8%2C11%2C15%2C16%2C9%2C12%2C13%2C14%2C17%2C4' - elif sLanguage == '1': - sPrefLang = 'ListNeededLanguage=25%2C24%2C26%2C5%2C6%2C7%2C8%2C11%2C15%2C16%2C9%2C12%2C13%2C14%2C17%2C4%2C1' - else: - sPrefLang = '' - return sPrefLang - -def __getSecurityCookieValue(): - oRequestHandler = cRequestHandler(URL_NEWS, False) - oRequestHandler.removeNewLines(False) - oRequestHandler.removeBreakLines(False) - sHtmlContent = oRequestHandler.request() - sPattern = "var hash=\[(.*?)\]" - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - if aResult[0] == False: - logger.error("Can't find script file for cookie") - result = jsunprotect.jsunprotect(sHtmlContent) - if not result: - logger.error("Not protected or Deactivator not found") - return '' - else: - logger.info(result) - oRequestHandler = cRequestHandler(URL_MAIN+'/?'+result, False) - oRequestHandler.addHeaderEntry('Referer', URL_MAIN) - #oRequestHandler.addHeaderEntry('Accept', '*/*') - oRequestHandler.addHeaderEntry('Host', domain) - oRequestHandler.request() - return '' - for aEntry in aResult[1][0].split(","): - sScriptFile = URL_MAIN +'/'+ str(aEntry).replace("'","").strip() - sScriptFile.replace(" ","") - - logger.info("scriptfile: %s" % sScriptFile) - oRequestHandler = cRequestHandler(sScriptFile) - oRequestHandler.addHeaderEntry('Referer', URL_MAIN) - oRequestHandler.addHeaderEntry('Accept', '*/*') - oRequestHandler.addHeaderEntry('Host', domain) - sHtmlContent = oRequestHandler.request() - - sPattern = "escape\(hsh \+ \"([^\"]+)\"\)" - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - - if not aResult[0]: - logger.info("No hash value found for the cookie") - return '' - - sHash = aResult[1][0] - - sHash = sHashSnippet + sHash - sSecurityCookieValue = "sitechrx=" + str(sHash) + ";Path=/" - - oRequestHandler = cRequestHandler(URL_MAIN) - oRequestHandler.addHeaderEntry("Cookie", sSecurityCookieValue) - oRequestHandler.request() - - logger.info("Token: %s" % sSecurityCookieValue) - - return sSecurityCookieValue - -def showSearch(): - oGui = cGui() - # Show the keyboard and test if anything was entered - sSearchText = oGui.showKeyBoard() - if not sSearchText: - oGui.setEndOfDirectory() - return - _search(oGui, sSearchText) - oGui.setEndOfDirectory() - -def _search(oGui, sSearchText): - # Create the request with the search value - sFullSearchUrl = URL_SEARCH + ("?q=%s" % sSearchText) - logger.info("Search URL: %s" % sFullSearchUrl) - sHtmlContent = __getHtmlContent(sFullSearchUrl) - # Display all items returned... - __displayItems(oGui, sHtmlContent) - - -def __displayItems(oGui, sHtmlContent): - # Test if a cookie was set, else define the default empty one - sSecurityValue = "" - oParams = ParameterHandler() - if oParams.exist("securityCookie"): - sSecurityValue = oParams.getValue("securityCookie") - - # The pattern to filter every item of the list - sPattern = '
    language.*?([^<]+) ([0-9]+)' - - # Parse to get all items of the list - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - if not aResult[0]: - logger.error("Could not find an item") - return - # Go throught all items and create a gui element for them. - total = len(aResult[1]) - for aEntry in aResult[1]: - sTitle = cUtil().unescape(aEntry[3]) - # split title and subtitle language - sTitle, subLang = __checkSubLanguage(sTitle) - # get audio language - sLang = __createLanguage(aEntry[0]) - sUrl = URL_MAIN + aEntry[2] - mediaType = '' - if aEntry[1] == 'movie' or aEntry[1] == 'cinema': - mediaType = 'movie' - elif aEntry[1] == 'series': - mediaType = 'series' - else: - mediaType = 'documentation' - - oGuiElement = cGuiElement(sTitle, SITE_IDENTIFIER, 'parseMovieEntrySite') - oGuiElement.setLanguage(sLang) - oGuiElement.setSubLanguage(subLang) - oGuiElement.setYear(aEntry[4]) - oParams.setParam('sUrl',sUrl) - oParams.setParam('mediaType',mediaType) - if mediaType == 'series': - oGuiElement.setMediaType('tvshow') - oGui.addFolder(oGuiElement, oParams, iTotal = total) - elif mediaType == 'movie': - oGuiElement.setMediaType('movie') - oGui.addFolder(oGuiElement,oParams,bIsFolder=False, iTotal = total) - else: - oGui.addFolder(oGuiElement,oParams,bIsFolder=False, iTotal = total) - - -def showFavItems(): - oGui = cGui() - sHtmlContent = __getHtmlContent() - __displayItems(oGui, sHtmlContent) - oGui.setEndOfDirectory() - - -def showNews(): - oParams = ParameterHandler() - sSecurityValue = oParams.getValue('securityCookie') - sUrl = oParams.getValue('sUrl') - - sPattern = '

    ([a-zA-Z0-9\s.]+)'+\ - '

    \s*
    Insgesamt: (.*?)
    ' - - sHtmlContent = __getHtmlContent(sUrl = sUrl, sSecurityValue = sSecurityValue) - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - oGui = cGui() - if (aResult[0] == True): - for aEntry in aResult[1]: - sTitle = str(aEntry[0]) + ' (' + str(aEntry[1]) + ')' - oGuiElement = cGuiElement(sTitle, SITE_IDENTIFIER,'parseNews') - oParams.addParams({'sUrl':URL_NEWS, 'page':1, 'mediaType':'news', 'sNewsTitle':aEntry[0]}) - oGui.addFolder(oGuiElement, oParams) - oGui.setEndOfDirectory() - - -def parseNews(): - oGui = cGui() - - oParams = ParameterHandler() - sSecurityValue = oParams.getValue('securityCookie') - sUrl = oParams.getValue('sUrl') - sNewsTitle = oParams.getValue('sNewsTitle') - oParser = cParser() - aResult = oParser.parse(sNewsTitle, 'Neue (.*?) online') - if aResult[0]: - if str(aResult[1][0]) == 'Serien': - mediaType = 'series' - else: - mediaType = 'movie' - sPattern = '

    '+sNewsTitle\ - +'

    (.*?)
    ' - sHtmlContent = __getHtmlContent(sUrl = sUrl, sSecurityValue = sSecurityValue) - aResult = oParser.parse(sHtmlContent, sPattern) - - if not aResult[0]: - logger.info("Can't get any news") - oGui.setEndOfDirectory() - return - sPattern = '
    language([^<]+)<'+\ - '(span class="EpisodeDescr">)?([^<]+)' - - aResult = oParser.parse(aResult[1][0], sPattern) - if not aResult[0]: - logger.info("Can't get any news") - oGui.setEndOfDirectory() - return - total = len(aResult[1]) - # Create an entry for every news line - for aEntry in aResult[1]: - sLang = __createLanguage(aEntry[0]) - sTitle = cUtil().unescape(aEntry[3]).strip() - if sTitle.endswith(':'): - sTitle = sTitle[:-1] - sTitle, subLang = __checkSubLanguage(sTitle) - sUrl = aEntry[2] - # If there are several urls, just pick the first one - aUrl = sUrl.split(",") - if len(aUrl) > 0: - sUrl = aUrl[0] - oGuiElement = cGuiElement(sTitle, SITE_IDENTIFIER,'parseMovieEntrySite') - oGuiElement.setLanguage(sLang) - oGuiElement.setSubLanguage(subLang) - oGuiElement.setThumbnail(URL_MAIN + str(aEntry[1])) - - oParams.setParam('sUrl',URL_MAIN + sUrl) - oParams.setParam('mediaType',mediaType) - if mediaType == 'series': - oGuiElement.setMediaType('tvshow') - oGui.addFolder(oGuiElement, oParams, iTotal = total) - oGui.setView('tvshows') - else: - oGuiElement.setMediaType('movie') - oGui.addFolder(oGuiElement, oParams, bIsFolder = False, iTotal = total) - oGui.setView('movies') - oGui.setEndOfDirectory() - - -def showCharacters(): - logger.info('load showCharacters') - oGui = cGui() - - oParams = ParameterHandler() - sSecurityValue = oParams.getValue('securityCookie') - if (oParams.exist('sUrl') and oParams.exist('page') and oParams.exist('mediaType')): - siteUrl = oParams.getValue('sUrl') - #iPage = oParams.getValue('page') - #sMediaType = oParams.getValue('mediaType') - # request - sHtmlContent =__getHtmlContent(siteUrl, sSecurityValue) - # parse content - sPattern = 'class="LetterMode.*?>([^>]+)' - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - - if (aResult[0] == True): - for aEntry in aResult[1]: - oGuiElement = cGuiElement(aEntry, SITE_IDENTIFIER, 'ajaxCall') - #oOutputParameterHandler = ParameterHandler() - oParams.setParam('character', aEntry[0]) - #oOutputParameterHandler.addParameter('page', iPage) - #oOutputParameterHandler.addParameter('mediaType', sMediaType) - #oOutputParameterHandler.addParameter('securityCookie', sSecurityValue) - if oParams.exist('mediaTypePageId'): - sMediaTypePageId = oParams.getValue('mediaTypePageId') - oParams.setParam('mediaTypePageId', sMediaTypePageId) - oGui.addFolder(oGuiElement, oParams) - - oGui.setEndOfDirectory() - -def showGenres(): - logger.info('load displayGenreSite') - sPattern = '([^<]+).*?Tipp-([0-9]+).html">' - - oParams = ParameterHandler() - sSecurityValue = oParams.getValue('securityCookie') - - # request - sHtmlContent =__getHtmlContent(URL_GENRE_PAGE, sSecurityValue) - # parse content - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - - oGui = cGui() - if (aResult[0] == True): - for aEntry in aResult[1]: - iGenreId = aEntry[2] - __createMenuEntry(oGui, 'showCharacters', aEntry[1], - {'page':1, 'mediaType':'fGenre', 'mediaTypePageId': iGenreId, - 'securityCookie':sSecurityValue, 'sUrl':URL_MOVIE_PAGE}) - oGui.setEndOfDirectory() - -def showCinemaMovies(): - logger.info('load displayCinemaSite') - oGui = cGui() - _cinema(oGui) - oGui.setView('movies') - oGui.setEndOfDirectory() - -def _cinema(oGui): - sPattern = '
    .*?src="(.*?)".*?class="Descriptor">(.*?) (.*?) /' - oParams = ParameterHandler() - sSecurityValue = oParams.getValue('securityCookie') - sHtmlContent = __getHtmlContent(URL_CINEMA_PAGE, sSecurityValue) - # parse content - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - # iterate result and create GuiElements - if (aResult[0] == True): - total = len(aResult[1]) - for aEntry in aResult[1]: - sMovieTitle = aEntry[0] - lang = __createLanguage(aEntry[4]) - rating = aEntry[5] - oGuiElement = cGuiElement() - oGuiElement.setSiteName(SITE_IDENTIFIER) - oGuiElement.setFunction('parseMovieEntrySite') - oGuiElement.setLanguage(lang) - oGuiElement.setTitle(sMovieTitle) - oGuiElement.setDescription(aEntry[3]) - oGuiElement.setMediaType('movie') - oGuiElement.setThumbnail(URL_MAIN + str(aEntry[2])) - oGuiElement.addItemValue('rating',rating) - oParams.setParam('sUrl', URL_MAIN + str(aEntry[1])) - oGui.addFolder(oGuiElement, oParams, bIsFolder = False, iTotal = total) - -def parseMovieEntrySite(): - oParams = ParameterHandler() - sSecurityValue = oParams.getValue('securityCookie') - if (oParams.exist('sUrl')): - sUrl = oParams.getValue('sUrl') - # get movieEntrySite content - sHtmlContent = __getHtmlContent(sUrl, sSecurityValue) - sMovieTitle = __createMovieTitle(sHtmlContent) - # get thumbnail - result = cParser().parse(sHtmlContent, '
    .*? 0): - imdbID = oParams.getValue('imdbID') - for item in aSeriesItems: - oGuiElement = cGuiElement(item['title'], SITE_IDENTIFIER, 'showHosters') - sShowTitle = sMovieTitle.split('(')[0].split('*')[0] - oGuiElement.setThumbnail(thumbnail) - oGuiElement.setMediaType('episode') - oGuiElement.setSeason(item['season']) - oGuiElement.setEpisode(item['episode']) - oGuiElement.setTVShowTitle(sShowTitle) - - oParams.addParams({'sUrl':item['url'], 'episode':item['episode'], 'season':item['season']}) - oGui.addFolder(oGuiElement, oParams, bIsFolder = False, iTotal = len(aSeriesItems)) - oGui.setView('episodes') - oGui.setEndOfDirectory() - else: - logger.info('Movie') - result = showHosters(sHtmlContent, sMovieTitle) - return result - -def __createMovieTitle(sHtmlContent): - sPattern = '

    (.*?)

    ' - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - - if (aResult[0] == True): - sTitle = cUtil().removeHtmlTags(str(aResult[1][0])) - return sTitle - return False - -def __createInfoItem(oGui, sHtmlContent): - sThumbnail = __getThumbnail(sHtmlContent) - sDescription = __getDescription(sHtmlContent) - - oGuiElement = cGuiElement() - oGuiElement.setSiteName(SITE_IDENTIFIER) - oGuiElement.setTitle('info (press Info Button)') - oGuiElement.setThumbnail(sThumbnail) - oGuiElement.setFunction('dummyFolder') - oGuiElement.setDescription(sDescription) - - oOutputParameterHandler = ParameterHandler() - oOutputParameterHandler.setParam('sThumbnail', sThumbnail) - oOutputParameterHandler.setParam('sDescription', sDescription) - - oGui.addFolder(oGuiElement, oOutputParameterHandler) - - -def dummyFolder(): - oGui = cGui() - oGui.setEndOfDirectory() - - -def parseSerieSite(sHtmlContent): - aSeriesItems = [] - - sPattern = 'id="SeasonSelection" rel="([^"]+)"' - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - if (aResult[0] == True): - aSeriesUrls = aResult[1][0].split("&") - sSeriesUrl = '&' + str(aSeriesUrls[0]) + '&' + str(aSeriesUrls[1]) - - sPattern = 'Staffel ([^<]+) 1): - mirrorName = " Mirror " +str(i) - sUrl = re.sub(r'Mirror=[1-9]','Mirror='+str(i),sUrl) - hoster = {} - hoster['name'] = sHoster - hoster['link'] = sUrl - hoster['displayedName'] = sHoster+mirrorName - hosters.append(hoster) - hosters.append('getHosterUrlandPlay') - return hosters - - -def getHosterUrlandPlay(sUrl = False): - results = [] - oParams = ParameterHandler() - sSecurityValue = oParams.getValue('securityCookie') - sTitle = oParams.getValue('title') - if not sUrl: - sUrl = oParams.getValue('url') - sUrl = sUrl.replace('&', '&') - oRequest = cRequestHandler(sUrl) - oRequest.addHeaderEntry('Cookie', sSecurityValue) - oRequest.addHeaderEntry('Referer', URL_MAIN) - sHtmlContent = oRequest.request() - #pattern for multipart stream - sPattern = '
    Stream ansehen - sMovieTitle = sMovieTitle[6:len(sMovieTitle)-15] - coverUrl = '' - else: - coverUrl = str(aEntry[1])+"_145_215.jpg" - sMovieTitle = str(aEntry[2]).replace(" Stream","") - oGuiElement = cGuiElement() - oGuiElement.setSiteName(SITE_IDENTIFIER) - serie = False - if (sRootUrl.startswith(URL_SERIES) | ((not sRootUrl.startswith(URL_CURRENT_MOVIES)) & _mediaIsASerie(newUrl))): - serie = True - oGuiElement.setFunction('showAllSeasons') - oGuiElement.setMediaType('tvshow') - oOutputParameterHandler.setParam(PARAM_MOVIESEGMENT_KEY,movieUrlSegment) - else: - oGuiElement.setMediaType('movie') - oGuiElement.setFunction('showHosters') - oGuiElement.setTitle(sMovieTitle) - oGuiElement.setThumbnail(coverUrl) - - oOutputParameterHandler.setParam(PARAM_URL_KEY, newUrl) - oOutputParameterHandler.setParam('sMovieTitle', sMovieTitle) - if not serie: - oGui.addFolder(oGuiElement, oOutputParameterHandler, bIsFolder = False, iTotal = total) - else: - oGui.addFolder(oGuiElement, oOutputParameterHandler, iTotal = total) - - sNextPageNo = __checkForNextPage(sHtmlContent, iPage) - if (sNextPageNo != False): - params = ParameterHandler() - params.setParam(PARAM_ROOTURL_KEY,sRootUrl) - params.setParam(PARAM_URL_KEY, sRootUrl + '?page=' + sNextPageNo) - params.setParam(PARAM_PAGE_KEY,int(sNextPageNo)) - oGui.addNextPage(SITE_IDENTIFIER, 'showMovies',params) - - oGui.setView('movies') - else: - oGui.showError('Fehler','Keine Eintraege gefunden') - -def showAllSeasons(): - oGui = cGui() - - iParams = ParameterHandler() - sUrl = iParams.getValue(PARAM_URL_KEY) - sMovieTitle = iParams.getValue('sMovieTitle') - sHtmlContent = cRequestHandler(sUrl).request() - - sPattern = 'Ecostream ([^<]+)' - aResult = cParser().parse(sHtmlContent, sPattern) - results = [] - - if aResult[0]: # multipart stream - for aEntry in aResult[1]: - result = {} - result['streamUrl'] = 'http://www.ecostream.tv/'+aEntry[0] - result['resolved'] = False - result['title'] = sMovieTitle + ' ' +aEntry[1] - results.append(result) - return results - -def _mediaIsASerie(sUrl): - logger.info('check if %s is a serie' % (sUrl)) - - oRequestHandler = cRequestHandler(sUrl) - sHtmlContent = oRequestHandler.request() - - oParser = cParser() - aResult = oParser.parse(sHtmlContent, '(.*?)' - oParser = cParser() - - aResult = oParser.parse(sHtmlContent, sPattern) - if not aResult[0]: - return - sPattern = '' - aResult = oParser.parse(sHtmlContent,sPattern) - if (aResult[0] == True): - total = len(aResult[1]) - for aEntry in aResult[1]: - season = aEntry[0] - oGuiElement = cGuiElement() - oGuiElement.setSiteName(SITE_IDENTIFIER) - oGuiElement.setFunction('showAllEpisodes') - - sTitle = aEntry[1].strip() - oGuiElement.setTitle(sTitle) - oGuiElement.setSeason(season) - oGuiElement.setMediaType('season') - - oOutputParameterHandler = ParameterHandler() - oOutputParameterHandler.setParam('sUrl', sUrl) - oOutputParameterHandler.setParam('season', season) - - oGui.addFolder(oGuiElement, oOutputParameterHandler, iTotal = total) - oGui.setView('seasons') - oGui.setEndOfDirectory() - -def showAllEpisodes(): - oGui = cGui() - params = ParameterHandler() - sUrl = '' - if not params.exist('sUrl'): - return - sUrl = params.getValue('sUrl') - if not params.exist('season'): - return - sSeason = params.getValue('season') - oRequest = cRequestHandler(sUrl) - sHtmlContent = oRequest.request() - - - - sPattern = '
    (.*?)
    ' - aResult = cParser().parse(sHtmlContent, sPattern) - sHtmlContent = aResult[1][0] - - sPattern = '' - oParser = cParser() - - aResult = oParser.parse(sHtmlContent, sPattern) - if not aResult[0]: - return - sPattern = '' - aResult = oParser.parse(aResult[1][0],sPattern) - if not aResult[0]: - return - for aEntry in aResult[1]: - sUrl = aEntry[0] - if not sUrl.startswith('http'): - sUrl = URL_MAIN +'/'+ sUrl - sMovieTitle = aEntry[1].strip() - episodeNr = aEntry[1].strip().split(' ')[-1] - - oGuiElement = cGuiElement(sMovieTitle, SITE_IDENTIFIER, 'showHostersSeries') - oGuiElement.setEpisode(episodeNr) - if sSeason: - oGuiElement.setSeason(sSeason) - oGuiElement.setMediaType('episode') - - params.setParam('sUrl', sUrl) - params.setParam('sMovieTitle', sMovieTitle) - params.setParam('episode', episodeNr) - oGui.addFolder(oGuiElement, params, bIsFolder = False, iTotal = len(aResult[1])) - oGui.setView('episodes') - oGui.setEndOfDirectory() - -def showSearch(): - oGui = cGui() - - sSearchText = oGui.showKeyBoard() - if (sSearchText != False and sSearchText != ''): - _search(oGui, sSearchText) - else: - return - oGui.setView('movies') - oGui.setEndOfDirectory() - -def _search(oGui, sSearchText): - # add wildcard to find results where seatchText is part of a word - sSearchText = '%'+sSearchText+'%' - # perform search - oRequest = cRequestHandler(URL_SEARCH) - oRequest.addParameters('search', sSearchText) - #oRequest.addParameters('securekey', key) - response = oRequest.request() - sUrl = URL_SEARCH - __parseMovieSimpleList(sUrl, 1, oGui, response) - -def __checkForNextPage(sHtmlContent, iCurrentPage): - iNextPage = int(iCurrentPage) + 1 - iNextPage = str(iNextPage) + ' ' - - sPattern = '
    ' + iNextPage + '' - - oParser = cParser() - aResult = oParser.parse(sHtmlContent, sPattern) - if (aResult[0] == True): - return aResult[1][0] - return False - -def showGenre(): - oGui = cGui() - - params = ParameterHandler() - if (params.exist('sUrl')): - sUrl = params.getValue('sUrl') - - oRequest = cRequestHandler(sUrl) - sHtmlContent = oRequest.request() - - sPattern = '