Ivars 7 years ago
parent
commit
dfef8a53e5
100 changed files with 903 additions and 24830 deletions
  1. 3
    0
      .gitmodules
  2. 94
    28
      addon.py
  3. 5
    1
      addon.xml
  4. 37
    2
      changelog.md
  5. 32
    3
      context_menu.py
  6. 43
    37
      deploy.bat
  7. 35
    9
      download_service.py
  8. 44
    37
      kmake.bat
  9. 2
    4
      kodiswift/cli/console.py
  10. 75
    31
      kodiswift/mockxbmc/xbmcplugin.py
  11. 1
    1
      kodiswift/xbmcmixin.py
  12. 11
    6
      make_links.bat
  13. 0
    328
      playstreamproxy.py
  14. 513
    408
      project.wpr
  15. 1
    0
      readme.md
  16. BIN
      release/plugin.video.playstream-0.1.40.zip
  17. BIN
      release/plugin.video.playstream-0.1.41.zip
  18. BIN
      release/plugin.video.playstream-0.1.42.zip
  19. BIN
      release/plugin.video.playstream-0.1.43.zip
  20. BIN
      release/plugin.video.playstream-0.1.44.zip
  21. 6
    2
      resources/language/English/strings.xml
  22. 0
    237
      resources/lib/ContentSources.py
  23. 0
    272
      resources/lib/Downloader.py
  24. 1
    0
      resources/lib/content
  25. 0
    6281
      resources/lib/demjson.py
  26. 0
    127
      resources/lib/ordereddict.py
  27. 0
    137
      resources/lib/resolver.py
  28. 0
    31
      resources/lib/resolvers/__init__.py
  29. 0
    209
      resources/lib/resolvers/aadecode.py
  30. 0
    100
      resources/lib/resolvers/hdgo.py
  31. 0
    239
      resources/lib/resolvers/hqqresolver.py
  32. 0
    99
      resources/lib/resolvers/kapnob.py
  33. 0
    100
      resources/lib/resolvers/kodik.py
  34. 0
    114
      resources/lib/resolvers/openload3.py
  35. 0
    347
      resources/lib/resolvers/youtuberesolver.py
  36. 0
    31
      resources/lib/resolvers0/__init__.py
  37. 0
    209
      resources/lib/resolvers0/aadecode.py
  38. 0
    97
      resources/lib/resolvers0/hdgo.py
  39. 0
    234
      resources/lib/resolvers0/hqqresolver.py
  40. 0
    94
      resources/lib/resolvers0/kapnob.py
  41. 0
    95
      resources/lib/resolvers0/kodik.py
  42. 0
    109
      resources/lib/resolvers0/openload3.py
  43. 0
    347
      resources/lib/resolvers0/youtuberesolver.py
  44. 0
    158
      resources/lib/sources/SourceBase.py
  45. 0
    404
      resources/lib/sources/YouTubeVideoUrl.py
  46. 0
    209
      resources/lib/sources/cinemalive.py
  47. 0
    113
      resources/lib/sources/config.py
  48. 0
    3
      resources/lib/sources/euronews.cfg
  49. 0
    287
      resources/lib/sources/euronews.py
  50. 0
    353
      resources/lib/sources/filmix.py
  51. 0
    272
      resources/lib/sources/filmon.py
  52. 0
    4
      resources/lib/sources/iplayer.cfg
  53. 0
    551
      resources/lib/sources/iplayer.py
  54. 0
    261
      resources/lib/sources/jsinterp.py
  55. 0
    189
      resources/lib/sources/lmt.py
  56. 0
    4
      resources/lib/sources/ltc.cfg
  57. 0
    1062
      resources/lib/sources/ltc.py
  58. 0
    230
      resources/lib/sources/movieplace.py
  59. 0
    279
      resources/lib/sources/mtgplay.py
  60. 0
    212
      resources/lib/sources/play24.py
  61. 0
    305
      resources/lib/sources/replay.py
  62. 0
    230
      resources/lib/sources/serialguru.py
  63. 0
    117
      resources/lib/sources/streams.cfg
  64. 0
    828
      resources/lib/sources/swfinterp.py
  65. 0
    4
      resources/lib/sources/tvdom.cfg
  66. 0
    282
      resources/lib/sources/tvdom.py
  67. 0
    4
      resources/lib/sources/ustvnow.cfg
  68. 0
    181
      resources/lib/sources/ustvnow.py
  69. 0
    5
      resources/lib/sources/viaplay.cfg
  70. 0
    484
      resources/lib/sources/viaplay.py
  71. 0
    149
      resources/lib/sources0/SourceBase.py
  72. 0
    404
      resources/lib/sources0/YouTubeVideoUrl.py
  73. 0
    0
      resources/lib/sources0/__init__.py
  74. 0
    209
      resources/lib/sources0/cinemalive.py
  75. 0
    99
      resources/lib/sources0/config.py
  76. 0
    3
      resources/lib/sources0/euronews.cfg
  77. 0
    287
      resources/lib/sources0/euronews.py
  78. 0
    336
      resources/lib/sources0/filmix.py
  79. 0
    272
      resources/lib/sources0/filmon.py
  80. 0
    4
      resources/lib/sources0/iplayer.cfg
  81. 0
    524
      resources/lib/sources0/iplayer.py
  82. 0
    261
      resources/lib/sources0/jsinterp.py
  83. 0
    4
      resources/lib/sources0/ltc.cfg
  84. 0
    1018
      resources/lib/sources0/ltc.py
  85. 0
    230
      resources/lib/sources0/movieplace.py
  86. 0
    279
      resources/lib/sources0/mtgplay.py
  87. 0
    212
      resources/lib/sources0/play24.py
  88. 0
    305
      resources/lib/sources0/replay.py
  89. 0
    230
      resources/lib/sources0/serialguru.py
  90. 0
    108
      resources/lib/sources0/streams.cfg
  91. 0
    828
      resources/lib/sources0/swfinterp.py
  92. 0
    4
      resources/lib/sources0/tvdom.cfg
  93. 0
    277
      resources/lib/sources0/tvdom.py
  94. 0
    4
      resources/lib/sources0/ustvnow.cfg
  95. 0
    176
      resources/lib/sources0/ustvnow.py
  96. 0
    5
      resources/lib/sources0/viaplay.cfg
  97. 0
    478
      resources/lib/sources0/viaplay.py
  98. 0
    687
      resources/lib/util.py
  99. BIN
      resources/picons/art-default.jpg
  100. 0
    0
      resources/picons/back.png

+ 3
- 0
.gitmodules View File

@@ -0,0 +1,3 @@
1
+[submodule "resources/lib/content"]
2
+	path = resources/lib/content
3
+	url = http://root@git.blue.lv/home/content.git

+ 94
- 28
addon.py View File

@@ -1,29 +1,59 @@
1 1
 # -*- coding: utf-8 -*-
2
-import os,os.path,sys, urllib, traceback
2
+import os,os.path,sys, glob, shutil, re
3
+import urllib, traceback
3 4
 try:
4
-    import cPickle as pickle2
5
+    import cPickle as pickle
5 6
 except:
6 7
     import pickle
7 8
 import pickle
8 9
 from kodiswift import Plugin, ListItem, storage
9
-from kodiswift import xbmc, xbmcgui, xbmcplugin, xbmcvfs, CLI_MODE
10
-from resources.lib import ContentSources, util
11
-sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),"resources","lib","sources"))
10
+from kodiswift import xbmc, xbmcgui, xbmcplugin, xbmcvfs, xbmcaddon, CLI_MODE
11
+from resources.lib.content import ContentSources, util
12
+cur_directory = os.path.dirname(__file__)
13
+icon_folder = os.path.join(cur_directory, "resources", "picons")
14
+icong_url =  xbmcaddon.Addon().getAddonInfo("path") + "/resources/picons/"
15
+sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),"resources","lib", "content", "sources"))
12 16
 
13 17
 plugin = Plugin()
14 18
 plugin.load_addon_settings()
15
-use_storage = False # TODO parametrs settingos + vajag nočekot vai nav labāk lietot pickle
19
+use_storage = plugin.get_setting("general_use_storage",bool) # TODO vajag nočekot vai nav labāk lietot pickle
20
+storage_ttl = plugin.get_setting("general_ttl",int)
21
+use_proxy = plugin.get_setting("general_proxy_use",bool)
22
+proxy_url = plugin.get_setting("general_proxy_url",str)
23
+playlist = plugin.get_setting("general_playlist",str)
24
+
16 25
 #storage_path = os.path.join(plugin.storage_path,"sources.p")
17 26
 if use_storage:
18
-    storage = plugin.get_storage("playstream","pickle",ttl=30)
27
+    try:
28
+        storage = plugin.get_storage("playstream","pickle",ttl=30)
29
+    except Exception as e:
30
+        os.remove(os.path.join(plugin.storage_path, "playstream"))
31
+        try:
32
+            storage = plugin.get_storage("playstream", "pickle", ttl=30)
33
+        except Exception as e:
34
+            print "[playstream] error opening storage", plugin.storage_path
35
+            print "Got Exception: ", str(e)
36
+            import traceback
37
+            traceback.print_exc()
38
+            plugin.notify("Error opening permament storage", "Info", 10000, xbmcgui.NOTIFICATION_INFO)
39
+            storage = None
40
+            os.remove(os.path.join(plugin.storage_path, "playstream"))
41
+cur_directory = os.path.dirname(__file__)
42
+sources_directory = os.path.join(cur_directory,"resources","lib", "content", "sources")
43
+cfg_list = glob.glob(os.path.join(sources_directory,"*.cfg"))
44
+for cf in cfg_list:
45
+    cf2 = os.path.join(plugin.storage_path,os.path.split(cf)[1])
46
+    if not os.path.exists(cf2):
47
+        shutil.copyfile(cf,cf2)
19 48
 
20
-if use_storage and "sources" in storage:
21
-    print "Restore sources from storage"
49
+if use_storage and storage is not None and "sources" in storage:
50
+    print "[playstream] Restore sources from storage"
22 51
     sources = storage["sources"]
23 52
 # if use_storage and os.path.exists(storage_path): #"sources" in storage:
24 53
     #sources = pickle.load(open(storage_path,"rb"))
25 54
 else:
26
-    sources = ContentSources.ContentSources(os.path.join(os.path.dirname(__file__),"resources","lib","sources"))
55
+    print "[playstream] Create sources objects"
56
+    sources = ContentSources.ContentSources(sources_directory)
27 57
 
28 58
 for source in sources.plugins:
29 59
     if not ("options" in dir(sources.plugins[source]) and sources.plugins[source].options): continue
@@ -47,7 +77,8 @@ def main():
47 77
     data = urllib.unquote(data)
48 78
     sources.plugins["config"].read_streams()
49 79
     if not data:
50
-        data = "config::home"
80
+        data = u"config::home"
81
+    print "[playstream] processing data=%s"%data
51 82
     if sources.is_video(data):
52 83
         try:
53 84
             streams = sources.get_streams(data)
@@ -64,6 +95,10 @@ def main():
64 95
     else:
65 96
         if "{0}" in data:
66 97
             q = plugin.keyboard(default=None, heading="Search for", hidden=False)
98
+            if isinstance(q,str):
99
+                q = q.decode("utf8")
100
+            if isinstance(data,str):
101
+                data = data.decode("utf8")
67 102
             data = data.format(q)
68 103
         try:
69 104
             items = get_list(data)
@@ -73,35 +108,43 @@ def main():
73 108
             return []
74 109
         #xbmc.executebuiltin('Container.SetViewMode(500)')
75 110
         plugin.set_view_mode(50)
76
-        if use_storage:
77
-            print "Save sources to storage"
111
+        if use_storage and storage is not None:
112
+            print "[playstream] Save sources to storage"
78 113
             storage["sources"] = sources
79 114
             storage.sync()
80 115
         return items
81 116
 
82 117
 def get_list(data):
118
+    if isinstance(data,unicode):
119
+        data = data.encode("utf8")
83 120
     content = sources.get_content(data)
121
+    print "[playstream] %s items returned"%len(content)
84 122
     items = []
85 123
     for item in content:
86 124
         if item[1] == "back": continue
87
-        title = item[0].decode("utf8")
88
-        data2 = prefix+item[1]
125
+        title = item[0].decode("utf8") if isinstance(item[0],str) else item[0]
126
+        data2 = item[1].decode("utf8") if isinstance(item[1],str) else item[1]
89 127
         is_playable = True if  sources.is_video(item[1]) else False
90
-        img = item[2]
91
-        desc = item[3].decode("utf8")
128
+        img = item[2].decode("utf8") if isinstance(item[2],str) else item[2]
129
+        desc = item[3].decode("utf8") if isinstance(item[3],str) else item[3]
92 130
         context_menu = [
93
-            ("Add to PlayStream favorites", 'RunScript(special://home/addons/%s/context_menu.py,"add","%s","%s","%s","%s")'%(plugin.id, title,  item[1],img, desc)),
131
+            ("Add to PlayStream playlist",
132
+             u'RunScript(special://home/addons/%s/context_menu.py,"playlist","%s","%s","%s","%s")' % (
133
+                 plugin.id, title, data2, playlist, proxy_url)),
134
+            ("Add to PlayStream favorites",
135
+                u'RunScript(special://home/addons/%s/context_menu.py,"add","%s","%s","%s","%s")'%(
136
+                plugin.id, title,  data2 ,img, desc)),
94 137
             ("Delete from PlayStream favorites",
95
-                 'RunScript(special://home/addons/%s/context_menu.py,"delete","%s","%s","%s","%s")' % (
96
-                 plugin.id, title, item[1], img, desc)),
138
+                u'RunScript(special://home/addons/%s/context_menu.py,"delete","%s","%s","%s","%s")' % (
139
+                plugin.id, title, data2, img, desc)),
97 140
             ("Download",
98
-             'RunScript(special://home/addons/%s/context_menu.py,"download","%s","%s","%s","%s")' % (
99
-                 plugin.id, title, item[1], img, desc)),
141
+             u'RunScript(special://home/addons/%s/context_menu.py,"download","%s","%s","%s","%s")' % (
142
+                plugin.id, title, data2, img, desc)),
100 143
         ]
101 144
         items.append({
102 145
             "label": title,
103
-            "path": data2,
104
-            "thumbnail":img,
146
+            "path": prefix+data2,
147
+            "thumbnail":thumb_data(img, is_playable),
105 148
             "info":{"plot":desc},
106 149
             "is_playable":is_playable,
107 150
             "context_menu": context_menu,
@@ -119,8 +162,22 @@ def play_video(streams):
119 162
     else:
120 163
         stream = streams[0]
121 164
     subfiles = []
122
-    stream = util.stream_change(stream)
123
-    print "play_video ", stream["url"]
165
+    #stream = util.stream_chamge(stream)
166
+    if use_proxy:
167
+        if "resolver" in stream and stream["resolver"] in ("hqq","filmas") or \
168
+            "surl" in stream and re.search("http*://(hqq|goo\.gl)",stream["surl"]) or \
169
+            "lattelecom.tv/mobile-vod/" in stream["url"]: # TODO
170
+            #re.search(r"http*://.+?lattelecom\.tv/.+?auth_token=[^=]+=", stream["url"]):
171
+            stream["url"] = util.streamproxy_encode(stream["url"],stream["headers"],proxy_url)
172
+            stream["headers"] = {}
173
+    if stream["headers"]:
174
+        hh = []
175
+        for k in stream["headers"]:
176
+            h = "%s=%s"%(k,urllib.quote(stream["headers"][k]))
177
+            hh.append(h)
178
+        hh = "&".join(hh)
179
+        stream["url"] = stream["url"] +"|"+hh
180
+    print "[playstream] play_video ", stream["url"]
124 181
     if "subs" in stream and stream["subs"]:
125 182
         for sub in stream["subs"]:
126 183
             suburl = sub["url"]
@@ -132,19 +189,28 @@ def play_video(streams):
132 189
             f.write(srt)
133 190
             f.close()
134 191
             subfiles.append(subfile)
135
-    item = ListItem(label=stream["name"], thumbnail=stream["img"], path=stream["url"])
192
+    item = ListItem(label=stream["name"], thumbnail=thumb_data(stream["img"], True), path=stream["url"])
136 193
     item.set_info("video",{"plot":stream["desc"]})
137 194
     item.set_is_playable(True)
138 195
     return plugin.set_resolved_url(item,subfiles)
139 196
     #return plugin.play_video(item)
140 197
 
198
+def thumb_data(img, video=False):
199
+    default = "video.png" if video else "folder.png"
200
+    if img in ("default", ""):
201
+        img = default
202
+    if not img.startswith("http"):
203
+        img = icong_url + img
204
+    return img
205
+
141 206
 if __name__ == '__main__':
142 207
     if CLI_MODE:
143 208
         from kodiswift.cli.cli import main as start
144 209
         start()
145 210
     else:
146 211
         plugin.run()
147
-        if use_storage:
212
+        if use_storage and storage is not None:
213
+            print "[playstream] Save sources to storage"
148 214
             storage["sources"] = sources
149 215
             storage.sync()
150 216
             print "Save sources to storage"

+ 5
- 1
addon.xml View File

@@ -1,5 +1,5 @@
1 1
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
-<addon version="0.1.30" id="plugin.video.playstream" name="PlayStream" provider-name="ivars777"  >
2
+<addon version="0.1.44" id="plugin.video.playstream" name="PlayStream" provider-name="ivars777"  >
3 3
   <requires>
4 4
     <import addon="xbmc.python" version="2.1.0"/>
5 5
     <import addon="script.module.requests" />
@@ -8,6 +8,10 @@
8 8
   <extension point="xbmc.python.pluginsource" library="addon.py">
9 9
     <provides>video</provides>
10 10
   </extension>
11
+  <extension point="xbmc.python.pluginsource" library="addon.py">
12
+    <provides>video</provides>
13
+  </extension>
14
+  <extension point="xbmc.service" library="service.py" />
11 15
   <extension point="xbmc.addon.metadata">
12 16
     <platform>all</platform>
13 17
     <language></language>

+ 37
- 2
changelog.md View File

@@ -1,8 +1,43 @@
1
+**0.1.44** (03.09.2017)
2
+- [change] Sakārtotas pikonas
3
+
4
+**0.1.43** (03.09.2017)
5
+- [bugfix] Salaboti video avoti atbilstoši PlayStream 0.7e (lattelekom u.c.)
6
+- [change] pārstrukturets kods (video satura avoti atseviškā git modulī)
7
+- [change] opcija nelietot proxy problemātiskajiem strimiem (lattlecom.tv, viaplay u.c.), izskatās, ka Web serveris stradā par lēnu
8
+
9
+**0.1.41** (03.09.2017)
10
+- [bugfix] Salabots filmix (pamainīts direct url avots uz html5 + dekodēšana kods)
11
+
12
+**0.1.40** (27.08.2017
13
+- [change] Salabots TVDom atbilstoši jaunajam API (papildus parametri - reģions, valoda)
14
+- [bugfix] Salabots Euronews
15
+- [change] Nestrādājošie avoti noslēpti menu, kad tiks salaboti parādīsies atkal
16
+- [change] Sataisīts izmainītais Filmix.me
17
+
18
+**0.1.38** (11.04.2016):
19
+- [feature] options to set local proxy port (by default 8880), proxy url in order to use remote proxy
20
+
21
+**0.1.35** (10.04.2016):
22
+- [feature] option to save plugin status state between calls (necessary to lattelecom.tv archive)
23
+
24
+**0.1.34** (09.04.2016):
25
+- [feature] proxy hack to play full lattelecom.tv videos (more than 5-6 minutes), turn on proxy in settings and restart kodi
26
+
27
+**0.1.33** (01.04.2016):
28
+- [feature] LMT straume (without TV streams)
29
+
30
+**0.1.32** (28.03.2016):
31
+- [feature] sources configod files stored in user_data area (remains after update)
32
+- [feature] option to use persistent storage to store sources objects (including login status) between calls (exprerimental, not very useful currently)
33
+- [feature] proxy server to play encoded hls streams as well as hqq and some other resolved streams (exprerimental, not working correctly)
34
+- [bugfix] viaplay login
35
+
1 36
 **0.1.24** (23.03.2016):
2
-- subtitles, context menu etc added
37
+- [feature] subtitles, context menu etc added
3 38
 
4 39
 **0.1.5** (14.02.2016):
5
-- addon settings added
40
+- [feature] addon settings added
6 41
 
7 42
 **0.1.2** (12.02.2016):
8 43
 - initial exprerimental version

+ 32
- 3
context_menu.py View File

@@ -1,23 +1,52 @@
1 1
 import sys, os, os.path
2 2
 from kodiswift import xbmc, xbmcgui, CLI_MODE
3
+from kodiswift import Plugin, storage
3 4
 from  resources.lib.sources.config import Source
5
+from resources.lib import util
4 6
 
7
+
8
+#plugin = Plugin()
9
+#plugin.load_addon_settings()
10
+#playlist = plugin.get_setting("general_playlist",str)
11
+#proxy_url = plugin.get_setting("general_proxy_url",str)
12
+
13
+# PlaysTream streams.cfg
5 14
 cfg = Source()
6 15
 lists = cfg.get_lists()
7 16
 titles = [cfg.get_title(name) for name in lists]
8 17
 cmd = sys.argv[1]
18
+#title = sys.argv[2]
19
+#data = sys.argv[3]
20
+#img = sys.argv[4]
21
+#desc = sys.argv[5]
9 22
 
10 23
 if cmd == "add":
11 24
     if not CLI_MODE:
12 25
         ret = xbmcgui.Dialog().select("Select menu",titles)
13 26
     else:
14 27
         ret = 3
15
-    title = sys.argv[2]
16
-    img = sys.argv[3]
17
-    desc = sys.argv[4]
18 28
     cfg.add_item(lists[ret],sys.argv[2:])
19 29
     cfg.write_streams()
20 30
 
31
+elif cmd == "playlist":
32
+    title = sys.argv[2]
33
+    data = sys.argv[3]
34
+    playlist = sys.argv[4]
35
+    proxy_url = sys.argv[5]
36
+    if not os.path.exists(playlist):
37
+        pl = open(playlist,"wb")
38
+        pl.write('#EXTM3U\n')
39
+    else:
40
+        pl = open(playlist,"a")
41
+    urlp = util.streamproxy_encode2(data,{},proxy_url)
42
+    if isinstance(urlp,unicode):
43
+        urlp = urlp.encode("utf8")
44
+    if isinstance(title,unicode):
45
+        title = title.encode("utf8")
46
+    pl.write("#EXTINF:0,%s\n%s\n"%(title,urlp))
47
+    pl.close()
48
+    #plugin.notify("Item '%s' added to %s"%(title,playlist), "Info", 10000, xbmcgui.NOTIFICATION_INFO)
49
+
21 50
 elif cmd == "delete":
22 51
     xbmcgui.Dialog().ok("Info","Not yet implemented!")
23 52
 

+ 43
- 37
deploy.bat View File

@@ -5,13 +5,13 @@ if (abox)==(%1%) (
5 5
     set TARGET=C:\Users\User\AppData\Roaming\Kodi\addons\plugin.video.playstream\
6 6
 )
7 7
 
8
-
9 8
 for %%f in (
10 9
 readme.md
11 10
 changelog.md
12 11
 addon.xml
13 12
 addon.py
14 13
 context_menu.py
14
+service.py
15 15
 icon.png
16 16
 kodiswift\*.py
17 17
 resources\__init__.py
@@ -19,41 +19,47 @@ resources\settings.xml
19 19
 resources\icon.png
20 20
 resources\language\English\*
21 21
 resources\lib\__init__.py
22
-resources\lib\ContentSources.py
23
-resources\lib\resolver.py
24
-resources\lib\util.py
25
-resources\lib\demjson.py
26
-resources\lib\ordereddict.py
27
-resources\lib\sources\__init__.py
28
-resources\lib\sources\SourceBase.py
29
-resources\lib\sources\cinemalive.py
30
-resources\lib\sources\config.py
31
-resources\lib\sources\euronews.py
32
-resources\lib\sources\filmix.py
33
-resources\lib\sources\filmon.py
34
-resources\lib\sources\iplayer.py
35
-resources\lib\sources\movieplace.py
36
-resources\lib\sources\ltc.py
37
-resources\lib\sources\mtgplay.py
38
-resources\lib\sources\play24.py
39
-resources\lib\sources\replay.py
40
-resources\lib\sources\serialguru.py
41
-resources\lib\sources\tvdom.py
42
-resources\lib\sources\ustvnow.py
43
-resources\lib\sources\viaplay.py
44
-resources\lib\sources\filmas.py
45
-resources\lib\sources\YouTubeVideoUrl.py
46
-resources\lib\sources\jsinterp.py
47
-resources\lib\sources\swfinterp.py
48
-resources\lib\sources\streams.cfg
49
-resources\lib\resolvers\__init__.py
50
-resources\lib\resolvers\aadecode.py
51
-resources\lib\resolvers\hqqresolver.py
52
-resources\lib\resolvers\openload3.py
53
-resources\lib\resolvers\hdgo.py
54
-resources\lib\resolvers\kapnob.py
55
-resources\lib\resolvers\kodik.py
56
-resources\lib\resolvers\youtuberesolver.py
57
-) do echo f | xcopy /y /d  %%f %TARGET%%%f
22
+resources\lib\content\__init__.py
23
+resources\lib\content\ContentSources.py
24
+resources\lib\content\playstreamproxy.py
25
+resources\lib\content\util.py
26
+resources\lib\content\resolver.py
27
+resources\lib\content\demjson.py
28
+resources\lib\content\ordereddict.py
29
+resources\lib\content\sources\__init__.py
30
+resources\lib\content\sources\SourceBase.py
31
+resources\lib\content\sources\cinemalive.py
32
+resources\lib\content\sources\config.py
33
+resources\lib\content\sources\euronews.py
34
+resources\lib\content\sources\filmix.py
35
+resources\lib\content\sources\filmon.py
36
+resources\lib\content\sources\iplayer.py
37
+resources\lib\content\sources\movieplace.py
38
+resources\lib\content\sources\ltc.py
39
+resources\lib\content\sources\mtgplay.py
40
+resources\lib\content\sources\play24.py
41
+resources\lib\content\sources\replay.py
42
+resources\lib\content\sources\serialguru.py
43
+resources\lib\content\sources\tvdom.py
44
+resources\lib\content\sources\ustvnow.py
45
+resources\lib\content\sources\viaplay.py
46
+resources\lib\content\sources\lmt.py
47
+resources\lib\content\sources\filmas.py
48
+resources\lib\content\sources\YouTubeVideoUrl.py
49
+resources\lib\content\sources\jsinterp.py
50
+resources\lib\content\sources\swfinterp.py
51
+resources\lib\content\sources\streams.cfg
52
+resources\lib\content\resolvers\__init__.py
53
+resources\lib\content\resolvers\aadecode.py
54
+resources\lib\content\resolvers\hqqresolver.py
55
+resources\lib\content\resolvers\openload3.py
56
+resources\lib\content\resolvers\hdgo.py
57
+resources\lib\content\resolvers\kapnob.py
58
+resources\lib\content\resolvers\kodik.py
59
+resources\lib\content\resolvers\youtuberesolver.py
60
+resources\picons\*
61
+) do echo f | xcopy /y   %%f %TARGET%%%f
62
+
63
+rem xcopy /y /d addon_data\settings.xml "C:\Users\user\AppData\Roaming\Kodi\userdata\addon_data\plugin.video.playstream\settings.xml"
58 64
 
59 65
 pause

+ 35
- 9
download_service.py View File

@@ -1,18 +1,44 @@
1 1
 # -*- coding: utf-8 -*-
2
-import os,os.path,sys, urllib, traceback
2
+import os,os.path,sys, datetime, traceback
3 3
 from kodiswift import Plugin, ListItem, storage
4 4
 from kodiswift import xbmc, xbmcgui, xbmcplugin, xbmcvfs, CLI_MODE
5 5
 #from resources.lib import ContentSources, util
6 6
 #sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),"resources","lib","sources"))
7
-import playstreamproxy
8
-#monitor = xbmc.Monitor()
7
+import resources.lib.Downloader as Downloader
8
+import sys,os, os.path, re
9
+import urlparse, requests
10
+from twisted.web import client
11
+from twisted.internet import reactor, defer, ssl, task
9 12
 
13
+#str(time.time())
10 14
 
11 15
 plugin = Plugin()
12 16
 plugin.load_addon_settings()
13
-port = plugin.get_setting("general_port",int)
14
-start_proxy = plugin.get_setting("general_proxy",bool)
15
-host = "localhost"
16
-if start_proxy:
17
-    plugin.notify("Starting playstreamproxy","Info",10000, xbmcgui.NOTIFICATION_INFO)
18
-    playstreamproxy.start(host, port)
17
+download_dir = plugin.get_setting("general_download_dir",str)
18
+queue_dir = os.path.join(plugin.storage_path,"downloads)")
19
+if not os.path.exists(queue_dir):
20
+    os.mkdir(queue_dir)
21
+
22
+class DownloadQueue(object):
23
+    def __init__(self):
24
+        self.flist=[]
25
+        self.q=[]
26
+
27
+    def check_queue(self):
28
+        flist = os.listdir(queue_dir)
29
+        print "Checking queue"
30
+
31
+    def start_download(self):
32
+        pass
33
+
34
+    def download_ok(self):
35
+        pass
36
+
37
+    def download_err(self):
38
+        pass
39
+
40
+
41
+queue = DownloadQueue()
42
+loop = task.LoopingCall(queue.check_queue)
43
+loop.start(2)
44
+reactor.run()

+ 44
- 37
kmake.bat View File

@@ -12,7 +12,7 @@ set desc=Play online streams from various sources, mostly Latvian
12 12
 set ipk_dir=ipkg\
13 13
 set release_dir=release\
14 14
 set repo_dir=..\repo\
15
-set feed_dir=w:\repo\
15
+set feed_dir=q:\web\repo\
16 16
 
17 17
 set AR=\MinGW\bin\ar.exe
18 18
 set TAR=\MinGW\msys\1.0\bin\tar.exe
@@ -32,6 +32,7 @@ changelog.md
32 32
 addon.xml
33 33
 addon.py
34 34
 context_menu.py
35
+service.py
35 36
 icon.png
36 37
 kodiswift\*.py
37 38
 resources\__init__.py
@@ -39,42 +40,47 @@ resources\settings.xml
39 40
 resources\icon.png
40 41
 resources\language\English\*
41 42
 resources\lib\__init__.py
42
-resources\lib\ContentSources.py
43
-resources\lib\resolver.py
44
-resources\lib\util.py
45
-resources\lib\demjson.py
46
-resources\lib\ordereddict.py
47
-resources\lib\sources\__init__.py
48
-resources\lib\sources\SourceBase.py
49
-resources\lib\sources\cinemalive.py
50
-resources\lib\sources\config.py
51
-resources\lib\sources\euronews.py
52
-resources\lib\sources\filmix.py
53
-resources\lib\sources\filmon.py
54
-resources\lib\sources\iplayer.py
55
-resources\lib\sources\movieplace.py
56
-resources\lib\sources\ltc.py
57
-resources\lib\sources\mtgplay.py
58
-resources\lib\sources\play24.py
59
-resources\lib\sources\replay.py
60
-resources\lib\sources\serialguru.py
61
-resources\lib\sources\tvdom.py
62
-resources\lib\sources\ustvnow.py
63
-resources\lib\sources\viaplay.py
64
-resources\lib\sources\viaplay.py
65
-resources\lib\sources\YouTubeVideoUrl.py
66
-resources\lib\sources\jsinterp.py
67
-resources\lib\sources\swfinterp.py
68
-resources\lib\sources\streams.cfg
69
-resources\lib\resolvers\__init__.py
70
-resources\lib\resolvers\aadecode.py
71
-resources\lib\resolvers\hqqresolver.py
72
-resources\lib\resolvers\openload3.py
73
-resources\lib\resolvers\hdgo.py
74
-resources\lib\resolvers\kapnob.py
75
-resources\lib\resolvers\kodik.py
76
-resources\lib\resolvers\youtuberesolver.py
43
+resources\lib\content\__init__.py
44
+resources\lib\content\ContentSources.py
45
+resources\lib\content\playstreamproxy.py
46
+resources\lib\content\Downloader.py
47
+resources\lib\content\resolver.py
48
+resources\lib\content\util.py
49
+resources\lib\content\demjson.py
50
+resources\lib\content\ordereddict.py
51
+resources\lib\content\sources\__init__.py
52
+resources\lib\content\sources\SourceBase.py
53
+resources\lib\content\sources\cinemalive.py
54
+resources\lib\content\sources\config.py
55
+resources\lib\content\sources\euronews.py
56
+resources\lib\content\sources\filmix.py
57
+resources\lib\content\sources\filmon.py
58
+resources\lib\content\sources\iplayer.py
59
+resources\lib\content\sources\movieplace.py
60
+resources\lib\content\sources\ltc.py
61
+resources\lib\content\sources\mtgplay.py
62
+resources\lib\content\sources\play24.py
63
+resources\lib\content\sources\replay.py
64
+resources\lib\content\sources\lmt.py
65
+resources\lib\content\sources\serialguru.py
66
+resources\lib\content\sources\tvdom.py
67
+resources\lib\content\sources\ustvnow.py
68
+resources\lib\content\sources\viaplay.py
69
+resources\lib\content\sources\viaplay.py
70
+resources\lib\content\sources\YouTubeVideoUrl.py
71
+resources\lib\content\sources\jsinterp.py
72
+resources\lib\content\sources\swfinterp.py
73
+resources\lib\content\sources\streams.cfg
74
+resources\lib\content\resolvers\__init__.py
75
+resources\lib\content\resolvers\aadecode.py
76
+resources\lib\content\resolvers\hqqresolver.py
77
+resources\lib\content\resolvers\openload3.py
78
+resources\lib\content\resolvers\hdgo.py
79
+resources\lib\content\resolvers\kapnob.py
80
+resources\lib\content\resolvers\kodik.py
81
+resources\lib\content\resolvers\youtuberesolver.py
77 82
 ) do echo f| xcopy %%f %pack_name%\%%f
83
+pause
78 84
 
79 85
 if exist  %release_dir%%pack_name%-%ver%.zip rm %release_dir%%pack_name%-%ver%.zip
80 86
 rem zip  -r %release_dir%%pack_name%-%ver%.zip %pack_name%
@@ -87,8 +93,9 @@ git add %release_dir%%pack_name%-%ver%.zip
87 93
 if not ()==(%1%) (
88 94
 git commit -m %ver%
89 95
 git tag %ver%
90
-)
91 96
 git push
97
+)
98
+
92 99
 
93 100
 pushd  %repo_dir%..
94 101
 call update_repo.bat

+ 2
- 4
kodiswift/cli/console.py View File

@@ -60,10 +60,8 @@ def display_video(items):
60 60
     """
61 61
     parent_item, played_item = items
62 62
 
63
-    title_line = 'Playing Media %s (%s)' % (played_item.label,
64
-                                            played_item.path)
65
-    parent_line = '[0] %s (%s)' % (parent_item.label,
66
-                                   parent_item.path)
63
+    title_line = 'Playing Media %s (%s)' % (played_item.label, played_item.path.encode("utf8"))
64
+    parent_line = '[0] %s (%s)' % (parent_item.label, parent_item.path)
67 65
     line_width = get_max_len([title_line, parent_line])
68 66
 
69 67
     output = [

+ 75
- 31
kodiswift/mockxbmc/xbmcplugin.py View File

@@ -1,44 +1,88 @@
1
-# -*- code: utf-8 -*-
1
+# coding: utf-8
2
+"""
3
+Functions for Kodi plugins
4
+"""
5
+import sys
2 6
 
3
-SORT_METHOD_ALBUM = 14
4
-SORT_METHOD_ALBUM_IGNORE_THE = 15
7
+SORT_METHOD_ALBUM = 13
8
+SORT_METHOD_ALBUM_IGNORE_THE = 14
5 9
 SORT_METHOD_ARTIST = 11
6
-SORT_METHOD_ARTIST_IGNORE_THE = 13
7
-SORT_METHOD_BITRATE = 42
8
-SORT_METHOD_CHANNEL = 40
9
-SORT_METHOD_COUNTRY = 17
10
+SORT_METHOD_ARTIST_IGNORE_THE = 12
11
+SORT_METHOD_BITRATE = 40
12
+SORT_METHOD_CHANNEL = 38
13
+SORT_METHOD_COUNTRY = 16
10 14
 SORT_METHOD_DATE = 3
11
-SORT_METHOD_DATEADDED = 21
12
-SORT_METHOD_DATE_TAKEN = 43
15
+SORT_METHOD_DATEADDED = 19
16
+SORT_METHOD_DATE_TAKEN = 41
13 17
 SORT_METHOD_DRIVE_TYPE = 6
14 18
 SORT_METHOD_DURATION = 8
15
-SORT_METHOD_EPISODE = 24
19
+SORT_METHOD_EPISODE = 22
16 20
 SORT_METHOD_FILE = 5
17
-SORT_METHOD_FULLPATH = 34
18
-SORT_METHOD_GENRE = 16
21
+SORT_METHOD_FULLPATH = 32
22
+SORT_METHOD_GENRE = 15
19 23
 SORT_METHOD_LABEL = 1
20
-SORT_METHOD_LABEL_IGNORE_FOLDERS = 35
24
+SORT_METHOD_LABEL_IGNORE_FOLDERS = 33
21 25
 SORT_METHOD_LABEL_IGNORE_THE = 2
22
-SORT_METHOD_LASTPLAYED = 36
23
-SORT_METHOD_LISTENERS = 38
24
-SORT_METHOD_MPAA_RATING = 30
26
+SORT_METHOD_LASTPLAYED = 34
27
+SORT_METHOD_LISTENERS = 36
28
+SORT_METHOD_MPAA_RATING = 28
25 29
 SORT_METHOD_NONE = 0
26
-SORT_METHOD_PLAYCOUNT = 37
27
-SORT_METHOD_PLAYLIST_ORDER = 23
28
-SORT_METHOD_PRODUCTIONCODE = 28
29
-SORT_METHOD_PROGRAM_COUNT = 22
30
+SORT_METHOD_PLAYCOUNT = 35
31
+SORT_METHOD_PLAYLIST_ORDER = 21
32
+SORT_METHOD_PRODUCTIONCODE = 26
33
+SORT_METHOD_PROGRAM_COUNT = 20
30 34
 SORT_METHOD_SIZE = 4
31
-SORT_METHOD_SONG_RATING = 29
32
-SORT_METHOD_STUDIO = 32
33
-SORT_METHOD_STUDIO_IGNORE_THE = 33
35
+SORT_METHOD_SONG_RATING = 27
36
+SORT_METHOD_STUDIO = 30
37
+SORT_METHOD_STUDIO_IGNORE_THE = 31
34 38
 SORT_METHOD_TITLE = 9
35 39
 SORT_METHOD_TITLE_IGNORE_THE = 10
36 40
 SORT_METHOD_TRACKNUM = 7
37
-SORT_METHOD_UNSORTED = 39
38
-SORT_METHOD_VIDEO_RATING = 19
39
-SORT_METHOD_VIDEO_RUNTIME = 31
40
-SORT_METHOD_VIDEO_SORT_TITLE = 26
41
-SORT_METHOD_VIDEO_SORT_TITLE_IGNORE_THE = 27
42
-SORT_METHOD_VIDEO_TITLE = 25
43
-SORT_METHOD_VIDEO_USER_RATING = 20
44
-SORT_METHOD_VIDEO_YEAR = 18
41
+SORT_METHOD_UNSORTED = 37
42
+SORT_METHOD_VIDEO_RATING = 18
43
+SORT_METHOD_VIDEO_RUNTIME = 29
44
+SORT_METHOD_VIDEO_SORT_TITLE = 24
45
+SORT_METHOD_VIDEO_SORT_TITLE_IGNORE_THE = 25
46
+SORT_METHOD_VIDEO_TITLE = 23
47
+SORT_METHOD_VIDEO_YEAR = 17
48
+
49
+def player(url, title = "", suburl= "",headers={}):
50
+    from subprocess import call
51
+    if not url:
52
+        return
53
+    cmd1 = [r"c:\Program Files\VideoLAN\VLC\vlc.exe",url,
54
+           "--meta-title",title.decode("utf8").encode(sys.getfilesystemencoding()),
55
+           "--http-user-agent","Enigma2"
56
+    ]
57
+    # gst-launch-1.0 -v souphttpsrc ssl-strict=false proxy=127.0.0.1:8888 extra-headers="Origin:adadadasd"  location="http://bitdash-a.akamaihd.net/content/sintel/sintel.mpd" ! decodebin! autovideosink
58
+    cmd2 = [
59
+        r"C:\gstreamer\1.0\x86_64\bin\gst-launch-1.0","-v",
60
+        "playbin", 'uri="%s"'%url,
61
+        #"souphttpsrc", "ssl-strict=false",
62
+        #"proxy=127.0.0.1:8888",
63
+        #'location="%s"'%url,
64
+        #'!decodebin!autovideosink'
65
+    ]
66
+    cmd3 = ["ffplay.exe",url]
67
+    cmd = cmd1 if url.startswith("https") else cmd2
68
+    ret = call(cmd3)
69
+    #if ret:
70
+        #a = raw_input("*** Error, continue")
71
+    return
72
+
73
+def setResolvedUrl(handle, succeeded, listitem):
74
+    """Callback function to tell XBMC that the file plugin has been resolved to a url
75
+
76
+    :param handle: integer - handle the plugin was started with.
77
+    :param succeeded: bool - True=script completed successfully/False=Script did not.
78
+    :param listitem: ListItem - item the file plugin resolved to for playback.
79
+
80
+    Example::
81
+
82
+        xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
83
+
84
+    """
85
+    url = listitem.path
86
+    title = listitem.label
87
+    player(url,title)
88
+    pass

+ 1
- 1
kodiswift/xbmcmixin.py View File

@@ -218,7 +218,7 @@ class XBMCMixin(object):
218 218
         elif converter is unicode:
219 219
             return value.decode('utf-8')
220 220
         elif converter is bool:
221
-            return value == 'true'
221
+            return not(value.lower()=="false" or value=="0")
222 222
         elif converter is int:
223 223
             return int(value)
224 224
         elif isinstance(choices, (list, tuple)):

+ 11
- 6
make_links.bat View File

@@ -1,6 +1,11 @@
1
-mklink /h resources\lib\ContentSources.py \Data\Programming\enigma2\PlayStream2\ContentSources.py
2
-mklink /h resources\lib\util.py \Data\Programming\enigma2\PlayStream2\util.py
3
-mklink /h resources\lib\resolver.py \Data\Programming\enigma2\PlayStream2\resolver.py
4
-mklink /h resources\lib\demjson.py \Data\Programming\enigma2\PlayStream2\demjson.py
5
-mklink /j resources\lib\sources \Data\Programming\enigma2\PlayStream2\sources
6
-mklink /j resources\lib\resolvers \Data\Programming\enigma2\PlayStream2\resolvers
1
+set dir1=\Data\Programming\Kodi\plugin.video.playstream\
2
+set dir2=\Data\Programming\enigma2\PlayStream2\
3
+
4
+mklink \Data\Programming\Kodi\plugin.video.playstream\resources\lib\ContentSources.py \Data\Programming\enigma2\PlayStream2\ContentSources.py
5
+mklink \Data\Programming\Kodi\plugin.video.playstream\resources\lib\Downloader.py \Data\Programming\enigma2\PlayStream2\Downloader.py
6
+mklink \Data\Programming\Kodi\plugin.video.playstream\resources\lib\util.py \Data\Programming\enigma2\PlayStream2\util.py
7
+mklink \Data\Programming\Kodi\plugin.video.playstream\resources\lib\resolver.py \Data\Programming\enigma2\PlayStream2\resolver.py
8
+mklink \Data\Programming\Kodi\plugin.video.playstream\resources\lib\playstreamproxy.py \Data\Programming\enigma2\PlayStream2\playstreamproxy.py
9
+mklink \Data\Programming\Kodi\plugin.video.playstream\resources\lib\demjson.py \Data\Programming\enigma2\PlayStream2\demjson.py
10
+mklink /j \Data\Programming\Kodi\plugin.video.playstream\resources\lib\sources \Data\Programming\enigma2\PlayStream2\sources
11
+mklink /j \Data\Programming\Kodi\plugin.video.playstream\resources\lib\resolvers \Data\Programming\enigma2\PlayStream2\resolvers

+ 0
- 328
playstreamproxy.py View File

@@ -1,328 +0,0 @@
1
-#!/usr/bin/python
2
-"""
3
-StreamProxy daemon (based on Livestream daemon)
4
-Ensures persistent cookies, User-Agents and others tricks to play protected HLS/DASH streams
5
-"""
6
-import os
7
-import sys
8
-import time
9
-import atexit
10
-import re
11
-import binascii
12
-
13
-from signal import SIGTERM
14
-
15
-from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
16
-from SocketServer import ThreadingMixIn
17
-from urllib import unquote, quote
18
-import urllib,urlparse
19
-#import cookielib,urllib2
20
-import requests
21
-try:
22
-    from requests.packages.urllib3.exceptions import InsecureRequestWarning
23
-    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
24
-except:
25
-    pass
26
-
27
-HOST_NAME = ""
28
-PORT_NUMBER = 88
29
-DEBUG = False
30
-
31
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
32
-sessions = {}
33
-
34
-class StreamHandler(BaseHTTPRequestHandler):
35
-
36
-    def do_HEAD(self):
37
-        self.send_response(200)
38
-        self.send_header("Server", "StreamProxy")
39
-        self.send_header("Content-type", "text/html")
40
-        self.end_headers()
41
-
42
-    def do_GET(self):
43
-        """Respond to a GET request."""
44
-        SPLIT_CHAR = "~"
45
-        SPLIT_CODE = "%7E"
46
-        EQ_CODE = "%3D"
47
-        COL_CODE = "%3A"
48
-        self.log_message("get_url: \n%s", self.path)
49
-        p = self.path.split("~")
50
-        url = urllib.unquote(p[0][1:])
51
-        url = url.replace(COL_CODE, ":")
52
-        headers = headers2dict("""
53
-        User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 8_0_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12A366 Safari/600.1.4
54
-        """)
55
-        if len(p)>1:
56
-            for h in p[1:]:
57
-                headers[h.split("=")[0]]=urllib.unquote(h.split("=")[1])
58
-        #self.fetch_offline(self.wfile)
59
-        try:
60
-            self.fetch_url2(self.wfile, url, headers)
61
-        except Exception as e:
62
-            print "Got Exception: ", str(e)
63
-
64
-    def fetch_offline(self,wfile):
65
-        self.send_response(200)
66
-        self.send_header("Server", "StreamProxy")
67
-        self.send_header("Content-type", "video/mp4")
68
-        self.end_headers()
69
-        self.wfile.write(open("offline.mp4", "rb").read())
70
-        self.wfile.close()
71
-
72
-
73
-    def fetch_url2(self, wfile, url, headers):
74
-        if DEBUG: print "\n***********************************************************"
75
-        self.log_message("fetch_url: \n%s", url)
76
-        #self.log_message("headers: %s", headers)
77
-
78
-        base_url = "/".join(url.split("/")[0:-1])
79
-        if base_url not in sessions:
80
-            sessions[base_url]={}
81
-            sessions[base_url]["session"] = requests.Session()
82
-            sessions[base_url]["key"] = binascii.a2b_hex(headers["key"]) if "key" in headers and headers["key"] else None
83
-            #cj = cookielib.CookieJar()
84
-            #sessions[base_url] = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
85
-        else:
86
-            if "key" in headers and headers["key"]: sessions[base_url]["key"] = binascii.a2b_hex(headers["key"])
87
-        ses = sessions[base_url]["session"]
88
-        key = sessions[base_url]["key"]
89
-
90
-        if DEBUG: print "**Request headers: "
91
-        ses.headers.update(headers)
92
-        #ses.addheaders=[]
93
-        for h in ses.headers:
94
-            #ses.addheaders.append((h,headers[h]))
95
-            if DEBUG: print h,"=",ses.headers[h]
96
-        r = ses.get(url, stream=True,verify=False)
97
-        #r = ses.open(url)
98
-        code = r.status_code #r.status_code
99
-        if DEBUG: print "**Response:", code #r.status_code
100
-        if DEBUG: print "**Response headers: "
101
-        for h in r.headers:
102
-            if DEBUG: print h,"=",r.headers[h]
103
-        self.send_response(code)
104
-
105
-        print code
106
-        if code <> 200:
107
-            self.fetch_offline(wfile)
108
-            return
109
-
110
-        if DEBUG: print "**Return headers:"
111
-        headers2 = {}
112
-        for h in r.headers:
113
-            if h.lower() in ("user-agent","server","transfer-encoding","content-encoding","connection"):
114
-                if DEBUG: print h," - skipped"
115
-                continue
116
-            else:
117
-                headers2[h] = r.headers[h]
118
-                if DEBUG:print h,"=",r.headers[h]
119
-
120
-        # Content-Type: application/vnd.apple.mpegurl
121
-        if r.headers["Content-Type"] == "application/vnd.apple.mpegurl" and key:
122
-            content = r.content
123
-            content = r.content.replace(base_url+"/","")
124
-            content = re.sub("#EXT-X-KEY:METHOD=AES-128.+\n", "", content, 0, re.IGNORECASE | re.MULTILINE)
125
-            headers2["Content-Length"] = "%s"%len(content)
126
-            self.send_headers(headers2)
127
-            wfile.write(content)
128
-
129
-        # Content-Type: video/MP2T
130
-        elif r.headers["Content-Type"] == "video/MP2T" and key:
131
-            content = r.content
132
-            from Crypto.Cipher import AES
133
-            iv = content[:16]
134
-            d = AES.new(key, AES.MODE_CBC, iv)
135
-            content = d.decrypt(content[16:])
136
-            headers2["Content-Length"] = "%s"%len(content)
137
-            self.send_headers(headers2)
138
-            wfile.write(content)
139
-
140
-        else:
141
-            self.send_headers(headers2)
142
-            CHUNK_SIZE = 4 * 1024
143
-            if code == 200:
144
-                #while True:
145
-                    #chunk = r.read(CHUNK_SIZE)
146
-                    #if not chunk:
147
-                        #break
148
-                    #wfile.write(chunk)
149
-                #pass
150
-                #wfile.close()
151
-                for chunk in r.iter_content(1024):
152
-                    try:
153
-                        #print "#",
154
-                        wfile.write(chunk)
155
-                    except Exception as e:
156
-                        print "Exception: ", str(e)
157
-                        return
158
-                if DEBUG: print "  = file downloaded = "
159
-                time.sleep(1)
160
-        self.wfile.close()
161
-
162
-    def send_headers(self,headers):
163
-        for h in headers:
164
-            self.send_header(h, headers[h])
165
-        self.end_headers()
166
-
167
-
168
-class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
169
-    """Handle requests in a separate thread."""
170
-
171
-def start(host = HOST_NAME, port = PORT_NUMBER):
172
-    httpd = ThreadedHTTPServer((host, port), StreamHandler)
173
-    print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
174
-    try:
175
-        httpd.serve_forever()
176
-    except KeyboardInterrupt:
177
-        pass
178
-    httpd.server_close()
179
-    print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)
180
-
181
-
182
-class Daemon:
183
-    """
184
-    A generic daemon class.
185
-    Usage: subclass the Daemon class and override the run() method
186
-    """
187
-    def __init__(self, pidfile, stdin="/dev/null", stdout="/dev/null", stderr="/dev/null"):
188
-        self.stdin = stdin
189
-        self.stdout = stdout
190
-        self.stderr = stderr
191
-        self.pidfile = pidfile
192
-
193
-    def daemonize(self):
194
-        """
195
-        do the UNIX double-fork magic, see Stevens' "Advanced
196
-        Programming in the UNIX Environment" for details (ISBN 0201563177)
197
-        http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
198
-        """
199
-        try:
200
-            pid = os.fork()
201
-            if pid > 0:
202
-                # exit first parent
203
-                sys.exit(0)
204
-        except OSError, e:
205
-            sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
206
-            sys.exit(1)
207
-
208
-        # decouple from parent environment
209
-        os.chdir("/")
210
-        os.setsid()
211
-        os.umask(0)
212
-
213
-        # do second fork
214
-        try:
215
-            pid = os.fork()
216
-            if pid > 0:
217
-                # exit from second parent
218
-                sys.exit(0)
219
-        except OSError, e:
220
-            sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
221
-            sys.exit(1)
222
-
223
-        # redirect standard file descriptors
224
-        sys.stdout.flush()
225
-        sys.stderr.flush()
226
-        si = file(self.stdin, "r")
227
-        so = file(self.stdout, "a+")
228
-        se = file(self.stderr, "a+", 0)
229
-        os.dup2(si.fileno(), sys.stdin.fileno())
230
-        os.dup2(so.fileno(), sys.stdout.fileno())
231
-        os.dup2(se.fileno(), sys.stderr.fileno())
232
-
233
-        # write pidfile
234
-        atexit.register(self.delpid)
235
-        pid = str(os.getpid())
236
-        file(self.pidfile,"w+").write("%s\n" % pid)
237
-
238
-    def delpid(self):
239
-        os.remove(self.pidfile)
240
-
241
-    def start(self):
242
-        """
243
-        Start the daemon
244
-        """
245
-        # Check for a pidfile to see if the daemon already runs
246
-        try:
247
-            pf = file(self.pidfile,"r")
248
-            pid = int(pf.read().strip())
249
-            pf.close()
250
-        except IOError:
251
-            pid = None
252
-
253
-        if pid:
254
-            message = "pidfile %s already exist. Daemon already running?\n"
255
-            sys.stderr.write(message % self.pidfile)
256
-            sys.exit(1)
257
-
258
-        # Start the daemon
259
-        self.daemonize()
260
-        self.run()
261
-
262
-    def stop(self):
263
-        """
264
-        Stop the daemon
265
-        """
266
-        # Get the pid from the pidfile
267
-        try:
268
-            pf = file(self.pidfile,"r")
269
-            pid = int(pf.read().strip())
270
-            pf.close()
271
-        except IOError:
272
-            pid = None
273
-
274
-        if not pid:
275
-            message = "pidfile %s does not exist. Daemon not running?\n"
276
-            sys.stderr.write(message % self.pidfile)
277
-            return # not an error in a restart
278
-
279
-        # Try killing the daemon process
280
-        try:
281
-            while 1:
282
-                os.kill(pid, SIGTERM)
283
-                time.sleep(0.1)
284
-        except OSError, err:
285
-            err = str(err)
286
-            if err.find("No such process") > 0:
287
-                if os.path.exists(self.pidfile):
288
-                    os.remove(self.pidfile)
289
-            else:
290
-                print str(err)
291
-                sys.exit(1)
292
-
293
-    def restart(self):
294
-        """
295
-        Restart the daemon
296
-        """
297
-        self.stop()
298
-        self.start()
299
-
300
-    def run(self):
301
-        """
302
-        You should override this method when you subclass Daemon. It will be called after the process has been
303
-        daemonized by start() or restart().
304
-        """
305
-
306
-class ProxyDaemon(Daemon):
307
-    def run(self):
308
-        start()
309
-
310
-if __name__ == "__main__":
311
-    daemon = ProxyDaemon("/var/run/playstreamproxy.pid")
312
-    if len(sys.argv) == 2:
313
-        if "start" == sys.argv[1]:
314
-            daemon.start()
315
-        elif "stop" == sys.argv[1]:
316
-            daemon.stop()
317
-        elif "restart" == sys.argv[1]:
318
-            daemon.restart()
319
-        elif "manualstart" == sys.argv[1]:
320
-            start()
321
-        else:
322
-            print "Unknown command"
323
-            sys.exit(2)
324
-        sys.exit(0)
325
-    else:
326
-        print "usage: %s start|stop|restart|manualstart" % sys.argv[0]
327
-        sys.exit(2)
328
-

+ 513
- 408
project.wpr
File diff suppressed because it is too large
View File


+ 1
- 0
readme.md View File

@@ -10,6 +10,7 @@ Currently implemented:
10 10
 - **lattelecom.tv(shortcut.lv)** - live, archive and video (Latvian, English, Russian), account required
11 11
 - **play24.lv** - RigaTV24 live and archive (Latvian)
12 12
 - **viaplay.lv** - video streams (partly working, only non-DRM - Latvian, Russian)
13
+- **LMT straume** - LMT video streams (Latvian)
13 14
 - **cinemalive.tv** - movies and series in Latvian (partly working)
14 15
 - **movieplace.lv** - movies and series in Latvian (partly working)
15 16
 - **dom.tv** - live and archive of Latvian and Russion TV channels, registration required

BIN
release/plugin.video.playstream-0.1.40.zip View File


BIN
release/plugin.video.playstream-0.1.41.zip View File


BIN
release/plugin.video.playstream-0.1.42.zip View File


BIN
release/plugin.video.playstream-0.1.43.zip View File


BIN
release/plugin.video.playstream-0.1.44.zip View File


+ 6
- 2
resources/language/English/strings.xml View File

@@ -23,11 +23,15 @@
23 23
   <string id="50001">Username</string>
24 24
   <string id="50002">Password</string>
25 25
   <string id="50003">Language</string>
26
+  <string id="50004">Region</string>
26 27
 
27 28
   <string id="50010">Save plugin status between call</string>
28 29
   <string id="50011">Time to live for status</string>
29 30
   <string id="50012">Download directory</string>
30
-  <string id="50013">Start stream proxy</string>
31
-  <string id="50014">Proxy port</string>
31
+  <string id="50013">Start local proxy server</string>
32
+  <string id="50014">Local proxy server port</string>
33
+  <string id="50017">Use proxy for problematic streams</string>
34
+  <string id="50015">Stream proxy url</string>
35
+  <string id="50016">Playlist file (m3u)</string>
32 36
 
33 37
 </strings>

+ 0
- 237
resources/lib/ContentSources.py View File

@@ -1,237 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-
9
-import sys, os, re
10
-import glob, traceback
11
-sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
12
-from sources.SourceBase import stream_type
13
-import util
14
-
15
-
16
-class ContentSources(object):
17
-    """Wrapper for content sources plugin"""
18
-
19
-    #----------------------------------------------------------------------
20
-    def __init__(self, plugin_path):
21
-        self.plugins = {}
22
-        self.error_content = [("..atpakaļ", "back", None, "Kļūda, atgriezties atpakaļ")]
23
-        sys.path.insert(0, plugin_path)
24
-        #for f in os.listdir(plugin_path):
25
-        #for f in next(os.walk(plugin_path))[2]:
26
-        print "ContentSources: Importing sources from "+plugin_path
27
-        files = glob.glob(os.path.join(plugin_path, "*.py"))
28
-        for f in files:
29
-            fname, ext = os.path.splitext(f)
30
-            fname = os.path.split(fname)[1]
31
-            if fname == "__init__": continue
32
-            if ext == '.py':
33
-                mod = __import__(fname)
34
-                reload(mod)
35
-                if "Source" in dir(mod):
36
-                    self.plugins[fname] = mod.Source()
37
-                    print fname+ " imported"
38
-                else:
39
-                    pass
40
-                    #print fname+ "skipped"
41
-        sys.path.pop(0)
42
-        if not "config" in self.plugins:
43
-            raise Exception("Problem importing content sources")
44
-        cfg = self.plugins["config"]
45
-        for pl in self.plugins.keys():
46
-            found = False
47
-            for lst in cfg.get_lists():
48
-                for item in cfg.lists[lst]:
49
-                    if item[1].split("::")[0]==pl:
50
-                        found = True
51
-                        break
52
-                    if found: break
53
-            if not found:
54
-                title = self.plugins[pl].title if "title" in dir(self.plugins[pl]) else pl
55
-                img = self.plugins[pl].img if "img" in dir(self.plugins[pl]) else ""
56
-                desc = self.plugins[pl].desc if "desc" in dir(self.plugins[pl]) else title
57
-                cfg.add_item("home",(title,"%s::home"%pl,img,desc))
58
-                cfg.write_streams()
59
-
60
-    def get_content(self,data):
61
-        source = data.split("::")[0]
62
-        if source in self.plugins:
63
-            content = self.plugins[source].get_content(data)
64
-            if content:
65
-                if isinstance(content,list):
66
-                    for i,item in enumerate(content):
67
-                        item2=[]
68
-                        for el in item:
69
-                            if isinstance(el,unicode):
70
-                                el = el.encode("utf8")
71
-                            item2.append(el)
72
-                        content[i]=tuple(item2)
73
-                else:
74
-                    item2=[]
75
-                    for el in content:
76
-                        if isinstance(el,unicode):
77
-                            el = el.encode("utf8")
78
-                        item2.append(el)
79
-                    content=tuple(item2)
80
-                return content
81
-            else:
82
-                return self.error_content
83
-        else:
84
-            return self.error_content
85
-
86
-    def get_streams(self,data):
87
-        if stream_type(data):
88
-            if "::" in data:
89
-                data = data.split("::")[1]
90
-            content = self.get_content(data)
91
-            stream = util.item()
92
-            stream["name"] = data
93
-            stream["url"] = data
94
-            stream["type"] = stream_type(data)
95
-            #stream["img"] = ""
96
-            #stream["desc"] = ""
97
-            return[stream]
98
-
99
-        if not self.is_video(data):
100
-            return []
101
-        source = data.split("::")[0]
102
-        if source in self.plugins:
103
-            streams = self.plugins[source].get_streams(data)
104
-            for s in streams:
105
-                for k in s:
106
-                    if isinstance(s[k],unicode):
107
-                        s[k] = s[k].encode("utf8")
108
-                if not "resolver" in s:
109
-                    s["resolver"] = source
110
-                if not "surl" in s or not s["surl"]:
111
-                    s["surl"] = data
112
-                if not "nfo" in s:
113
-                    s["nfo"]={"movie":{"title":s["name"],"thumb":s["img"],"plot":s["desc"]}}
114
-            return streams
115
-        else:
116
-            return []
117
-
118
-    def get_info(self,data):
119
-        nfo = {}
120
-        if self.is_video(data):
121
-            source = data.split("::")[0]
122
-            if source in self.plugins:
123
-                if "get_info" in dir(self.plugins[source]):
124
-                    streams = self.get_streams(data)
125
-                    nfo = streams[0]["nfo"] if streams and "nfo" in streams[0] else {}
126
-                else:
127
-                    nfo = self.plugins[source].get_info(data)
128
-        else:
129
-            pass    # TODO create nfo for listing
130
-        return nfo
131
-
132
-
133
-    def stream_type(self,data):
134
-        return stream_type(data)
135
-
136
-    def is_video(self,data):
137
-        if self.stream_type(data):
138
-            return True
139
-        source = data.split("::")[0]
140
-        if source in self.plugins:
141
-            return self.plugins[source].is_video(data)
142
-        else:
143
-            return False
144
-
145
-    def options_read(self,source):
146
-        if source in self.plugins:
147
-            options = self.plugins[source].options_read()
148
-            if options:
149
-                return options
150
-            else:
151
-                return None
152
-        else:
153
-            return None
154
-
155
-    def options_write(self,source,options):
156
-        if source in self.plugins:
157
-            return self.plugins[source].options_write(options)
158
-        else:
159
-            return None
160
-
161
-if __name__ == "__main__":
162
-
163
-    sources = ContentSources("sources")
164
-    if len(sys.argv)>1:
165
-        data= sys.argv[1]
166
-    else:
167
-        data = "config::home"
168
-
169
-    #options = sources.options_read("ltc")
170
-    #print options
171
-    history = []
172
-    cur = ("Home",data,None,None)
173
-    content = sources.get_content(cur[1])
174
-
175
-    exit_loop = False
176
-    while True:
177
-        print
178
-        for i,item in enumerate(content):
179
-            s = "%i: %s - %s %s"%(i,item[0],item[1],item[2])
180
-            print s #.encode(sys.stdout.encoding,"replace")
181
-
182
-        while True:
183
-            a = raw_input("Enter numeber, q for exit: ")
184
-            if a in ("q","Q","x","X"):
185
-                exit_loop = True
186
-                print "Exiting"
187
-                break
188
-            try:
189
-                n = int(a)
190
-                break
191
-            except:
192
-                print "Not number!"
193
-        if exit_loop: break
194
-        cur2 = content[n]
195
-
196
-        data0 = cur2[1].split("::")[1] if "::" in cur2[1] else cur2[1]
197
-        if not data0:
198
-            pass
199
-
200
-        elif cur2[1] == "back":
201
-            cur = history.pop()
202
-        elif sources.is_video(cur2[1]):
203
-            if sources.stream_type(cur2[1]):
204
-                stream = util.item()
205
-                stream["url"] = cur2[1]
206
-                stream["name"] = cur2[0]
207
-                streams = [stream]
208
-            else:
209
-                try:
210
-                    streams = sources.get_streams(cur2[1])
211
-                except Exception as e:
212
-                    print unicode(e)
213
-                    traceback.print_exc()
214
-                    streams = []
215
-            if streams:
216
-                util.play_video(streams)
217
-            else:
218
-                print "**No stream to play - %s "%(
219
-                    cur2[1])
220
-                raw_input("Press any key")
221
-            #import os
222
-            #os.system('"c:\Program Files (x86)\VideoLAN\VLC\vlc.exe" "%s"'%cur2[1])
223
-
224
-        else:
225
-            if "{0}" in cur2[1]:
226
-                a = raw_input("Enter value:")
227
-                cur2 = (cur2[0],cur2[1].format(a),cur2[2],cur2[3])
228
-            history.append(cur)
229
-            cur = cur2
230
-        try:
231
-            content = sources.get_content(cur[1])
232
-        except Exception as e:
233
-            print unicode(e)
234
-            traceback.print_exc()
235
-            raw_input("Continue?")
236
-
237
-

+ 0
- 272
resources/lib/Downloader.py View File

@@ -1,272 +0,0 @@
1
-#from boxbranding import getMachineBrand, getMachineName
2
-import sys,os, os.path, re
3
-import urlparse, requests
4
-from twisted.web import client
5
-from twisted.internet import reactor, defer, ssl
6
-
7
-USER_AGENT = "Enigma2 HbbTV/1.1.1 (+PVR+RTSP+DL;OpenATV;;;)"
8
-
9
-#####################################################################################################
10
-class HTTPProgressDownloader(client.HTTPDownloader):
11
-    def __init__(self, url, outfile, headers=None):
12
-        agent = USER_AGENT
13
-        if headers and "user-agent" in headers:
14
-            agent = headers["user-agent"]
15
-        if headers and "User-Agent" in headers:
16
-            agent = headers["User-Agent"]
17
-        client.HTTPDownloader.__init__(self, url, outfile, headers=headers, agent=agent)
18
-        self.status = None
19
-        self.progress_callback = None
20
-        self.deferred = defer.Deferred()
21
-
22
-    def noPage(self, reason):
23
-        if self.status == "304":
24
-            print reason.getErrorMessage()
25
-            client.HTTPDownloader.page(self, "")
26
-        else:
27
-            client.HTTPDownloader.noPage(self, reason)
28
-
29
-    def gotHeaders(self, headers):
30
-        if self.status == "200":
31
-            if headers.has_key("content-length"):
32
-                self.totalbytes = int(headers["content-length"][0])
33
-            else:
34
-                self.totalbytes = 0
35
-            self.currentbytes = 0.0
36
-        return client.HTTPDownloader.gotHeaders(self, headers)
37
-
38
-    def pagePart(self, packet):
39
-        if self.status == "200":
40
-            self.currentbytes += len(packet)
41
-        if self.totalbytes and self.progress_callback:
42
-            self.progress_callback(self.currentbytes, self.totalbytes)
43
-        return client.HTTPDownloader.pagePart(self, packet)
44
-
45
-    def pageEnd(self):
46
-        return client.HTTPDownloader.pageEnd(self)
47
-
48
-class DownloadWithProgress:
49
-    def __init__(self, url, outputfile, headers=None, limit=0, contextFactory=None, *args, **kwargs):
50
-        self.limit = limit
51
-        uri = urlparse.urlparse(url)
52
-        scheme = uri.scheme
53
-        host = uri.hostname
54
-        port = uri.port if uri.port else 80
55
-        path = uri.path
56
-        if not headers:
57
-            headers = {"user-agent":USER_AGENT}
58
-        self.factory = HTTPProgressDownloader(url, outputfile, headers, *args, **kwargs)
59
-        if scheme == "https":
60
-            self.connection = reactor.connectSSL(host, port, self.factory, ssl.ClientContextFactory())
61
-        else:
62
-            self.connection = reactor.connectTCP(host, port, self.factory)
63
-
64
-    def start(self):
65
-        return self.factory.deferred
66
-
67
-    def stop(self):
68
-        if self.connection:
69
-            print "[stop]"
70
-            self.connection.disconnect()
71
-
72
-    def addProgress(self, progress_callback):
73
-        print "[addProgress]"
74
-        self.factory.progress_callback = progress_callback
75
-
76
-#####################################################################################################
77
-class DownloadWithProgressFragmented:
78
-    def __init__(self, url, outputfile, headers = None, limit = 0, contextFactory=None, *args, **kwargs):
79
-        self.url = url
80
-        self.outputfile = outputfile
81
-        self.base_url = "/".join(url.split("/")[:-1])+"/"
82
-        self.headers = headers if headers else  {"user-agent":"Enigma2"}
83
-        self.limit = limit
84
-        self.agent = kwargs["agent"] if "agent" in kwargs else None
85
-        self.cookie = kwargs["cookie"] if "cookie" in kwargs else None
86
-        self.deferred = defer.Deferred()
87
-        #self.deferred.addCallback(self.start_download)
88
-
89
-    def start_download(self):
90
-        print "Start download"
91
-        try:
92
-            r = requests.get(self.url,headers=self.headers)
93
-        except Exception as e:
94
-            #self.deferred.errback("Cannot open manifsest file - %s"%url)
95
-            self.deferred.errback(e)
96
-        if not r.content.startswith("#EXTM3U"):
97
-            self.deferred.errback(Exception("Not valid manifest file - %s"%self.url))
98
-        streams = re.findall(r"#EXT-X-STREAM-INF:.*?BANDWIDTH=(\d+).*?\n(.+?)$", r.content, re.IGNORECASE | re.MULTILINE)
99
-        if streams:
100
-            sorted(streams, key=lambda item: int(item[0]), reverse=True)
101
-            url = streams[0][1]
102
-            if not url.startswith("http"):
103
-                url = self.base_url + url
104
-            try:
105
-                r = requests.get(url, headers=self.headers)
106
-            except Exception as e:
107
-                self.deferred.errback(Exception("Cannot open manifsest file - %s"%url))
108
-        self.ts_list = re.findall(r"#EXTINF:([\d\.]+),.*?\n(.+?)$", r.content, re.IGNORECASE | re.MULTILINE)
109
-        if not len(self.ts_list):
110
-            self.deferred.errback(Exception("Cannot read fragment list in  manifsest file - %s"%url))
111
-        self.ts_num = 0
112
-        self.type = "vod" if "#EXT-X-ENDLIST" in r.content else "live"
113
-        self.currentbytes = 0.0
114
-        self.totalbytes = -1
115
-        self.currenttime = 0.0
116
-        self.totaltime = sum(map(float,zip(*self.ts_list)[0]))
117
-        try:
118
-            self.ts_file = open(self.outputfile, "wb")
119
-        except Exception as e:
120
-            self.deferred.errback(Exception("Cannot open output file - %s" % self.outputfile))
121
-        self.download_fragment()
122
-
123
-    def download_fragment(self):
124
-        if self.ts_num>=len(self.ts_list):
125
-            pass
126
-            print "Call later"
127
-            reactor.callLater(10,self.update_manifest)
128
-            reactor.callLater(10, self.download_fragment)
129
-        else:
130
-            print "Start fragment download"
131
-            url = self.ts_list[self.ts_num][1]
132
-            if not "://" in url:
133
-                url = self.base_url+url
134
-            self.d = client.getPage(url,headers = self.headers)
135
-            self.d.addCallbacks(self.download_ok,self.download_err)
136
-
137
-
138
-    def download_ok(self,content):
139
-        content_length = len(content)
140
-        self.currentbytes += content_length
141
-        self.currenttime += float(self.ts_list[self.ts_num][0])
142
-        self.totalbytes = self.currentbytes * self.totaltime / self.currenttime
143
-        self.ts_num += 1
144
-        #print "Fragment %s downloaded (%s)"%(self.ts_num,len(content))
145
-        self.ts_file.write(content)
146
-        self.progress_callback(self.currentbytes, self.totalbytes)
147
-        if self.type == "vod":
148
-            if self.ts_num >= len(self.ts_list) or (self.limit and self.currenttime>self.limit):
149
-                self.ts_file.close()
150
-                self.download_finished()
151
-            else:
152
-                self.download_fragment()
153
-        else:
154
-            if self.limit and self.currenttime>self.limit: # TODO
155
-                self.ts_file.close()
156
-                self.download_finished()
157
-            else:
158
-                self.download_fragment()
159
-
160
-    def update_manifest(self):
161
-        self.d2 = client.getPage(self.url, headers=self.headers)
162
-        self.d2.addCallbacks(self.update_manifest_ok, self.update_manifest_err)
163
-
164
-    def update_manifest_ok(self,content):
165
-        print "Update manifest"
166
-        ts_list = re.findall(r"#EXTINF:([\d\.]+),\n(.+?)$", content, re.IGNORECASE | re.MULTILINE)
167
-        last_ts = self.ts_list[-1]
168
-        found = False
169
-        for ts in ts_list:
170
-            if ts == last_ts:
171
-                found = True
172
-            elif found:
173
-                print "Append %s"%ts[1]
174
-                self.ts_list.append(ts)
175
-        #reactor.callLater(5,self.download_fragment)
176
-
177
-    def update_manifest_err(self,content):
178
-        return
179
-
180
-    def download_err(self,content):
181
-        self.deferred.errback("Error while downloading %s"%self.ts_list[self.ts_num][1])
182
-
183
-    def download_finished(self):
184
-        self.totalbytes = self.currentbytes
185
-        self.deferred.callback("Done")
186
-
187
-    def start(self):
188
-        reactor.callLater(1,self.start_download)
189
-        return self.deferred
190
-
191
-    def stop(self):
192
-        self.deferred.errback() # TODO
193
-
194
-    def addProgress(self, progress_callback):
195
-        print "[addProgress]"
196
-        self.progress_callback = progress_callback
197
-
198
-#####################################################################################################
199
-def get_header(url,headers=None):
200
-    headers = {"user-agent":USER_AGENT}
201
-    r = requests.head(url,headers=headers)
202
-    return r.headers
203
-
204
-def get_ext(mtype):
205
-    stype = "http"
206
-    if mtype in ("vnd.apple.mpegURL","application/x-mpegURL",'application/x-mpegurl',"application/vnd.apple.mpegurl"):
207
-        return ".ts","hls"
208
-    elif mtype in ("application/dash+xml"):
209
-        return ".ts","dash" # TODO dash stream type  could be different !
210
-    elif mtype in ("video/mp4"):
211
-        return ".mp4","http"
212
-    elif mtype in ("video/MP2T","video/mp2t"):
213
-        return ".ts","http"
214
-    elif mtype in ("video/x-flv"):
215
-        return ".flv","http"
216
-    elif mtype in ("video/quicktime"):
217
-        return ".mov","http"
218
-    elif mtype in ("video/x-msvideo"):
219
-        return ".avi","http"
220
-    elif mtype in ("video/x-ms-wmv"):
221
-        return ".wmv","http"
222
-    elif mtype in ("video/x-matroska"):
223
-        return ".mkv","http"
224
-    else:
225
-        return ".mp4","http"
226
-
227
-
228
-
229
-##############################################
230
-def print_progress(currentbytes, totalbytes):
231
-    progress = float(currentbytes)/float(totalbytes)*100
232
-    print "%s (%i/%i)"%(progress,currentbytes,totalbytes)
233
-
234
-def download_ok(*args):
235
-    print "Download OK"
236
-    reactor.stop()
237
-
238
-def download_err(e):
239
-    print "Download Error %s"%e.getBriefTraceback()
240
-    pass
241
-def stop():
242
-    reactor.stop()
243
-###############################################
244
-
245
-if __name__ == "__main__":
246
-    if len(sys.argv)>2:
247
-        url= sys.argv[1]
248
-        output = sys.argv[1]
249
-    else:
250
-        url = "http://walterebert.com/playground/video/hls/ts/480x270.m3u8"
251
-        url = "http://techslides.com/demos/sample-videos/small.mp4"
252
-        #url = "http://wx17.poiuytrew.pw/s/c507282042b1bf25e0b72c34a68426f3/hd_30/Jackie.2016.D.iTunes.BDRip.1080p_720.mp4"
253
-        url = "http://player.tvnet.lv/live/amlst:11/chunklist_w361981294_b528000.m3u8"
254
-        #url = "http://vod-hls-uk-live.akamaized.net/usp/auth/vod/piff_abr_full_hd/a3e90e-b08ktytr/vf_b08ktytr_f9d55583-afc7-49bb-9bf4-d8f1ac99f56f.ism.hlsv2.ism/vf_b08ktytr_f9d55583-afc7-49bb-9bf4-d8f1ac99f56f.ism.hlsv2-audio=128000-video=5070000.m3u8"
255
-        #url = "https://58174450afee9.streamlock.net/vod/mp4:_definst_/f/e/8e49fc32.mp4/playlist.m3u8?safwerwfasendtime=1490877870&safwerwfasstarttime=1490859339&safwerwfashash=hS2FfVZysQVazBQ6RJn1IhUevBkKxIF09Ly3BjfT43U="
256
-    try:
257
-        h = get_header(url,headers={"user-agent":"Enigma2"})
258
-        mtype = h.get("content-type")
259
-        ext,stream_type = get_ext(mtype)
260
-    except:
261
-        ext,stream_type = (".ts","hls")
262
-    output = urlparse.urlparse(url)[2].split('/')[-1] + ext
263
-    output = os.path.join("downloads", output)
264
-    if stream_type == "hls":
265
-        d = DownloadWithProgressFragmented(url,output,headers={"user-agent":"Enigma2"})
266
-    else:
267
-        d = DownloadWithProgress(url,output,headers={"user-agent":"Enigma2"})
268
-    d.addProgress(print_progress)
269
-    d.start().addCallback(download_ok).addErrback(download_err)
270
-    reactor.run()
271
-
272
-

+ 1
- 0
resources/lib/content

@@ -0,0 +1 @@
1
+Subproject commit c417a711b9e4bf6c08a014573ddfa02f19869401

+ 0
- 6281
resources/lib/demjson.py
File diff suppressed because it is too large
View File


+ 0
- 127
resources/lib/ordereddict.py View File

@@ -1,127 +0,0 @@
1
-# Copyright (c) 2009 Raymond Hettinger
2
-#
3
-# Permission is hereby granted, free of charge, to any person
4
-# obtaining a copy of this software and associated documentation files
5
-# (the "Software"), to deal in the Software without restriction,
6
-# including without limitation the rights to use, copy, modify, merge,
7
-# publish, distribute, sublicense, and/or sell copies of the Software,
8
-# and to permit persons to whom the Software is furnished to do so,
9
-# subject to the following conditions:
10
-#
11
-#     The above copyright notice and this permission notice shall be
12
-#     included in all copies or substantial portions of the Software.
13
-#
14
-#     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
-#     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16
-#     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
-#     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18
-#     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19
-#     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
-#     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21
-#     OTHER DEALINGS IN THE SOFTWARE.
22
-
23
-from UserDict import DictMixin
24
-
25
-class OrderedDict(dict, DictMixin):
26
-
27
-    def __init__(self, *args, **kwds):
28
-        if len(args) > 1:
29
-            raise TypeError('expected at most 1 arguments, got %d' % len(args))
30
-        try:
31
-            self.__end
32
-        except AttributeError:
33
-            self.clear()
34
-        self.update(*args, **kwds)
35
-
36
-    def clear(self):
37
-        self.__end = end = []
38
-        end += [None, end, end]         # sentinel node for doubly linked list
39
-        self.__map = {}                 # key --> [key, prev, next]
40
-        dict.clear(self)
41
-
42
-    def __setitem__(self, key, value):
43
-        if key not in self:
44
-            end = self.__end
45
-            curr = end[1]
46
-            curr[2] = end[1] = self.__map[key] = [key, curr, end]
47
-        dict.__setitem__(self, key, value)
48
-
49
-    def __delitem__(self, key):
50
-        dict.__delitem__(self, key)
51
-        key, prev, next = self.__map.pop(key)
52
-        prev[2] = next
53
-        next[1] = prev
54
-
55
-    def __iter__(self):
56
-        end = self.__end
57
-        curr = end[2]
58
-        while curr is not end:
59
-            yield curr[0]
60
-            curr = curr[2]
61
-
62
-    def __reversed__(self):
63
-        end = self.__end
64
-        curr = end[1]
65
-        while curr is not end:
66
-            yield curr[0]
67
-            curr = curr[1]
68
-
69
-    def popitem(self, last=True):
70
-        if not self:
71
-            raise KeyError('dictionary is empty')
72
-        if last:
73
-            key = reversed(self).next()
74
-        else:
75
-            key = iter(self).next()
76
-        value = self.pop(key)
77
-        return key, value
78
-
79
-    def __reduce__(self):
80
-        items = [[k, self[k]] for k in self]
81
-        tmp = self.__map, self.__end
82
-        del self.__map, self.__end
83
-        inst_dict = vars(self).copy()
84
-        self.__map, self.__end = tmp
85
-        if inst_dict:
86
-            return (self.__class__, (items,), inst_dict)
87
-        return self.__class__, (items,)
88
-
89
-    def keys(self):
90
-        return list(self)
91
-
92
-    setdefault = DictMixin.setdefault
93
-    update = DictMixin.update
94
-    pop = DictMixin.pop
95
-    values = DictMixin.values
96
-    items = DictMixin.items
97
-    iterkeys = DictMixin.iterkeys
98
-    itervalues = DictMixin.itervalues
99
-    iteritems = DictMixin.iteritems
100
-
101
-    def __repr__(self):
102
-        if not self:
103
-            return '%s()' % (self.__class__.__name__,)
104
-        return '%s(%r)' % (self.__class__.__name__, self.items())
105
-
106
-    def copy(self):
107
-        return self.__class__(self)
108
-
109
-    @classmethod
110
-    def fromkeys(cls, iterable, value=None):
111
-        d = cls()
112
-        for key in iterable:
113
-            d[key] = value
114
-        return d
115
-
116
-    def __eq__(self, other):
117
-        if isinstance(other, OrderedDict):
118
-            if len(self) != len(other):
119
-                return False
120
-            for p, q in  zip(self.items(), other.items()):
121
-                if p != q:
122
-                    return False
123
-            return True
124
-        return dict.__eq__(self, other)
125
-
126
-    def __ne__(self, other):
127
-        return not self == other

+ 0
- 137
resources/lib/resolver.py View File

@@ -1,137 +0,0 @@
1
-# *      Copyright (C) 2011 Libor Zoubek
2
-# *      Modified by ivars777
3
-# *      Based in code from https://github.com/kodi-czsk/script.module.stream.resolver
4
-# *
5
-# *
6
-# *  This Program is free software; you can redistribute it and/or modify
7
-# *  it under the terms of the GNU General Public License as published by
8
-# *  the Free Software Foundation; either version 2, or (at your option)
9
-# *  any later version.
10
-# *
11
-# *  This Program is distributed in the hope that it will be useful,
12
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
-# *  GNU General Public License for more details.
15
-# *
16
-# *  You should have received a copy of the GNU General Public License
17
-# *  along with this program; see the file COPYING.  If not, write to
18
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
-# *  http://www.gnu.org/copyleft/gpl.html
20
-# *
21
-# */
22
-# Based in code from https://github.com/kodi-czsk/script.module.stream.resolver
23
-
24
-import re
25
-import traceback
26
-
27
-import util
28
-import sys,os
29
-#sys.path.insert(0,os.path.dirname(os.path.abspath(__file__)))
30
-server_path = "resolvers"
31
-sys.path.append(os.path.join(os.path.dirname(__file__), server_path))
32
-
33
-RESOLVERS = []
34
-util.debug('%s searching for modules' % __name__)
35
-
36
-for module in os.listdir(os.path.join(os.path.dirname(__file__), server_path)):
37
-    if module == '__init__.py' or module[-3:] != '.py':
38
-        continue
39
-    module = module[:-3]
40
-    #exec 'import %s' % module
41
-    #resolver = eval(module)
42
-    resolver = __import__(module)
43
-    #reload(resolver)
44
-
45
-    if not hasattr(resolver, 'resolve'):
46
-        continue
47
-    print 'found %s %s' % (resolver, dir(resolver))
48
-    #util.debug('found %s %s' % (resolver, dir(resolver)))
49
-    if not hasattr(resolver, '__priority__'):
50
-        resolver.__priority__ = 0
51
-    RESOLVERS.append(resolver)
52
-    del module
53
-RESOLVERS = sorted(RESOLVERS, key=lambda m: -m.__priority__)
54
-
55
-
56
-def resolve(url):
57
-    """
58
-        resolves given url by asking all resolvers
59
-        returns Array of resolved objects in positive usecase
60
-    """
61
-    url = util.decode_html(url)
62
-    util.info('Resolving ' + url)
63
-    resolver = _get_resolver(url)
64
-    if resolver is None:
65
-        return []
66
-    util.info('Using resolver \'%s\'' % str(resolver.__name__));
67
-    value = resolver.resolve(url)
68
-    if not value:
69
-        return []
70
-    default = util.item()
71
-    for i in value:
72
-        i["resolver"] = resolver.__name__
73
-        if 'name' not in i.keys():
74
-            i['name'] = resolver.__name__
75
-        i['surl'] = url
76
-        for key in default.keys():
77
-            if key not in i.keys():
78
-                i[key] = default[key]
79
-        if "|" in i["url"]:
80
-            headers = i["url"].split("|")[1]
81
-            i["url"]=i["url"].split("|")[0]
82
-            for h in headers.split("&"):
83
-                if "=" in h:
84
-                    i["headers"][h.split("=")[0]] = h.split("=")[1]
85
-
86
-    return sorted(value, key=lambda i: i['quality'], reverse=True) # TODO sorted by order?
87
-
88
-
89
-def _get_resolver(url):
90
-    util.debug('Get resolver for ' + url)
91
-    for r in RESOLVERS:
92
-        util.debug('querying %s' % r)
93
-        if r.supports(url):
94
-            return r
95
-
96
-def can_resolve(url):
97
-    """ Returns true if we are able to resolve stream by given URL """
98
-    return _get_resolver(url) is not None
99
-
100
-
101
-if __name__ == "__main__":
102
-
103
-    from subprocess import call
104
-    #url = "http://hqq.tv/player/embed_player.php?vid=235238210241210222228241233208212245&autoplay=no"
105
-    #url = "http://hqq.tv/player/embed_player.php?vid=243221241234244238208213206212211231&autoplay=no"
106
-    url = "http://hqq.tv/player/embed_player.php?vid=208231211231207221227243206206221244&autoplay=no"
107
-    #url = "https://openload.co/embed/TMthIdpy4PI/"
108
-    #url = "https://www.youtube.com/watch?v=Tx1K51_F99o"
109
-    #url = "https://www.youtube.com/watch?v=8BkcX7O1890"
110
-    #url = "https://www.youtube.com/watch?v=Se07R8SYsg0"
111
-    #url = "https://kinostok.tv/embed/731f3437e3c53104dd56d04039a0b15a"
112
-    #url = "http://vk.com/video_ext.php?oid=246066565&id=169244575&hash=d430ab0e76c9f7a1&hd=3"
113
-    #url ="https://openload.co/embed/rPMXJYPTkw4/"
114
-    #url = "https://openload.co/embed/bE7WfZ-vz_A/"
115
-    #url = "https://openload.co/embed/bE7WfZ/"
116
-    #url = "https://openload.co/embed/OuskaKyC2GU/"
117
-    url = "http://hqq.tv/player/embed_player.php?vid=235238210241210222228241233208212245&autoplay=no"
118
-    url = "https://hqq.tv/player/embed_player.php?vid=235242211228257255206246241253244213194271217261258"
119
-    #url = "https://openload.co/embed/rmNcP-0QopE/"
120
-    #url = "https://openload.co/embed/gpLF6Grzy80/"
121
-    #url = "https://openload.co/embed/oQLXcU1ITAY/"
122
-    #url = "http://hqq.tv/player/embed_player.php?vid=245208228234224222241224221239207212&autoplay=no"
123
-    url = "https://goo.gl/yMTzqf"
124
-    url = "http://cdn.kapnob.ru/video/5e67c8b1ad018ffa/iframe"
125
-    url = "http://kodik.cc/video/10830/4269a802d1a9d9bdc53fe38488d53a52/720p"
126
-    streams = resolve(url)
127
-    if not streams:
128
-        print "No streams found"
129
-        sys.exit()
130
-
131
-    for s in streams:
132
-        print s
133
-
134
-    print streams[0]["url"]
135
-    util.play_video(streams)
136
-    ##call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",streams[0]["url"]])
137
-    pass

+ 0
- 31
resources/lib/resolvers/__init__.py View File

@@ -1,31 +0,0 @@
1
-#/*
2
-# *      Copyright (C) 2011 Libor Zoubek
3
-# *
4
-# *
5
-# *  This Program is free software; you can redistribute it and/or modify
6
-# *  it under the terms of the GNU General Public License as published by
7
-# *  the Free Software Foundation; either version 2, or (at your option)
8
-# *  any later version.
9
-# *
10
-# *  This Program is distributed in the hope that it will be useful,
11
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
-# *  GNU General Public License for more details.
14
-# *
15
-# *  You should have received a copy of the GNU General Public License
16
-# *  along with this program; see the file COPYING.  If not, write to
17
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18
-# *  http://www.gnu.org/copyleft/gpl.html
19
-# *
20
-# */
21
-
22
-
23
-##########################################################3
24
-# all resolvers modules in this directory must have following methods:
25
-
26
-# __name__ - name of the resolver module - can override module filename
27
-# def supports(url) - returns true iff resolver is able to resolve url to stream otherwise false
28
-# def resolve(url) - returns array of all hashmaps that were resolved
29
-#   - if resolving fails, nothing is returned
30
-#   - a hash MUST contain key 'url' - it's value is stream URL
31
-#   - optional keys are 'subs' (link to subtitle), 'quality' (quality string like '240p' or just 'HD'

+ 0
- 209
resources/lib/resolvers/aadecode.py View File

@@ -1,209 +0,0 @@
1
-#-*- coding: utf-8 -*-
2
-#
3
-# author : Djeman
4
-# Updated by Shani-08 (https://github.com/Shani-08/ShaniXBMCWork2)
5
-
6
-import re
7
-
8
-class AADecoder(object):
9
-    def __init__(self, aa_encoded_data):
10
-        self.encoded_str = aa_encoded_data.replace('/*´∇`*/','')
11
-
12
-        self.b = ["(c^_^o)", "(゚Θ゚)", "((o^_^o) - (゚Θ゚))", "(o^_^o)",
13
-                  "(゚ー゚)", "((゚ー゚) + (゚Θ゚))", "((o^_^o) +(o^_^o))", "((゚ー゚) + (o^_^o))",
14
-                  "((゚ー゚) + (゚ー゚))", "((゚ー゚) + (゚ー゚) + (゚Θ゚))", "(゚Д゚) .゚ω゚ノ", "(゚Д゚) .゚Θ゚ノ",
15
-                  "(゚Д゚) ['c']", "(゚Д゚) .゚ー゚ノ", "(゚Д゚) .゚Д゚ノ", "(゚Д゚) [゚Θ゚]"]
16
-
17
-    def is_aaencoded(self):
18
-        idx = self.encoded_str.find("゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); ")
19
-        if idx == -1:
20
-            return False
21
-
22
-        if self.encoded_str.find("(゚Д゚)[゚o゚]) (゚Θ゚)) ('_');", idx) == -1:
23
-            return False
24
-
25
-        return True
26
-
27
-    def base_repr(self, number, base=2, padding=0):
28
-        digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
29
-        if base > len(digits):
30
-            base = len(digits)
31
-
32
-        num = abs(number)
33
-        res = []
34
-        while num:
35
-            res.append(digits[num % base])
36
-            num //= base
37
-        if padding:
38
-            res.append('0' * padding)
39
-        if number < 0:
40
-            res.append('-')
41
-        return ''.join(reversed(res or '0'))
42
-
43
-    def decode_char(self, enc_char, radix):
44
-        end_char = "+ "
45
-        str_char = ""
46
-        while enc_char != '':
47
-            found = False
48
-
49
-            if not found:
50
-                for i in range(len(self.b)):             
51
-                    enc_char=enc_char.replace(self.b[i], str(i))
52
-                
53
-                startpos=0
54
-                findClose=True
55
-                balance=1
56
-                result=[]
57
-                if enc_char.startswith('('):
58
-                    l=0
59
-                    
60
-                    for t in enc_char[1:]:
61
-                        l+=1
62
-                        if findClose and t==')':
63
-                            balance-=1;
64
-                            if balance==0:
65
-                                result+=[enc_char[startpos:l+1]]
66
-                                findClose=False
67
-                                continue
68
-                        elif not findClose and t=='(':
69
-                            startpos=l
70
-                            findClose=True
71
-                            balance=1
72
-                            continue
73
-                        elif t=='(':
74
-                            balance+=1
75
-                 
76
-
77
-                if result is None or len(result)==0:
78
-                    return ""
79
-                else:
80
-                    
81
-                    for r in result:
82
-                        value = self.decode_digit(r, radix)
83
-                        if value == "":
84
-                            return ""
85
-                        else:
86
-                            str_char += value
87
-                            
88
-                    return str_char
89
-
90
-            enc_char = enc_char[len(end_char):]
91
-
92
-        return str_char
93
-
94
-        
95
-              
96
-    def decode_digit(self, enc_int, radix):
97
-
98
-        rr = '(\(.+?\)\))\+'
99
-        rerr=enc_int.split('))+')
100
-        v = ''
101
-        
102
-        #new mode
103
-
104
-        for c in rerr:
105
-            
106
-            if len(c)>0:
107
-                if c.strip().endswith('+'):
108
-                    c=c.strip()[:-1]
109
-
110
-                startbrackets=len(c)-len(c.replace('(',''))
111
-                endbrackets=len(c)-len(c.replace(')',''))
112
-                    
113
-                if startbrackets>endbrackets:
114
-                    c+=')'*startbrackets-endbrackets
115
-                    
116
-                c = c.replace('!+[]','1')
117
-                c = c.replace('-~','1+')
118
-                c = c.replace('[]','0')
119
-                    
120
-                v+=str(eval(c))
121
-                    
122
-        return v
123
-         
124
-        mode = 0
125
-        value = 0
126
-
127
-        while enc_int != '':
128
-            found = False
129
-            for i in range(len(self.b)):
130
-                if enc_int.find(self.b[i]) == 0:
131
-                    if mode == 0:
132
-                        value += i
133
-                    else:
134
-                        value -= i
135
-                    enc_int = enc_int[len(self.b[i]):]
136
-                    found = True
137
-                    break
138
-
139
-            if not found:
140
-                return ""
141
-
142
-            enc_int = re.sub('^\s+|\s+$', '', enc_int)
143
-            if enc_int.find("+") == 0:
144
-                mode = 0
145
-            else:
146
-                mode = 1
147
-
148
-            enc_int = enc_int[1:]
149
-            enc_int = re.sub('^\s+|\s+$', '', enc_int)
150
-
151
-        return self.base_repr(value, radix)
152
-
153
-    def decode(self):
154
-
155
-        self.encoded_str = re.sub('^\s+|\s+$', '', self.encoded_str)
156
-
157
-        # get data
158
-        pattern = (r"\(゚Д゚\)\[゚o゚\]\+ (.+?)\(゚Д゚\)\[゚o゚\]\)")
159
-        result = re.search(pattern, self.encoded_str, re.DOTALL)
160
-        if result is None:
161
-            print "AADecoder: data not found"
162
-            return False
163
-
164
-        data = result.group(1)
165
-
166
-        # hex decode string
167
-        begin_char = "(゚Д゚)[゚ε゚]+"
168
-        alt_char = "(o゚ー゚o)+ "
169
-
170
-        out = ''
171
-
172
-        while data != '':
173
-            # Check new char
174
-            if data.find(begin_char) != 0:
175
-                print "AADecoder: data not found"
176
-                return False
177
-
178
-            data = data[len(begin_char):]
179
-
180
-            # Find encoded char
181
-            enc_char = ""
182
-            if data.find(begin_char) == -1:
183
-                enc_char = data
184
-                data = ""
185
-            else:
186
-                enc_char = data[:data.find(begin_char)]
187
-                data = data[len(enc_char):]
188
-
189
-            
190
-            radix = 8
191
-            # Detect radix 16 for utf8 char
192
-            if enc_char.find(alt_char) == 0:
193
-                enc_char = enc_char[len(alt_char):]
194
-                radix = 16
195
-
196
-            str_char = self.decode_char(enc_char, radix)
197
-            
198
-            if str_char == "":
199
-                print "no match :  "
200
-                print  data + "\nout = " + out + "\n"
201
-                return False
202
-            
203
-            out += chr(int(str_char, radix))
204
-
205
-        if out == "":
206
-            print "no match : " + data
207
-            return False
208
-
209
-        return out

+ 0
- 100
resources/lib/resolvers/hdgo.py View File

@@ -1,100 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# /*
3
-# *      Copyright (C) 2016 ivars777
4
-# *
5
-# *
6
-# *  This Program is free software; you can redistribute it and/or modify
7
-# *  it under the terms of the GNU General Public License as published by
8
-# *  the Free Software Foundation; either version 2, or (at your option)
9
-# *  any later version.
10
-# *
11
-# *  This Program is distributed in the hope that it will be useful,
12
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
-# *  GNU General Public License for more details.
15
-# *
16
-# *  You should have received a copy of the GNU General Public License
17
-# *  along with this program; see the file COPYING.  If not, write to
18
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
-# *  http://www.gnu.org/copyleft/gpl.html
20
-# *
21
-# */
22
-
23
-import re,os,sys
24
-import json
25
-try:
26
-    import util
27
-except:
28
-    pp = os.path.dirname(os.path.abspath(__file__))
29
-    sys.path.insert(0,os.sep.join(pp.split(os.sep)[:-1]))
30
-    import util
31
-import urllib2
32
-import requests
33
-try:
34
-    from requests.packages.urllib3.exceptions import InsecureRequestWarning
35
-    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
36
-except:
37
-    pass
38
-#from aadecode import AADecoder
39
-
40
-if __name__ <> "__main__":
41
-    __name__ = 'hqq'
42
-
43
-def supports(url):
44
-    m = re.search(r"https?://hdgo\.\w+/(.+?)$", url, re.DOTALL)
45
-    if m:
46
-        return True
47
-    else:
48
-        return False
49
-
50
-def resolve(url):
51
-    HTTP_HEADER = {
52
-        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0',
53
-        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
54
-        'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
55
-        'Accept-Encoding': 'none',
56
-        'Accept-Language': 'en-US,en;q=0.8',
57
-        'Referer': url}  # 'Connection': 'keep-alive'
58
-    streams = []
59
-    m = re.search(r"https?://hdgo\.\w+/(.+?)$", url, re.DOTALL)
60
-    vid=m.group(1)
61
-    url2 = "http://couber.be/"+vid
62
-    r = requests.get(url2,headers=HTTP_HEADER)
63
-    if r.status_code <> 200:
64
-        return streams
65
-    m = re.search('<iframe src="([^"]+)"', r.content, re.DOTALL)
66
-    if not m: return streams
67
-    url3 = m.group(1)
68
-    HTTP_HEADER["Rererer"] = url2
69
-    r = requests.get(url3,headers=HTTP_HEADER)
70
-    m = re.search(r"else{\s+setFlash\('([^']+)'\);", r.content, re.DOTALL)
71
-    if not m: return streams
72
-    q = ["1080p","720p","480p","360p"]
73
-    for i,ss in enumerate(m.group(1).split(",")):
74
-        s = ss.split(" or ")
75
-        if not s[0]: continue
76
-        stream = util.item()
77
-        stream["url"] = s[0]
78
-        stream["name"] = s[0]
79
-        stream["quality"] = q[i]
80
-        streams.append(stream)
81
-    return streams
82
-
83
-
84
-if __name__ == "__main__":
85
-
86
-    from subprocess import call
87
-    url = "http://hdgo.cc/video/t/Qrz0riUvA65GtkTpDvmlD9TBOn56HSm2/127280/"
88
-    url = "http://hdgo.cc/video/t/Qrz0riUvA65GtkTpDvmlD9TBOn56HSm2/34879/"
89
-    streams = resolve(url)
90
-    if not streams:
91
-        print "No streams found"
92
-        sys.exit()
93
-    for s in streams:
94
-        print s
95
-    util.play_video(streams)
96
-
97
-
98
-    #print streams[0]["url"]
99
-    #call([r"gst-launch-1.0.exe",'uri="%s""'%streams[0]["url"]])
100
-    pass

+ 0
- 239
resources/lib/resolvers/hqqresolver.py View File

@@ -1,239 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# *  GNU General Public License for more details.
3
-# *
4
-# *
5
-# *  You should have received a copy of the GNU General Public License
6
-# *  along with this program; see the file COPYING.  If not, write to
7
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8
-# *  http://www.gnu.org/copyleft/gpl.html
9
-# *
10
-# *
11
-# *  based on https://gitorious.org/iptv-pl-dla-openpli/ urlresolver
12
-# */
13
-from StringIO import StringIO
14
-import json
15
-import re
16
-import base64
17
-import urllib
18
-import sys,os
19
-
20
-try:
21
-    import util
22
-except:
23
-    pp = os.path.dirname(os.path.abspath(__file__))
24
-    sys.path.insert(0, os.sep.join(pp.split(os.sep)[:-1]))
25
-    import util
26
-import requests
27
-try:
28
-    from requests.packages.urllib3.exceptions import InsecureRequestWarning
29
-    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
30
-except:
31
-    pass
32
-
33
-__author__ = 'ivars777'
34
-if __name__ <> "__main__":
35
-    __name__ = 'hqq'
36
-
37
-
38
-def supports(url):
39
-    #return False
40
-    return _regex(url) is not None
41
-
42
-
43
-def _decode(data):
44
-    def O1l(string):
45
-        ret = ""
46
-        i = len(string) - 1
47
-        while i >= 0:
48
-            ret += string[i]
49
-            i -= 1
50
-        return ret
51
-
52
-    def l0I(string):
53
-        enc = ""
54
-        dec = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
55
-        i = 0
56
-        while True:
57
-            h1 = dec.find(string[i])
58
-            i += 1
59
-            h2 = dec.find(string[i])
60
-            i += 1
61
-            h3 = dec.find(string[i])
62
-            i += 1
63
-            h4 = dec.find(string[i])
64
-            i += 1
65
-            bits = h1 << 18 | h2 << 12 | h3 << 6 | h4
66
-            o1 = bits >> 16 & 0xff
67
-            o2 = bits >> 8 & 0xff
68
-            o3 = bits & 0xff
69
-            if h3 == 64:
70
-                enc += unichr(o1)
71
-            else:
72
-                if h4 == 64:
73
-                    enc += unichr(o1) + unichr(o2)
74
-                else:
75
-                    enc += unichr(o1) + unichr(o2) + unichr(o3)
76
-            if i >= len(string):
77
-                break
78
-        return enc
79
-
80
-    escape = re.search("var _escape=\'([^\']+)", l0I(O1l(data))).group(1)
81
-    return escape.replace('%', '\\').decode('unicode-escape')
82
-
83
-
84
-def _decode2(file_url):
85
-    def K12K(a, typ='b'):
86
-        codec_a = ["G", "L", "M", "N", "Z", "o", "I", "t", "V", "y", "x", "p", "R", "m", "z", "u",
87
-                   "D", "7", "W", "v", "Q", "n", "e", "0", "b", "="]
88
-        codec_b = ["2", "6", "i", "k", "8", "X", "J", "B", "a", "s", "d", "H", "w", "f", "T", "3",
89
-                   "l", "c", "5", "Y", "g", "1", "4", "9", "U", "A"]
90
-        if 'd' == typ:
91
-            tmp = codec_a
92
-            codec_a = codec_b
93
-            codec_b = tmp
94
-        idx = 0
95
-        while idx < len(codec_a):
96
-            a = a.replace(codec_a[idx], "___")
97
-            a = a.replace(codec_b[idx], codec_a[idx])
98
-            a = a.replace("___", codec_b[idx])
99
-            idx += 1
100
-        return a
101
-
102
-    def _xc13(_arg1):
103
-        _lg27 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
104
-        _local2 = ""
105
-        _local3 = [0, 0, 0, 0]
106
-        _local4 = [0, 0, 0]
107
-        _local5 = 0
108
-        while _local5 < len(_arg1):
109
-            _local6 = 0
110
-            while _local6 < 4 and (_local5 + _local6) < len(_arg1):
111
-                _local3[_local6] = _lg27.find(_arg1[_local5 + _local6])
112
-                _local6 += 1
113
-            _local4[0] = ((_local3[0] << 2) + ((_local3[1] & 48) >> 4))
114
-            _local4[1] = (((_local3[1] & 15) << 4) + ((_local3[2] & 60) >> 2))
115
-            _local4[2] = (((_local3[2] & 3) << 6) + _local3[3])
116
-
117
-            _local7 = 0
118
-            while _local7 < len(_local4):
119
-                if _local3[_local7 + 1] == 64:
120
-                    break
121
-                _local2 += chr(_local4[_local7])
122
-                _local7 += 1
123
-            _local5 += 4
124
-        return _local2
125
-
126
-    return _xc13(K12K(file_url, 'e'))
127
-
128
-
129
-def resolve(url):
130
-    m = _regex(url)
131
-    if m:
132
-        headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
133
-                   'Content-Type': 'text/html; charset=utf-8'}
134
-        if "goo.gl" in url:
135
-            data = util.request(url, headers)
136
-            player_url = re.search("var ppage = '(.+?)'",data).group(1)
137
-            player_url = urllib.unquote(player_url)
138
-        else:
139
-            vid = m.group('vid')
140
-            player_url = "http://hqq.tv/player/embed_player.php?vid=%s&autoplay=no" % vid
141
-            data = util.request(player_url, headers)
142
-        b64enc = re.search('base64([^\"]+)', data, re.DOTALL)
143
-        b64dec = b64enc and base64.decodestring(b64enc.group(1))
144
-        enc = b64dec and re.search("\'([^']+)\'", b64dec).group(1)
145
-        if enc:
146
-            data = re.findall('<input name="([^"]+?)" [^>]+? value="([^"]+?)">', _decode(enc))
147
-            post_data = {}
148
-            for idx in range(len(data)):
149
-                post_data[data[idx][0]] = data[idx][1]
150
-            data = util.post(player_url, post_data, headers)
151
-            b64enc = re.search('base64([^\"]+)', data, re.DOTALL)
152
-            b64dec = b64enc and base64.decodestring(b64enc.group(1))
153
-            enc = b64dec and re.search("\'([^']+)\'", b64dec).group(1)
154
-            if enc:
155
-                data = re.findall('<input name="([^"]+?)" [^>]+? value="([^"]*)">', _decode(enc))
156
-                post_data = {}
157
-                for idx in range(len(data)):
158
-                    post_data[data[idx][0]] = data[idx][1]
159
-                data = urllib.unquote(util.request("http://hqq.tv/sec/player/embed_player.php?" +
160
-                                                   urllib.urlencode(post_data), headers))
161
-                server_1 = re.search("server_1: (\w+)",data).group(1)
162
-                link_1 = re.search("link_1: (\w+)",data).group(1)
163
-                vid_server = re.search(r'var\s*%s\s*=\s*"([^"]*?)"'%server_1, data)
164
-                vid_link = re.search(r'var\s*%s\s*=\s*"([^"]*?)"'%link_1, data)
165
-                at = re.search(r'var\s*at\s*=\s*"([^"]*?)"', data)
166
-                vid = re.search('vid: "([^"]+)"',data)
167
-                sub_url = re.search('sub:"(.+?)"',data).group(1) if re.search('sub:"(.+?)"',data) else ""
168
-                subs_lang = re.search('sublangs:"(.+?)"',data).group(1) if re.search('sub:"(.+?)"',data) else ""
169
-                if sub_url:
170
-                    subs=[{"url":sub_url,'name':subs_lang,"lang":subs_lang}]
171
-                else:
172
-                    subs = []
173
-                if vid_server and vid_link and at:
174
-                    get_data = {'server_1': vid_server.group(1),
175
-                                'link_1': vid_link.group(1),
176
-                                'at': at.group(1),
177
-                                'adb': '0/',
178
-                                'b':'1',
179
-                                'vid': vid.group(1)}
180
-                    # X-Requested-With: XMLHttpRequest
181
-                    headers["X-Requested-With"] = "XMLHttpRequest"
182
-                    html = util.request("http://hqq.tv/player/get_md5.php?"+urllib.urlencode(get_data), headers)
183
-                    data = json.load(StringIO(html))
184
-                    if 'file' in data:
185
-                        file_url = _decode2(data['file'])
186
-                        file_url = re.sub(r'\?socket=?$', '.mp4.m3u8',file_url)
187
-                        stream  = {
188
-                            'url': file_url,
189
-                            'name': file_url,
190
-                            'subs':subs,
191
-                            'quality': 'hqq',
192
-                            'resolver': 'hqq',
193
-                            "headers":{"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46"}
194
-                        }
195
-                        return [stream]
196
-    return []
197
-
198
-
199
-def _regex(url):
200
-    # https://goo.gl/yMTzqf
201
-    match = re.search("(hqq|netu)\.tv/watch_video\.php\?v=(?P<vid>[0-9A-Z]+)", url)
202
-    if match:
203
-        return match
204
-    match = re.search(r'(hqq|netu)\.tv/player/embed_player\.php\?vid=(?P<vid>[0-9A-Za-z]+)', url)
205
-    if match:
206
-        return match
207
-    match = re.search(r'(hqq|netu)\.tv/player/hash\.php\?hash=\d+', url)
208
-    if match:
209
-        match = re.search(r'var\s+vid\s*=\s*\'(?P<vid>[^\']+)\'', urllib.unquote(util.request(url)))
210
-        if match:
211
-            return match
212
-    # https://goo.gl/yMTzqf
213
-    match = re.search("(goo)\.gl/(?P<vid>[\w]+)", url)
214
-    if match:
215
-        return match
216
-
217
-    b64enc = re.search(r'data:text/javascript\;charset\=utf\-8\;base64([^\"]+)', url)
218
-    b64dec = b64enc and base64.decodestring(b64enc.group(1))
219
-    enc = b64dec and re.search(r"\'([^']+)\'", b64dec).group(1)
220
-    if enc:
221
-        decoded = _decode(enc)
222
-        match = re.search(r'<input name="vid"[^>]+? value="(?P<vid>[^"]+?)">', decoded)
223
-        if re.search(r'<form(.+?)action="[^"]*(hqq|netu)\.tv/player/embed_player\.php"[^>]*>',
224
-                     decoded) and match:
225
-            return match
226
-    return None
227
-
228
-if __name__ == "__main__":
229
-
230
-    url = "http://hqq.tv/player/embed_player.php?vid=nYAKgzBAf7ll"
231
-    streams = resolve(url)
232
-    if not streams:
233
-        print "No streams found"
234
-        sys.exit()
235
-    for s in streams:
236
-        print s
237
-    print streams[0]["url"]
238
-    util.play_video(streams)
239
-    pass

+ 0
- 99
resources/lib/resolvers/kapnob.py View File

@@ -1,99 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# /*
3
-# *      Copyright (C) 2016 Ivars777
4
-# *
5
-# *
6
-# *  This Program is free software; you can redistribute it and/or modify
7
-# *  it under the terms of the GNU General Public License as published by
8
-# *  the Free Software Foundation; either version 2, or (at your option)
9
-# *  any later version.
10
-# *
11
-# *  This Program is distributed in the hope that it will be useful,
12
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
-# *  GNU General Public License for more details.
15
-# *
16
-# *  You should have received a copy of the GNU General Public License
17
-# *  along with this program; see the file COPYING.  If not, write to
18
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
-# *  http://www.gnu.org/copyleft/gpl.html
20
-# *
21
-# */
22
-
23
-import re,os,sys
24
-import json
25
-try:
26
-    import util
27
-except:
28
-    pp = os.path.dirname(os.path.abspath(__file__))
29
-    sys.path.insert(0,os.sep.join(pp.split(os.sep)[:-1]))
30
-    import util
31
-import requests
32
-try:
33
-    from requests.packages.urllib3.exceptions import InsecureRequestWarning
34
-    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
35
-except:
36
-    pass
37
-
38
-__author__ = 'ivars777'
39
-if __name__ <> "__main__":
40
-    __name__ = 'kapnob'
41
-
42
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
43
-headers = headers2dict("""
44
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
45
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
46
-Accept-Language: en-US,en;q=0.5
47
-""")
48
-
49
-
50
-def supports(url):
51
-    return True if "kapnob.ru" in url else False
52
-
53
-def resolve(url):
54
-    HTTP_HEADER = {
55
-        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0',
56
-        'Referer': url}  # 'Connection': 'keep-alive'
57
-    stream = util.item()
58
-    data = requests.get(url,headers = HTTP_HEADER).content
59
-    m = re.search(r'subtitles: \[\s+{\s+src: "(.+?)",\s+label: "(.+?)",\s+language: "(.+?)"', data, re.DOTALL)
60
-    if m:
61
-        sub = {}
62
-        sub["url"] = m.group(1)
63
-        sub["name"] = m.group(2)
64
-        sub["lang"] = m.group(3)
65
-        sub["type"] = "srt"
66
-        stream["subs"]=[sub]
67
-
68
-    video_token = re.search("video_token: '(.+?)'",data).group(1)
69
-    content_type = re.search("content_type: '(.+?)'",data).group(1)
70
-    mw_key = re.search("mw_key: '(.+?)'",data).group(1)
71
-    mw_domain_id = re.search("mw_domain_id: (\d+)",data).group(1)
72
-    uuid = re.search("uuid: '(.+?)'",data).group(1)
73
-    params = "video_token=%s&content_type=%s&mw_key=%s&mw_pid=&mw_domain_id=%s&ad_attr=0&debug=false&uuid=%s"%(
74
-        video_token,content_type,mw_key,mw_domain_id,uuid)
75
-    headers = headers2dict("""
76
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
77
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
78
-X-Iframe-Option: Direct
79
-X-Requested-With: XMLHttpRequest
80
-""")
81
-    data = requests.post("http://cdn.kapnob.ru/sessions/new_session", data=params,headers=headers).content
82
-    js = json.loads(data)
83
-    stream["url"] = js["mans"]["manifest_m3u8"]
84
-    stream["name"]= stream["url"]
85
-    return [stream]
86
-
87
-
88
-if __name__ == "__main__":
89
-
90
-    url = "http://cdn.kapnob.ru/video/5e67c8b1ad018ffa/iframe"
91
-    streams = resolve(url)
92
-    if not streams:
93
-        print "No streams found"
94
-        sys.exit()
95
-    for s in streams:
96
-        print s
97
-    print streams[0]["url"]
98
-    util.play_video(streams)
99
-    pass

+ 0
- 100
resources/lib/resolvers/kodik.py View File

@@ -1,100 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# /*
3
-# *      Copyright (C) 2016 Ivars777
4
-# *
5
-# *
6
-# *  This Program is free software; you can redistribute it and/or modify
7
-# *  it under the terms of the GNU General Public License as published by
8
-# *  the Free Software Foundation; either version 2, or (at your option)
9
-# *  any later version.
10
-# *
11
-# *  This Program is distributed in the hope that it will be useful,
12
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
-# *  GNU General Public License for more details.
15
-# *
16
-# *  You should have received a copy of the GNU General Public License
17
-# *  along with this program; see the file COPYING.  If not, write to
18
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
-# *  http://www.gnu.org/copyleft/gpl.html
20
-# *
21
-# */
22
-
23
-import re,os,sys
24
-import json
25
-try:
26
-    import util
27
-except:
28
-    pp = os.path.dirname(os.path.abspath(__file__))
29
-    sys.path.insert(0,os.sep.join(pp.split(os.sep)[:-1]))
30
-    import util
31
-import requests
32
-try:
33
-    from requests.packages.urllib3.exceptions import InsecureRequestWarning
34
-    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
35
-except:
36
-    pass
37
-
38
-__author__ = 'ivars777'
39
-if __name__ <> "__main__":
40
-    __name__ = 'kodik'
41
-
42
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
43
-headers0 = headers2dict("""
44
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
45
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
46
-Upgrade-Insecure-Requests: 1
47
-DNT: 1
48
-Connection: keep-alive
49
-Upgrade-Insecure-Requests: 1
50
-Cache-Control: max-age=0
51
-
52
-""")
53
-
54
-
55
-def supports(url):
56
-    return True if "kodik.cc" in url else False
57
-
58
-def resolve(url):
59
-    global headers0
60
-    streams = []
61
-    try:
62
-        r = requests.get(url,headers=headers0)
63
-    except:
64
-        return []
65
-    if r.status_code<>200:
66
-        return []
67
-    data = r.content
68
-    hash = re.search('hash: "(.+?)"',data).group(1)
69
-    vid = re.search('id: "(.+?)"',data).group(1)
70
-    quality = re.search('quality: "(.+?)"',data).group(1)
71
-    params = "domain=&url=&type=database&hash=%s&id=%s&quality=%s"%(hash,vid,quality)
72
-    headers = headers2dict("""
73
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
74
-Accept: application/json, text/javascript, */*; q=0.01
75
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
76
-X-Requested-With: XMLHttpRequest
77
-Referer: %s
78
-"""%url)
79
-    data = requests.post("http://kodik.cc/get-video", data=params,headers=headers).content
80
-    js = json.loads(data)
81
-    for st in js["qualities"]:
82
-        stream = util.item()
83
-        stream["url"] = js["qualities"][st]["src"]
84
-        stream["quality"]=int(st)
85
-        stream["name"]= stream["url"]
86
-        streams.append(stream)
87
-    return streams
88
-
89
-if __name__ == "__main__":
90
-
91
-    url = "http://kodik.cc/video/10830/4269a802d1a9d9bdc53fe38488d53a52/720p"
92
-    streams = resolve(url)
93
-    if not streams:
94
-        print "No streams found"
95
-        sys.exit()
96
-    for s in streams:
97
-        print s
98
-    print streams[0]["url"]
99
-    util.play_video(streams)
100
-    pass

+ 0
- 114
resources/lib/resolvers/openload3.py View File

@@ -1,114 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# /*
3
-# *      Copyright (C) 2015 Lubomir Kucera
4
-# *
5
-# *
6
-# *  This Program is free software; you can redistribute it and/or modify
7
-# *  it under the terms of the GNU General Public License as published by
8
-# *  the Free Software Foundation; either version 2, or (at your option)
9
-# *  any later version.
10
-# *
11
-# *  This Program is distributed in the hope that it will be useful,
12
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
-# *  GNU General Public License for more details.
15
-# *
16
-# *  You should have received a copy of the GNU General Public License
17
-# *  along with this program; see the file COPYING.  If not, write to
18
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
-# *  http://www.gnu.org/copyleft/gpl.html
20
-# *
21
-# */
22
-
23
-import re,os,sys
24
-import json
25
-try:
26
-    import util
27
-except:
28
-    pp = os.path.dirname(os.path.abspath(__file__))
29
-    sys.path.insert(0,os.sep.join(pp.split(os.sep)[:-1]))
30
-    import util
31
-import urllib2
32
-import requests
33
-try:
34
-    from requests.packages.urllib3.exceptions import InsecureRequestWarning
35
-    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
36
-except:
37
-    pass
38
-#from aadecode import AADecoder
39
-
40
-__author__ = 'Jose Riha/Lubomir Kucera'
41
-__name__ = 'openload3'
42
-
43
-
44
-def supports(url):
45
-    return re.search(r'openload\.\w+/embed/.+', url) is not None
46
-
47
-
48
-#INFO_URL = API_BASE_URL + '/streaming/info'
49
-
50
-def resolve(url):
51
-    HTTP_HEADER = {
52
-        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0',
53
-        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
54
-        'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
55
-        'Accept-Encoding': 'none',
56
-        'Accept-Language': 'en-US,en;q=0.8',
57
-        'Referer': url}  # 'Connection': 'keep-alive'
58
-
59
-    stream = util.item()
60
-    m = re.search('https*://openload\.\w+/embed/([^/]+)', url)
61
-    if not m:
62
-        return stream
63
-    vid=m.group(1)
64
-    url2 = "https://api.openload.co/1/streaming/get?file="+vid
65
-    r = requests.get(url2,headers=HTTP_HEADER)
66
-    try:
67
-        js = json.loads(r.content)
68
-    except:
69
-        return stream
70
-    if js["status"] <>200:
71
-        raise Exception(js["msg"])
72
-    res = js["result"]
73
-    stream["url"] = res["url"]
74
-    stream["name"]= res["url"]
75
-    ### Retrieve subtitles ####
76
-    html = requests.get(url, headers=HTTP_HEADER).content
77
-    m = re.search('<track kind="captions" src="([^"]+)" srclang="([^"]+)" label="([^"]+)"', html)
78
-    if m:
79
-        stream["subs"] = m.group(1)
80
-        stream["lang"] = m.group(2)
81
-
82
-    return [stream]
83
-
84
-
85
-if __name__ == "__main__":
86
-
87
-    from subprocess import call
88
-    #url = "http://hqq.tv/player/embed_player.php?vid=235238210241210222228241233208212245&autoplay=no"
89
-    #url = "http://hqq.tv/player/embed_player.php?vid=243221241234244238208213206212211231&autoplay=no"
90
-    url = "http://hqq.tv/player/embed_player.php?vid=208231211231207221227243206206221244&autoplay=no"
91
-    #url = "https://openload.co/embed/TMthIdpy4PI/"
92
-    #url = "https://www.youtube.com/watch?v=Tx1K51_F99o"
93
-    #url = "https://www.youtube.com/watch?v=8BkcX7O1890"
94
-    #url = "https://www.youtube.com/watch?v=Se07R8SYsg0"
95
-    #url = "https://kinostok.tv/embed/731f3437e3c53104dd56d04039a0b15a"
96
-    #url = "http://vk.com/video_ext.php?oid=246066565&id=169244575&hash=d430ab0e76c9f7a1&hd=3"
97
-    #url ="https://openload.co/embed/rPMXJYPTkw4/"
98
-    #url = "https://openload.co/embed/bE7WfZ-vz_A/"
99
-    #url = "https://openload.co/embed/bE7WfZ/"
100
-    #url = "https://openload.co/embed/OuskaKyC2GU/"
101
-    url = "http://hqq.tv/player/embed_player.php?vid=235238210241210222228241233208212245&autoplay=no"
102
-    url = "https://openload.co/embed/rmNcP-0QopE/"
103
-    url = "https://openload.co/embed/oQLXcU1ITAY/"
104
-    streams = resolve(url)
105
-    if not streams:
106
-        print "No streams found"
107
-        sys.exit()
108
-
109
-    for s in streams:
110
-        print s
111
-
112
-    print streams[0]["url"]
113
-    call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",streams[0]["url"]])
114
-    pass

+ 0
- 347
resources/lib/resolvers/youtuberesolver.py View File

@@ -1,347 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-
3
-import urllib2
4
-# source from https://github.com/rg3/youtube-dl/issues/1208
5
-# removed some unnecessary debug messages..
6
-class CVevoSignAlgoExtractor:
7
-    # MAX RECURSION Depth for security
8
-    MAX_REC_DEPTH = 5
9
-
10
-    def __init__(self):
11
-        self.algoCache = {}
12
-        self._cleanTmpVariables()
13
-
14
-    def _cleanTmpVariables(self):
15
-        self.fullAlgoCode = ''
16
-        self.allLocalFunNamesTab = []
17
-        self.playerData = ''
18
-
19
-    def _jsToPy(self, jsFunBody):
20
-        pythonFunBody = jsFunBody.replace('function', 'def').replace('{', ':\n\t').replace('}', '').replace(';', '\n\t').replace('var ', '')
21
-        pythonFunBody = pythonFunBody.replace('.reverse()', '[::-1]')
22
-
23
-        lines = pythonFunBody.split('\n')
24
-        for i in range(len(lines)):
25
-            # a.split("") -> list(a)
26
-            match = re.search('(\w+?)\.split\(""\)', lines[i])
27
-            if match:
28
-                lines[i] = lines[i].replace(match.group(0), 'list(' + match.group(1) + ')')
29
-            # a.length -> len(a)
30
-            match = re.search('(\w+?)\.length', lines[i])
31
-            if match:
32
-                lines[i] = lines[i].replace(match.group(0), 'len(' + match.group(1) + ')')
33
-            # a.slice(3) -> a[3:]
34
-            match = re.search('(\w+?)\.slice\(([0-9]+?)\)', lines[i])
35
-            if match:
36
-                lines[i] = lines[i].replace(match.group(0), match.group(1) + ('[%s:]' % match.group(2)))
37
-            # a.join("") -> "".join(a)
38
-            match = re.search('(\w+?)\.join\(("[^"]*?")\)', lines[i])
39
-            if match:
40
-                lines[i] = lines[i].replace(match.group(0), match.group(2) + '.join(' + match.group(1) + ')')
41
-        return "\n".join(lines)
42
-
43
-    def _getLocalFunBody(self, funName):
44
-        # get function body
45
-        match = re.search('(function %s\([^)]+?\){[^}]+?})' % funName, self.playerData)
46
-        if match:
47
-            # return jsFunBody
48
-            return match.group(1)
49
-        return ''
50
-
51
-    def _getAllLocalSubFunNames(self, mainFunBody):
52
-        match = re.compile('[ =(,](\w+?)\([^)]*?\)').findall(mainFunBody)
53
-        if len(match):
54
-            # first item is name of main function, so omit it
55
-            funNameTab = set(match[1:])
56
-            return funNameTab
57
-        return set()
58
-
59
-    def decryptSignature(self, s, playerUrl):
60
-        playerUrl = playerUrl[:4] != 'http' and 'http:' + playerUrl or playerUrl
61
-        util.debug("decrypt_signature sign_len[%d] playerUrl[%s]" % (len(s), playerUrl))
62
-
63
-        # clear local data
64
-        self._cleanTmpVariables()
65
-
66
-        # use algoCache
67
-        if playerUrl not in self.algoCache:
68
-            # get player HTML 5 sript
69
-            request = urllib2.Request(playerUrl)
70
-            try:
71
-                self.playerData = urllib2.urlopen(request).read()
72
-                self.playerData = self.playerData.decode('utf-8', 'ignore')
73
-            except:
74
-                util.debug('Unable to download playerUrl webpage')
75
-                return ''
76
-
77
-            # get main function name
78
-            match = re.search("signature=(\w+?)\([^)]\)", self.playerData)
79
-            if match:
80
-                mainFunName = match.group(1)
81
-                util.debug('Main signature function name = "%s"' % mainFunName)
82
-            else:
83
-                util.debug('Can not get main signature function name')
84
-                return ''
85
-
86
-            self._getfullAlgoCode(mainFunName)
87
-
88
-            # wrap all local algo function into one function extractedSignatureAlgo()
89
-            algoLines = self.fullAlgoCode.split('\n')
90
-            for i in range(len(algoLines)):
91
-                algoLines[i] = '\t' + algoLines[i]
92
-            self.fullAlgoCode = 'def extractedSignatureAlgo(param):'
93
-            self.fullAlgoCode += '\n'.join(algoLines)
94
-            self.fullAlgoCode += '\n\treturn %s(param)' % mainFunName
95
-            self.fullAlgoCode += '\noutSignature = extractedSignatureAlgo( inSignature )\n'
96
-
97
-            # after this function we should have all needed code in self.fullAlgoCode
98
-            try:
99
-                algoCodeObj = compile(self.fullAlgoCode, '', 'exec')
100
-            except:
101
-                util.debug('decryptSignature compile algo code EXCEPTION')
102
-                return ''
103
-        else:
104
-            # get algoCodeObj from algoCache
105
-            util.debug('Algo taken from cache')
106
-            algoCodeObj = self.algoCache[playerUrl]
107
-
108
-        # for security alow only flew python global function in algo code
109
-        vGlobals = {"__builtins__": None, 'len': len, 'list': list}
110
-
111
-        # local variable to pass encrypted sign and get decrypted sign
112
-        vLocals = { 'inSignature': s, 'outSignature': '' }
113
-
114
-        # execute prepared code
115
-        try:
116
-            exec(algoCodeObj, vGlobals, vLocals)
117
-        except:
118
-            util.debug('decryptSignature exec code EXCEPTION')
119
-            return ''
120
-
121
-        util.debug('Decrypted signature = [%s]' % vLocals['outSignature'])
122
-        # if algo seems ok and not in cache, add it to cache
123
-        if playerUrl not in self.algoCache and '' != vLocals['outSignature']:
124
-            util.debug('Algo from player [%s] added to cache' % playerUrl)
125
-            self.algoCache[playerUrl] = algoCodeObj
126
-
127
-        # free not needed data
128
-        self._cleanTmpVariables()
129
-
130
-        return vLocals['outSignature']
131
-
132
-    # Note, this method is using a recursion
133
-    def _getfullAlgoCode(self, mainFunName, recDepth=0):
134
-        if self.MAX_REC_DEPTH <= recDepth:
135
-            util.debug('_getfullAlgoCode: Maximum recursion depth exceeded')
136
-            return
137
-
138
-        funBody = self._getLocalFunBody(mainFunName)
139
-        if '' != funBody:
140
-            funNames = self._getAllLocalSubFunNames(funBody)
141
-            if len(funNames):
142
-                for funName in funNames:
143
-                    if funName not in self.allLocalFunNamesTab:
144
-                        self.allLocalFunNamesTab.append(funName)
145
-                        util.debug("Add local function %s to known functions" % mainFunName)
146
-                        self._getfullAlgoCode(funName, recDepth + 1)
147
-
148
-            # conver code from javascript to python
149
-            funBody = self._jsToPy(funBody)
150
-            self.fullAlgoCode += '\n' + funBody + '\n'
151
-        return
152
-
153
-decryptor = CVevoSignAlgoExtractor()
154
-
155
-'''
156
-   YouTube plugin for XBMC
157
-    Copyright (C) 2010-2012 Tobias Ussing And Henrik Mosgaard Jensen
158
-
159
-    This program is free software: you can redistribute it and/or modify
160
-    it under the terms of the GNU General Public License as published by
161
-    the Free Software Foundation, either version 3 of the License, or
162
-    (at your option) any later version.
163
-
164
-    This program is distributed in the hope that it will be useful,
165
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
166
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
167
-    GNU General Public License for more details.
168
-
169
-    You should have received a copy of the GNU General Public License
170
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
171
-'''
172
-
173
-import sys
174
-import urllib
175
-import cgi
176
-import simplejson as json
177
-
178
-
179
-class YoutubePlayer(object):
180
-    fmt_value = {
181
-            5: "240p",
182
-            18: "360p",
183
-            22: "720p",
184
-            26: "???",
185
-            33: "???",
186
-            34: "360p",
187
-            35: "480p",
188
-            37: "1080p",
189
-            38: "720p",
190
-            43: "360p",
191
-            44: "480p",
192
-            45: "720p",
193
-            46: "520p",
194
-            59: "480",
195
-            78: "400",
196
-            82: "360p",
197
-            83: "240p",
198
-            84: "720p",
199
-            85: "520p",
200
-            100: "360p",
201
-            101: "480p",
202
-            102: "720p",
203
-            120: "hd720",
204
-            121: "hd1080"
205
-            }
206
-
207
-    # YouTube Playback Feeds
208
-    urls = {}
209
-    urls['video_stream'] = "http://www.youtube.com/watch?v=%s&safeSearch=none"
210
-    urls['embed_stream'] = "http://www.youtube.com/get_video_info?video_id=%s"
211
-    urls['video_info'] = "http://gdata.youtube.com/feeds/api/videos/%s"
212
-
213
-    def __init__(self):
214
-        pass
215
-
216
-    def removeAdditionalEndingDelimiter(self, data):
217
-        pos = data.find("};")
218
-        if pos != -1:
219
-            data = data[:pos + 1]
220
-        return data
221
-
222
-    def extractFlashVars(self, data, assets):
223
-        flashvars = {}
224
-        found = False
225
-
226
-        for line in data.split("\n"):
227
-            if line.strip().find(";ytplayer.config = ") > 0:
228
-                found = True
229
-                p1 = line.find(";ytplayer.config = ") + len(";ytplayer.config = ") - 1
230
-                p2 = line.rfind(";")
231
-                if p1 <= 0 or p2 <= 0:
232
-                    continue
233
-                data = line[p1 + 1:p2]
234
-                break
235
-        data = self.removeAdditionalEndingDelimiter(data)
236
-
237
-        if found:
238
-            data = json.loads(data)
239
-            if assets:
240
-                flashvars = data["assets"]
241
-            else:
242
-                flashvars = data["args"]
243
-        return flashvars
244
-
245
-    def scrapeWebPageForVideoLinks(self, result, video):
246
-        links = {}
247
-        flashvars = self.extractFlashVars(result, 0)
248
-        if not flashvars.has_key(u"url_encoded_fmt_stream_map"):
249
-            return links
250
-
251
-        if flashvars.has_key(u"ttsurl"):
252
-            video[u"ttsurl"] = flashvars[u"ttsurl"]
253
-        if flashvars.has_key("title"):
254
-            video["title"] = flashvars["title"]
255
-
256
-        for url_desc in flashvars[u"url_encoded_fmt_stream_map"].split(u","):
257
-            url_desc_map = cgi.parse_qs(url_desc)
258
-            if not (url_desc_map.has_key(u"url") or url_desc_map.has_key(u"stream")):
259
-                continue
260
-
261
-            key = int(url_desc_map[u"itag"][0])
262
-            url = u""
263
-            if url_desc_map.has_key(u"url"):
264
-                url = urllib.unquote(url_desc_map[u"url"][0])
265
-            elif url_desc_map.has_key(u"conn") and url_desc_map.has_key(u"stream"):
266
-                url = urllib.unquote(url_desc_map[u"conn"][0])
267
-                if url.rfind("/") < len(url) - 1:
268
-                    url = url + "/"
269
-                url = url + urllib.unquote(url_desc_map[u"stream"][0])
270
-            elif url_desc_map.has_key(u"stream") and not url_desc_map.has_key(u"conn"):
271
-                url = urllib.unquote(url_desc_map[u"stream"][0])
272
-
273
-            if url_desc_map.has_key(u"sig"):
274
-                url = url + u"&signature=" + url_desc_map[u"sig"][0]
275
-            elif url_desc_map.has_key(u"s"):
276
-                sig = url_desc_map[u"s"][0]
277
-                flashvars = self.extractFlashVars(result, 1)
278
-                js = flashvars[u"js"]
279
-                url = url + u"&signature=" + self.decrypt_signature(sig, js)
280
-
281
-            links[key] = url
282
-
283
-        return links
284
-
285
-    def decrypt_signature(self, s, js):
286
-        return decryptor.decryptSignature(s, js)
287
-
288
-
289
-    def extractVideoLinksFromYoutube(self, url, videoid, video):
290
-        result = util.request(self.urls[u"video_stream"] % videoid)
291
-        links = self.scrapeWebPageForVideoLinks(result, video)
292
-        if len(links) == 0:
293
-            util.error(u"Couldn't find video url- or stream-map.")
294
-        return links
295
-# /*
296
-# *      Copyright (C) 2011 Libor Zoubek
297
-# *
298
-# *
299
-# *  This Program is free software; you can redistribute it and/or modify
300
-# *  it under the terms of the GNU General Public License as published by
301
-# *  the Free Software Foundation; either version 2, or (at your option)
302
-# *  any later version.
303
-# *
304
-# *  This Program is distributed in the hope that it will be useful,
305
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
306
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
307
-# *  GNU General Public License for more details.
308
-# *
309
-# *  You should have received a copy of the GNU General Public License
310
-# *  along with this program; see the file COPYING.  If not, write to
311
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
312
-# *  http://www.gnu.org/copyleft/gpl.html
313
-# *
314
-# */
315
-import re, util, urllib
316
-__name__ = 'youtube'
317
-
318
-
319
-def supports(url):
320
-    return not _regex(url) == None
321
-
322
-def resolve(url):
323
-    m = _regex(url)
324
-    if not m == None:
325
-        player = YoutubePlayer()
326
-        video = {'title':'žádný název'}
327
-        index = url.find('&')  # strip out everytihing after &
328
-        if index > 0:
329
-            url = url[:index]
330
-        links = player.extractVideoLinksFromYoutube(url, m.group('id'), video)
331
-        resolved = []
332
-        for q in links:
333
-            if q in player.fmt_value.keys():
334
-                quality = player.fmt_value[q]
335
-                item = {}
336
-                item['name'] = __name__
337
-                item['url'] = links[q]
338
-                item['quality'] = quality
339
-                item['surl'] = url
340
-                item['subs'] = ''
341
-                item['title'] = video['title']
342
-                item['fmt'] = q
343
-                resolved.append(item)
344
-        return resolved
345
-
346
-def _regex(url):
347
-    return re.search('www\.youtube\.com/(watch\?v=|v/|embed/)(?P<id>.+?)(\?|$|&)', url, re.IGNORECASE | re.DOTALL)

+ 0
- 31
resources/lib/resolvers0/__init__.py View File

@@ -1,31 +0,0 @@
1
-#/*
2
-# *      Copyright (C) 2011 Libor Zoubek
3
-# *
4
-# *
5
-# *  This Program is free software; you can redistribute it and/or modify
6
-# *  it under the terms of the GNU General Public License as published by
7
-# *  the Free Software Foundation; either version 2, or (at your option)
8
-# *  any later version.
9
-# *
10
-# *  This Program is distributed in the hope that it will be useful,
11
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
-# *  GNU General Public License for more details.
14
-# *
15
-# *  You should have received a copy of the GNU General Public License
16
-# *  along with this program; see the file COPYING.  If not, write to
17
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18
-# *  http://www.gnu.org/copyleft/gpl.html
19
-# *
20
-# */
21
-
22
-
23
-##########################################################3
24
-# all resolvers modules in this directory must have following methods:
25
-
26
-# __name__ - name of the resolver module - can override module filename
27
-# def supports(url) - returns true iff resolver is able to resolve url to stream otherwise false
28
-# def resolve(url) - returns array of all hashmaps that were resolved
29
-#   - if resolving fails, nothing is returned
30
-#   - a hash MUST contain key 'url' - it's value is stream URL
31
-#   - optional keys are 'subs' (link to subtitle), 'quality' (quality string like '240p' or just 'HD'

+ 0
- 209
resources/lib/resolvers0/aadecode.py View File

@@ -1,209 +0,0 @@
1
-#-*- coding: utf-8 -*-
2
-#
3
-# author : Djeman
4
-# Updated by Shani-08 (https://github.com/Shani-08/ShaniXBMCWork2)
5
-
6
-import re
7
-
8
-class AADecoder(object):
9
-    def __init__(self, aa_encoded_data):
10
-        self.encoded_str = aa_encoded_data.replace('/*´∇`*/','')
11
-
12
-        self.b = ["(c^_^o)", "(゚Θ゚)", "((o^_^o) - (゚Θ゚))", "(o^_^o)",
13
-                  "(゚ー゚)", "((゚ー゚) + (゚Θ゚))", "((o^_^o) +(o^_^o))", "((゚ー゚) + (o^_^o))",
14
-                  "((゚ー゚) + (゚ー゚))", "((゚ー゚) + (゚ー゚) + (゚Θ゚))", "(゚Д゚) .゚ω゚ノ", "(゚Д゚) .゚Θ゚ノ",
15
-                  "(゚Д゚) ['c']", "(゚Д゚) .゚ー゚ノ", "(゚Д゚) .゚Д゚ノ", "(゚Д゚) [゚Θ゚]"]
16
-
17
-    def is_aaencoded(self):
18
-        idx = self.encoded_str.find("゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); ")
19
-        if idx == -1:
20
-            return False
21
-
22
-        if self.encoded_str.find("(゚Д゚)[゚o゚]) (゚Θ゚)) ('_');", idx) == -1:
23
-            return False
24
-
25
-        return True
26
-
27
-    def base_repr(self, number, base=2, padding=0):
28
-        digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
29
-        if base > len(digits):
30
-            base = len(digits)
31
-
32
-        num = abs(number)
33
-        res = []
34
-        while num:
35
-            res.append(digits[num % base])
36
-            num //= base
37
-        if padding:
38
-            res.append('0' * padding)
39
-        if number < 0:
40
-            res.append('-')
41
-        return ''.join(reversed(res or '0'))
42
-
43
-    def decode_char(self, enc_char, radix):
44
-        end_char = "+ "
45
-        str_char = ""
46
-        while enc_char != '':
47
-            found = False
48
-
49
-            if not found:
50
-                for i in range(len(self.b)):             
51
-                    enc_char=enc_char.replace(self.b[i], str(i))
52
-                
53
-                startpos=0
54
-                findClose=True
55
-                balance=1
56
-                result=[]
57
-                if enc_char.startswith('('):
58
-                    l=0
59
-                    
60
-                    for t in enc_char[1:]:
61
-                        l+=1
62
-                        if findClose and t==')':
63
-                            balance-=1;
64
-                            if balance==0:
65
-                                result+=[enc_char[startpos:l+1]]
66
-                                findClose=False
67
-                                continue
68
-                        elif not findClose and t=='(':
69
-                            startpos=l
70
-                            findClose=True
71
-                            balance=1
72
-                            continue
73
-                        elif t=='(':
74
-                            balance+=1
75
-                 
76
-
77
-                if result is None or len(result)==0:
78
-                    return ""
79
-                else:
80
-                    
81
-                    for r in result:
82
-                        value = self.decode_digit(r, radix)
83
-                        if value == "":
84
-                            return ""
85
-                        else:
86
-                            str_char += value
87
-                            
88
-                    return str_char
89
-
90
-            enc_char = enc_char[len(end_char):]
91
-
92
-        return str_char
93
-
94
-        
95
-              
96
-    def decode_digit(self, enc_int, radix):
97
-
98
-        rr = '(\(.+?\)\))\+'
99
-        rerr=enc_int.split('))+')
100
-        v = ''
101
-        
102
-        #new mode
103
-
104
-        for c in rerr:
105
-            
106
-            if len(c)>0:
107
-                if c.strip().endswith('+'):
108
-                    c=c.strip()[:-1]
109
-
110
-                startbrackets=len(c)-len(c.replace('(',''))
111
-                endbrackets=len(c)-len(c.replace(')',''))
112
-                    
113
-                if startbrackets>endbrackets:
114
-                    c+=')'*startbrackets-endbrackets
115
-                    
116
-                c = c.replace('!+[]','1')
117
-                c = c.replace('-~','1+')
118
-                c = c.replace('[]','0')
119
-                    
120
-                v+=str(eval(c))
121
-                    
122
-        return v
123
-         
124
-        mode = 0
125
-        value = 0
126
-
127
-        while enc_int != '':
128
-            found = False
129
-            for i in range(len(self.b)):
130
-                if enc_int.find(self.b[i]) == 0:
131
-                    if mode == 0:
132
-                        value += i
133
-                    else:
134
-                        value -= i
135
-                    enc_int = enc_int[len(self.b[i]):]
136
-                    found = True
137
-                    break
138
-
139
-            if not found:
140
-                return ""
141
-
142
-            enc_int = re.sub('^\s+|\s+$', '', enc_int)
143
-            if enc_int.find("+") == 0:
144
-                mode = 0
145
-            else:
146
-                mode = 1
147
-
148
-            enc_int = enc_int[1:]
149
-            enc_int = re.sub('^\s+|\s+$', '', enc_int)
150
-
151
-        return self.base_repr(value, radix)
152
-
153
-    def decode(self):
154
-
155
-        self.encoded_str = re.sub('^\s+|\s+$', '', self.encoded_str)
156
-
157
-        # get data
158
-        pattern = (r"\(゚Д゚\)\[゚o゚\]\+ (.+?)\(゚Д゚\)\[゚o゚\]\)")
159
-        result = re.search(pattern, self.encoded_str, re.DOTALL)
160
-        if result is None:
161
-            print "AADecoder: data not found"
162
-            return False
163
-
164
-        data = result.group(1)
165
-
166
-        # hex decode string
167
-        begin_char = "(゚Д゚)[゚ε゚]+"
168
-        alt_char = "(o゚ー゚o)+ "
169
-
170
-        out = ''
171
-
172
-        while data != '':
173
-            # Check new char
174
-            if data.find(begin_char) != 0:
175
-                print "AADecoder: data not found"
176
-                return False
177
-
178
-            data = data[len(begin_char):]
179
-
180
-            # Find encoded char
181
-            enc_char = ""
182
-            if data.find(begin_char) == -1:
183
-                enc_char = data
184
-                data = ""
185
-            else:
186
-                enc_char = data[:data.find(begin_char)]
187
-                data = data[len(enc_char):]
188
-
189
-            
190
-            radix = 8
191
-            # Detect radix 16 for utf8 char
192
-            if enc_char.find(alt_char) == 0:
193
-                enc_char = enc_char[len(alt_char):]
194
-                radix = 16
195
-
196
-            str_char = self.decode_char(enc_char, radix)
197
-            
198
-            if str_char == "":
199
-                print "no match :  "
200
-                print  data + "\nout = " + out + "\n"
201
-                return False
202
-            
203
-            out += chr(int(str_char, radix))
204
-
205
-        if out == "":
206
-            print "no match : " + data
207
-            return False
208
-
209
-        return out

+ 0
- 97
resources/lib/resolvers0/hdgo.py View File

@@ -1,97 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# /*
3
-# *      Copyright (C) 2016 ivars777
4
-# *
5
-# *
6
-# *  This Program is free software; you can redistribute it and/or modify
7
-# *  it under the terms of the GNU General Public License as published by
8
-# *  the Free Software Foundation; either version 2, or (at your option)
9
-# *  any later version.
10
-# *
11
-# *  This Program is distributed in the hope that it will be useful,
12
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
-# *  GNU General Public License for more details.
15
-# *
16
-# *  You should have received a copy of the GNU General Public License
17
-# *  along with this program; see the file COPYING.  If not, write to
18
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
-# *  http://www.gnu.org/copyleft/gpl.html
20
-# *
21
-# */
22
-
23
-import re,os,sys
24
-import json
25
-try:
26
-    import util
27
-except:
28
-    pp = os.path.dirname(os.path.abspath(__file__))
29
-    sys.path.insert(0,os.sep.join(pp.split(os.sep)[:-1]))
30
-    import util
31
-import urllib2
32
-import requests
33
-from requests.packages.urllib3.exceptions import InsecureRequestWarning
34
-requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
35
-#from aadecode import AADecoder
36
-
37
-if __name__ <> "__main__":
38
-    __name__ = 'hqq'
39
-
40
-def supports(url):
41
-    m = re.search(r"https?://hdgo\.\w+/(.+?)$", url, re.DOTALL)
42
-    if m:
43
-        return True
44
-    else:
45
-        return False
46
-
47
-def resolve(url):
48
-    HTTP_HEADER = {
49
-        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0',
50
-        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
51
-        'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
52
-        'Accept-Encoding': 'none',
53
-        'Accept-Language': 'en-US,en;q=0.8',
54
-        'Referer': url}  # 'Connection': 'keep-alive'
55
-    streams = []
56
-    m = re.search(r"https?://hdgo\.\w+/(.+?)$", url, re.DOTALL)
57
-    vid=m.group(1)
58
-    url2 = "http://couber.be/"+vid
59
-    r = requests.get(url2,headers=HTTP_HEADER)
60
-    if r.status_code <> 200:
61
-        return streams
62
-    m = re.search('<iframe src="([^"]+)"', r.content, re.DOTALL)
63
-    if not m: return streams
64
-    url3 = m.group(1)
65
-    HTTP_HEADER["Rererer"] = url2
66
-    r = requests.get(url3,headers=HTTP_HEADER)
67
-    m = re.search(r"else{\s+setFlash\('([^']+)'\);", r.content, re.DOTALL)
68
-    if not m: return streams
69
-    q = ["1080p","720p","480p","360p"]
70
-    for i,ss in enumerate(m.group(1).split(",")):
71
-        s = ss.split(" or ")
72
-        if not s[0]: continue
73
-        stream = util.item()
74
-        stream["url"] = s[0]
75
-        stream["name"] = s[0]
76
-        stream["quality"] = q[i]
77
-        streams.append(stream)
78
-    return streams
79
-
80
-
81
-if __name__ == "__main__":
82
-
83
-    from subprocess import call
84
-    url = "http://hdgo.cc/video/t/Qrz0riUvA65GtkTpDvmlD9TBOn56HSm2/127280/"
85
-    url = "http://hdgo.cc/video/t/Qrz0riUvA65GtkTpDvmlD9TBOn56HSm2/34879/"
86
-    streams = resolve(url)
87
-    if not streams:
88
-        print "No streams found"
89
-        sys.exit()
90
-    for s in streams:
91
-        print s
92
-    util.play_video(streams)
93
-
94
-
95
-    #print streams[0]["url"]
96
-    #call([r"gst-launch-1.0.exe",'uri="%s""'%streams[0]["url"]])
97
-    pass

+ 0
- 234
resources/lib/resolvers0/hqqresolver.py View File

@@ -1,234 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# *  GNU General Public License for more details.
3
-# *
4
-# *
5
-# *  You should have received a copy of the GNU General Public License
6
-# *  along with this program; see the file COPYING.  If not, write to
7
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8
-# *  http://www.gnu.org/copyleft/gpl.html
9
-# *
10
-# *
11
-# *  based on https://gitorious.org/iptv-pl-dla-openpli/ urlresolver
12
-# */
13
-from StringIO import StringIO
14
-import json
15
-import re
16
-import base64
17
-import urllib
18
-import sys,os
19
-
20
-try:
21
-    import util
22
-except:
23
-    pp = os.path.dirname(os.path.abspath(__file__))
24
-    sys.path.insert(0, os.sep.join(pp.split(os.sep)[:-1]))
25
-    import util
26
-import requests
27
-
28
-__author__ = 'ivars777'
29
-if __name__ <> "__main__":
30
-    __name__ = 'hqq'
31
-
32
-
33
-def supports(url):
34
-    #return False
35
-    return _regex(url) is not None
36
-
37
-
38
-def _decode(data):
39
-    def O1l(string):
40
-        ret = ""
41
-        i = len(string) - 1
42
-        while i >= 0:
43
-            ret += string[i]
44
-            i -= 1
45
-        return ret
46
-
47
-    def l0I(string):
48
-        enc = ""
49
-        dec = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
50
-        i = 0
51
-        while True:
52
-            h1 = dec.find(string[i])
53
-            i += 1
54
-            h2 = dec.find(string[i])
55
-            i += 1
56
-            h3 = dec.find(string[i])
57
-            i += 1
58
-            h4 = dec.find(string[i])
59
-            i += 1
60
-            bits = h1 << 18 | h2 << 12 | h3 << 6 | h4
61
-            o1 = bits >> 16 & 0xff
62
-            o2 = bits >> 8 & 0xff
63
-            o3 = bits & 0xff
64
-            if h3 == 64:
65
-                enc += unichr(o1)
66
-            else:
67
-                if h4 == 64:
68
-                    enc += unichr(o1) + unichr(o2)
69
-                else:
70
-                    enc += unichr(o1) + unichr(o2) + unichr(o3)
71
-            if i >= len(string):
72
-                break
73
-        return enc
74
-
75
-    escape = re.search("var _escape=\'([^\']+)", l0I(O1l(data))).group(1)
76
-    return escape.replace('%', '\\').decode('unicode-escape')
77
-
78
-
79
-def _decode2(file_url):
80
-    def K12K(a, typ='b'):
81
-        codec_a = ["G", "L", "M", "N", "Z", "o", "I", "t", "V", "y", "x", "p", "R", "m", "z", "u",
82
-                   "D", "7", "W", "v", "Q", "n", "e", "0", "b", "="]
83
-        codec_b = ["2", "6", "i", "k", "8", "X", "J", "B", "a", "s", "d", "H", "w", "f", "T", "3",
84
-                   "l", "c", "5", "Y", "g", "1", "4", "9", "U", "A"]
85
-        if 'd' == typ:
86
-            tmp = codec_a
87
-            codec_a = codec_b
88
-            codec_b = tmp
89
-        idx = 0
90
-        while idx < len(codec_a):
91
-            a = a.replace(codec_a[idx], "___")
92
-            a = a.replace(codec_b[idx], codec_a[idx])
93
-            a = a.replace("___", codec_b[idx])
94
-            idx += 1
95
-        return a
96
-
97
-    def _xc13(_arg1):
98
-        _lg27 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
99
-        _local2 = ""
100
-        _local3 = [0, 0, 0, 0]
101
-        _local4 = [0, 0, 0]
102
-        _local5 = 0
103
-        while _local5 < len(_arg1):
104
-            _local6 = 0
105
-            while _local6 < 4 and (_local5 + _local6) < len(_arg1):
106
-                _local3[_local6] = _lg27.find(_arg1[_local5 + _local6])
107
-                _local6 += 1
108
-            _local4[0] = ((_local3[0] << 2) + ((_local3[1] & 48) >> 4))
109
-            _local4[1] = (((_local3[1] & 15) << 4) + ((_local3[2] & 60) >> 2))
110
-            _local4[2] = (((_local3[2] & 3) << 6) + _local3[3])
111
-
112
-            _local7 = 0
113
-            while _local7 < len(_local4):
114
-                if _local3[_local7 + 1] == 64:
115
-                    break
116
-                _local2 += chr(_local4[_local7])
117
-                _local7 += 1
118
-            _local5 += 4
119
-        return _local2
120
-
121
-    return _xc13(K12K(file_url, 'e'))
122
-
123
-
124
-def resolve(url):
125
-    m = _regex(url)
126
-    if m:
127
-        headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
128
-                   'Content-Type': 'text/html; charset=utf-8'}
129
-        if "goo.gl" in url:
130
-            data = util.request(url, headers)
131
-            player_url = re.search("var ppage = '(.+?)'",data).group(1)
132
-            player_url = urllib.unquote(player_url)
133
-        else:
134
-            vid = m.group('vid')
135
-            player_url = "http://hqq.tv/player/embed_player.php?vid=%s&autoplay=no" % vid
136
-            data = util.request(player_url, headers)
137
-        b64enc = re.search('base64([^\"]+)', data, re.DOTALL)
138
-        b64dec = b64enc and base64.decodestring(b64enc.group(1))
139
-        enc = b64dec and re.search("\'([^']+)\'", b64dec).group(1)
140
-        if enc:
141
-            data = re.findall('<input name="([^"]+?)" [^>]+? value="([^"]+?)">', _decode(enc))
142
-            post_data = {}
143
-            for idx in range(len(data)):
144
-                post_data[data[idx][0]] = data[idx][1]
145
-            data = util.post(player_url, post_data, headers)
146
-            b64enc = re.search('base64([^\"]+)', data, re.DOTALL)
147
-            b64dec = b64enc and base64.decodestring(b64enc.group(1))
148
-            enc = b64dec and re.search("\'([^']+)\'", b64dec).group(1)
149
-            if enc:
150
-                data = re.findall('<input name="([^"]+?)" [^>]+? value="([^"]*)">', _decode(enc))
151
-                post_data = {}
152
-                for idx in range(len(data)):
153
-                    post_data[data[idx][0]] = data[idx][1]
154
-                data = urllib.unquote(util.request("http://hqq.tv/sec/player/embed_player.php?" +
155
-                                                   urllib.urlencode(post_data), headers))
156
-                server_1 = re.search("server_1: (\w+)",data).group(1)
157
-                link_1 = re.search("link_1: (\w+)",data).group(1)
158
-                vid_server = re.search(r'var\s*%s\s*=\s*"([^"]*?)"'%server_1, data)
159
-                vid_link = re.search(r'var\s*%s\s*=\s*"([^"]*?)"'%link_1, data)
160
-                at = re.search(r'var\s*at\s*=\s*"([^"]*?)"', data)
161
-                vid = re.search('vid: "([^"]+)"',data)
162
-                sub_url = re.search('sub:"(.+?)"',data).group(1) if re.search('sub:"(.+?)"',data) else ""
163
-                subs_lang = re.search('sublangs:"(.+?)"',data).group(1) if re.search('sub:"(.+?)"',data) else ""
164
-                if sub_url:
165
-                    subs=[{"url":sub_url,'name':subs_lang,"lang":subs_lang}]
166
-                else:
167
-                    subs = []
168
-                if vid_server and vid_link and at:
169
-                    get_data = {'server_1': vid_server.group(1),
170
-                                'link_1': vid_link.group(1),
171
-                                'at': at.group(1),
172
-                                'adb': '0/',
173
-                                'b':'1',
174
-                                'vid': vid.group(1)}
175
-                    # X-Requested-With: XMLHttpRequest
176
-                    headers["X-Requested-With"] = "XMLHttpRequest"
177
-                    html = util.request("http://hqq.tv/player/get_md5.php?"+urllib.urlencode(get_data), headers)
178
-                    data = json.load(StringIO(html))
179
-                    if 'file' in data:
180
-                        file_url = _decode2(data['file'])
181
-                        file_url = re.sub(r'\?socket=?$', '.mp4.m3u8',file_url)
182
-                        stream  = {
183
-                            'url': file_url,
184
-                            'name': file_url,
185
-                            'subs':subs,
186
-                            'quality': 'hqq',
187
-                            'resolver': 'hqq',
188
-                            "headers":{"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46"}
189
-                        }
190
-                        return [stream]
191
-    return []
192
-
193
-
194
-def _regex(url):
195
-    # https://goo.gl/yMTzqf
196
-    match = re.search("(hqq|netu)\.tv/watch_video\.php\?v=(?P<vid>[0-9A-Z]+)", url)
197
-    if match:
198
-        return match
199
-    match = re.search(r'(hqq|netu)\.tv/player/embed_player\.php\?vid=(?P<vid>[0-9A-Za-z]+)', url)
200
-    if match:
201
-        return match
202
-    match = re.search(r'(hqq|netu)\.tv/player/hash\.php\?hash=\d+', url)
203
-    if match:
204
-        match = re.search(r'var\s+vid\s*=\s*\'(?P<vid>[^\']+)\'', urllib.unquote(util.request(url)))
205
-        if match:
206
-            return match
207
-    # https://goo.gl/yMTzqf
208
-    match = re.search("(goo)\.gl/(?P<vid>[\w]+)", url)
209
-    if match:
210
-        return match
211
-
212
-    b64enc = re.search(r'data:text/javascript\;charset\=utf\-8\;base64([^\"]+)', url)
213
-    b64dec = b64enc and base64.decodestring(b64enc.group(1))
214
-    enc = b64dec and re.search(r"\'([^']+)\'", b64dec).group(1)
215
-    if enc:
216
-        decoded = _decode(enc)
217
-        match = re.search(r'<input name="vid"[^>]+? value="(?P<vid>[^"]+?)">', decoded)
218
-        if re.search(r'<form(.+?)action="[^"]*(hqq|netu)\.tv/player/embed_player\.php"[^>]*>',
219
-                     decoded) and match:
220
-            return match
221
-    return None
222
-
223
-if __name__ == "__main__":
224
-
225
-    url = "http://hqq.tv/player/embed_player.php?vid=nYAKgzBAf7ll"
226
-    streams = resolve(url)
227
-    if not streams:
228
-        print "No streams found"
229
-        sys.exit()
230
-    for s in streams:
231
-        print s
232
-    print streams[0]["url"]
233
-    util.play_video(streams)
234
-    pass

+ 0
- 94
resources/lib/resolvers0/kapnob.py View File

@@ -1,94 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# /*
3
-# *      Copyright (C) 2016 Ivars777
4
-# *
5
-# *
6
-# *  This Program is free software; you can redistribute it and/or modify
7
-# *  it under the terms of the GNU General Public License as published by
8
-# *  the Free Software Foundation; either version 2, or (at your option)
9
-# *  any later version.
10
-# *
11
-# *  This Program is distributed in the hope that it will be useful,
12
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
-# *  GNU General Public License for more details.
15
-# *
16
-# *  You should have received a copy of the GNU General Public License
17
-# *  along with this program; see the file COPYING.  If not, write to
18
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
-# *  http://www.gnu.org/copyleft/gpl.html
20
-# *
21
-# */
22
-
23
-import re,os,sys
24
-import json
25
-try:
26
-    import util
27
-except:
28
-    pp = os.path.dirname(os.path.abspath(__file__))
29
-    sys.path.insert(0,os.sep.join(pp.split(os.sep)[:-1]))
30
-    import util
31
-import requests
32
-
33
-__author__ = 'ivars777'
34
-if __name__ <> "__main__":
35
-    __name__ = 'kapnob'
36
-
37
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
38
-headers = headers2dict("""
39
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
40
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
41
-Accept-Language: en-US,en;q=0.5
42
-""")
43
-
44
-
45
-def supports(url):
46
-    return True if "kapnob.ru" in url else False
47
-
48
-def resolve(url):
49
-    HTTP_HEADER = {
50
-        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0',
51
-        'Referer': url}  # 'Connection': 'keep-alive'
52
-    stream = util.item()
53
-    data = requests.get(url,headers = HTTP_HEADER).content
54
-    m = re.search(r'subtitles: \[\s+{\s+src: "(.+?)",\s+label: "(.+?)",\s+language: "(.+?)"', data, re.DOTALL)
55
-    if m:
56
-        sub = {}
57
-        sub["url"] = m.group(1)
58
-        sub["name"] = m.group(2)
59
-        sub["lang"] = m.group(3)
60
-        sub["type"] = "srt"
61
-        stream["subs"]=[sub]
62
-
63
-    video_token = re.search("video_token: '(.+?)'",data).group(1)
64
-    content_type = re.search("content_type: '(.+?)'",data).group(1)
65
-    mw_key = re.search("mw_key: '(.+?)'",data).group(1)
66
-    mw_domain_id = re.search("mw_domain_id: (\d+)",data).group(1)
67
-    uuid = re.search("uuid: '(.+?)'",data).group(1)
68
-    params = "video_token=%s&content_type=%s&mw_key=%s&mw_pid=&mw_domain_id=%s&ad_attr=0&debug=false&uuid=%s"%(
69
-        video_token,content_type,mw_key,mw_domain_id,uuid)
70
-    headers = headers2dict("""
71
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
72
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
73
-X-Iframe-Option: Direct
74
-X-Requested-With: XMLHttpRequest
75
-""")
76
-    data = requests.post("http://cdn.kapnob.ru/sessions/new_session", data=params,headers=headers).content
77
-    js = json.loads(data)
78
-    stream["url"] = js["mans"]["manifest_m3u8"]
79
-    stream["name"]= stream["url"]
80
-    return [stream]
81
-
82
-
83
-if __name__ == "__main__":
84
-
85
-    url = "http://cdn.kapnob.ru/video/5e67c8b1ad018ffa/iframe"
86
-    streams = resolve(url)
87
-    if not streams:
88
-        print "No streams found"
89
-        sys.exit()
90
-    for s in streams:
91
-        print s
92
-    print streams[0]["url"]    
93
-    util.play_video(streams)
94
-    pass

+ 0
- 95
resources/lib/resolvers0/kodik.py View File

@@ -1,95 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# /*
3
-# *      Copyright (C) 2016 Ivars777
4
-# *
5
-# *
6
-# *  This Program is free software; you can redistribute it and/or modify
7
-# *  it under the terms of the GNU General Public License as published by
8
-# *  the Free Software Foundation; either version 2, or (at your option)
9
-# *  any later version.
10
-# *
11
-# *  This Program is distributed in the hope that it will be useful,
12
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
-# *  GNU General Public License for more details.
15
-# *
16
-# *  You should have received a copy of the GNU General Public License
17
-# *  along with this program; see the file COPYING.  If not, write to
18
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
-# *  http://www.gnu.org/copyleft/gpl.html
20
-# *
21
-# */
22
-
23
-import re,os,sys
24
-import json
25
-try:
26
-    import util
27
-except:
28
-    pp = os.path.dirname(os.path.abspath(__file__))
29
-    sys.path.insert(0,os.sep.join(pp.split(os.sep)[:-1]))
30
-    import util
31
-import requests
32
-
33
-__author__ = 'ivars777'
34
-if __name__ <> "__main__":
35
-    __name__ = 'kodik'
36
-
37
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
38
-headers0 = headers2dict("""
39
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
40
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
41
-Upgrade-Insecure-Requests: 1
42
-DNT: 1
43
-Connection: keep-alive
44
-Upgrade-Insecure-Requests: 1
45
-Cache-Control: max-age=0
46
-
47
-""")
48
-
49
-
50
-def supports(url):
51
-    return True if "kodik.cc" in url else False
52
-
53
-def resolve(url):
54
-    global headers0
55
-    streams = []
56
-    try:
57
-        r = requests.get(url,headers=headers0)
58
-    except:
59
-        return []
60
-    if r.status_code<>200:
61
-        return []
62
-    data = r.content
63
-    hash = re.search('hash: "(.+?)"',data).group(1)
64
-    vid = re.search('id: "(.+?)"',data).group(1)
65
-    quality = re.search('quality: "(.+?)"',data).group(1)
66
-    params = "domain=&url=&type=database&hash=%s&id=%s&quality=%s"%(hash,vid,quality)
67
-    headers = headers2dict("""
68
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
69
-Accept: application/json, text/javascript, */*; q=0.01
70
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
71
-X-Requested-With: XMLHttpRequest
72
-Referer: %s
73
-"""%url)
74
-    data = requests.post("http://kodik.cc/get-video", data=params,headers=headers).content
75
-    js = json.loads(data)
76
-    for st in js["qualities"]:
77
-        stream = util.item()
78
-        stream["url"] = js["qualities"][st]["src"]
79
-        stream["quality"]=int(st)
80
-        stream["name"]= stream["url"]
81
-        streams.append(stream)
82
-    return streams
83
-
84
-if __name__ == "__main__":
85
-
86
-    url = "http://kodik.cc/video/10830/4269a802d1a9d9bdc53fe38488d53a52/720p"
87
-    streams = resolve(url)
88
-    if not streams:
89
-        print "No streams found"
90
-        sys.exit()
91
-    for s in streams:
92
-        print s
93
-    print streams[0]["url"]    
94
-    util.play_video(streams)
95
-    pass

+ 0
- 109
resources/lib/resolvers0/openload3.py View File

@@ -1,109 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# /*
3
-# *      Copyright (C) 2015 Lubomir Kucera
4
-# *
5
-# *
6
-# *  This Program is free software; you can redistribute it and/or modify
7
-# *  it under the terms of the GNU General Public License as published by
8
-# *  the Free Software Foundation; either version 2, or (at your option)
9
-# *  any later version.
10
-# *
11
-# *  This Program is distributed in the hope that it will be useful,
12
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
-# *  GNU General Public License for more details.
15
-# *
16
-# *  You should have received a copy of the GNU General Public License
17
-# *  along with this program; see the file COPYING.  If not, write to
18
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
-# *  http://www.gnu.org/copyleft/gpl.html
20
-# *
21
-# */
22
-
23
-import re,os,sys
24
-import json
25
-try:
26
-    import util
27
-except:
28
-    pp = os.path.dirname(os.path.abspath(__file__))
29
-    sys.path.insert(0,os.sep.join(pp.split(os.sep)[:-1]))
30
-    import util
31
-import urllib2
32
-import requests
33
-#from aadecode import AADecoder
34
-
35
-__author__ = 'Jose Riha/Lubomir Kucera'
36
-__name__ = 'openload3'
37
-
38
-
39
-def supports(url):
40
-    return re.search(r'openload\.\w+/embed/.+', url) is not None
41
-
42
-
43
-#INFO_URL = API_BASE_URL + '/streaming/info'
44
-
45
-def resolve(url):
46
-    HTTP_HEADER = {
47
-        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0',
48
-        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
49
-        'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
50
-        'Accept-Encoding': 'none',
51
-        'Accept-Language': 'en-US,en;q=0.8',
52
-        'Referer': url}  # 'Connection': 'keep-alive'    
53
-
54
-    stream = util.item()
55
-    m = re.search('https*://openload\.\w+/embed/([^/]+)', url)
56
-    if not m:
57
-        return stream
58
-    vid=m.group(1)
59
-    url2 = "https://api.openload.co/1/streaming/get?file="+vid
60
-    r = requests.get(url2,headers=HTTP_HEADER)
61
-    try:
62
-        js = json.loads(r.content)
63
-    except:
64
-        return stream
65
-    if js["status"] <>200:
66
-        raise Exception(js["msg"])
67
-    res = js["result"]
68
-    stream["url"] = res["url"]
69
-    stream["name"]= res["url"]
70
-    ### Retrieve subtitles ####
71
-    html = requests.get(url, headers=HTTP_HEADER).content 
72
-    m = re.search('<track kind="captions" src="([^"]+)" srclang="([^"]+)" label="([^"]+)"', html)
73
-    if m:
74
-        stream["subs"] = m.group(1)
75
-        stream["lang"] = m.group(2)   
76
-
77
-    return [stream]
78
-
79
-
80
-if __name__ == "__main__":
81
-
82
-    from subprocess import call
83
-    #url = "http://hqq.tv/player/embed_player.php?vid=235238210241210222228241233208212245&autoplay=no"
84
-    #url = "http://hqq.tv/player/embed_player.php?vid=243221241234244238208213206212211231&autoplay=no"
85
-    url = "http://hqq.tv/player/embed_player.php?vid=208231211231207221227243206206221244&autoplay=no"
86
-    #url = "https://openload.co/embed/TMthIdpy4PI/"
87
-    #url = "https://www.youtube.com/watch?v=Tx1K51_F99o"
88
-    #url = "https://www.youtube.com/watch?v=8BkcX7O1890"
89
-    #url = "https://www.youtube.com/watch?v=Se07R8SYsg0"
90
-    #url = "https://kinostok.tv/embed/731f3437e3c53104dd56d04039a0b15a"
91
-    #url = "http://vk.com/video_ext.php?oid=246066565&id=169244575&hash=d430ab0e76c9f7a1&hd=3"
92
-    #url ="https://openload.co/embed/rPMXJYPTkw4/"
93
-    #url = "https://openload.co/embed/bE7WfZ-vz_A/" 
94
-    #url = "https://openload.co/embed/bE7WfZ/" 
95
-    #url = "https://openload.co/embed/OuskaKyC2GU/"
96
-    url = "http://hqq.tv/player/embed_player.php?vid=235238210241210222228241233208212245&autoplay=no"
97
-    url = "https://openload.co/embed/rmNcP-0QopE/"
98
-    url = "https://openload.co/embed/oQLXcU1ITAY/"
99
-    streams = resolve(url)
100
-    if not streams:
101
-        print "No streams found"
102
-        sys.exit()
103
-
104
-    for s in streams:
105
-        print s
106
-
107
-    print streams[0]["url"]    
108
-    call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",streams[0]["url"]])
109
-    pass

+ 0
- 347
resources/lib/resolvers0/youtuberesolver.py View File

@@ -1,347 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-
3
-import urllib2
4
-# source from https://github.com/rg3/youtube-dl/issues/1208
5
-# removed some unnecessary debug messages..
6
-class CVevoSignAlgoExtractor:
7
-    # MAX RECURSION Depth for security
8
-    MAX_REC_DEPTH = 5
9
-
10
-    def __init__(self):
11
-        self.algoCache = {}
12
-        self._cleanTmpVariables()
13
-
14
-    def _cleanTmpVariables(self):
15
-        self.fullAlgoCode = ''
16
-        self.allLocalFunNamesTab = []
17
-        self.playerData = ''
18
-
19
-    def _jsToPy(self, jsFunBody):
20
-        pythonFunBody = jsFunBody.replace('function', 'def').replace('{', ':\n\t').replace('}', '').replace(';', '\n\t').replace('var ', '')
21
-        pythonFunBody = pythonFunBody.replace('.reverse()', '[::-1]')
22
-
23
-        lines = pythonFunBody.split('\n')
24
-        for i in range(len(lines)):
25
-            # a.split("") -> list(a)
26
-            match = re.search('(\w+?)\.split\(""\)', lines[i])
27
-            if match:
28
-                lines[i] = lines[i].replace(match.group(0), 'list(' + match.group(1) + ')')
29
-            # a.length -> len(a)
30
-            match = re.search('(\w+?)\.length', lines[i])
31
-            if match:
32
-                lines[i] = lines[i].replace(match.group(0), 'len(' + match.group(1) + ')')
33
-            # a.slice(3) -> a[3:]
34
-            match = re.search('(\w+?)\.slice\(([0-9]+?)\)', lines[i])
35
-            if match:
36
-                lines[i] = lines[i].replace(match.group(0), match.group(1) + ('[%s:]' % match.group(2)))
37
-            # a.join("") -> "".join(a)
38
-            match = re.search('(\w+?)\.join\(("[^"]*?")\)', lines[i])
39
-            if match:
40
-                lines[i] = lines[i].replace(match.group(0), match.group(2) + '.join(' + match.group(1) + ')')
41
-        return "\n".join(lines)
42
-
43
-    def _getLocalFunBody(self, funName):
44
-        # get function body
45
-        match = re.search('(function %s\([^)]+?\){[^}]+?})' % funName, self.playerData)
46
-        if match:
47
-            # return jsFunBody
48
-            return match.group(1)
49
-        return ''
50
-
51
-    def _getAllLocalSubFunNames(self, mainFunBody):
52
-        match = re.compile('[ =(,](\w+?)\([^)]*?\)').findall(mainFunBody)
53
-        if len(match):
54
-            # first item is name of main function, so omit it
55
-            funNameTab = set(match[1:])
56
-            return funNameTab
57
-        return set()
58
-
59
-    def decryptSignature(self, s, playerUrl):
60
-        playerUrl = playerUrl[:4] != 'http' and 'http:' + playerUrl or playerUrl
61
-        util.debug("decrypt_signature sign_len[%d] playerUrl[%s]" % (len(s), playerUrl))
62
-
63
-        # clear local data
64
-        self._cleanTmpVariables()
65
-
66
-        # use algoCache
67
-        if playerUrl not in self.algoCache:
68
-            # get player HTML 5 sript
69
-            request = urllib2.Request(playerUrl)
70
-            try:
71
-                self.playerData = urllib2.urlopen(request).read()
72
-                self.playerData = self.playerData.decode('utf-8', 'ignore')
73
-            except:
74
-                util.debug('Unable to download playerUrl webpage')
75
-                return ''
76
-
77
-            # get main function name
78
-            match = re.search("signature=(\w+?)\([^)]\)", self.playerData)
79
-            if match:
80
-                mainFunName = match.group(1)
81
-                util.debug('Main signature function name = "%s"' % mainFunName)
82
-            else:
83
-                util.debug('Can not get main signature function name')
84
-                return ''
85
-
86
-            self._getfullAlgoCode(mainFunName)
87
-
88
-            # wrap all local algo function into one function extractedSignatureAlgo()
89
-            algoLines = self.fullAlgoCode.split('\n')
90
-            for i in range(len(algoLines)):
91
-                algoLines[i] = '\t' + algoLines[i]
92
-            self.fullAlgoCode = 'def extractedSignatureAlgo(param):'
93
-            self.fullAlgoCode += '\n'.join(algoLines)
94
-            self.fullAlgoCode += '\n\treturn %s(param)' % mainFunName
95
-            self.fullAlgoCode += '\noutSignature = extractedSignatureAlgo( inSignature )\n'
96
-
97
-            # after this function we should have all needed code in self.fullAlgoCode
98
-            try:
99
-                algoCodeObj = compile(self.fullAlgoCode, '', 'exec')
100
-            except:
101
-                util.debug('decryptSignature compile algo code EXCEPTION')
102
-                return ''
103
-        else:
104
-            # get algoCodeObj from algoCache
105
-            util.debug('Algo taken from cache')
106
-            algoCodeObj = self.algoCache[playerUrl]
107
-
108
-        # for security alow only flew python global function in algo code
109
-        vGlobals = {"__builtins__": None, 'len': len, 'list': list}
110
-
111
-        # local variable to pass encrypted sign and get decrypted sign
112
-        vLocals = { 'inSignature': s, 'outSignature': '' }
113
-
114
-        # execute prepared code
115
-        try:
116
-            exec(algoCodeObj, vGlobals, vLocals)
117
-        except:
118
-            util.debug('decryptSignature exec code EXCEPTION')
119
-            return ''
120
-
121
-        util.debug('Decrypted signature = [%s]' % vLocals['outSignature'])
122
-        # if algo seems ok and not in cache, add it to cache
123
-        if playerUrl not in self.algoCache and '' != vLocals['outSignature']:
124
-            util.debug('Algo from player [%s] added to cache' % playerUrl)
125
-            self.algoCache[playerUrl] = algoCodeObj
126
-
127
-        # free not needed data
128
-        self._cleanTmpVariables()
129
-
130
-        return vLocals['outSignature']
131
-
132
-    # Note, this method is using a recursion
133
-    def _getfullAlgoCode(self, mainFunName, recDepth=0):
134
-        if self.MAX_REC_DEPTH <= recDepth:
135
-            util.debug('_getfullAlgoCode: Maximum recursion depth exceeded')
136
-            return
137
-
138
-        funBody = self._getLocalFunBody(mainFunName)
139
-        if '' != funBody:
140
-            funNames = self._getAllLocalSubFunNames(funBody)
141
-            if len(funNames):
142
-                for funName in funNames:
143
-                    if funName not in self.allLocalFunNamesTab:
144
-                        self.allLocalFunNamesTab.append(funName)
145
-                        util.debug("Add local function %s to known functions" % mainFunName)
146
-                        self._getfullAlgoCode(funName, recDepth + 1)
147
-
148
-            # conver code from javascript to python
149
-            funBody = self._jsToPy(funBody)
150
-            self.fullAlgoCode += '\n' + funBody + '\n'
151
-        return
152
-
153
-decryptor = CVevoSignAlgoExtractor()
154
-
155
-'''
156
-   YouTube plugin for XBMC
157
-    Copyright (C) 2010-2012 Tobias Ussing And Henrik Mosgaard Jensen
158
-
159
-    This program is free software: you can redistribute it and/or modify
160
-    it under the terms of the GNU General Public License as published by
161
-    the Free Software Foundation, either version 3 of the License, or
162
-    (at your option) any later version.
163
-
164
-    This program is distributed in the hope that it will be useful,
165
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
166
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
167
-    GNU General Public License for more details.
168
-
169
-    You should have received a copy of the GNU General Public License
170
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
171
-'''
172
-
173
-import sys
174
-import urllib
175
-import cgi
176
-import simplejson as json
177
-
178
-
179
-class YoutubePlayer(object):
180
-    fmt_value = {
181
-            5: "240p",
182
-            18: "360p",
183
-            22: "720p",
184
-            26: "???",
185
-            33: "???",
186
-            34: "360p",
187
-            35: "480p",
188
-            37: "1080p",
189
-            38: "720p",
190
-            43: "360p",
191
-            44: "480p",
192
-            45: "720p",
193
-            46: "520p",
194
-            59: "480",
195
-            78: "400",
196
-            82: "360p",
197
-            83: "240p",
198
-            84: "720p",
199
-            85: "520p",
200
-            100: "360p",
201
-            101: "480p",
202
-            102: "720p",
203
-            120: "hd720",
204
-            121: "hd1080"
205
-            }
206
-
207
-    # YouTube Playback Feeds
208
-    urls = {}
209
-    urls['video_stream'] = "http://www.youtube.com/watch?v=%s&safeSearch=none"
210
-    urls['embed_stream'] = "http://www.youtube.com/get_video_info?video_id=%s"
211
-    urls['video_info'] = "http://gdata.youtube.com/feeds/api/videos/%s"
212
-
213
-    def __init__(self):
214
-        pass
215
-
216
-    def removeAdditionalEndingDelimiter(self, data):
217
-        pos = data.find("};")
218
-        if pos != -1:
219
-            data = data[:pos + 1]
220
-        return data
221
-
222
-    def extractFlashVars(self, data, assets):
223
-        flashvars = {}
224
-        found = False
225
-
226
-        for line in data.split("\n"):
227
-            if line.strip().find(";ytplayer.config = ") > 0:
228
-                found = True
229
-                p1 = line.find(";ytplayer.config = ") + len(";ytplayer.config = ") - 1
230
-                p2 = line.rfind(";")
231
-                if p1 <= 0 or p2 <= 0:
232
-                    continue
233
-                data = line[p1 + 1:p2]
234
-                break
235
-        data = self.removeAdditionalEndingDelimiter(data)
236
-
237
-        if found:
238
-            data = json.loads(data)
239
-            if assets:
240
-                flashvars = data["assets"]
241
-            else:
242
-                flashvars = data["args"]
243
-        return flashvars
244
-
245
-    def scrapeWebPageForVideoLinks(self, result, video):
246
-        links = {}
247
-        flashvars = self.extractFlashVars(result, 0)
248
-        if not flashvars.has_key(u"url_encoded_fmt_stream_map"):
249
-            return links
250
-
251
-        if flashvars.has_key(u"ttsurl"):
252
-            video[u"ttsurl"] = flashvars[u"ttsurl"]
253
-        if flashvars.has_key("title"):
254
-            video["title"] = flashvars["title"]
255
-
256
-        for url_desc in flashvars[u"url_encoded_fmt_stream_map"].split(u","):
257
-            url_desc_map = cgi.parse_qs(url_desc)
258
-            if not (url_desc_map.has_key(u"url") or url_desc_map.has_key(u"stream")):
259
-                continue
260
-
261
-            key = int(url_desc_map[u"itag"][0])
262
-            url = u""
263
-            if url_desc_map.has_key(u"url"):
264
-                url = urllib.unquote(url_desc_map[u"url"][0])
265
-            elif url_desc_map.has_key(u"conn") and url_desc_map.has_key(u"stream"):
266
-                url = urllib.unquote(url_desc_map[u"conn"][0])
267
-                if url.rfind("/") < len(url) - 1:
268
-                    url = url + "/"
269
-                url = url + urllib.unquote(url_desc_map[u"stream"][0])
270
-            elif url_desc_map.has_key(u"stream") and not url_desc_map.has_key(u"conn"):
271
-                url = urllib.unquote(url_desc_map[u"stream"][0])
272
-
273
-            if url_desc_map.has_key(u"sig"):
274
-                url = url + u"&signature=" + url_desc_map[u"sig"][0]
275
-            elif url_desc_map.has_key(u"s"):
276
-                sig = url_desc_map[u"s"][0]
277
-                flashvars = self.extractFlashVars(result, 1)
278
-                js = flashvars[u"js"]
279
-                url = url + u"&signature=" + self.decrypt_signature(sig, js)
280
-
281
-            links[key] = url
282
-
283
-        return links
284
-
285
-    def decrypt_signature(self, s, js):
286
-        return decryptor.decryptSignature(s, js)
287
-
288
-
289
-    def extractVideoLinksFromYoutube(self, url, videoid, video):
290
-        result = util.request(self.urls[u"video_stream"] % videoid)
291
-        links = self.scrapeWebPageForVideoLinks(result, video)
292
-        if len(links) == 0:
293
-            util.error(u"Couldn't find video url- or stream-map.")
294
-        return links
295
-# /*
296
-# *      Copyright (C) 2011 Libor Zoubek
297
-# *
298
-# *
299
-# *  This Program is free software; you can redistribute it and/or modify
300
-# *  it under the terms of the GNU General Public License as published by
301
-# *  the Free Software Foundation; either version 2, or (at your option)
302
-# *  any later version.
303
-# *
304
-# *  This Program is distributed in the hope that it will be useful,
305
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
306
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
307
-# *  GNU General Public License for more details.
308
-# *
309
-# *  You should have received a copy of the GNU General Public License
310
-# *  along with this program; see the file COPYING.  If not, write to
311
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
312
-# *  http://www.gnu.org/copyleft/gpl.html
313
-# *
314
-# */
315
-import re, util, urllib
316
-__name__ = 'youtube'
317
-
318
-
319
-def supports(url):
320
-    return not _regex(url) == None
321
-
322
-def resolve(url):
323
-    m = _regex(url)
324
-    if not m == None:
325
-        player = YoutubePlayer()
326
-        video = {'title':'žádný název'}
327
-        index = url.find('&')  # strip out everytihing after &
328
-        if index > 0:
329
-            url = url[:index]
330
-        links = player.extractVideoLinksFromYoutube(url, m.group('id'), video)
331
-        resolved = []
332
-        for q in links:
333
-            if q in player.fmt_value.keys():
334
-                quality = player.fmt_value[q]
335
-                item = {}
336
-                item['name'] = __name__
337
-                item['url'] = links[q]
338
-                item['quality'] = quality
339
-                item['surl'] = url
340
-                item['subs'] = ''
341
-                item['title'] = video['title']
342
-                item['fmt'] = q
343
-                resolved.append(item)
344
-        return resolved
345
-
346
-def _regex(url):
347
-    return re.search('www\.youtube\.com/(watch\?v=|v/|embed/)(?P<id>.+?)(\?|$|&)', url, re.IGNORECASE | re.DOTALL)

+ 0
- 158
resources/lib/sources/SourceBase.py View File

@@ -1,158 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-
9
-import urllib2, urllib
10
-import datetime, re, sys,os
11
-import requests
12
-try:
13
-    from requests.packages.urllib3.exceptions import InsecureRequestWarning
14
-    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
15
-except:
16
-    pass
17
-from collections import OrderedDict
18
-import ConfigParser
19
-try:
20
-    import util
21
-except:
22
-    parent = os.path.dirname(os.path.abspath(__file__))
23
-    parent = os.sep.join(parent.split(os.sep)[:-1])
24
-    sys.path.insert(0,parent)
25
-    import util
26
-
27
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
28
-
29
-class SourceBase(object):
30
-    """Stream source base class"""
31
-
32
-    def __init__(self,country="lv"):
33
-        self.name = "name"
34
-        self.title = "Title"
35
-        self.img = ""
36
-        self.desc = ""
37
-        self.options = OrderedDict()
38
-        self.config_file = ""
39
-        self.url = "http://www.bbb.com/"
40
-        self.headers = headers2dict("""
41
-User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
42
-""")
43
-
44
-    def login(self,user="",password=""):
45
-        return False
46
-
47
-    def logout(self):
48
-        return True
49
-
50
-    def get_content(self,data):
51
-        ### To be overriden in child class
52
-        return [("..atpakaļ","back",None,"Kļūda, atgriezties atpakaļ")]
53
-
54
-    def is_video(self,data):
55
-        ### To be overriden in child class
56
-        return False
57
-
58
-    def get_streams(self,data):
59
-        ### Normally to be overrided in child class
60
-
61
-        if not self.is_video(data):
62
-            return []
63
-        content = self.get_content(data)
64
-        stream = util.item()
65
-        stream["name"] = content[0].encode("utf8") if isinstance(content[0],unicode) else content[0]
66
-        stream["url"] = content[1].encode("utf8") if isinstance(content[1],unicode) else content[1]
67
-        stream["img"] = content[2].encode("utf8") if isinstance(content[2],unicode) else content[2]
68
-        stream["desc"] = content[3].encode("utf8") if isinstance(content[3],unicode) else content[3]
69
-        stream["type"] = stream_type(content[1]).encode("utf8")
70
-        return[stream]
71
-
72
-    def get_epg(self,data):
73
-        ### Normally to be overrided in child class
74
-        return [self.get_info(data)]
75
-
76
-    def options_read(self):
77
-        if not ("options" in dir(self) and self.options): # process options only if self.options defined, self.config_file should be defined too
78
-            return None
79
-        config = ConfigParser.ConfigParser()
80
-        if os.path.exists(self.config_file):
81
-            config.read(self.config_file)
82
-            self.options = OrderedDict(config.items(self.name))
83
-        else:
84
-            self.options_write(self.options)
85
-        return self.options
86
-
87
-    def options_write(self,options):
88
-        config = ConfigParser.ConfigParser()
89
-        config.add_section(self.name)
90
-        for k in options.keys():
91
-            config.set(self.name, k,options[k])
92
-        with open(self.config_file,"w") as f:
93
-            config.write(f)
94
-        self.options = OrderedDict(config.items(self.name))
95
-
96
-    def call(self, data,params=None,headers=None,lang=""):
97
-        if not headers: headers = self.headers
98
-        url = self.url+data
99
-        result = self._http_request(url,params,headers=headers)
100
-        return result
101
-
102
-    def call_json(self, data,params=None,headers=None,lang=""):
103
-        result = self.call(url,params,headers=headers)
104
-        if result:
105
-            result = json.loads(content)
106
-            return result
107
-        else:
108
-            raise "No data returned"
109
-
110
-    def _http_request(self, url,params = None, headers=None):
111
-        if not headers:
112
-            headers = self.headers if "headers" in dir(self) else headers2dict("User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0")
113
-        try:
114
-            if params:
115
-                r = requests.post(url, data=params, headers=headers,verify=False)
116
-            else:
117
-                r = requests.get(url, headers=headers,verify=False)
118
-            return r.content
119
-        except Exception as ex:
120
-            if "read" in ex:
121
-                content = ex.read()
122
-            else:
123
-                content = None
124
-            return content
125
-
126
-    @staticmethod
127
-    def stream_type(data):
128
-        return stream_type(data)
129
-
130
-    @staticmethod
131
-    def parse_data(data):
132
-        if "::" in data:
133
-            source = data.split("::")[0]
134
-            data = data.split("::")[1]
135
-        else:
136
-            source = ""
137
-        path = data.split("?")[0]
138
-        plist = path.split("/")
139
-        clist = plist[0]
140
-        params = data[data.find("?"):] if "?" in data else ""
141
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
142
-        return source,data,path,plist,clist,params,qs
143
-
144
-def stream_type(data):
145
-    if "::" in data:
146
-        data = data.split("::")[1]
147
-    data = data.lower()
148
-    m = re.search(r"^(\w+)://", data)
149
-    prefix = m.group(1) if m else ""
150
-    if prefix in ("http","https") and ".m3u8" in data:
151
-        return "hls"
152
-    elif prefix == "http":
153
-        return "http"
154
-    else:
155
-        return prefix
156
-
157
-if __name__ == "__main__":
158
-    pass

+ 0
- 404
resources/lib/sources/YouTubeVideoUrl.py View File

@@ -1,404 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# This video extraction code based on youtube-dl: https://github.com/rg3/youtube-dl
3
-
4
-import codecs
5
-import json
6
-import re
7
-
8
-from urllib import urlencode
9
-from urllib2 import urlopen, URLError
10
-import sys
11
-
12
-#from Components.config import config
13
-
14
-#from . import sslContext
15
-sslContext = None
16
-if sys.version_info >= (2, 7, 9):
17
-	try:
18
-		import ssl
19
-		sslContext = ssl._create_unverified_context()
20
-	except:
21
-		pass 
22
-from jsinterp import JSInterpreter
23
-from swfinterp import SWFInterpreter
24
-
25
-
26
-PRIORITY_VIDEO_FORMAT = []
27
-maxResolution =  '22'
28
-
29
-
30
-def createPriorityFormats():
31
-	global PRIORITY_VIDEO_FORMAT,maxResolution
32
-	PRIORITY_VIDEO_FORMAT = []
33
-	use_format = False
34
-	for itag_value in ['38', '37', '96', '22', '95', '120',
35
-		'35', '94', '18', '93', '5', '92', '132', '17']:
36
-		if itag_value == maxResolution: #config.plugins.YouTube.maxResolution.value:
37
-			use_format = True
38
-		if use_format:
39
-			PRIORITY_VIDEO_FORMAT.append(itag_value)
40
-
41
-createPriorityFormats()
42
-
43
-IGNORE_VIDEO_FORMAT = [
44
-		'43',  # webm
45
-		'44',  # webm
46
-		'45',  # webm
47
-		'46',  # webm
48
-		'100',  # webm
49
-		'101',  # webm
50
-		'102'  # webm
51
-	]
52
-
53
-
54
-def uppercase_escape(s):
55
-	unicode_escape = codecs.getdecoder('unicode_escape')
56
-	return re.sub(
57
-		r'\\U[0-9a-fA-F]{8}',
58
-		lambda m: unicode_escape(m.group(0))[0],
59
-		s)
60
-
61
-
62
-def compat_urllib_parse_unquote(string, encoding='utf-8', errors='replace'):
63
-	if string == '':
64
-		return string
65
-	res = string.split('%')
66
-	if len(res) == 1:
67
-		return string
68
-	if encoding is None:
69
-		encoding = 'utf-8'
70
-	if errors is None:
71
-		errors = 'replace'
72
-	# pct_sequence: contiguous sequence of percent-encoded bytes, decoded
73
-	pct_sequence = b''
74
-	string = res[0]
75
-	for item in res[1:]:
76
-		try:
77
-			if not item:
78
-				raise ValueError
79
-			pct_sequence += item[:2].decode('hex')
80
-			rest = item[2:]
81
-			if not rest:
82
-				# This segment was just a single percent-encoded character.
83
-				# May be part of a sequence of code units, so delay decoding.
84
-				# (Stored in pct_sequence).
85
-				continue
86
-		except ValueError:
87
-			rest = '%' + item
88
-		# Encountered non-percent-encoded characters. Flush the current
89
-		# pct_sequence.
90
-		string += pct_sequence.decode(encoding, errors) + rest
91
-		pct_sequence = b''
92
-	if pct_sequence:
93
-		# Flush the final pct_sequence
94
-		string += pct_sequence.decode(encoding, errors)
95
-	return string
96
-
97
-
98
-def _parse_qsl(qs, keep_blank_values=False, strict_parsing=False,
99
-			encoding='utf-8', errors='replace'):
100
-	qs, _coerce_result = qs, unicode
101
-	pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
102
-	r = []
103
-	for name_value in pairs:
104
-		if not name_value and not strict_parsing:
105
-			continue
106
-		nv = name_value.split('=', 1)
107
-		if len(nv) != 2:
108
-			if strict_parsing:
109
-				raise ValueError("bad query field: %r" % (name_value,))
110
-			# Handle case of a control-name with no equal sign
111
-			if keep_blank_values:
112
-				nv.append('')
113
-			else:
114
-				continue
115
-		if len(nv[1]) or keep_blank_values:
116
-			name = nv[0].replace('+', ' ')
117
-			name = compat_urllib_parse_unquote(
118
-				name, encoding=encoding, errors=errors)
119
-			name = _coerce_result(name)
120
-			value = nv[1].replace('+', ' ')
121
-			value = compat_urllib_parse_unquote(
122
-				value, encoding=encoding, errors=errors)
123
-			value = _coerce_result(value)
124
-			r.append((name, value))
125
-	return r
126
-
127
-
128
-def compat_parse_qs(qs, keep_blank_values=False, strict_parsing=False,
129
-					encoding='utf-8', errors='replace'):
130
-	parsed_result = {}
131
-	pairs = _parse_qsl(qs, keep_blank_values, strict_parsing,
132
-					encoding=encoding, errors=errors)
133
-	for name, value in pairs:
134
-		if name in parsed_result:
135
-			parsed_result[name].append(value)
136
-		else:
137
-			parsed_result[name] = [value]
138
-	return parsed_result
139
-
140
-
141
-class YouTubeVideoUrl():
142
-
143
-	def _download_webpage(self, url):
144
-		""" Returns a tuple (page content as string, URL handle) """
145
-		try:
146
-			if sslContext:
147
-				urlh = urlopen(url, context = sslContext)
148
-			else:
149
-				urlh = urlopen(url)
150
-		except URLError, e:
151
-			#raise Exception(e.reason)
152
-			return ""
153
-		return urlh.read()
154
-
155
-	def _search_regex(self, pattern, string):
156
-		"""
157
-		Perform a regex search on the given string, using a single or a list of
158
-		patterns returning the first matching group.
159
-		"""
160
-		mobj = re.search(pattern, string, 0)
161
-		if mobj:
162
-			# return the first matching group
163
-			return next(g for g in mobj.groups() if g is not None)
164
-		else:
165
-			raise Exception('Unable extract pattern from string!')
166
-
167
-	def _decrypt_signature(self, s, player_url):
168
-		"""Turn the encrypted s field into a working signature"""
169
-
170
-		if player_url is None:
171
-			raise Exception('Cannot decrypt signature without player_url!')
172
-
173
-		if player_url[:2] == '//':
174
-			player_url = 'https:' + player_url
175
-		try:
176
-			func = self._extract_signature_function(player_url)
177
-			return func(s)
178
-		except:
179
-			raise Exception('Signature extraction failed!')
180
-
181
-	def _extract_signature_function(self, player_url):
182
-		id_m = re.match(
183
-			r'.*?-(?P<id>[a-zA-Z0-9_-]+)(?:/watch_as3|/html5player(?:-new)?|/base)?\.(?P<ext>[a-z]+)$',
184
-			player_url)
185
-		if not id_m:
186
-			raise Exception('Cannot identify player %r!' % player_url)
187
-		player_type = id_m.group('ext')
188
-		code = self._download_webpage(player_url)
189
-		if player_type == 'js':
190
-			return self._parse_sig_js(code)
191
-		elif player_type == 'swf':
192
-			return self._parse_sig_swf(code)
193
-		else:
194
-			raise Exception('Invalid player type %r!' % player_type)
195
-
196
-	def _parse_sig_js(self, jscode):
197
-		funcname = self._search_regex(r'\.sig\|\|([a-zA-Z0-9$]+)\(', jscode)
198
-		jsi = JSInterpreter(jscode)
199
-		initial_function = jsi.extract_function(funcname)
200
-		return lambda s: initial_function([s])
201
-
202
-	def _parse_sig_swf(self, file_contents):
203
-		swfi = SWFInterpreter(file_contents)
204
-		TARGET_CLASSNAME = 'SignatureDecipher'
205
-		searched_class = swfi.extract_class(TARGET_CLASSNAME)
206
-		initial_function = swfi.extract_function(searched_class, 'decipher')
207
-		return lambda s: initial_function([s])
208
-
209
-	def _extract_from_m3u8(self, manifest_url):
210
-		url_map = {}
211
-
212
-		def _get_urls(_manifest):
213
-			lines = _manifest.split('\n')
214
-			urls = filter(lambda l: l and not l.startswith('#'), lines)
215
-			return urls
216
-
217
-		manifest = self._download_webpage(manifest_url)
218
-		formats_urls = _get_urls(manifest)
219
-		for format_url in formats_urls:
220
-			itag = self._search_regex(r'itag/(\d+?)/', format_url)
221
-			url_map[itag] = format_url
222
-		return url_map
223
-
224
-	def _get_ytplayer_config(self, webpage):
225
-		# User data may contain arbitrary character sequences that may affect
226
-		# JSON extraction with regex, e.g. when '};' is contained the second
227
-		# regex won't capture the whole JSON. Yet working around by trying more
228
-		# concrete regex first keeping in mind proper quoted string handling
229
-		# to be implemented in future that will replace this workaround (see
230
-		# https://github.com/rg3/youtube-dl/issues/7468,
231
-		# https://github.com/rg3/youtube-dl/pull/7599)
232
-		patterns = [
233
-			r';ytplayer\.config\s*=\s*({.+?});ytplayer',
234
-			r';ytplayer\.config\s*=\s*({.+?});',
235
-		]
236
-		for pattern in patterns:
237
-			config = self._search_regex(pattern, webpage)
238
-			if config:
239
-				return json.loads(uppercase_escape(config))
240
-
241
-	def extract(self, video_id):
242
-		url = 'https://www.youtube.com/watch?v=%s&gl=US&hl=en&has_verified=1&bpctr=9999999999' % video_id
243
-
244
-		# Get video webpage
245
-		video_webpage = self._download_webpage(url)
246
-		if not video_webpage:
247
-			#raise Exception('Video webpage not found!')
248
-			return ""
249
-
250
-		# Attempt to extract SWF player URL
251
-		mobj = re.search(r'swfConfig.*?"(https?:\\/\\/.*?watch.*?-.*?\.swf)"', video_webpage)
252
-		if mobj is not None:
253
-			player_url = re.sub(r'\\(.)', r'\1', mobj.group(1))
254
-		else:
255
-			player_url = None
256
-
257
-		# Get video info
258
-		embed_webpage = None
259
-		if re.search(r'player-age-gate-content">', video_webpage) is not None:
260
-			age_gate = True
261
-			# We simulate the access to the video from www.youtube.com/v/{video_id}
262
-			# this can be viewed without login into Youtube
263
-			url = 'https://www.youtube.com/embed/%s' % video_id
264
-			embed_webpage = self._download_webpage(url)
265
-			data = urlencode({
266
-				'video_id': video_id,
267
-				'eurl': 'https://youtube.googleapis.com/v/' + video_id,
268
-				'sts': self._search_regex(r'"sts"\s*:\s*(\d+)', embed_webpage),
269
-			})
270
-			video_info_url = 'https://www.youtube.com/get_video_info?' + data
271
-			video_info_webpage = self._download_webpage(video_info_url)
272
-			video_info = compat_parse_qs(video_info_webpage)
273
-		else:
274
-			age_gate = False
275
-			video_info = None
276
-			# Try looking directly into the video webpage
277
-			ytplayer_config = self._get_ytplayer_config(video_webpage)
278
-			if ytplayer_config:
279
-				args = ytplayer_config['args']
280
-				if args.get('url_encoded_fmt_stream_map'):
281
-					# Convert to the same format returned by compat_parse_qs
282
-					video_info = dict((k, [v]) for k, v in args.items())
283
-
284
-			if not video_info:
285
-				# We also try looking in get_video_info since it may contain different dashmpd
286
-				# URL that points to a DASH manifest with possibly different itag set (some itags
287
-				# are missing from DASH manifest pointed by webpage's dashmpd, some - from DASH
288
-				# manifest pointed by get_video_info's dashmpd).
289
-				# The general idea is to take a union of itags of both DASH manifests (for example
290
-				# video with such 'manifest behavior' see https://github.com/rg3/youtube-dl/issues/6093)
291
-				for el_type in ['&el=info', '&el=embedded', '&el=detailpage', '&el=vevo', '']:
292
-					video_info_url = (
293
-						'https://www.youtube.com/get_video_info?&video_id=%s%s&ps=default&eurl=&gl=US&hl=en'
294
-						% (video_id, el_type))
295
-					video_info_webpage = self._download_webpage(video_info_url)
296
-					video_info = compat_parse_qs(video_info_webpage)
297
-					if 'token' in video_info:
298
-						break
299
-		if 'token' not in video_info:
300
-			if 'reason' in video_info:
301
-				print '[YouTubeVideoUrl] %s' % video_info['reason'][0]
302
-			else:
303
-				print '[YouTubeVideoUrl] "token" parameter not in video info for unknown reason'
304
-
305
-		# Start extracting information
306
-		if 'conn' in video_info and video_info['conn'][0][:4] == 'rtmp':
307
-			url = video_info['conn'][0]
308
-		elif len(video_info.get('url_encoded_fmt_stream_map', [''])[0]) >= 1 or \
309
-			len(video_info.get('adaptive_fmts', [''])[0]) >= 1:
310
-			encoded_url_map = video_info.get('url_encoded_fmt_stream_map', [''])[0] + \
311
-				',' + video_info.get('adaptive_fmts', [''])[0]
312
-			if 'rtmpe%3Dyes' in encoded_url_map:
313
-				raise Exception('rtmpe downloads are not supported, see https://github.com/rg3/youtube-dl/issues/343')
314
-
315
-			# Find the best format from our format priority map
316
-			encoded_url_map = encoded_url_map.split(',')
317
-			url_map_str = None
318
-			# If format changed in config, recreate priority list
319
-			if PRIORITY_VIDEO_FORMAT[0] != maxResolution: #config.plugins.YouTube.maxResolution.value:
320
-				createPriorityFormats()
321
-			for our_format in PRIORITY_VIDEO_FORMAT:
322
-				our_format = 'itag=' + our_format
323
-				for encoded_url in encoded_url_map:
324
-					if our_format in encoded_url and 'url=' in encoded_url:
325
-						url_map_str = encoded_url
326
-						break
327
-				if url_map_str:
328
-					break
329
-			# If anything not found, used first in the list if it not in ignore map
330
-			if not url_map_str:
331
-				for encoded_url in encoded_url_map:
332
-					if 'url=' in encoded_url:
333
-						url_map_str = encoded_url
334
-						for ignore_format in IGNORE_VIDEO_FORMAT:
335
-							ignore_format = 'itag=' + ignore_format
336
-							if ignore_format in encoded_url:
337
-								url_map_str = None
338
-								break
339
-					if url_map_str:
340
-						break
341
-			if not url_map_str:
342
-				url_map_str = encoded_url_map[0]
343
-
344
-			url_data = compat_parse_qs(url_map_str)
345
-			url = url_data['url'][0]
346
-			if 'sig' in url_data:
347
-				url += '&signature=' + url_data['sig'][0]
348
-			elif 's' in url_data:
349
-				encrypted_sig = url_data['s'][0]
350
-				ASSETS_RE = r'"assets":.+?"js":\s*("[^"]+")'
351
-
352
-				jsplayer_url_json = self._search_regex(ASSETS_RE,
353
-					embed_webpage if age_gate else video_webpage)
354
-				if not jsplayer_url_json and not age_gate:
355
-					# We need the embed website after all
356
-					if embed_webpage is None:
357
-						embed_url = 'https://www.youtube.com/embed/%s' % video_id
358
-						embed_webpage = self._download_webpage(embed_url)
359
-					jsplayer_url_json = self._search_regex(ASSETS_RE, embed_webpage)
360
-
361
-				player_url = json.loads(jsplayer_url_json)
362
-				if player_url is None:
363
-					player_url_json = self._search_regex(
364
-						r'ytplayer\.config.*?"url"\s*:\s*("[^"]+")',
365
-						video_webpage)
366
-					player_url = json.loads(player_url_json)
367
-
368
-				signature = self._decrypt_signature(encrypted_sig, player_url)
369
-				url += '&signature=' + signature
370
-			if 'ratebypass' not in url:
371
-				url += '&ratebypass=yes'
372
-		elif video_info.get('hlsvp'):
373
-			url = None
374
-			manifest_url = video_info['hlsvp'][0]
375
-			url_map = self._extract_from_m3u8(manifest_url)
376
-
377
-			# Find the best format from our format priority map
378
-			for our_format in PRIORITY_VIDEO_FORMAT:
379
-				if url_map.get(our_format):
380
-					url = url_map[our_format]
381
-					break
382
-			# If anything not found, used first in the list if it not in ignore map
383
-			if not url:
384
-				for url_map_key in url_map.keys():
385
-					if url_map_key not in IGNORE_VIDEO_FORMAT:
386
-						url = url_map[url_map_key]
387
-						break
388
-			if not url:
389
-				url = url_map.values()[0]
390
-		else:
391
-			#raise Exception('No supported formats found in video info!')
392
-			return ""
393
-
394
-		return str(url)
395
-
396
-if __name__ == "__main__":
397
-
398
-	#yt = YouTubeVideoUrl()
399
-	if len(sys.argv)>1:
400
-		video_id= sys.argv[1]
401
-	else:
402
-		video_id = "2rlTF6HiMGg"
403
-	e = YouTubeVideoUrl().extract(video_id)
404
-	print e

+ 0
- 209
resources/lib/sources/cinemalive.py View File

@@ -1,209 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-import urllib2, urllib
13
-import datetime, re, sys,os
14
-import ConfigParser
15
-from SourceBase import SourceBase
16
-#from collections import OrderedDict
17
-import os
18
-
19
-#sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 
20
-from resolver import resolve
21
-import util
22
-
23
-
24
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
25
-import HTMLParser
26
-h = HTMLParser.HTMLParser()
27
-    
28
-class Source(SourceBase):
29
-    
30
-    def __init__(self,country=""):
31
-        self.name = "cinemalive"
32
-        self.title = "cinemalive.tv"
33
-        self.img = "picons/cinemalive.png" #"https://cinemalive.tv/assets/img/logo.png"
34
-        self.desc = "cinemalive.tv satura skatīšanās"
35
-        self.country=country
36
-        self.headers = headers2dict("""
37
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
38
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
39
-""")
40
-        self.headers2 = headers2dict("""
41
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
42
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
43
-Accept-Language: en-US,en;q=0.8
44
-""")
45
-        self.url = "https://cinemalive.tv/"
46
-        #self.login()
47
-        
48
-            
49
-    ######### Entry point ########
50
-    def get_content(self, data):
51
-        print "[cinemalive] get_content:", data
52
-        source,data,path,plist,clist,params,qs = self.parse_data(data)     
53
-        content=[]
54
-        content.append(("..return", "back","","Return back"))
55
-        
56
-        if clist=="home":
57
-            content.extend([
58
-                ("Search", "cinemalive::scripts/search.php?search={0}","","Search"),            
59
-                ("Filmas latviski - visas", "cinemalive::filmaslatviski/visas/lapa/1","","Filmas latviski - visas"),
60
-                ("Filmas angliski", "cinemalive::home_en","","Filmas angliski"),
61
-                ("Filmas latviski - jaunākās", "cinemalive::filmaslatviski/jaunakas/lapa/1","","Filmas latviski - jaunākās"),
62
-                ("Filmas latviski - vertētākās", "cinemalive::filmaslatviski/vertetakas/lapa/1","","Filmas latviski - vērtētākās"),
63
-                ("Filmas latviski - skatitakās", "cinemalive::filmaslatviski/skatitakas/lapa/1","","Filmas latviski - skatītākās"),
64
-            ])
65
-            r = self.call("filmaslatviski")
66
-            for item in re.findall(r'<li class="nav-submenu-item"><a href="/([\w/]+)">(.+?)</a></li>', r):
67
-                title = "Filmas latviski - "+item[1]
68
-                data2 = item[0]+"/lapa/1"
69
-                img = self.img
70
-                desc = title
71
-                content.append((title,self.name+"::"+data2,img,desc))      
72
-            return content
73
-
74
-        elif clist=="home_en":
75
-            content.extend([
76
-                ("Search", "cinemalive::scripts/search.php?search={0}","","Search"),            
77
-                ("Movies English - all", "cinemalive::moviesenglish/all/page/1","","Movies English - all"),
78
-                ("Movies Latvian", "cinemalive::home","","Filmas latviski"),
79
-                ("Movies English - newest", "cinemalive::moviesenglish/newestmovies/page/1","","Movies English - newest"),
80
-                ("Movies English - top rated", "cinemalive::moviesenglish/toprated/page/1","","Movies English - top rated"),
81
-                ("Movies English - most watched", "cinemalive::moviesenglish/mostwatched/page/1","","Movies English - most watched"),
82
-            ])
83
-            r = self.call("moviesenglish")
84
-            for item in re.findall(r'<li class="nav-submenu-item"><a href="/([\w/]+)">(.+?)</a></li>', r):
85
-                title = "Movies English - "+item[1]
86
-                data2 = item[0]+"/page/1"
87
-                img = self.img
88
-                desc = title
89
-                content.append((title,self.name+"::"+data2,img,desc))      
90
-            return content
91
-
92
-    
93
-        elif "search.php" in data:
94
-            
95
-            r=self.call(path,params=params[1:],headers=self.headers2)
96
-            result = re.findall(r'<div class="results.+?<a href="https://cinemalive\.tv/(.+?)">.+?<img src="(.+?)".+?<span style="color:#bcbcbc">([^<]+)</span> <span style="color:#5a606d;font-size:12px;">([^<]+)</span><br/>.+?<p class="dec" style="font-size:12px; color:#777;line-height:14px;">([^<]+)</p>', r, re.DOTALL)            
97
-            for item in result:
98
-                title = item[2]
99
-                title0 = re.sub(" \(\d+\)","",title)
100
-                if title0 == item[3]:
101
-                    title = title+" [EN]"
102
-                else:
103
-                    title = title + "/"+ item[3]+" [LV]"
104
-                title = util.unescape(title)
105
-                data2 = item[0]
106
-                img = item[1].replace("xs.","sm.")
107
-                desc = util.unescape(item[4])
108
-                content.append((title,self.name+"::"+data2,img,desc))            
109
-            return content
110
-
111
-        elif clist in ("filmaslatviski","moviesenglish"):
112
-            r = self.call(data)
113
-            if not r:
114
-                return content
115
-            result = re.findall(r'<div class="base-used">.+?<a href="https://cinemalive.tv/([^"]+)">.+?<img class="img-thumbnail" src="/([^"]+)" alt="([^"]+)"/>.+?<p class="year">(\d+)</p>', r, re.DOTALL)
116
-            for item in result:
117
-                title = item[2] + " (%s)"%item[3]
118
-                data2 = item[0]
119
-                img = "https://cinemalive.tv/"+item[1]
120
-                title = util.unescape(title)
121
-                desc = title
122
-                content.append((title,self.name+"::"+data2,img,desc)) 
123
-            m = re.search(r"""<a href='https://cinemalive\.tv/([^']+)' style="border-right:none;">»</a>""", r, re.DOTALL)
124
-            if m:
125
-                data2 = m.group(1)
126
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))                                  
127
-            return content      
128
-         
129
-        else:
130
-            return content                            
131
-              
132
-    def is_video(self,data):
133
-        source,data,path,plist,clist,params,qs = self.parse_data(data)        
134
-        if clist=="movie":
135
-            return True
136
-        else:
137
-            return False
138
-                        
139
-    def get_streams(self, data):
140
-        print "[cinemalive] get_streams:", data
141
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
142
-        r = self.call(path)
143
-        if not r:
144
-            return []
145
-        streams = []
146
-        title0 = re.search("<title>([^<]+)</title>", r).group(1)
147
-        lang = "LV" if "Filma Online Latviski" in title0 else "EN"
148
-        title = title0.replace(" - Filma Online Latviski","").replace(" - Movie Online English HD","")
149
-        desc = re.search('<p class="plot">(.+?)</p>', r).group(1)
150
-        img = "http://cinemalive.tv"+re.search('<img src="(.+?)" class="img-thumbnail"', r).group(1)
151
-        
152
-        m = re.search(r'<video id=.+?<source src="([^"]+\.mp4)"', r, re.DOTALL)
153
-        if m:
154
-            s = util.item()
155
-            s["url"] = m.group(1)
156
-            s["name"] = util.unescape(title)
157
-            s["desc"] = util.unescape(desc)
158
-            s["img"] = img
159
-            s["type"] = self.stream_type(s["url"])
160
-            s["lang"] = lang 
161
-            return [s]
162
-        
163
-        #m = re.search('<div class="viboom-overroll"><iframe src="([^"]+)"', r)
164
-        #if m:
165
-        result = re.findall('<div id="video_container"><iframe.+?src="(.+?)"', r)
166
-        if result:
167
-            streams = resolve(result[0])
168
-            for s in streams:
169
-                s["name"] = util.unescape(title)
170
-                s["desc"] = util.unescape(desc)
171
-                s["img"] = img
172
-                s["type"] = self.stream_type(s["url"])
173
-                s["lang"] = lang
174
-            if len(result)>1:
175
-                lang2 = "EN" if lang=="LV" else "LV"
176
-                streams2 = resolve(result[1])
177
-                for s in streams2:
178
-                    s["name"] = util.unescape(title)
179
-                    s["desc"] = util.unescape(desc)
180
-                    s["img"] = img
181
-                    s["type"]= self.stream_type(s["url"])
182
-                    s["lang"] = lang2
183
-                    streams.append(s)  
184
-            return streams
185
-        else:
186
-            return []
187
-
188
-                    
189
-if __name__ == "__main__":
190
-    country= "lv"
191
-    c = Source(country)
192
-    if len(sys.argv)>1:
193
-        data= sys.argv[1]
194
-    else:
195
-        data = "home"
196
-    content = c.get_content(data)
197
-    for item in content:
198
-        print item
199
-    #cat = api.get_categories(country)
200
-    #chan = api.get_channels("lv")
201
-    #prog = api.get_programs(channel=6400)
202
-    #prog = api.get_programs(category=55)
203
-    #seas = api.get_seasons(program=6453)
204
-    #str = api.get_streams(660243)
205
-    #res = api.get_videos(802)
206
-    #formats = api.getAllFormats()
207
-    #det = api.detailed("1516")
208
-    #vid = api.getVideos("13170")
209
-    pass

+ 0
- 113
resources/lib/sources/config.py View File

@@ -1,113 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-import os.path,re
9
-import collections
10
-from SourceBase import SourceBase
11
-
12
-os.path.dirname(os.path.abspath(__file__))
13
-class Source(SourceBase):
14
-
15
-    def __init__(self,country="lv"):
16
-        self.name = "config"
17
-        self.country=country
18
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
19
-        self.streams_file = os.path.join(cur_directory,"streams.cfg")
20
-        self.lists = collections.OrderedDict()
21
-        self.titles = {}
22
-        self.read_streams()
23
-
24
-    def get_content(self, data):
25
-        self.read_streams()
26
-        if "::" in data:
27
-            data = data.split("::")[1]
28
-        if not data in self.lists:
29
-            return []
30
-        return self.lists[data]
31
-
32
-    def is_video(self,data):
33
-        return False
34
-
35
-    def read_streams(self):
36
-        for line in open(self.streams_file,"r"):
37
-            r = re.search("^\[(\w+)\]", line)
38
-            if r:
39
-                name = r.group(1)
40
-                self.lists[name] = []
41
-            else:
42
-                if line[0] in ("#"): continue
43
-                items = line.strip().split("|")
44
-                if not items[0]: continue
45
-                if len(items)==1:
46
-                    self.titles[name] = items[0]
47
-                else:
48
-                    if len(items) == 4:
49
-                        items[3] = items[3].replace("\\n","\n")
50
-                    self.lists[name].append(items)
51
-
52
-    def write_streams(self):
53
-        f = open(self.streams_file,"w")
54
-        for l in self.lists.keys():
55
-            f.write("[%s]\n"%l)
56
-            t = self.get_title(l)
57
-            if t<>l:
58
-                f.write("%s\n"%t)
59
-            for item in self.lists[l]:
60
-                f.write("%s|%s|%s|%s\n"%(item[0].replace("\n",""),item[1],item[2],item[3].replace("\n","\\n")))
61
-            f.write("\n")
62
-        f.close()
63
-
64
-    def get_lists(self):
65
-        return self.lists.keys()
66
-
67
-    def get_list_items(self,name):
68
-        return self.lists[name]
69
-
70
-    def get_title(self,name):
71
-        if name in self.titles:
72
-            return self.titles[name]
73
-        else:
74
-            return name
75
-
76
-    def add_list(self,name):
77
-        if not name in self.lists.keys():
78
-            self.lists[name] = []
79
-
80
-    def del_list(self,name):
81
-        if name in self.lists.keys():
82
-            del self.lists[name]
83
-
84
-    def add_item(self,name,item,pos=None):
85
-        if name in self.lists.keys():
86
-            if pos==None:
87
-                self.lists[name].append(item)
88
-            else:
89
-                self.lists[name].insert(pos,item)
90
-
91
-    def del_item(self,name,pos):
92
-        self.lists[name].pop(pos)
93
-
94
-    def replace_item(self,name,item,pos):
95
-        self.lists[name][pos]=item
96
-
97
-
98
-if __name__ == "__main__":
99
-    c = Source()
100
-    content = c.get_content("home")
101
-    for item in content: print item
102
-    #c.del_item("home",0)
103
-    #c.del_list("favorites")
104
-
105
-    #c.add_item("home",("My Streams","config::favorites","","Mani saglabātie TV kanāli un video"),0)
106
-    c.replace_item("home",("My Streams","config::my_streams","default","Mani saglabātie TV kanāli un video"),0)
107
-    #c.add_list("favorites")
108
-    #c.add_item("favorites",("..return","back","","Atgriezties atpakaļ"))
109
-    #c.add_item("favorites",("LTV1","http://streamltv.cloudy.services/ltv/LTV02.smil/playlist.m3u8","picons/latvia1.png", "Latvijas televīzijas 1.kanāls"))
110
-
111
-    c.write_streams()
112
-    for item in content: print item
113
-

+ 0
- 3
resources/lib/sources/euronews.cfg View File

@@ -1,3 +0,0 @@
1
-[euronews]
2
-language = en
3
-

+ 0
- 287
resources/lib/sources/euronews.py View File

@@ -1,287 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, time,re, sys,os
15
-from collections import OrderedDict
16
-from SourceBase import SourceBase
17
-import util
18
-
19
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
20
-import HTMLParser
21
-h = HTMLParser.HTMLParser()
22
-
23
-class Source(SourceBase):
24
-
25
-    def __init__(self,language="en"):
26
-        self.name = "euronews"
27
-        self.title = "Euronews"
28
-        self.img = "http://pbs.twimg.com/profile_images/732665354242150400/tZsCnjuh_400x400.jpg"
29
-        self.desc = "Euronews live and archive"
30
-        self.headers = headers2dict("""
31
-User-Agent: Euronews/4.0.126
32
-Content-Type: application/json
33
-Connection: keep-alive
34
-        """)
35
-        #self.language=language
36
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
37
-        self.config_file = os.path.join(cur_directory,self.name+".cfg")
38
-        self.options = OrderedDict([("language","en")])
39
-        self.options_read()
40
-        self.vid={"1": "News", "2": "European Affairs", "3": "Lifestyle", "4": "Knowledge"}
41
-        self.languages = []
42
-        try:
43
-            self.get_languages()
44
-        except:
45
-            pass
46
-
47
-    def login(self,user="",password=""):
48
-        return True
49
-
50
-    def get_content(self, data):
51
-        print "[%s] get_content:"%self.name, data
52
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
53
-        #lang = qs["lang"] if "lang" in qs else self.language
54
-        lang = self.options["language"]
55
-        if not lang in self.get_languages():
56
-            raise Exception("Not valid default language - '%s'"%lang)
57
-
58
-        content=[]
59
-        content.append(("..return", "back","","Return back"))
60
-
61
-        if clist=="home":
62
-            content.extend([
63
-                ("Search", "euronews::content/getSearch?lang=%s&byPage=40&page=1&text={0}"%lang,self.img,"Top stories timeline"),
64
-                ("Live stream", "euronews::live?lang=%s"%lang,self.img,"Euronews live stream"),
65
-                ("Just in", "euronews::content/getTimeline?lang=%s&byPage=40&page=1"%lang,self.img,"News timeline"),
66
-                ("Top stories", "euronews::content/getTopStories?lang=%s"%lang,self.img,"Top stories timeline"),
67
-                ("Category - News", "euronews::content/getVertical?lang=%s&byPage=40&page=1&vId=1"%lang,self.img,"Category - News"),
68
-                ("Category - European Affairs", "euronews::content/getVertical?lang=%s&byPage=40&page=1&vId=2"%lang,self.img,"Category - European Affairs"),
69
-                ("Category - Lifestyle", "euronews::content/getVertical?lang=%s&byPage=40&page=1&vId=3"%lang,self.img,"Category - Lifestyle"),
70
-                ("Category - Knowledge", "euronews::content/getVertical?lang=%s&byPage=40&page=1&vId=4"%lang,self.img,"Category - Knowledge"),
71
-                ("Latest programs", "euronews::content/getLatestPrograms?lang=%s&byPage=40&page=1"%lang,self.img,"Latest programs"),
72
-                ("Programs list", "euronews::content/getPrograms?lang=%s"%lang,self.img,"Programs list"),
73
-             ])
74
-            return content
75
-
76
-
77
-        ### Video arhīvs ###
78
-        elif clist=="content":
79
-            if "lang" in qs:
80
-                del qs["lang"]
81
-            params = json.dumps(qs)
82
-
83
-            req = '{"methodName":"content.%s","apiKey":"androidPhoneEuronews-1.0","params":%s,"language":"%s"}'%(plist[1],params,lang)
84
-            r = self.call(req)
85
-            if not r:
86
-                return content
87
-            lst = r["timeline"] if "timeline" in r else\
88
-                r["topstorieslist"] if "topstorieslist" in r else\
89
-                r["programs"] if "programs" in r else\
90
-                r["programDetailsList"] if "programDetailsList" in r else\
91
-                r["programlist"] if "programlist" in r else\
92
-                r["articlelist"] if "articlelist" in r else\
93
-                r["verticals"] if "verticals" in r else\
94
-                []
95
-            if not lst:
96
-                return content
97
-
98
-            for item in lst:
99
-                if plist[1] in ("getTimeline"):
100
-                    article = item["article"]
101
-                    atype = item["type"]
102
-                    #if item["type"] == "wire":
103
-                        #continue # TODO
104
-                else:
105
-                    article = item
106
-                    atype = "article"
107
-                if plist[1]=="getPrograms":
108
-                    title = article["title"]
109
-                    id = article["pId"]
110
-                    desc = title
111
-                    img = "http://static.euronews.com/articles/programs/533x360_%s"%article["img"]
112
-                    data2 = "content/getProgramDetails?lang=%s&byPage=40&page=1&pId=%s"%(lang,id)
113
-                    content.append((title,self.name+"::"+data2,img,desc))
114
-                else:
115
-                    title = article["title"] if "title" in article else article["text"] if "text" in article else "No title"
116
-                    if atype <> "article":
117
-                        title = "[%s] %s"%(atype,title)
118
-                    atime = datetime.datetime.fromtimestamp(int(article["uts"]))
119
-                    #atime = datetime.datetime.fromtimestamp(int(article["uts"])-time.altzone)
120
-                    atime = atime.strftime("%Y-%m-%d %H:%M")
121
-                    vert = self.vid[article["vId"]] if "vId" in article else ""
122
-                    ptitle = article["pTitle"] if "pTitle" in article else ""
123
-                    id = article["id"]
124
-                    desc = "%s\n%s\n%s %s"%(title,atime,vert,ptitle)
125
-                    img = "http://static.euronews.com/articles/%s/399x225_%s.jpg"%(id,id)
126
-                    if not atype in ("breakingnews","wire"):
127
-                        data2 = "content/getArticle?lang=%s&id=%s"%(lang,id)
128
-                    else:
129
-                        data2 = ""
130
-                    content.append((title,self.name+"::"+data2,img,desc))
131
-            if "page=" in data:
132
-                data2 = re.sub("page=\d+","page=%s"%(int(qs["page"])+1),data)
133
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
134
-            return content
135
-
136
-
137
-    def is_video(self,data):
138
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
139
-        if path == "live":
140
-            return True
141
-        elif clist=="content" and plist[1]=="getArticle":
142
-            return True
143
-        else:
144
-            return False
145
-
146
-    def get_streams(self, data):
147
-        print "[euronews] get_streams:", data
148
-        if not self.is_video(data):
149
-            return []
150
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
151
-        #lang = qs["lang"] if "lang" in qs else self.language
152
-        lang = self.options["language"]
153
-        if not lang in self.get_languages():
154
-            raise Exception("Not valid default language - '%s'"%lang)
155
-
156
-        streams = []
157
-
158
-        if path == "live":
159
-            url = "http://www.euronews.com/api/watchlive.json"
160
-            r = self._http_request(url)
161
-            try:
162
-                js = json.loads(r)
163
-                url = js["url"]
164
-            except:
165
-                raise Exception("No live stream found")
166
-            r = self._http_request(url)
167
-            try:
168
-                js = json.loads(r)
169
-                if not js["status"]=="ok":
170
-                    raise Exception("No live stream found")
171
-            except:
172
-                raise Exception("No live stream found")
173
-
174
-            slist = js["primary"]
175
-
176
-            for l in slist:
177
-                stream = util.item()
178
-                stream["url"]=slist[l]["hls"]
179
-                stream["lang"]=l
180
-                stream["quality"]="variant"
181
-                stream["name"]="Euronews live [%s]"%l
182
-                stream["desc"]=stream["name"]
183
-                stream["type"]="hls" #stream_type(url)
184
-                streams.append(stream)
185
-
186
-        elif clist=="content" and plist[1] == "getArticle":
187
-            if "lang" in qs:
188
-                del qs["lang"]
189
-            languages = self.get_languages()
190
-            for lang in languages:
191
-                id = qs["id"]
192
-                req = '{"methodName":"content.getArticle","apiKey":"androidPhoneEuronews-1.0","params":{"id":"%s"},"language":"%s"}'%(id,lang)
193
-                r = self.call(req)
194
-                if not r:
195
-                    raise Exception("No live stream found")
196
-                if not "articlelist" in r:
197
-                    msg = r["label"] if "label" in r else "No article finde"
198
-                    raise Exception(msg)
199
-                article = r["articlelist"]
200
-                stream = util.item()
201
-                stream["url"]=article["videoUri"] if "videoUri" in article else ""
202
-                if not stream["url"]:
203
-                    return []
204
-                stream["lang"]=lang
205
-                stream["quality"]="?"
206
-                stream["name"]= article["title"]
207
-                stream["desc"]=article["text"] if "text" in article else article["title"]
208
-                stream["type"]="http" #stream_type(url)
209
-                streams.append(stream)
210
-
211
-        else:
212
-            raise Exception("No live stream found")
213
-
214
-        ### TODO - sakārtot sarakstu, lai pirmais ir labakais video
215
-        qlist = ["???","lq","mq","hq","hd","variant"]
216
-        llist = ["fr","en","ru","lv"]
217
-        for s in streams:
218
-            if s["lang"]==self.options["language"]:
219
-                s["order"] = 10000
220
-                continue
221
-            lv = llist.index(s["lang"])*10 if s["lang"] in llist else 0
222
-            qv=qlist.index(s["quality"]) if s["quality"] in qlist else 0
223
-            s["order"] = lv+qv
224
-        streams = sorted(streams,key=lambda item: item["order"],reverse=True)
225
-        return streams
226
-    def get_languages(self):
227
-        if self.languages: return self.languages
228
-        url = "http://www.euronews.com/api/watchlive.json"
229
-        r = self._http_request(url)
230
-        try:
231
-            js = json.loads(r)
232
-            url = js["url"]
233
-        except:
234
-            raise Exception("Can not get languages list")
235
-        r = self._http_request(url)
236
-        try:
237
-            js = json.loads(r)
238
-            if not js["status"]=="ok":
239
-                raise Exception("Can not get languages list")
240
-        except:
241
-            raise Exception("Can not get languages list")
242
-
243
-        slist = js["primary"]
244
-        self.languages=slist.keys()
245
-        return self.languages
246
-
247
-    def call(self, data,params = None, headers=None):
248
-        if not headers: headers = self.headers
249
-        #if not lang: lang = self.country
250
-        url = "http://api.euronews.com/ipad/"
251
-        headers = headers2dict("""
252
-User-Agent: Euronews/4.0.126
253
-Content-Type: multipart/form-data, boundary=AaB03xBounDaRy; charset=UTF-8
254
-Host: api.euronews.com
255
-Connection: Keep-Alive
256
-        """)
257
-        params = """
258
---AaB03xBounDaRy
259
-content-disposition: form-data; name=request
260
-
261
-%s
262
---AaB03xBounDaRy--
263
-"""%data
264
-        content = self._http_request(url, params, headers)
265
-        if content:
266
-            try:
267
-                result = json.loads(content)
268
-                return result
269
-            except Exception, ex:
270
-                return None
271
-        else:
272
-            return None
273
-
274
-
275
-if __name__ == "__main__":
276
-    language= "en"
277
-    c = Source(language)
278
-    data = '{"methodName":"content.getTimeline","apiKey":"androidPhoneEuronews-1.0","params":{"page":"1","byPage":"30"},"language":"en"}'
279
-    r = c.call(data)
280
-    if len(sys.argv)>1:
281
-        data= sys.argv[1]
282
-    else:
283
-        data = "home"
284
-    content = c.get_content(data)
285
-    for item in content:
286
-        print item
287
-    pass

+ 0
- 353
resources/lib/sources/filmix.py View File

@@ -1,353 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys,os
15
-import ConfigParser
16
-from SourceBase import SourceBase
17
-import base64
18
-from collections import OrderedDict
19
-import sys
20
-try:
21
-    import util
22
-except:
23
-    sys.path.insert(0,'..')
24
-    import util
25
-
26
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
27
-
28
-class Source(SourceBase):
29
-
30
-    def __init__(self,country=""):
31
-        self.name = "filmix"
32
-        self.title = "filmix.me"
33
-        self.img = "http://cs5324.vk.me/g33668783/a_903fcc63.jpg"
34
-        self.desc = "filmix.me satura skatīšanās"
35
-        self.country=country
36
-        self.headers = headers2dict("""
37
-Host: filmix.me
38
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
39
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
40
-Accept-Language: en-US,en;q=0.5
41
-""")
42
-        self.headers2 = headers2dict("""
43
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
44
-X-Requested-With: XMLHttpRequest
45
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
46
-""")
47
-        self.url = "https://filmix.me/"
48
-        #self.login()
49
-
50
-    def login(self,user="",password=""):
51
-        return True
52
-
53
-    def get_content(self, data):
54
-        print "[filmix] get_content:", data
55
-        source, data, path, plist, clist, params, qs = self.parse_data(data)
56
-        content=[]
57
-        content.append(("..return", "back","","Return back"))
58
-
59
-        if clist=="home":
60
-            content.extend([
61
-                ("Search", "filmix::search/{0}","","Search"),
62
-                ("Movies", "filmix::movies","","Movies"),
63
-                ("Series", "filmix::series","","TV Series"),
64
-                ("Cartoons", "filmix::cartoons","","Cartoons"),
65
-            ])
66
-            return content
67
-
68
-        #elif clist=="search":
69
-            # TODO
70
-            #return content
71
-
72
-        elif data in ("movies","series","cartoons"):
73
-            r = self.call("")
74
-            r = r.decode("cp1251").encode("utf8")
75
-            if data == "movies":
76
-                sname = "Фильмы"
77
-            elif data=="series":
78
-                sname = "Сериалы"
79
-            else:
80
-                sname = "Мультфильмы"
81
-            # <span class="menu-title">Фильмы</span>
82
-            m = re.search('<span class="menu-title">%s</span>(.+?)<li>\s+?<span'%sname, r, re.DOTALL|re.UNICODE)
83
-            if not m: return content
84
-            r2 = m.group(1)
85
-            result = re.findall(r'<a .*?href="https://filmix\.me/([^"]+)".*?>([^<]+)</', r2, re.DOTALL)
86
-            for item in result:
87
-                if "catalog" in item[0]: continue
88
-                title = item[1]
89
-                data2 = item[0]
90
-                img = self.img
91
-                desc = title
92
-                content.append((title,self.name+"::"+data2,img,desc))
93
-            return content
94
-
95
-        ## Seriāls
96
-        elif clist=="play":
97
-            r = self.call(path)
98
-            r = r.decode("cp1251").encode("utf8")
99
-            title = title0 = util.unescape(re.search("titlePlayer = '([^']+)'", r, re.DOTALL).group(1))
100
-            m = re.search('<meta itemprop="thumbnailUrl" content="([^"]+)',r,re.DOTALL)
101
-            img = m.group(1) if m else self.img
102
-            m = re.search('<meta itemprop="duration" content="([^"]+)" />', r, re.DOTALL)
103
-            duration = "(%s)"%m.group(1) if m else ""
104
-            m = re.search('<p itemprop="description"[^>]+>([^<]+)<', r, re.DOTALL)
105
-            desc = desc0 =  util.unescape(m.group(1).strip()) if m else ""
106
-            vid = plist[-1]
107
-            js = self.get_movie_info(vid)
108
-            translations = js["message"]["translations"]["flash"]
109
-            for pl  in translations:
110
-                if translations[pl].startswith("http"):
111
-                    continue
112
-                pl_link = translations[pl]
113
-                lang = pl.encode("utf8")
114
-                break
115
-            else:
116
-                raise Exception("No episodes list found!")
117
-            #pl_link = js["message"]["translations"]["flash"].values()[0]
118
-            #  TODO process several players, currently taking the first
119
-            if not pl_link.startswith("http"):
120
-                pl_link = self.decode_uppod_text(pl_link)
121
-            js = self._http_request(pl_link)
122
-            js = self.decode_uppod_text(js)
123
-            js = json.loads(js)
124
-            if "s" in qs:
125
-                s = int(qs["s"])
126
-                for i,ep in enumerate(js["playlist"][s-1]["playlist"]):
127
-                    title = title0+" - "+js["playlist"][s-1]["playlist"][i]["comment"].encode("utf8")
128
-                    serie = js["playlist"][s-1]["playlist"][i]["comment"].encode("utf8")
129
-                    data2 = data+"&e=%s"%(i+1)
130
-                    desc = serie +"\n"+desc0
131
-                    content.append((title,self.name+"::"+data2,img,desc))
132
-            else:
133
-                for i,ep in enumerate(js["playlist"]):
134
-                    title = title0 +" - "+js["playlist"][i]["comment"].encode("utf8")
135
-                    serie = js["playlist"][i]["comment"].encode("utf8")
136
-                    data2 = data+"?s=%s"%(i+1)
137
-                    desc = serie +"\n"+desc0
138
-                    content.append((title,self.name+"::"+data2,img,desc))
139
-            return content
140
-            #r = self._http_request(url)
141
-
142
-
143
-        ### saraksts ###
144
-        else:
145
-            r = self.call(data)
146
-            r = r.decode("cp1251").encode("utf8")
147
-            for r2 in re.findall('<article class="shortstory line".+?</article>', r, re.DOTALL):
148
-                m = re.search(r'<a href="https://filmix\.me/play/(\d+)" class="watch icon-play">', r2, re.DOTALL)
149
-                if not m: continue
150
-                vid = m.group(1)
151
-                data2 = "play/%s"%vid
152
-                #title = re.search('itemprop="name">([^<]+)</div>', r2, re.DOTALL).group(1)
153
-                title = re.search('itemprop="name" content="([^"]+)"', r2, re.DOTALL).group(1)
154
-                m = re.search('itemprop="alternativeHeadline" content="([^"]+)"', r2, re.DOTALL)
155
-                if m:
156
-                    title = title + "/"+m.group(1)
157
-                m = re.search('<img src="([^"]+.jpg)"', r2, re.DOTALL)
158
-                img = m.group(1) if m else self.img
159
-                m = re.search(r'<a itemprop="copyrightYear".+?>(\d+)<', r2, re.DOTALL)
160
-                if m:
161
-                    year = m.group(1) if m else ""
162
-                    title = "%s (%s)"%(title,year)
163
-                title = util.unescape(title)
164
-                genre = re.findall('<a itemprop="genre"[^>]+?">([^<]+)</a>', r2, re.DOTALL)
165
-                genre = ",".join(genre)
166
-                m = re.search('<p itemprop="description">([^<]+)</p>', r2, re.DOTALL)
167
-                desc0 = util.unescape(m.group(1)) if m else ""
168
-                m = re.search('<div class="quality">([^<]+)</div>', r2, re.DOTALL)
169
-                quality = m.group(1) if m else ""
170
-                actors = re.findall('itemprop="actor">([^<]+)<', r2, re.DOTALL)
171
-                actors = ",".join(actors)
172
-                desc="%s\n%s\n%s\n%s\n%s"%(title,genre,desc0,actors,quality)
173
-                content.append((title,self.name+"::"+data2,img,desc))
174
-            if '<div class="navigation">' in r:
175
-                m = re.search(r'href="https://filmix\.me/([^"]+)" class="next icon-arowRight btn-tooltip"', r, re.DOTALL)
176
-                if m:
177
-                    data2 = m.group(1)
178
-                else:
179
-                    m = re.search("/page/(\d)+",data)
180
-                    if m:
181
-                        page = int(m.group(1))+1
182
-                        data2 = re.sub("/page/(\d)+", "/page/%s"%page, data)
183
-                    else:
184
-                        data2 = data + "/page/2"
185
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
186
-
187
-            return content
188
-
189
-    def is_video(self,data):
190
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
191
-        if clist == "play" and "s=" in data and "e=" in data:
192
-            return True
193
-        elif clist=="play" and not params:
194
-            r = self.call(path)
195
-            #r = r.decode("cp1251").encode("utf8")
196
-            m = re.search('itemprop="contentUrl" content="(.+?)"', r, re.IGNORECASE | re.DOTALL)
197
-            if not m:
198
-                raise Exception("Can not find video link")
199
-                #return False
200
-            video_link = m.group(1)
201
-            if video_link=='{video-link}':
202
-                return False
203
-            else:
204
-                return True
205
-        else:
206
-            return False
207
-
208
-    def get_streams(self, data):
209
-        print "[filmix] get_streams:", data
210
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
211
-
212
-        r = self.call(path)
213
-        if not r:
214
-            return []
215
-        streams = []
216
-        r = r.decode("cp1251").encode("utf8")
217
-        title = title0 = util.unescape(re.search("titlePlayer = '([^']+)'", r, re.DOTALL).group(1))
218
-        m = re.search('<meta itemprop="thumbnailUrl" content="([^"]+)',r,re.DOTALL)
219
-        img = m.group(1) if m else self.img
220
-        m = re.search('<meta itemprop="duration" content="([^"]+)" />', r, re.DOTALL)
221
-        duration = "(%s)"%m.group(1) if m else ""
222
-        m = re.search('<p itemprop="description"[^>]+>([^<]+)<', r, re.DOTALL)
223
-        desc = desc0 =  util.unescape(m.group(1).strip()) if m else ""
224
-        m = re.search('itemprop="contentUrl" content="(.+?)"', r, re.IGNORECASE | re.DOTALL)
225
-        if not m:
226
-            raise Exception("Can not find video link")
227
-            #return []
228
-        video_link = m.group(1)
229
-        series = True if video_link == '{video-link}' else False
230
-        vid = plist[1]
231
-        js = self.get_movie_info(vid)
232
-        translations = js["message"]["translations"]["flash"]
233
-        for pl in translations:
234
-            if translations[pl].startswith("http"):
235
-                continue
236
-            pl_link = translations[pl]
237
-            lang = pl.encode("utf8")
238
-            break
239
-        else:
240
-            raise Exception("No episodes list found!")
241
-        if not pl_link.startswith("http"):
242
-            pl_link = self.decode_uppod_text(pl_link)
243
-
244
-        if not series : # Filma
245
-            url0 = pl_link
246
-            streams2 = self.get_streams2(url0)
247
-            for st in streams2:
248
-                stream = util.item()
249
-                stream["url"]=st[1]
250
-                stream["lang"]=lang
251
-                stream["quality"]=st[0]
252
-                stream["name"]= title
253
-                stream["desc"]=desc
254
-                streams.append(stream)
255
-            return streams
256
-
257
-        else: # Seriāls
258
-            #pl_link = video_link
259
-            js = self._http_request(pl_link)
260
-            js = self.decode_uppod_text(js)
261
-            js = json.loads(js)
262
-            if "s" in qs and "e" in qs:
263
-                s = int(qs["s"])
264
-                e = int(qs["e"])
265
-                serie = js["playlist"][s-1]["playlist"][e-1]["comment"].encode("utf8")
266
-                title = title0+" - "+ serie
267
-                url0 = js["playlist"][s-1]["playlist"][e-1]["file"].encode("utf8")
268
-                streams2 = self.get_streams2(url0)
269
-                for st in streams2:
270
-                    stream = util.item()
271
-                    stream["url"]=st[1]
272
-                    stream["lang"]=lang
273
-                    stream["quality"]=st[0]
274
-                    stream["name"]= title
275
-                    stream["desc"]=desc
276
-                    streams.append(stream)
277
-                return streams
278
-
279
-    def call(self, data,params=None,headers=None,lang=""):
280
-        if not headers: headers = self.headers
281
-        url = self.url+data
282
-        result = self._http_request(url,params,headers=headers)
283
-        return result
284
-
285
-    def get_movie_info(self,vid):
286
-        headers = headers2dict("""
287
-    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
288
-    Accept: application/json, text/javascript, */*; q=0.01
289
-    Accept-Language: en-US,en;q=0.5
290
-    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
291
-    X-Requested-With: XMLHttpRequest
292
-    Referer: https://filmix.me/play/%s
293
-    """%vid )
294
-        post_data = {"post_id":vid}
295
-        r = util.post("https://filmix.me/api/movies/player_data", data=post_data, headers = headers)
296
-        if not r:
297
-            raise Exception("Can not get movie info")
298
-            #return []
299
-        js = json.loads(r)
300
-        return js
301
-
302
-    def decode_uppod_text(self, text):
303
-        Client_codec_a = ["l", "u", "T", "D", "Q", "H", "0", "3", "G", "1", "f", "M", "p", "U", "a", "I", "6", "k", "d", "s", "b", "W", "5", "e", "y", "="]
304
-        Client_codec_b = ["w", "g", "i", "Z", "c", "R", "z", "v", "x", "n", "N", "2", "8", "J", "X", "t", "9", "V", "7", "4", "B", "m", "Y", "o", "L", "h"]
305
-        text = text.replace("\n", "").strip()
306
-        for i in range(len(Client_codec_a)):
307
-            char1 = Client_codec_b[i]
308
-            char2 = Client_codec_a[i]
309
-            text = text.replace(char1, "___")
310
-            text = text.replace(char2, char1)
311
-            text = text.replace("___", char2)
312
-        result = base64.b64decode(text)
313
-        print result
314
-        return result
315
-
316
-    def get_streams2(self,url0):
317
-        m = re.search("\[([\d\w,]+)\]",url0)
318
-        if not m:
319
-            return [("?",url0)]
320
-        res = m.group(1)
321
-        streams=[]
322
-        for res in res.split(","):
323
-            if not res: continue
324
-            if res in ["1080p"]: continue #TODO fullhd only in PRO+ version
325
-            url=re.sub("\[[\d\w,]+\]",res,url0)
326
-            streams.append((res,url))
327
-        return streams
328
-
329
-
330
-if __name__ == "__main__":
331
-
332
-    c = Source()
333
-    #s = "ZnVuY3Rpb24gc2VuZE1lc3NhZ2U2MDc3ODkoZSl7dmFyIGg9bWdfd3M2MDc3ODkub25tZXNzYWdlOyBtZ193czYwNzc4OS5yZWFkeVN0YXRlPT1tZ193czYwNzc4OS5DTE9TRUQmJihtZ193czYwNzc4OT1uZXcgV2ViU29ja2V0KG1nX3dzNjA3Nzg5X2xvY2F0aW9uKSksbWdfd3M2MDc3ODkub25tZXNzYWdlPWgsd2FpdEZvclNvY2tldENvbm5lY3Rpb242MDc3ODkobWdfd3M2MDc3ODksZnVuY3Rpb24oKXttZ193czYwNzc4OS5zZW5kKGUpfSl9ZnVuY3Rpb24gd2FpdEZvclNvY2tldENvbm5lY3Rpb242MDc3ODkoZSx0KXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7cmV0dXJuIDE9PT1lLnJlYWR5U3RhdGU/dm9pZChudWxsIT10JiZ0KCkpOnZvaWQgd2FpdEZvclNvY2tldENvbm5lY3Rpb242MDc3ODkoZSx0KX0sNSl9OyB2YXIgbWdfd3M2MDc3ODlfbG9jYXRpb24gPSAid3NzOi8vd3NwLm1hcmtldGdpZC5jb20vd3MiOyBtZ193czYwNzc4OSA9IG5ldyBXZWJTb2NrZXQobWdfd3M2MDc3ODlfbG9jYXRpb24pLCBtZ193czYwNzc4OS5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAodCkge3Bvc3RNZXNzYWdlKHQuZGF0YSk7fSwgb25tZXNzYWdlID0gZnVuY3Rpb24oZSl7c2VuZE1lc3NhZ2U2MDc3ODkoZS5kYXRhKX0="
334
-
335
-    #txt = c.decode_uppod_text(s)
336
-    if len(sys.argv)>1:
337
-        data= sys.argv[1]
338
-    else:
339
-        data = "home"
340
-    content = c.get_content(data)
341
-    for item in content:
342
-        print item
343
-    #cat = api.get_categories(country)
344
-    #chan = api.get_channels("lv")
345
-    #prog = api.get_programs(channel=6400)
346
-    #prog = api.get_programs(category=55)
347
-    #seas = api.get_seasons(program=6453)
348
-    #str = api.get_streams(660243)
349
-    #res = api.get_videos(802)
350
-    #formats = api.getAllFormats()
351
-    #det = api.detailed("1516")
352
-    #vid = api.getVideos("13170")
353
-    pass

+ 0
- 272
resources/lib/sources/filmon.py View File

@@ -1,272 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys
15
-from SourceBase import SourceBase
16
-
17
-API_URL = 'http://www.filmon.com/'
18
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
19
-#User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
20
-headers0 = headers2dict("""
21
-User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46
22
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
23
-Accept-Language: en-US,en;q=0.5
24
-Accept-Encoding: deflate
25
-Connection: keep-alive
26
-""")
27
-import HTMLParser
28
-h = HTMLParser.HTMLParser()
29
-
30
-class Source(SourceBase):
31
-
32
-    def __init__(self,country="lv"):
33
-        self.name = "filmon"
34
-        self.title = "FilmOn"
35
-        self.img = "http://behindthegloves.com/wp-content/uploads/2016/01/FilmOn-logo1.jpg"
36
-        self.desc = "FilmOn portāla satura skatīšanās"
37
-        self.headers = headers0
38
-
39
-        self.country=country
40
-        self.jstv = None
41
-        self.session_key = None
42
-        self.cookie = None
43
-
44
-    def get_content(self, data):
45
-        print "[filmon] get_content:", data
46
-        if "::" in data:
47
-            data = data.split("::")[1] 
48
-        path = data.split("?")[0]
49
-        clist = path.split("/")[0]
50
-        params = data[data.find("?"):] if "?" in data else ""
51
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
52
-        lang = qs["lang"] if "lang" in qs else self.country
53
-
54
-        if not self.jstv:
55
-            self.jstv = self.get_tv_channels()
56
-        #if not self.session_key: # TODO izskatās, ka strādā bez, vismaz ja nelogojas iekšā,  jānočeko
57
-        #    html = self._http_request("http://www.filmon.com/api/init")
58
-        #    js = json.loads(html)
59
-        #    self.session_key = js["session_key"]
60
-
61
-        content=[]
62
-        content.append(("..return", "back","","Return back"))
63
-
64
-        if clist=="home":
65
-            content.extend([
66
-                ("Live streams", "filmon::tv","","TV live streams"),
67
-                ("Video on demand", "filmon::vod","","Last videos"),
68
-            ])
69
-            return content
70
-
71
-        ### TV Groups ###
72
-        elif clist in ("tv","home"):
73
-            for gr in self.jstv:
74
-                title = gr["name"].encode("utf8")
75
-                data2 = "group?id=%s"%gr["id"]
76
-                img = gr["logo_148x148_uri"].encode("utf8")
77
-                desc = gr["description"].encode("utf8")
78
-                content.append((title,self.name+"::"+data2,img,desc))
79
-            return content
80
-
81
-        ### TV group channels ###
82
-        elif clist=="group":
83
-            if "id" in qs:
84
-                group_id = qs["id"] 
85
-            else:
86
-                return content
87
-            group = None
88
-            for gr in self.jstv:
89
-                if gr["id"]==group_id:
90
-                    group = gr
91
-                    break
92
-            if not group:
93
-                return content
94
-            for ch in group["channels"]:
95
-                title = ch["title"].encode("utf8")
96
-                data2 = "channel?id=%s"%ch["id"]
97
-                img = ch["big_logo"].encode("utf8")
98
-                desc = ch["description"].encode("utf8") if ch["description"] else title
99
-                content.append((title,self.name+"::"+data2,img,desc))
100
-            return content
101
-
102
-        ### TV Channel ###
103
-        elif clist == "channel" or clist == "video":
104
-            if "id" in qs:
105
-                ch_id = qs["id"] 
106
-            else:
107
-                return ("No stream found %s"%data,"","","No stream found")
108
-            ch = self.get_tv_channel_info(ch_id)
109
-            if ch["now_playing"]:
110
-                current_event = ch["now_playing"]["programme_name"] if "programme_name" in ch["now_playing"] else ""
111
-            else:
112
-                current_event = ""
113
-            title = u"%s - %s"%(ch["title"],current_event)
114
-            title = title.encode("utf8")
115
-            if current_event:
116
-                desc = ch["now_playing"]["programme_description"].encode("utf8")
117
-            else:
118
-                desc = title
119
-            data2 = ""
120
-            for t in ("SD","HD"):
121
-                for s in ch["streams"]:
122
-                    if s["name"]==t:
123
-                        data2 = s["url"].encode("utf8")
124
-                        break
125
-                if data2: break
126
-            return (title,data2,"",desc)
127
-
128
-        ### VOD genres ###
129
-        elif path in ("vod","vod/genres"):
130
-            data = "vod/genres"
131
-            js = self.call(data)
132
-            for gr in js["response"]:
133
-                title = gr["name"].encode("utf8")
134
-                data2 = "vod/search?genre=%s&max_results=30&no_episode=true&start_index=0"%(gr["slug"].encode("utf8"))
135
-                img = gr["images"][0]["url"].encode("utf8")
136
-                desc = gr["description"].encode("utf8") if gr["description"] else title
137
-                content.append((title,self.name+"::"+data2,img,desc))
138
-            return content           
139
-
140
-        ### VOD genre videos ###
141
-        elif path == "vod/search":
142
-            js = self.call(data)
143
-            for vid in js["response"]:
144
-                title = vid["title"].encode("utf8")
145
-                if vid["type"]=="series":
146
-                    title = "[Series] "+title
147
-                data2 = "vod/movie?id=%s&type=%s"%(vid["id"],vid["type"].encode("utf8"))
148
-                img = "http://static.filmon.com/assets/"+vid["poster"]["couchdb_url"].encode("utf8")
149
-                desc = vid["description"].encode("utf8") if vid["description"] else title
150
-                content.append((title,self.name+"::"+data2,img,desc))
151
-            start_index = int(qs["start_index"]) if "start_index" in qs else 0
152
-            if start_index+js["total"]<js["total_found"]:
153
-                start_index += 30
154
-                data2 = re.sub("start_index=\d+","start_index=%s"%start_index,data) if "start_index" in qs else data +"&start_index=30"
155
-                content.append(("Next page",self.name+"::"+data2,"","Next page"))                                            
156
-            return content
157
-
158
-        ### VOD video sigle/series ###
159
-        elif path == "vod/movie":
160
-            js = self.call(data)
161
-            if js["response"]["type"] == "series":
162
-                ids = ",".join(js["response"]["episodes"])
163
-                data2 = "vod/movies?ids=%s"%ids
164
-                js2 = self.call(data2)
165
-                for vid in js2["response"]:
166
-                    title = vid["title"].encode("utf8")
167
-                    if vid["type"]=="series":
168
-                        title = "[Series] "+title
169
-                    data2 = "vod/movie?id=%s&type=%s"%(vid["id"],vid["type"].encode("utf8"))
170
-                    img = "http://static.filmon.com/assets/"+vid["poster"]["couchdb_url"].encode("utf8")
171
-                    desc = vid["description"].encode("utf8") if vid["description"] else title
172
-                    content.append((title,self.name+"::"+data2,img,desc))
173
-                return content
174
-            else:
175
-                title = js["response"]["title"].encode("utf8")
176
-                desc = js["response"]["description"].encode("utf8") if js["response"]["description"] else title
177
-                data2 = js["response"]["streams"]["low"]["url"].encode("utf8")
178
-                return (title,data2,"",desc)
179
-
180
-    def is_video(self,data):
181
-        if "::" in data:
182
-            data = data.split("::")[1]
183
-        cmd = data.split("?")
184
-        if cmd[0] in ("video","channel"):
185
-            return True
186
-        elif cmd[0] == "vod/movie" and "type=movie" in data:
187
-            return True
188
-        else:
189
-            return False
190
-
191
-    def call(self, data,headers=headers0,lang=""):
192
-        if not lang: lang = self.country
193
-        url = "http://www.filmon.com/api/" + data
194
-        #if not "?" in url: url += "?session_key=%s"%self.session_key
195
-        #if not "session_key=" in url: url += "&session_key=%s"%self.session_key
196
-        #print "[TVPlay Api] url: ",url
197
-        result = []
198
-        content = self._http_request(url)
199
-        if content:
200
-            try:
201
-                result = json.loads(content)
202
-            except Exception, ex:
203
-                return None
204
-        return result
205
-
206
-    #----------------------------------------------------------------------
207
-    def get_tv_channel_info(self,id):
208
-        url = "http://www.filmon.com/ajax/getChannelInfo"
209
-        headers = headers2dict("""
210
-Host: www.filmon.com
211
-User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0
212
-Accept: application/json, text/javascript, */*; q=0.01
213
-Accept-Language: en-US,en;q=0.5
214
-Accept-Encoding: deflate
215
-DNT: 1
216
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
217
-X-Requested-With: XMLHttpRequest
218
-Referer: http://www.filmon.com/tv/live
219
-Connection: keep-alive
220
-Pragma: no-cache
221
-Cache-Control: no-cache
222
-""")
223
-        headers["Cookie"] = self.cookie
224
-        data = "channel_id=%s&quality=low"%id
225
-        response = urllib2.urlopen(urllib2.Request(url, headers=headers,data=data))
226
-        html =  response.read()
227
-        js = json.loads(html)
228
-        return js
229
-
230
-    #----------------------------------------------------------------------
231
-    def get_tv_channels(self):
232
-        """Get tv channels list"""
233
-        headers = headers2dict("""
234
-Host: www.filmon.com
235
-User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0
236
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
237
-Accept-Language: en-US,en;q=0.5
238
-Accept-Encoding: deflate
239
-DNT: 1
240
-Connection: keep-alive
241
-    """)
242
-
243
-        url = "http://www.filmon.com/tv"
244
-        response = urllib2.urlopen(urllib2.Request(url, headers=headers))
245
-        if "set-cookie" in response.headers:
246
-            self.cookie = response.headers["set-cookie"]
247
-        html =  response.read()
248
-        s = re.search("(?i)var groups = (.*);", html).groups(1)[0]
249
-        js = json.loads(s)
250
-        return js
251
-
252
-if __name__ == "__main__":
253
-    country= "lv"
254
-    c = Source(country)
255
-    if len(sys.argv)>1:
256
-        data= sys.argv[1]
257
-    else:
258
-        data = "home"
259
-    content = c.get_content(data)
260
-    for item in content:
261
-        print item
262
-    #cat = api.get_categories(country)
263
-    #chan = api.get_channels("lv")
264
-    #prog = api.get_programs(channel=6400)
265
-    #prog = api.get_programs(category=55)
266
-    #seas = api.get_seasons(program=6453)
267
-    #str = api.get_streams(660243)
268
-    #res = api.get_videos(802)
269
-    #formats = api.getAllFormats()
270
-    #det = api.detailed("1516")
271
-    #vid = api.getVideos("13170")
272
-    pass

+ 0
- 4
resources/lib/sources/iplayer.cfg View File

@@ -1,4 +0,0 @@
1
-[iplayer]
2
-user = ivars777@gmail.com
3
-password = kaskade7
4
-

+ 0
- 551
resources/lib/sources/iplayer.py View File

@@ -1,551 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-import sys, os, os.path, re, sys
9
-import urllib,urllib2
10
-from xml.sax.saxutils import unescape,escape
11
-from urllib import quote, unquote
12
-import datetime
13
-import HTMLParser
14
-import json
15
-import datetime,time
16
-from SourceBase import SourceBase, stream_type
17
-import util
18
-from collections import OrderedDict
19
-
20
-API_URL = 'https://m.lattelecom.tv/'
21
-user_agent = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; da-dk) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3"
22
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
23
-h = HTMLParser.HTMLParser()
24
-
25
-class Source(SourceBase):
26
-
27
-    def __init__(self):
28
-        self.name = "iplayer"
29
-        self.title = "BBC iPlayer"
30
-        self.img = "http://www.userlogos.org/files/logos/inductiveload/BBC_iPlayer_logo.png"
31
-        self.desc = "BBC iPlayer portal content"
32
-
33
-        self.api_url = "http://ibl.api.bbci.co.uk/ibl/v1/"
34
-        self.headers = headers2dict("""
35
-User-Agent: BBCiPlayer/4.19.0.3021 (SM-G900FD; Android 4.4.2)
36
-Connection: Keep-Alive
37
-        """)
38
-        self.headers2 = headers2dict("""
39
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
40
-Connection: Keep-Alive
41
-        """)
42
-
43
-        self.ch = []
44
-        self.ch_id={}
45
-        self.ch_id2={}
46
-        self.ch_name={}
47
-        self.logos ={
48
-            "bbc_one_london":"http://www.lyngsat-logo.com/hires/bb/bbc_one.png",
49
-            "bbc_two_england":"http://www.lyngsat-logo.com/hires/bb/bbc_two_uk.png",
50
-            "bbc_three":"http://www.lyngsat-logo.com/hires/bb/bbc_three_uk.png",
51
-            "bbc_four":"http://www.lyngsat-logo.com/hires/bb/bbc_four_uk.png",
52
-            "bbc_radio_one":"http://www.lyngsat-logo.com/hires/bb/bbc_radio1.png",
53
-            "cbbc":"http://www.lyngsat-logo.com/hires/bb/bbc_cbbc.png",
54
-            "cbeebies":"http://www.lyngsat-logo.com/hires/bb/bbc_cbeebies_uk.png",
55
-            "bbc_news24":"http://www.lyngsat-logo.com/hires/bb/bbc_news.png",
56
-            "bbc_parliament":"http://www.lyngsat-logo.com/hires/bb/bbc_parliament.png",
57
-            "bbc_alba":"http://www.lyngsat-logo.com/hires/bb/bbc_alba.png",
58
-            "s4cpbs":"http://www.lyngsat-logo.com/hires/ss/s4c_uk.png"
59
-        }
60
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
61
-        self.config_file = os.path.join(cur_directory,self.name+".cfg")
62
-        self.options = OrderedDict([("user","lietotajs"),("password","parole")])
63
-        self.options_read()
64
-
65
-    def get_content(self, data):
66
-        print "[iplayer] get_content:", data
67
-        if "::" in data:
68
-            data = data.split("::")[1]
69
-        path = data.split("?")[0]
70
-        clist = path.split("/")[0]
71
-        params = data[data.find("?"):] if "?" in data else ""
72
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=[\w-]+",params)))
73
-        #lang = qs["lang"] if "lang" in qs else self.country
74
-
75
-        content=[]
76
-        content.append(("..return", "back","","Return back"))
77
-
78
-        ### Home ###
79
-        if data=="home":
80
-            content.extend([
81
-                ("Search TV", "iplayer::search/{0}","","Search in iPlayer"),
82
-                ("Live streams", "iplayer::live","","TV live streams"),
83
-                ("Channels", "iplayer::channels","","Programmes by channel/date"),
84
-                ("Categories", "iplayer::categories","","Programmes by categories"),
85
-                ("A-Z", "iplayer::a-z","","All programmes by name"),
86
-                ("Highlights", "iplayer::home/highlights","","Current highlights"),
87
-                ("Most popular", "iplayer::groups/popular/episodes?per_page=40&page=1","","Most popular programmes")
88
-            ])
89
-            return content
90
-
91
-        ### Search ###
92
-        elif clist=="search":
93
-            data_ = "search-suggest/?q=%s&rights=mobile&initial_child_count=1"%data.split("/")[1]
94
-            r = self.call(data_)
95
-            for item in r["search_suggest"]["results"]:
96
-                title,data2,img,desc = self.get_data_element(item)
97
-                content.append((title,self.name+"::"+data2,img,desc))
98
-            return content
99
-
100
-
101
-        ### Live main ###
102
-        elif data=="live":
103
-            for ch in self.get_channels():
104
-                title = ch["title"]
105
-                img = self.logos[ch["id"]] if ch["id"] in self.logos else  "http://static.bbci.co.uk/mobileiplayerappbranding/1.9/android/images/channels/tv-guide-wide-logo/layout_normal/xxhdpi/%s_tv-guide-wide-logo.png"%ch["id"]
106
-                desc = title
107
-                data2 = "live/%s"%ch["id"]
108
-                ee = self.get_epg_live(ch["id"])
109
-                desc = ee[2]
110
-                content.append((title,self.name+"::"+data2,img,desc))
111
-            return content
112
-
113
-        ### Categories ###
114
-        elif data == "categories":
115
-            r = self.call(data)
116
-            if not "categories":
117
-                raise Exception("Error reading categories")
118
-            for item in r["categories"]:
119
-                data2 = "categories/%s"%(item["id"])
120
-                title = item["title"]
121
-                desc = title
122
-                img = self.img
123
-                content.append((title,self.name+"::"+data2,img,desc))
124
-            return content
125
-
126
-        ### Catetory root ###
127
-        elif clist == "categories" and len(data.split("/"))==2:
128
-            r = self.call(data)
129
-            title = "%s - highlights"%r["category"]["title"]
130
-            content.append((title,self.name+"::"+data+"/highlights?lang=en&rights=mobile&availability=available",self.img,title))
131
-            title = "%s - recent (%s programmes, %s episodes)"%(r["category"]["title"],r["category"]["child_programme_count"],r["category"]["child_episode_count"])
132
-            content.append((title,self.name+"::"+data+"/programmes?rights=mobile&page=1&per_page=40&sort=recent&sort_direction=asc&initial_child_count=1&availability=available",self.img,title))
133
-            title = "%s - a-z (%s programmes, %s episodes)"%(r["category"]["title"],r["category"]["child_programme_count"],r["category"]["child_episode_count"])
134
-            content.append((title,self.name+"::"+data+"/programmes?rights=mobile&page=1&per_page=40&sort=title&sort_direction=asc&initial_child_count=1&availability=available",self.img,title))
135
-            return content
136
-
137
-        ### Program/episodes list ###
138
-        elif   re.search("categories/([\w\-]+)/(highlights|programmes).+",data) or\
139
-               re.search("programmes/(\w+)/episodes.+",data) or\
140
-               re.search("groups/(\w+)/episodes.+",data) or\
141
-               re.search("atoz/([\w]+)/programmes.+",data) or\
142
-               re.search("channels/(\w+)/schedule/[\d\-].+",data) or\
143
-               re.search("channels/(\w+)/programmes.+",data) or\
144
-               re.search("channels/(\w+)/highlights.+",data) or\
145
-               data == "home/highlights":
146
-            r = self.call(data)
147
-            lst = r["category_highlights"] if "category_highlights" in r else\
148
-                  r["category_programmes"] if "category_programmes" in r else\
149
-                  r["programme_episodes"] if "programme_episodes" in r else\
150
-                  r["atoz_programmes"] if "atoz_programmes" in r else\
151
-                  r["group_episodes"] if "group_episodes" in r else\
152
-                  r["schedule"] if "schedule" in r else\
153
-                  r["channel_highlights"] if "channel_highlights" in r else\
154
-                  r["channel_programmes"] if "channel_programmes" in r else\
155
-                  r["home_highlights"] if "home_highlights" in r else\
156
-                  []
157
-            if not lst:
158
-                return content
159
-            for el in lst["elements"]:
160
-                if el["type"] == "broadcast":
161
-                    if not len(el["episode"]["versions"]):continue
162
-                    title,data2,img,desc = self.get_data_element(el["episode"])
163
-                    t1 = gt(el['scheduled_start'])
164
-                    t2 = gt(el['scheduled_end'])
165
-                    title = "[%s-%s]%s"%(t1.strftime("%d.%m.%Y %H:%M"),t2.strftime("%H:%M"),title)
166
-                else:
167
-                    title,data2,img,desc = self.get_data_element(el)
168
-                content.append((title,self.name+"::"+data2,img,desc))
169
-
170
-            if "&page=" in data and lst["page"]*lst["per_page"]<lst["count"]:
171
-                data2 = re.sub("&page=\d+","&page=%s"%(lst["page"]+1),data)
172
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
173
-            return content
174
-
175
-        ### A-z root ###
176
-        elif data=="a-z":
177
-            url = "http://www.bbc.co.uk/programmes/a-z/by/x/all.json?page=1"
178
-            r = self._http_request(url)
179
-            if not r:
180
-                raise Exception("Can not read %s"%s)
181
-            js = json.loads(r)
182
-            for ch in js["atoz"]["letters"]:
183
-                title = ch.upper()
184
-                desc = "Programmes beginning with %s"%title
185
-                img = self.img
186
-                data2 = "atoz/%s/programmes?rights=mobile&page=1&per_page=40&initial_child_count=1&sort=title&sort_direction=asc&availability=available"%ch
187
-                content.append((title,self.name+"::"+data2,img,desc))
188
-            return content
189
-
190
-        ###  Channels home ###
191
-        elif data=="channels":
192
-            for ch in self.get_channels():
193
-                title = ch["title"]
194
-                img = self.logos[ch["id"]] if ch["id"] in self.logos else  "http://static.bbci.co.uk/mobileiplayerappbranding/1.9/android/images/channels/tv-guide-wide-logo/layout_normal/xxhdpi/%s_tv-guide-wide-logo.png"%ch["id"]
195
-                desc = title
196
-                data2 = "channels/%s"%ch["id"]
197
-                #ee = self.get_epg_live(ch["id"])
198
-                desc = title
199
-                content.append((title,self.name+"::"+data2,img,desc))
200
-            return content
201
-
202
-        ### Channel higlihts/progrmmes/days ###
203
-        elif clist=="channels" and len(data.split("/"))==2:
204
-            r = self.call(data)
205
-            chid = data.split("/")[1]
206
-            ch = self.get_channel_by_id(chid)
207
-
208
-            # Highlights
209
-            title = ch["title"] + " - highlights"
210
-            img = "http://static.bbci.co.uk/mobileiplayerappbranding/1.9/android/images/channels/tv-guide-wide-logo/layout_normal/xxhdpi/%s_tv-guide-wide-logo.png"%ch["id"]
211
-            data2 = "channels/%s/highlights?lang=en&rights=mobile&availability=available"%ch["id"]
212
-            desc = title
213
-            content.append((title,self.name+"::"+data2,img,desc))
214
-
215
-            #AtoZ
216
-            title = ch["title"] + " - programmes AtoZ"
217
-            data2 = "channels/%s/programmes?rights=mobile&page=1&per_page=40&sort=recent&sort_direction=asc&initial_child_count=1&availability=available"%ch["id"]
218
-            desc = title
219
-            content.append((title,self.name+"::"+data2,img,desc))
220
-
221
-            day0 = datetime.date.today()
222
-            for i in range(10):
223
-                day = day0-datetime.timedelta(days=i)
224
-                days = day.strftime("%Y-%m-%d")
225
-                title = ch["title"] + " - " + days
226
-                img = "http://static.bbci.co.uk/mobileiplayerappbranding/1.9/android/images/channels/tv-guide-wide-logo/layout_normal/xxhdpi/%s_tv-guide-wide-logo.png"%ch["id"]
227
-                data2 = "channels/%s/schedule/%s?availability=available"%(ch["id"],days)
228
-                #ee = self.get_epg_live(ch["id"])
229
-                desc = title
230
-                content.append((title,self.name+"::"+data2,img,desc))
231
-            return content
232
-
233
-
234
-    def get_streams(self, data):
235
-        print "[iplayer] get_streams:", data
236
-        if "::" in data: data = data.split("::")[1]
237
-        if not self.is_video(data):
238
-            return []
239
-        cmd = data.split("/")
240
-        vid = cmd[1].split("?")[0]
241
-        if cmd[0] == "live":
242
-            title,img,desc,nfo = self.get_epg_live(vid)
243
-        else:
244
-            #data_ = "episodes/%s"%vid
245
-            #r = self.call(data_)
246
-            title,img,desc,vid,nfo = self.get_epg_video(vid)
247
-        url = "http://open.live.bbc.co.uk/mediaselector/5/select/version/2.0/format/json/mediaset/iptv-all/vpid/%s"%vid
248
-        print "vid=%s"%vid
249
-        print url
250
-        r = self._http_request(url) #,headers=self.headers2
251
-        if not r:
252
-            raise Exception("No streams found")
253
-        js = json.loads(r)
254
-        if "result" in js and js["result"]=="geolocation":
255
-            raise Exception("BBC iPlayer service available only from UK")
256
-        if not "media" in js:
257
-            raise Exception("No streams found")
258
-        streams = []
259
-        captions = []
260
-        for s in js["media"]:
261
-            if s["kind"] == "captions":
262
-                if s["connection"][0]["href"]:
263
-                    sub = {}
264
-                    sub["url"] = s["connection"][0]["href"].encode('utf8')
265
-                    sub["type"] = s["type"]
266
-                    sub["name"] = s["service"] if "service" in s else "captions (taff)"
267
-                    sub["lang"] = "en"
268
-                    captions.append(sub)
269
-
270
-            if s["kind"] <> "video":
271
-                continue
272
-            for c in s["connection"]:
273
-                if c["transferFormat"] <> "hls": continue
274
-                #if not (c["supplier"].startswith("mf_") or c["supplier"].startswith("ll_")) : continue # TODO ir kaut kādas VPN problēmas ar akamaihd
275
-                #if c["priority"] <> "1": continue
276
-                url=c["href"].encode("utf8")
277
-                r2 = self._http_request(url)
278
-                if not r2: continue
279
-                slist = re.findall("#EXT-X-STREAM-INF:([^\n]+)\n([^\n]+)", r2, re.DOTALL)
280
-                if not slist:
281
-                    stream = util.item()
282
-                    stream["url"]=url
283
-                    stream["name"]=title
284
-                    stream["desc"]=desc
285
-                    stream["img"]=img
286
-                    stream["type"]="hls"
287
-                    stream["quality"]=("%s %sx%s %s,%s"%(s["bitrate"],s["width"],s["height"],c["supplier"],c["priority"])).encode("utf8")
288
-                    stream["lang"]="en"
289
-                    stream["subs"]=captions
290
-                    stream["order"]=int(s["bitrate"])
291
-                    stream["nfo"] = nfo
292
-                    streams.append(stream)
293
-                else:
294
-                    for cc in slist:
295
-                        m = re.search("RESOLUTION=([\dx]+)",cc[0])
296
-                        resolution = m.group(1) if m else "%sx%s"%(s["width"],s["height"])
297
-                        m = re.search("BANDWIDTH=([\d]+)",cc[0])
298
-                        bitrate = m.group(1) if m else s["bitrate"]
299
-                        url2 = cc[1].encode("utf8")
300
-                        if not url2.startswith("http"):
301
-                            uu = url.split("/")[:-1]
302
-                            uu.append(url2)
303
-                            url2 = "/".join(uu)
304
-                        stream = util.item()
305
-                        stream["url"]=url2
306
-                        stream["name"]=title
307
-                        stream["desc"]=desc
308
-                        stream["img"]=img
309
-                        stream["type"]="hls"
310
-                        stream["quality"]=("%s %s %s,%s"%(bitrate,resolution,c["supplier"],c["priority"])).encode("utf8")
311
-                        stream["lang"]="en"
312
-                        stream["subs"]=captions
313
-                        stream["order"]=int(bitrate)
314
-                        stream["nfo"] = nfo
315
-                        streams.append(stream)
316
-        if captions:
317
-            for s in streams:
318
-                s["subs"]=captions
319
-        streams = sorted(streams,key=lambda item: item["order"],reverse=True)
320
-        return streams
321
-
322
-    def is_video(self,data):
323
-        if "::" in data:
324
-            data = data.split("::")[1]
325
-        cmd = data.split("/")
326
-        if cmd[0]=="live" and  len(cmd)==2:
327
-            return True
328
-        elif cmd[0]=="episodes" and len(cmd)==2:
329
-            return True
330
-        else:
331
-            return False
332
-
333
-    def get_data_element(self,item):
334
-        if ("programme" in item["type"] or "group" in item["type"]) and item["count"]>1:
335
-            ep = item.copy()
336
-        elif ("programme" in item["type"] or "group" in item["type"]) and item["count"]==1:
337
-            ep = item["initial_children"][0].copy()
338
-        elif item["type"] == "episode":
339
-            ep = item.copy()
340
-        elif item["type"] == "broadcast":
341
-            ep = item["episode"].copy()
342
-        else:
343
-            ep = item.copy()
344
-        title = ep["title"]
345
-        if "subtitle" in ep and ep["subtitle"]:
346
-            title = title+". "+ ep["subtitle"]
347
-        desc = ep["synopses"]["large"] if "large" in ep["synopses"] else ep["synopses"]["medium"] if "medium" in ep["synopses"] else ep["synopses"]["small"]
348
-        #TODO papildus info pie apraksta
349
-        img = ep["images"]["standard"].replace("{recipe}","512x288") if "images" in ep else self.img
350
-        if ep["type"] == "episode":
351
-            data2 = "episodes/%s"%ep["id"]
352
-        elif "programme" in ep["type"]:
353
-            data2 = "programmes/%s/episodes?per_page=40&page=1"%ep["id"]
354
-            title = "%s [%s episodes]"%(title,ep["count"])
355
-        elif "group" in ep["type"]:
356
-            data2 = "groups/%s/episodes?per_page=40&page=1"%ep["id"]
357
-            title = "%s [%s episodes]"%(title,ep["count"])
358
-        else:
359
-            data2 = "programmes/%s/episodes?per_page=40&page=1"%ep["id"]
360
-            title = "%s [%s episodes]"%(title,ep["count"])
361
-        return title,data2,img,desc
362
-
363
-    def get_epg_video(self,vid):
364
-        data = "episodes/%s"%vid
365
-        nfo = {}
366
-        r = self.call(data)
367
-        if "episodes" in r :
368
-            ep = r["episodes"][0]
369
-            title = ep["title"]
370
-            if "subtitle" in ep:
371
-                title = title +". "+ ep["subtitle"]
372
-            title = title
373
-            desc = ep["synopses"]["medium"] if "medium" in ep["synopses"] else p["synopses"]["small"] if "small" in ep["synopses"] else title
374
-            desc = desc
375
-            ver = ep["versions"][0]
376
-            vid = ver["id"]
377
-            remaining = ver["availability"]["end"].split("T")[0] #["remaining"]["text"]
378
-            duration = ver["duration"]["text"]
379
-            first_broadcast = ver["first_broadcast"]
380
-            desc =u"%s\n%s\%s\n%s\n%s"%(title,duration,remaining,first_broadcast,desc)
381
-            img = ep["images"]["standard"].replace("{recipe}","512x288")
382
-
383
-            #Create nfo dictionary
384
-            tt = lambda dd,k,d: dd[k] if k in dd else d
385
-            nfo_type = "movie" if True else "tvswhow" # TODO
386
-            t = OrderedDict()
387
-            t["title"] = title
388
-            t["originaltitle"] = tt(ep,"original_title","")
389
-            t["thumb"] = img
390
-            t["id"] = vid
391
-            t["outline"] = ep["synopses"]["small"] if "small" in ep["synopses"] else ep["synopses"]["editorial"] if "editorial" in ep["synopses"] else ""
392
-            t["plot"] = ep["synopses"]["large"] if "large" in ep["synopses"] else ep["synopses"]["medium"] if "medium" in ep["synopses"] else p["synopses"]["small"] if "small" in ep["synopses"] else title
393
-            t["tagline"] = ep["synopses"]["editorial"] if "editorial" in ep["synopses"] else ""
394
-            t["runtime"] = tt(ver["duration"],"text","")
395
-            t["premiered"] = tt(ep,"release_date","")
396
-            t["aired"] = ver["availability"]["start"].split("T")[0] if "start" in ver["availability"] else ""
397
-            if "parent_position" in ep: t["episode"] = ep["parent_position"]
398
-            nfo[nfo_type] = t
399
-
400
-            return title.encode("utf8"),img.encode("utf8"),desc.encode("utf8"),vid.encode("utf8"),nfo
401
-        else:
402
-            raise Exception("No video info")
403
-
404
-    def get_epg_live(self,channelid):
405
-        data = "channels/%s/highlights?live=true"%channelid
406
-        r = self.call(data)
407
-        nfo = {}
408
-        if "channel_highlights" in r and r["channel_highlights"]["elements"][0]["id"] == "live":
409
-            epg = r["channel_highlights"]["elements"][0]["initial_children"][0].copy()
410
-            t1 = gt(epg['scheduled_start'])
411
-            t2 = gt(epg['scheduled_end'])
412
-            ep = epg["episode"]
413
-            title = ep["title"]
414
-            if "subtitle" in ep:
415
-                title = title +". "+ ep["subtitle"]
416
-            title = "%s (%s-%s)"%(title,t1.strftime("%H:%M"),t2.strftime("%H:%M"))
417
-            title = title
418
-            desc = ep["synopses"]["medium"] if "medium" in ep["synopses"] else p["synopses"]["small"] if "small" in ep["synopses"] else title
419
-            desc = desc
420
-            desc ="%s\n%s"%(title,desc)
421
-            img = ep["images"]["standard"].replace("{recipe}","512x288")
422
-            #return title,img,desc
423
-        else:
424
-            title = r["channel_highlights"]["channel"]["title"]
425
-            img = ""
426
-            desc = title
427
-
428
-        return title.encode("utf8"),img.encode("utf8"),desc.encode("utf8"),nfo
429
-
430
-    def get_channels(self):
431
-        if self.ch:
432
-            return self.ch
433
-        r= self.call("channels")
434
-        self.ch=[]
435
-        for i,item in enumerate(r["channels"]):
436
-            self.ch.append(item)
437
-            self.ch_id[item["id"]]=i
438
-            self.ch_id2[item["master_brand_id"]]=i
439
-            self.ch_name[item["title"]]=i
440
-        return self.ch
441
-
442
-    def get_channel_by_id(self,chid):
443
-        if not self.ch:
444
-            self.get_channels()
445
-        if not self.ch:
446
-            return None
447
-        return self.ch[self.ch_id[chid]] if self.ch_id.has_key(chid) else None
448
-
449
-    def get_channel_by_id2(self,chid):
450
-        if not self.ch:
451
-            self.get_channels()
452
-        if not self.ch:
453
-            return None
454
-        return self.ch[self.ch_id2[chid]] if self.ch_id2.has_key(chid) else None
455
-
456
-    def get_channel_by_name(self,name):
457
-        if not self.ch:
458
-            self.get_channels()
459
-        ch2 = self.get_channel_by_name2(name)
460
-        if not ch2:
461
-            return None
462
-        ch = self.get_channel_by_id2(ch2["id2"])
463
-        return ch
464
-
465
-
466
-    def call(self, data,params = None, headers=None):
467
-        if not headers: headers = self.headers
468
-        #if not lang: lang = self.country
469
-        url = self.api_url + data
470
-        content = self._http_request(url,params, headers)
471
-        if content:
472
-            try:
473
-                result = json.loads(content)
474
-                return result
475
-            except Exception, ex:
476
-                return None
477
-        else:
478
-            return None
479
-
480
-    def call2(self, data,params = None, headers=None):
481
-        if not headers: headers = self.headers2
482
-        #if not lang: lang = self.country
483
-        url = self.api_url2 + data
484
-        content = self._http_request(url,params, headers)
485
-        return content
486
-
487
-    def _http_request(self, url,params = None, headers=None):
488
-        if not headers: headers = self.headers
489
-        import requests
490
-        try:
491
-            from requests.packages.urllib3.exceptions import InsecureRequestWarning
492
-            requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
493
-        except:
494
-            pass
495
-        try:
496
-            r = requests.get(url, headers=headers)
497
-            return r.content
498
-
499
-        except Exception as ex:
500
-            if ex.code==403:
501
-                return ex.read()
502
-            else:
503
-                return None
504
-
505
-def gt(dt_str):
506
-    dt, _, us= dt_str.partition(".")
507
-    dt= datetime.datetime.strptime(dt, "%Y-%m-%dT%H:%M:%S")
508
-    dt = dt - datetime.timedelta(seconds=time.altzone)
509
-    #us= int(us.rstrip("Z"), 10)
510
-    #r = dt + datetime.timedelta(microseconds=us)a
511
-    return dt
512
-
513
-if __name__ == "__main__":
514
-    c = Source()
515
-    from subprocess import call
516
-    #ch = c.get_channels()
517
-    #c.get_epg_live("bbc_two_england")
518
-
519
-    if len(sys.argv)>1 and  not "iplayer::" in sys.argv[1]:
520
-
521
-        vid = sys.argv[1]
522
-        print "login - %s"%c.login("ivars777","xxx")
523
-        vid = "1069"
524
-        vid = "1462566072086"
525
-        channelid="101"
526
-        vid = "1350462656767"
527
-        #data = c.get_stream_url(vid,"vod")
528
-        #call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",data["stream"]])
529
-        pass
530
-
531
-
532
-
533
-    else:
534
-        if len(sys.argv)>1:
535
-            data= sys.argv[1]
536
-        else:
537
-            data = "iplayer::home"
538
-        content = c.get_content(data)
539
-        for item in content:
540
-            print item
541
-        #cat = api.get_categories(country)
542
-        #chan = api.get_channels("lv")
543
-        #prog = api.get_programs(channel=6400)
544
-        #prog = api.get_programs(category=55)
545
-        #seas = api.get_seasons(program=6453)
546
-        #str = api.get_streams(660243)
547
-        #res = api.get_videos(802)
548
-        #formats = api.getAllFormats()
549
-        #det = api.detailed("1516")
550
-        #vid = api.getVideos("13170")
551
-        pass

+ 0
- 261
resources/lib/sources/jsinterp.py View File

@@ -1,261 +0,0 @@
1
-# This code comes from youtube-dl: https://github.com/rg3/youtube-dl/blob/master/youtube_dl/jsinterp.py
2
-
3
-from __future__ import unicode_literals
4
-
5
-import json
6
-import operator
7
-import re
8
-
9
-
10
-_OPERATORS = [
11
-    ('|', operator.or_),
12
-    ('^', operator.xor),
13
-    ('&', operator.and_),
14
-    ('>>', operator.rshift),
15
-    ('<<', operator.lshift),
16
-    ('-', operator.sub),
17
-    ('+', operator.add),
18
-    ('%', operator.mod),
19
-    ('/', operator.truediv),
20
-    ('*', operator.mul),
21
-]
22
-_ASSIGN_OPERATORS = [(op + '=', opfunc) for op, opfunc in _OPERATORS]
23
-_ASSIGN_OPERATORS.append(('=', lambda cur, right: right))
24
-
25
-_NAME_RE = r'[a-zA-Z_$][a-zA-Z_$0-9]*'
26
-
27
-
28
-class JSInterpreter(object):
29
-    def __init__(self, code, objects=None):
30
-        if objects is None:
31
-            objects = {}
32
-        self.code = code
33
-        self._functions = {}
34
-        self._objects = objects
35
-
36
-    def interpret_statement(self, stmt, local_vars, allow_recursion=100):
37
-        if allow_recursion < 0:
38
-            print '[JSInterpreter] Recursion limit reached'
39
-            return None
40
-
41
-        should_abort = False
42
-        stmt = stmt.lstrip()
43
-        stmt_m = re.match(r'var\s', stmt)
44
-        if stmt_m:
45
-            expr = stmt[len(stmt_m.group(0)):]
46
-        else:
47
-            return_m = re.match(r'return(?:\s+|$)', stmt)
48
-            if return_m:
49
-                expr = stmt[len(return_m.group(0)):]
50
-                should_abort = True
51
-            else:
52
-                # Try interpreting it as an expression
53
-                expr = stmt
54
-
55
-        v = self.interpret_expression(expr, local_vars, allow_recursion)
56
-        return v, should_abort
57
-
58
-    def interpret_expression(self, expr, local_vars, allow_recursion):
59
-        expr = expr.strip()
60
-
61
-        if expr == '':  # Empty expression
62
-            return None
63
-
64
-        if expr.startswith('('):
65
-            parens_count = 0
66
-            for m in re.finditer(r'[()]', expr):
67
-                if m.group(0) == '(':
68
-                    parens_count += 1
69
-                else:
70
-                    parens_count -= 1
71
-                    if parens_count == 0:
72
-                        sub_expr = expr[1:m.start()]
73
-                        sub_result = self.interpret_expression(
74
-                            sub_expr, local_vars, allow_recursion)
75
-                        remaining_expr = expr[m.end():].strip()
76
-                        if not remaining_expr:
77
-                            return sub_result
78
-                        else:
79
-                            expr = json.dumps(sub_result) + remaining_expr
80
-                        break
81
-            else:
82
-                print '[JSInterpreter] Premature end of parens in %r' % expr
83
-                return None
84
-
85
-        for op, opfunc in _ASSIGN_OPERATORS:
86
-            m = re.match(r'''(?x)
87
-                (?P<out>%s)(?:\[(?P<index>[^\]]+?)\])?
88
-                \s*%s
89
-                (?P<expr>.*)$''' % (_NAME_RE, re.escape(op)), expr)
90
-            if not m:
91
-                continue
92
-            right_val = self.interpret_expression(
93
-                m.group('expr'), local_vars, allow_recursion - 1)
94
-
95
-            if m.groupdict().get('index'):
96
-                lvar = local_vars[m.group('out')]
97
-                idx = self.interpret_expression(
98
-                    m.group('index'), local_vars, allow_recursion)
99
-                assert isinstance(idx, int)
100
-                cur = lvar[idx]
101
-                val = opfunc(cur, right_val)
102
-                lvar[idx] = val
103
-                return val
104
-            else:
105
-                cur = local_vars.get(m.group('out'))
106
-                val = opfunc(cur, right_val)
107
-                local_vars[m.group('out')] = val
108
-                return val
109
-
110
-        if expr.isdigit():
111
-            return int(expr)
112
-
113
-        var_m = re.match(
114
-            r'(?!if|return|true|false)(?P<name>%s)$' % _NAME_RE,
115
-            expr)
116
-        if var_m:
117
-            return local_vars[var_m.group('name')]
118
-
119
-        try:
120
-            return json.loads(expr)
121
-        except ValueError:
122
-            pass
123
-
124
-        m = re.match(
125
-            r'(?P<var>%s)\.(?P<member>[^(]+)(?:\(+(?P<args>[^()]*)\))?$' % _NAME_RE,
126
-            expr)
127
-        if m:
128
-            variable = m.group('var')
129
-            member = m.group('member')
130
-            arg_str = m.group('args')
131
-
132
-            if variable in local_vars:
133
-                obj = local_vars[variable]
134
-            else:
135
-                if variable not in self._objects:
136
-                    self._objects[variable] = self.extract_object(variable)
137
-                obj = self._objects[variable]
138
-
139
-            if arg_str is None:
140
-                # Member access
141
-                if member == 'length':
142
-                    return len(obj)
143
-                return obj[member]
144
-
145
-            assert expr.endswith(')')
146
-            # Function call
147
-            if arg_str == '':
148
-                argvals = tuple()
149
-            else:
150
-                argvals = tuple([
151
-                    self.interpret_expression(v, local_vars, allow_recursion)
152
-                    for v in arg_str.split(',')])
153
-
154
-            if member == 'split':
155
-                assert argvals == ('',)
156
-                return list(obj)
157
-            if member == 'join':
158
-                assert len(argvals) == 1
159
-                return argvals[0].join(obj)
160
-            if member == 'reverse':
161
-                assert len(argvals) == 0
162
-                obj.reverse()
163
-                return obj
164
-            if member == 'slice':
165
-                assert len(argvals) == 1
166
-                return obj[argvals[0]:]
167
-            if member == 'splice':
168
-                assert isinstance(obj, list)
169
-                index, howMany = argvals
170
-                res = []
171
-                for i in range(index, min(index + howMany, len(obj))):
172
-                    res.append(obj.pop(index))
173
-                return res
174
-
175
-            return obj[member](argvals)
176
-
177
-        m = re.match(
178
-            r'(?P<in>%s)\[(?P<idx>.+)\]$' % _NAME_RE, expr)
179
-        if m:
180
-            val = local_vars[m.group('in')]
181
-            idx = self.interpret_expression(
182
-                m.group('idx'), local_vars, allow_recursion - 1)
183
-            return val[idx]
184
-
185
-        for op, opfunc in _OPERATORS:
186
-            m = re.match(r'(?P<x>.+?)%s(?P<y>.+)' % re.escape(op), expr)
187
-            if not m:
188
-                continue
189
-            x, abort = self.interpret_statement(
190
-                m.group('x'), local_vars, allow_recursion - 1)
191
-            if abort:
192
-                print '[JSInterpreter] Premature left-side return of %s in %r' % (op, expr)
193
-                return None
194
-            y, abort = self.interpret_statement(
195
-                m.group('y'), local_vars, allow_recursion - 1)
196
-            if abort:
197
-                print '[JSInterpreter] Premature right-side return of %s in %r' % (op, expr)
198
-                return None
199
-            return opfunc(x, y)
200
-
201
-        m = re.match(
202
-            r'^(?P<func>%s)\((?P<args>[a-zA-Z0-9_$,]+)\)$' % _NAME_RE, expr)
203
-        if m:
204
-            fname = m.group('func')
205
-            argvals = tuple([
206
-                int(v) if v.isdigit() else local_vars[v]
207
-                for v in m.group('args').split(',')])
208
-            if fname not in self._functions:
209
-                self._functions[fname] = self.extract_function(fname)
210
-            return self._functions[fname](argvals)
211
-
212
-        print '[JSInterpreter] Unsupported JS expression %r' % expr
213
-        return None
214
-
215
-    def extract_object(self, objname):
216
-        obj = {}
217
-        obj_m = re.search(
218
-            (r'(?:var\s+)?%s\s*=\s*\{' % re.escape(objname)) +
219
-            r'\s*(?P<fields>([a-zA-Z$0-9]+\s*:\s*function\(.*?\)\s*\{.*?\}(?:,\s*)?)*)' +
220
-            r'\}\s*;',
221
-            self.code)
222
-        fields = obj_m.group('fields')
223
-        # Currently, it only supports function definitions
224
-        fields_m = re.finditer(
225
-            r'(?P<key>[a-zA-Z$0-9]+)\s*:\s*function'
226
-            r'\((?P<args>[a-z,]+)\){(?P<code>[^}]+)}',
227
-            fields)
228
-        for f in fields_m:
229
-            argnames = f.group('args').split(',')
230
-            obj[f.group('key')] = self.build_function(argnames, f.group('code'))
231
-
232
-        return obj
233
-
234
-    def extract_function(self, funcname):
235
-        func_m = re.search(
236
-            r'''(?x)
237
-                (?:function\s+%s|[{;,]%s\s*=\s*function|var\s+%s\s*=\s*function)\s*
238
-                \((?P<args>[^)]*)\)\s*
239
-                \{(?P<code>[^}]+)\}''' % (
240
-                re.escape(funcname), re.escape(funcname), re.escape(funcname)),
241
-            self.code)
242
-        if func_m is None:
243
-            print '[JSInterpreter] Could not find JS function %r' % funcname
244
-            return None
245
-        argnames = func_m.group('args').split(',')
246
-
247
-        return self.build_function(argnames, func_m.group('code'))
248
-
249
-    def call_function(self, funcname, *args):
250
-        f = self.extract_function(funcname)
251
-        return f(args)
252
-
253
-    def build_function(self, argnames, code):
254
-        def resf(args):
255
-            local_vars = dict(zip(argnames, args))
256
-            for stmt in code.split(';'):
257
-                res, abort = self.interpret_statement(stmt, local_vars)
258
-                if abort:
259
-                    break
260
-            return res
261
-        return resf

+ 0
- 189
resources/lib/sources/lmt.py View File

@@ -1,189 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-import requests
13
-import datetime, re, sys,os
14
-import ConfigParser
15
-from collections import OrderedDict
16
-from SourceBase import SourceBase
17
-import resolver
18
-try:
19
-    import util
20
-except:
21
-    sys.path.insert(0,'..')
22
-    import util
23
-
24
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
25
-import HTMLParser
26
-h = HTMLParser.HTMLParser()
27
-
28
-class Source(SourceBase):
29
-
30
-    def __init__(self, country="",cfg_path=None):
31
-        self.name = "lmt"
32
-        self.title = "LMT straume"
33
-        self.img = "http://www.lob.lv/images/logo/lmt_straume_vert_rgb.png"
34
-        self.desc = "LMT straume - dažādi video latviesu valodā"
35
-        self.headers = headers2dict("""
36
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
37
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
38
-Accept-Language: en-US,en;q=0.5
39
-""")
40
-        self.headers2 = headers2dict("""
41
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
42
-X-Requested-With: XMLHttpRequest
43
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
44
-""")
45
-        self.url = "http://straume.lmt.lv/lv/"
46
-
47
-
48
-    ######### Entry point ########
49
-    def get_content(self, data):
50
-        print "[lmt] get_content:", data
51
-        source, data, path, plist, clist, params, qs = self.parse_data(data)
52
-        content = []
53
-        content.append(("..return", "back","","Return back"))
54
-
55
-        if clist=="home":
56
-            content.extend([
57
-                ("Meklēt", "lmt::meklet?q={0}","","Meklēt"),
58
-                ("Straumes", "lmt::straumes","","Tiešraides un aktuāli video"),
59
-                #("TV", "lmt::tv","","TV tiešraides (tikai LMT tīklā)"),
60
-                ("Jaunākie", "lmt::video/jaunakie?videoPage=1", "", "Visu žanru jaunākie video"),
61
-                ("Sports", "lmt::video/sports?videoPage=1", "", "Sports"),
62
-                ("Kultūra un māksla", "lmt::video/kultura?videoPage=1", "", "Kultūra un māksla"),
63
-                ("Konferences", "lmt::video/konferences?videoPage=1", "", "Konferences"),
64
-                ("Raidījumi", "lmt::video/raidijumi?videoPage=1", "", "Raidījumi"),
65
-                ("Notikumi", "lmt::video/notikumi?videoPage=1", "", "Notikumi"),
66
-                ("Filmas un seriāli", "lmt::video/filmas?videoPage=1", "", "Filmas un seriāli"),
67
-                ("Dažādi video", "lmt::video/dazadi?videoPage=1", "", "Dažādi video"),
68
-            ])
69
-            return content
70
-
71
-        elif clist in ("meklet","video", "straumes","video-saraksts"):
72
-            r=self.call(data)
73
-            result = re.findall('<a class="video-picture" (.+?)</li>', r, re.IGNORECASE | re.MULTILINE)
74
-            for r2 in result:
75
-                m = re.search('<a class="video-title" href="/lv/([^"]+)">([^<]+)<', r2)
76
-                title = m.group(2)
77
-                data2 = m.group(1)
78
-                m = re.search("([^ ]+) 2x", r2)
79
-                if m:
80
-                    img = m.group(1)
81
-                else:
82
-                    m = re.search('<img src="([^"]+)', r2)
83
-                    img = m.group(1) if m else ""
84
-                m = re.search('<span class="playlist-overlay">([^<]+)</span>', r2)
85
-                overlay = m.group(1) if m else ""
86
-                m = re.search('<span class="badge badge-[^>]+>([^<]+)(<[^>]+>([^<]+))*</span>', r2, re.IGNORECASE)
87
-                badge = ""
88
-                if m:
89
-                    badge = m.group(1)
90
-                    if m.group(3):
91
-                        badge = badge + m.group(3)
92
-                categories = re.findall('<span class="category-title">([^<]+)</span>', r2)
93
-                categories = "".join(categories)
94
-                if overlay:
95
-                    title = "%s [%s]"%(title,overlay)
96
-                if badge:
97
-                    title = "%s [%s]"%(title,badge)
98
-                desc = title
99
-                if categories:
100
-                    desc = desc + "\n"+ categories
101
-                content.append((title,self.name+"::"+data2,img,desc))
102
-            m = re.search("videoPage=(\d+)",data)
103
-            if m:
104
-                page = int(m.group(1))+1
105
-                data2 = re.sub(r"videoPage=\d+", r"videoPage=%s"%page, data)
106
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
107
-            #print content
108
-            return content
109
-
110
-
111
-        ### kaut kas neparedzets ###
112
-        else:
113
-            return content
114
-
115
-    def is_video(self,data):
116
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
117
-        if not clist in ("meklet","video", "straumes","video-saraksts","home"):
118
-            return True
119
-
120
-    def call(self, data,params=None,headers=None,lang=""):
121
-        if not headers: headers = self.headers
122
-        url = self.url+data
123
-        r = requests.get(url,headers = headers)
124
-        return r.content
125
-        #result = self._http_request(url,params,headers=headers)
126
-        return result
127
-
128
-    def get_streams(self,data):
129
-        print "[lmt] get_streams:", data
130
-        if not self.is_video(data):
131
-            return []
132
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
133
-        r = self.call(path)
134
-        title = re.search("<h1>(.+?)</h1", r, re.IGNORECASE).group(1)
135
-        m = re.search('<a class="category-title".+?[^>]+>([^<]+)<', r, re.IGNORECASE | re.DOTALL)
136
-        categories = m.group(1) if m else ""
137
-        m = re.search('<span class="category-title">([^<]+)</span>.+?</p>', r, re.IGNORECASE | re.DOTALL)
138
-        if m:
139
-            categories = categories + m.group(1)
140
-        if categories:
141
-            tite = "%s [%s]"%(title,categories)
142
-        img = re.search('<meta property="twitter:image" content="([^"]+)">', r, re.IGNORECASE | re.DOTALL).group(1)
143
-        desc = title + "\n" + re.search('<meta property="og:description" content="([^"]+)">', r, re.IGNORECASE | re.DOTALL).group(1)
144
-        m = re.search('file: "([^"]+)"', r, re.IGNORECASE)
145
-        if m:
146
-            data2 = m.group(1)
147
-            stream = util.item()
148
-            stream["name"] = title
149
-            stream["url"] = data2
150
-            stream["img"] = img
151
-            stream["desc"] = desc
152
-            stream["resolver"] = "lmt"
153
-            return [stream]
154
-        else:
155
-            m = re.search('src="(http://www.youtube.com/[^"]+)"',r)
156
-            if m:
157
-                url = m.group(1)
158
-            else:
159
-                raise Exception("No stream found")
160
-            streams = resolver.resolve(url)
161
-            for s in streams:
162
-                s["name"] = title
163
-                s["desc"] = desc
164
-                s["img"] = img
165
-                streams.append(s)
166
-            return streams
167
-
168
-
169
-if __name__ == "__main__":
170
-    country= "lv"
171
-    c = Source(country)
172
-    if len(sys.argv)>1:
173
-        data= sys.argv[1]
174
-    else:
175
-        data = "home"
176
-    content = c.get_content(data)
177
-    for item in content:
178
-        print item
179
-    #cat = api.get_categories(country)
180
-    #chan = api.get_channels("lv")
181
-    #prog = api.get_programs(channel=6400)
182
-    #prog = api.get_programs(category=55)
183
-    #seas = api.get_seasons(program=6453)
184
-    #str = api.get_streams(660243)
185
-    #res = api.get_videos(802)
186
-    #formats = api.getAllFormats()
187
-    #det = api.detailed("1516")
188
-    #vid = api.getVideos("13170")
189
-    pass

+ 0
- 4
resources/lib/sources/ltc.cfg View File

@@ -1,4 +0,0 @@
1
-[ltc]
2
-user = ivars777
3
-password = kaskade7
4
-

+ 0
- 1062
resources/lib/sources/ltc.py
File diff suppressed because it is too large
View File


+ 0
- 230
resources/lib/sources/movieplace.py View File

@@ -1,230 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-import urllib2, urllib
13
-import datetime, re, sys,os
14
-import ConfigParser
15
-from collections import OrderedDict
16
-from SourceBase import SourceBase
17
-import resolver
18
-try:
19
-    import util
20
-except:
21
-    sys.path.insert(0,'..')
22
-    import util
23
-
24
-
25
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
26
-import HTMLParser
27
-h = HTMLParser.HTMLParser()
28
-
29
-class Source(SourceBase):
30
-
31
-    def __init__(self, country=""):
32
-        self.name = "movieplace"
33
-        self.title = "MoviePlace.lv"
34
-        self.img = "http://movieplace.lv/images/logo.png"
35
-        self.desc = "Movieplace.lv - filmas latviesu valodā"
36
-        self.headers = headers2dict("""
37
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
38
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
39
-Accept-Language: en-US,en;q=0.5
40
-""")
41
-        self.headers2 = headers2dict("""
42
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
43
-X-Requested-With: XMLHttpRequest
44
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
45
-""")
46
-        self.url = "http://movieplace.lv/"
47
-
48
-
49
-    ######### Entry point ########
50
-    def get_content(self, data):
51
-        print "[movieplace] get_content:", data
52
-        source, data, path, plist, clist, params, qs = self.parse_data(data)
53
-        content = []
54
-        content.append(("..return", "back","","Return back"))
55
-
56
-        if clist=="home":
57
-            content.extend([
58
-                ("Meklēt", "movieplace::search/?q={0}","","Meklēt"),
59
-                ("Jaunākās filmas", "movieplace::load/?page1","","Visu žanru jaunākās filmas"),
60
-                ("Jaunākie seriāli", "movieplace::dir/?page1","","Visu žanru jaunākās filmas"),
61
-                #("Top50 filmas", "movieplace::index/top_50_filmas/0-4","","Top 50 filmas"),
62
-            ])
63
-            r = self.call("load/")
64
-            #i = r.find('<div class="cat-title">Meklēt pēc žanriem</div>')
65
-            #if i<=0:
66
-            #    return content
67
-            i = 0
68
-            for item in re.findall('<a href="/([^"]+)" class="catName">([^>]+)</a>', r[i:]):
69
-                title = item[1]
70
-                data2 = item[0]+"-1"
71
-                img = self.img
72
-                desc = title
73
-                content.append((title,self.name+"::"+data2,img,desc))
74
-            return content
75
-
76
-        elif clist=="search":
77
-            # TODO
78
-            r=self.call(data)
79
-            result = re.findall('<a href="([^"]+)"> (.+?) </a></div>.+?> (.+?)</div>', r, re.DOTALL)
80
-            for item in result:
81
-                title = item[1].replace("<b>","").replace("</b>","")
82
-                data2 = item[0].replace("http://movieplace.lv/","")
83
-                img = self.img
84
-                desc = item[2].replace("<b>","").replace("</b>","")
85
-                content.append((title,self.name+"::"+data2,img,desc))
86
-            if '<span>&raquo;</span>' in r:
87
-                m = re.search("p=(\d+)",data)
88
-                if m:
89
-                    page = int(m.group(1))+1
90
-                    data2 = re.sub(r"p=\d+", r"p=%s"%page, data)
91
-                    content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
92
-            return content
93
-
94
-        # Filmu saraksti ##
95
-        elif clist in ["load","dir"] and len(plist)<=3:
96
-            if clist == "jaunakas":
97
-                r = self.call("")
98
-            else:
99
-                r = self.call(data)
100
-            #r = r.decode("cp1251").encode("utf8")
101
-            if clist == "load":
102
-                result = re.findall(r' <a href="/([^"]+)" alt="([^"]+)"><img src="/([^"]+)" title="([^"]+)">.+?<div class="years">([^<]+)</div>\s+<div class="country">([^<]+)</div>', r, re.DOTALL)
103
-            else:
104
-                result = re.findall(r' <a href="/([^"]+)" alt="([^"]+)"><img src="/([^"]+)" title="[^"]+">.+?<span>([^<]+)</span>\s*<div class="country">([^<]+)</div>', r, re.IGNORECASE | re.DOTALL)
105
-            for item in result:
106
-                title = item[1]+" [%s]"%item[4] if clist=="load" else item[1]+" / %s [%s]"%(item[3],item[4])
107
-                img = "http://movieplace.lv/"+item[2]
108
-                data2 = item[0]
109
-                desc = "%s\n%s"%(title,item[5]) if clist=="load" else title
110
-                content.append((title,self.name+"::"+data2,img,desc))
111
-            m = re.search('<[ab] class="swchItemA*1"( href="/([^"]+)" onclick="[^"]+")*><span>([^<]+)</span></[ab]> </span>', r, re.DOTALL)
112
-            if m:
113
-                if m.group(1):
114
-                    page = int(re.search("\d+$",data).group())
115
-                    page = page+1
116
-                    data2 = re.sub("\d$","%s"%page,data)
117
-                    content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
118
-            return content
119
-
120
-        ### Seriāls ###
121
-        elif clist=="dir" and len(plist)==4:
122
-            r = self.call(path)
123
-            title0 = re.search('<h2 class="title" itemprop="name">(.+?)</h2>', r, re.DOTALL).group(1)
124
-            m = re.search(r'<span>VALODA:</span> <b><em itemprop="alternativeHeadline"><a href="[^"]*" class="entAllCats">([^<]+)</a></em></b></div>\s+?<div><span>SEZONA:</span> <b>([^<]+)</b></div>', r, re.IGNORECASE | re.DOTALL)
125
-            if m:
126
-                title0 = "%s / Season %s [%s]"%(title0,m.group(2),m.group(1))
127
-            desc0 = title0
128
-            img0 = "http://movieplace.lv" + re.search('<img src="(.+?)".+?itemprop="image">', r, re.DOTALL).group(1)
129
-            #TODO
130
-            result = re.findall(r'<summary>([^<]+)</summary><iframe src="https://openload\.co/embed/[^/]+/"', r, re.DOTALL)
131
-            i = 1
132
-            for item in result:
133
-                title = title0+" - " + item
134
-                data2 = data+"?e=%s"%i
135
-                img = img0
136
-                desc = desc0
137
-                content.append((title,self.name+"::"+data2,img,desc))
138
-                i += 1
139
-            return content
140
-
141
-        ### kaut kas neparedzets ###
142
-        else:
143
-            return content
144
-
145
-    def is_video(self,data):
146
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
147
-        if clist=="dir" and len(plist) == 4 and "e"in qs: # sērija
148
-            return True
149
-        elif clist=="load" and len(plist) == 4:
150
-            return True
151
-        else:
152
-            return False
153
-
154
-    def call(self, data,params=None,headers=None,lang=""):
155
-        if not headers: headers = self.headers
156
-        url = self.url+data
157
-        result = self._http_request(url,params,headers=headers)
158
-        return result
159
-
160
-    def get_streams(self,data):
161
-        print "[movieplace] get_streams:", data
162
-        if not self.is_video(data):
163
-            return []
164
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
165
-        r = self.call(path)
166
-        if clist=="load":
167
-            m = re.search('<h2 class="title" itemprop="name">([^<]+)</h2>', r, re.DOTALL)
168
-            title = re.search('<itemprop="name">(.+?)</itemprop="name">', r, re.DOTALL).group(1)
169
-            m = re.search(r'<div role="tabpanel" class="tab-pane fade in active" id="heading-tab4">\s*(.+?)\s*</div>', r, re.DOTALL)
170
-            desc = m.group(1) if m else title
171
-            m = re.search('<meta property="og:image" content="([^"]+)" />', r, re.DOTALL)
172
-            img = m.group(1) if m else ""
173
-            rr = []
174
-            for m in re.finditer("(RU|ENG|LAT|LAT SUB)<BR( /)*>.*?>?<BR( /)*>.*?<iframe", r, re.IGNORECASE | re.DOTALL):
175
-                if len(rr)>0:
176
-                    rr[-1]["end"] = m.start()
177
-                rr.append({"lang":m.group(1),"start":m.start(),"end":len(r)})
178
-            streams = []
179
-            for m in re.finditer(r'src="(https*://(goo\.gl|songs2dl|kodik|cdn\.kapnob|hqq|openload|sv1.servkino|vidwatch|online\.kinozz).+?)"', r, re.IGNORECASE | re.DOTALL):
180
-                url = m.group(1)
181
-                lang = "?"
182
-                for rrr in rr:
183
-                    if m.start()>rrr["start"] and m.start()<rrr["end"]:
184
-                        lang = rrr["lang"]
185
-                        break
186
-                for s in resolver.resolve(url):
187
-                    s["name"] = title
188
-                    s["desc"] = desc
189
-                    s["img"] = img
190
-                    s["type"] = self.stream_type(s["url"])
191
-                    s["lang"] = lang
192
-                    streams.append(s)
193
-            return streams
194
-
195
-
196
-        elif clist=="dir" and "e" in qs: # serialā sērija
197
-            #TODO
198
-            result = re.findall(r'<summary>([^<]+)</summary><iframe src="([^"]+)"', r, re.DOTALL)
199
-            i = int(qs["s"])-1
200
-            url0 = result[i][1]
201
-            title = title + " - " + result[i][0]
202
-        else:
203
-            #iframe src="https://openload.co/embed/wlw6Vl9zwL0/"
204
-            result = re.findall(r'<iframe src="([^"]+)"', r, re.DOTALL)
205
-            if not result:
206
-                return []
207
-            url0 = result[0]
208
-        return streams
209
-
210
-if __name__ == "__main__":
211
-    country= "lv"
212
-    c = Source(country)
213
-    if len(sys.argv)>1:
214
-        data= sys.argv[1]
215
-    else:
216
-        data = "home"
217
-    content = c.get_content(data)
218
-    for item in content:
219
-        print item
220
-    #cat = api.get_categories(country)
221
-    #chan = api.get_channels("lv")
222
-    #prog = api.get_programs(channel=6400)
223
-    #prog = api.get_programs(category=55)
224
-    #seas = api.get_seasons(program=6453)
225
-    #str = api.get_streams(660243)
226
-    #res = api.get_videos(802)
227
-    #formats = api.getAllFormats()
228
-    #det = api.detailed("1516")
229
-    #vid = api.getVideos("13170")
230
-    pass

+ 0
- 279
resources/lib/sources/mtgplay.py View File

@@ -1,279 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-
9
-
10
-try:
11
-    import json
12
-except:
13
-    import simplejson as json
14
-#!/usr/bin/env python
15
-# coding=utf8
16
-import urllib2, urllib
17
-import datetime, re, sys
18
-from SourceBase import SourceBase
19
-
20
-API_URL = 'http://playapi.mtgx.tv/v3/'
21
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
22
-headers0 = headers2dict("""
23
-User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
24
-""")
25
-
26
-REGIONS = [
27
-    ("Latvia",None,"lv",""),
28
-    ("Estonia",None,"ee",""),
29
-    ("Lituania",None,"lt",""),
30
-    ("Sweden",None,"se",""),
31
-    ("Denmark",None,"dk",""),
32
-    ("Norway",None,"no",""),
33
-    ("Bulgaria",None,"bg","")
34
-]
35
-
36
-
37
-class Source(SourceBase):
38
-    
39
-    def __init__(self,country="lv"):
40
-        self.name = "mtgplay"
41
-        self.title = "Skaties.lv (TV3)"
42
-        self.img = "http://skaties.lv/touch-icon-192x192.png"
43
-        self.desc = "MTG skaties.lv satura skatīšanās (LNT,TV3, TV6 u.c.)"
44
-        
45
-        self.country=country
46
-        self.pic_size = "327x250" #"1000x765"
47
-        
48
-    def get_content(self, data):
49
-        print "[mtgplay] get_content:", data
50
-        if "::" in data:
51
-            data = data.split("::")[1]        
52
-        if "/" in data:
53
-            citem,cid = data.split("/")
54
-            clist = ""
55
-        else:
56
-            clist = data.split("?")[0]
57
-            qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",data)))
58
-            citem,cid = ("","")
59
-            self.country = qs["country"] if "country" in qs else "lv"
60
-        
61
-        content=[]
62
-        content.append(("..return", "back","","Return back"))
63
-        
64
-        if clist=="home":
65
-            content.extend([
66
-                #("Search", "mtgplay::meklet?country=%s&term={0}"%self.country,"","Search videos"), ### TODO                
67
-                ("TV Live", "mtgplay::videos?country=%s&order=title&type=live"%self.country,"","TV live streams(not always available)"),
68
-                ("Last videos", "mtgplay::videos?country=%s&order=-airdate"%self.country,"","Last aired videos"),
69
-                ("Categories", "mtgplay::categories?country=%s&order=name"%self.country,"","Categories"),
70
-                ("Channels", "mtgplay::channels?country=%s&order=id"%self.country,"","TV channels"),
71
-                ("Programs by name", "mtgplay::formats?country=%s&order=-title"%self.country,"","Programs by name"),             
72
-                ("Programs by popularity", "mtgplay::formats?country=%s&order=-popularity"%self.country,"","Programs by popularity")             
73
-            ])
74
-            return content
75
-        
76
-        r = self.call(data)
77
-        if not r:
78
-            content.append(("Error", "","","Error reading '%s'"%data))
79
-            return content
80
-        
81
-        if clist:
82
-            if r["_links"].has_key("prev"):
83
-                data2 = r["_links"]["prev"]["href"].replace(API_URL,"")
84
-                content.append(("Previous page", self.name+"::"+data2.encode("utf8"),"", "Goto previous page"))
85
-                
86
-            if "_embedded" in r:
87
-                for item in r["_embedded"][clist]:
88
-                    if "title" in item:
89
-                        title = item["title"]
90
-                    elif "name" in item:
91
-                        title = item["name"]
92
-                    #data2 = self.name+"::"+"%s/%s"%(clist,item["id"]) 
93
-                    img = item["_links"]["image"]["href"].replace("{size}",self.pic_size) if "image" in item["_links"] else ""
94
-                    desc = item["summary"] if "summary" in item and item["summary"] else ""
95
-                    
96
-                    ### Video ###
97
-                    if clist=="videos":
98
-                        data2 = "videos/%s"%item["id"]                            
99
-                        summary = item["summary"] if item["summary"] else ""
100
-                        air_at = item["broadcasts"][0]["air_at"] if "broadcasts" in item and len(item["broadcasts"])>0 and "air_at" in item["broadcasts"][0] else ""
101
-                        if not air_at:
102
-                            air_at = item["publish_at"] if "publish_at" in item else ""
103
-                        air_at = air_at[0:16].replace("T"," ") if air_at else ""
104
-                        try: playable_to = item["broadcasts"][0]["playable_to"]
105
-                        except: playable_to =""
106
-                        playable_to = "(till "+playable_to[0:10].replace("T"," ")+")" if playable_to else ""
107
-                        duration = item["duration"] if "duration" in item else ""
108
-                        duration = str(datetime.timedelta(seconds=int(duration))) if duration else ""
109
-                        try:
110
-                            views = item["views"]["total"] if "views" in item and "total" in item["views"] else ""
111
-                            views = views+" views"
112
-                        except: views = ""
113
-                        desc = "Aired: %s %s\nDuration: %s %s\n\n%s"%(air_at, playable_to,duration,views,summary)
114
-                        
115
-                    ### Categories ###     
116
-                    elif clist == "categories":
117
-                        #data2 = item["_links"]["formats"]["href"].replace(API_URL,"")
118
-                        data2 = "formats?category=%s"%item["id"]
119
-                        if "country" in qs: data2 += "&country="+qs["country"]
120
-                        if "category" in qs: data2 += "&category="+qs["category"]
121
-                        if "channel" in qs: data2 += "&channel="+qs["channel"]
122
-                        data2 += "&order=title"
123
-                        
124
-                    ### Channels ###     
125
-                    elif clist == "channels":
126
-                        #data2 = item["_links"]["categories"]["href"].replace(API_URL,"")
127
-                        data2 = "categories?channel=%s"%item["id"]
128
-                        if "country" in qs: data2 += "&country="+qs["country"]
129
-                        if "category" in qs: data2 += "&category="+qs["category"]
130
-                        if "channel" in qs: data2 += "&channel="+qs["channel"]
131
-                        data2 += "&order=name"
132
-                        
133
-                    ### Formats (programs) ###     
134
-                    elif clist == "formats":
135
-                        #data2 = item["_links"]["videos"]["href"].replace(API_URL,"")
136
-                        data2 = "seasons?format=%s"%item["id"]
137
-                        #if "country" in qs: data2 += "&country="+qs["country"]
138
-                        #if "category" in qs: data2 += "&category="+qs["category"]
139
-                        #if "channel" in qs: data2 += "&channel="+qs["channel"]
140
-                        data2 += "&order=title"
141
-                        air_at = item["latest_video"]["publish_at"] if "publish_at" in item["latest_video"] else ""
142
-                        air_at = air_at[0:16].replace("T"," ") if air_at else ""
143
-                        if air_at:
144
-                            desc = "Last video: %s\n"%air_at + desc                        
145
-                        
146
-                    ### Seasons ###     
147
-                    elif clist == "seasons":
148
-                        #data2 = item["_links"]["videos"]["href"].replace(API_URL,"")
149
-                        data2 = "videos?season=%s"%item["id"]
150
-                        #if "country" in qs: data2 += "&country="+qs["country"]
151
-                        #if "category" in qs: data2 += "&category="+qs["category"]
152
-                        #if "channel" in qs: data2 += "&channel="+qs["channel"]
153
-                        data2 += "&order=title"
154
-                        
155
-                        summary = item["summary"] if "summary" in item and item["summary"] else ""
156
-                        try:
157
-                            latest_video = item["latest_video"]["publish_at"]
158
-                            latest_video = latest_video[0:16].replace("T"," ")
159
-                        except: latest_video = ""
160
-                        desc = ("%s\nLatest video: %s"%(summary,latest_video))
161
-                                      
162
-                    content.append((title.encode("utf8"),self.name+"::"+data2.encode("utf8"),img.encode("utf8"),desc.encode("utf8")))
163
-                    
164
-            if r["_links"].has_key("next"):
165
-                data2 = r["_links"]["next"]["href"].replace(API_URL,"").encode("utf8")
166
-                content.append(("Next page", self.name+"::"+data2.encode("utf8"),"","Goto next page"))
167
-                
168
-        elif citem:
169
-            item = r
170
-            if "title" in item:
171
-                title = item["title"]
172
-            elif "name" in item:
173
-                title = r["name"]
174
-            #data2 = self.name+"::"+"%s/%s"%(clist,item["id"]) 
175
-            img = item["_links"]["image"]["href"].replace("{size}",self.pic_size) if "image" in item["_links"] else ""
176
-            desc = item["summary"] if "summary" in item and item["summary"] else ""
177
-            
178
-            dd = "videos/stream/%s"%cid
179
-            r2 = self.call(dd)
180
-            if "streams" in r2 and "hls" in r2["streams"]:
181
-                data2 = r2["streams"]["hls"]
182
-                content = (title.encode("utf8"),data2.encode("utf8"),img.encode("utf8"),desc.encode("utf8"))
183
-            elif "msg" in r2:
184
-                content = (r2["msg"].encode("utf8"),"","","")
185
-            else: 
186
-                content = ("Error getting stream","","","")            
187
-            
188
-        else:
189
-            pass
190
-        return content
191
-    
192
-    def is_video(self,data):
193
-        if "::" in data:
194
-            data = data.split("::")[1]
195
-        cmd = data.split("/")
196
-        if cmd[0]=="videos":
197
-            return True
198
-        else:
199
-            return False
200
-    
201
-    def get_stream(self,id):   
202
-        dd = "videos/stream/%s"%id
203
-        r2 = self.call(dd)
204
-        if "streams" in r2 and "hls" in r2["streams"]:
205
-            data2 = r2["streams"]["hls"]
206
-        else:
207
-            data2 = ""
208
-        return data2.encode("utf8")
209
-        
210
-    def call_all(self, endpoint, params = None):
211
-        url = API_URL % (endpoint)
212
-        if params:
213
-            url += '?' + params
214
-        print "[TVPlay Api] url: ",url
215
-        result = []
216
-        while True:
217
-            content = self._http_request(url)
218
-            if content:
219
-                try:
220
-                    content = json.loads(content)
221
-                except Exception, ex:
222
-                    return {" Error " : "in call_api: %s" % ex}
223
-            else: break
224
-            if content.has_key("_embedded") and content["_embedded"].has_key(endpoint):
225
-                result.extend(content["_embedded"][endpoint])
226
-                pass
227
-            else: break
228
-            if content.has_key("_links") and content["_links"].has_key("next"):
229
-                url = content["_links"]["next"]["href"]
230
-            else: break
231
-        return result
232
-    
233
-    def call(self, data,headers=headers0):
234
-        url = API_URL + data
235
-        #print "[TVPlay Api] url: ",url
236
-        result = []
237
-        content = self._http_request(url)
238
-        if content:
239
-            try:
240
-                result = json.loads(content)
241
-            except Exception, ex:
242
-                return None
243
-        return result
244
-
245
-    def _http_request0(self, url,headers=headers0):
246
-        try:
247
-            r = urllib2.Request(url, headers=headers)
248
-            u = urllib2.urlopen(r)
249
-            content = u.read()
250
-            u.close()
251
-            return content
252
-        except Exception as ex:
253
-            if "read" in ex:
254
-                content = ex.read()
255
-            else:
256
-                content = None
257
-            return content
258
-
259
-if __name__ == "__main__":
260
-    country= "lv"
261
-    c = Source(country)
262
-    if len(sys.argv)>1:
263
-        data= sys.argv[1]
264
-    else:
265
-        data = "home"
266
-    content = c.get_content(data)
267
-    for item in content:
268
-        print item
269
-    #cat = api.get_categories(country)
270
-    #chan = api.get_channels("lv")
271
-    #prog = api.get_programs(channel=6400)
272
-    #prog = api.get_programs(category=55)
273
-    #seas = api.get_seasons(program=6453)
274
-    #str = api.get_streams(660243)
275
-    #res = api.get_videos(802)
276
-    #formats = api.getAllFormats()
277
-    #det = api.detailed("1516")
278
-    #vid = api.getVideos("13170")
279
-    pass

+ 0
- 212
resources/lib/sources/play24.py View File

@@ -1,212 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys
15
-from SourceBase import SourceBase
16
-
17
-API_URL = 'http://replay.lsm.lv/'
18
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
19
-headers0 = headers2dict("""
20
-User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
21
-""")
22
-import HTMLParser
23
-h = HTMLParser.HTMLParser()
24
-    
25
-class Source(SourceBase):
26
-    
27
-    def __init__(self,country="lv"):
28
-        self.name = "play24"
29
-        self.title = "Play24.lv"
30
-        self.img = "http://play24.lv/images/play24-logo-black.png"
31
-        self.desc = "play24.lv (Riga24TV) satura skatīšanās"
32
-        
33
-        self.country=country
34
-        
35
-    def get_content(self, data):
36
-        print "[play24] get_content:", data
37
-        if "::" in data:
38
-            data = data.split("::")[1] 
39
-        path = data.split("?")[0]
40
-        clist = path.split("/")[0]
41
-        params = data[data.find("?"):] if "?" in data else ""
42
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
43
-        lang = qs["lang"] if "lang" in qs else self.country
44
-    
45
-        content=[]
46
-        content.append(("..return", "back","","Return back"))
47
-        
48
-        if clist=="home":
49
-            content.extend([
50
-                ("Live stream", "play24::tiesraide","","TV live streams"),
51
-                ("Last videos", "play24::jaunakie","","Last videos"),
52
-                ("Categories", "play24::kategorijas","","Categories"),
53
-                ("Programs", "play24::raidijumi","","Programs"),             
54
-             ])
55
-            return content
56
-  
57
-        ### Jaunākie video ###
58
-        elif clist=="jaunakie":
59
-            url = "http://play24.lv/"
60
-            r = self._http_request(url)
61
-            for item in re.findall(' <div class="top-article__image">.*?<a class="top-article__image-link" href="([^"]+)">.*?<img.+?src="([^"]+)".+?alt="([^"]+)" />.+?</picture>', r, re.DOTALL):
62
-                title = item[2]
63
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
64
-                img = item[1]
65
-                data2 = item[0].replace("http://play24.lv/","")
66
-                desc = title
67
-                content.append((title,self.name+"::"+data2,img,desc))
68
-            return content
69
-                
70
-        ### Kategorijas ###
71
-        elif clist=="kategorijas":
72
-            url = "http://play24.lv/"
73
-            r = self._http_request(url)
74
-            r2 = r[r.find('<div class="footer-navigation">'):]
75
-            for item in re.findall('<a href="http://play24.lv/(kategorija/[^"]+)" class="navigation__link">([^<]+)</a>', r2, re.DOTALL):
76
-                title = item[1]
77
-                data2 = item[0]
78
-                img = ""
79
-                desc = title
80
-                content.append((title,self.name+"::"+data2,img,desc))
81
-            return content
82
-       
83
-        elif clist=="kategorija":
84
-            url = "http://play24.lv/"+data
85
-            r = self._http_request(url)
86
-            for article in re.findall(r"<article\b[^>]*>(.+?)</article>", r, re.DOTALL):
87
-                m = re.search('<a class="masonry-item__link" href="http://play24\.lv/([^"]+)">', article, re.DOTALL)
88
-                data2 = m.group(1) if m else ""
89
-                m = re.search('<img src="([^"]+)" alt="([^"]+)" />', article, re.DOTALL)
90
-                if m:
91
-                    img = m.group(1)
92
-                    title = m.group(2)
93
-                    title =  h.unescape(title.decode("utf8")).encode("utf8")
94
-                else:
95
-                    img = ""
96
-                    title = ""
97
-                m = re.search(r'<span class="masonry-item__tags">\s+<a href="([^"]+)">([^<]+)</a>.*?</span>', article, re.DOTALL)
98
-                progr = m.group(2) if m else ""
99
-                m = re.search('<span class="masonry-item__date">([^<]+)</span>', article, re.DOTALL)
100
-                date = m.group(1).strip() if m else ""
101
-                         
102
-                if date:
103
-                    title = title + " (%s %s)"%(date,progr)
104
-                desc = title + "\n%s - %s"%(progr,date)
105
-                content.append((title,self.name+"::"+data2,img,desc))
106
-            m = re.search(r'<li><a href="http://play24\.lv/([^"]+)" rel="next">&raquo;</a></li>', r, re.DOTALL)
107
-            if m:
108
-                data2 = m.group(1)
109
-                content.append(("Next page",self.name+"::"+data2,"","Next page"))                                            
110
-            return content
111
-        
112
-        ### Raidijumi (programmas)
113
-        elif clist=="raidijumi":
114
-            url = "http://play24.lv/"
115
-            r = self._http_request(url)
116
-            for item in re.findall(r'<li class="tag-box__item">.*?<a href="http://play24\.lv/(birka/[^"]+)">([^<]+)</a>.*?</li>', r, re.DOTALL):
117
-                title = item[1]
118
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
119
-                data2 = item[0]
120
-                img = ""
121
-                desc = title
122
-                content.append((title,self.name+"::"+data2,img,desc))
123
-            return content
124
-
125
-        ### Programmas (video saraksts)
126
-        elif clist=="birka":
127
-            url = "http://play24.lv/"+data
128
-            r = self._http_request(url)
129
-            for item in re.findall(r'<article\b[^>]*>.+?<a class="masonry-item__link" href="http://play24.lv/([^"]+)">.*?<img src="([^"]+)" alt="([^"]+)" />.*?<span class="masonry-item__tags">.+?<a href="([^"]+)">([^<]+)</a>.*?<span class="masonry-item__date">([^<]+)</span>.*?</article>', r, re.DOTALL):
130
-                title = item[2]
131
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
132
-                title = title + " (%s)"%item[5].strip()
133
-                img = item[1]
134
-                data2 = item[0]
135
-                desc = title + "\n%s - %s"%(item[4],item[5].strip())
136
-                content.append((title,self.name+"::"+data2,img,desc))
137
-            m = re.search(r'<li><a href="http://play24\.lv/([^"]+)" rel="next">&raquo;</a></li>', r, re.DOTALL)
138
-            if m:
139
-                data2 = m.group(1)
140
-                content.append(("Next page",self.name+"::"+data2,"","Next page"))                                            
141
-            return content
142
-
143
-        elif clist == "video" or clist == "tiesraide":
144
-            if clist == "video":  
145
-                url = "http://play24.lv/"+data
146
-                r = self._http_request(url)
147
-                # var ov_video_id = '59422';
148
-                m = re.search(r"var ov_video_id = '(\d+)';", r, re.DOTALL)
149
-                if m:
150
-                    id = m.group(1)
151
-                else:
152
-                    return ("No stream found %s"%data,"","","No stream found")
153
-                m = re.search('<meta name="description" content="([^"]+)" />', r, re.DOTALL)
154
-                desc = m.group(1) if m else ""
155
-                desc = h.unescape(desc.decode("utf8")).encode("utf8")
156
-                
157
-                url = "http://player.tvnet.lv/v/%s"%id
158
-            else:
159
-                url = "http://player.tvnet.lv/l/11"
160
-                desc = ""
161
-            r = self._http_request(url)
162
-            m = re.search('<h1 class="static title">.+?<a href="[^"]+">([^<]+)</a>', r, re.DOTALL)
163
-            title = m.group(1) if m else ""   
164
-            s = {}
165
-            for item in re.findall('source src="([^"]+)" data-stream="([^"]+)" data-quality="([^"]+)"', r, re.DOTALL):
166
-                s[item[1]] = (item[0],item[2])
167
-            data2 = ""
168
-            for t in ("hls","http","rtmp"):
169
-                if t in s:
170
-                    data2 = s[t][0]
171
-                    break
172
-            return (title,data2,"",desc)
173
-               
174
-    
175
-    def is_video(self,data):
176
-        if "::" in data:
177
-            data = data.split("::")[1]
178
-        cmd = data.split("/")
179
-        if cmd[0] in ("video","tiesraide"):
180
-            return True
181
-        else:
182
-            return False
183
-    
184
-    def call(self, data,headers=headers0,lang=""):
185
-        if not lang: lang = self.country
186
-        url = API_URL%lang + data
187
-        #print "[TVPlay Api] url: ",url
188
-        result = []
189
-        content = self._http_request(url)
190
-        return content
191
-
192
-if __name__ == "__main__":
193
-    country= "lv"
194
-    c = Source(country)
195
-    if len(sys.argv)>1:
196
-        data= sys.argv[1]
197
-    else:
198
-        data = "home"
199
-    content = c.get_content(data)
200
-    for item in content:
201
-        print item
202
-    #cat = api.get_categories(country)
203
-    #chan = api.get_channels("lv")
204
-    #prog = api.get_programs(channel=6400)
205
-    #prog = api.get_programs(category=55)
206
-    #seas = api.get_seasons(program=6453)
207
-    #str = api.get_streams(660243)
208
-    #res = api.get_videos(802)
209
-    #formats = api.getAllFormats()
210
-    #det = api.detailed("1516")
211
-    #vid = api.getVideos("13170")
212
-    pass

+ 0
- 305
resources/lib/sources/replay.py View File

@@ -1,305 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys
15
-from SourceBase import SourceBase
16
-import util
17
-
18
-API_URL = 'http://replay.lsm.lv/%s/'
19
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
20
-headers0 = headers2dict("""
21
-User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
22
-""")
23
-import HTMLParser
24
-h = HTMLParser.HTMLParser()
25
-from YouTubeVideoUrl import YouTubeVideoUrl
26
-
27
-class Source(SourceBase):
28
-
29
-    def __init__(self,country="lv"):
30
-        self.name = "replay"
31
-        self.title = "Replay.lv (LTV)"
32
-        self.img = "http://replay.lsm.lv/apple-touch-icon.png"
33
-        self.desc = "LSM replay.lv satura skatīšanās"
34
-
35
-        self.country=country
36
-        self.pic_size = "327x250" #"1000x765"
37
-
38
-    def get_content(self, data):
39
-        print "[replay] get_content:", data
40
-        if "::" in data:
41
-            data = data.split("::")[1]
42
-        path = data.split("?")[0]
43
-        clist = path.split("/")[0]
44
-        params = data[data.find("?"):] if "?" in data else ""
45
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
46
-        lang = qs["lang"] if "lang" in qs else self.country
47
-
48
-        content=[]
49
-        content.append(("..return", "back","","Return back"))
50
-
51
-        if clist=="home":
52
-            content.extend([
53
-                ("Live streams", "replay::tiesraide","","TV live streams"),
54
-                ("Search LV", "replay::search/?term={0}&lang=lv","","Search content LV"),
55
-                ("Last videos LV", "replay::visi/jaunakie/?source=ltv&lang=lv","","Last aired videos LV"),
56
-                ("Last videos by categories LV", "replay::kategorijas/?lang=lv","","Last videos by categories LV"),
57
-                ("All programs LV", "replay::raidijumi/?type=video","","All programs by name LV"),
58
-                ("Programs by categories LV", "replay::categories?lang=lv","","All programs by categories LV"),
59
-                #("Channels", "replay::channels?language=%s"%self.country,"","TV channels"),
60
-                ("Videos by popularity LV", "replay::visi/popularie/?source=ltv&lang=lv","","Programs by popularity"),
61
-
62
-                ("Search RU", "replay::search/?term={0}&lang=ru","","Search content RU"),
63
-                ("Last videos RU", "replay::vse/novie/?source=ltv&lang=ru","","Last aired videos RU"),
64
-                ("Last videos by categories RU", "replay::kategorijas/?lang=ru","","Last videos by categories RU"),
65
-                ("All programs RU", "replay::peredachi/?lang=ru&type=video","","All programs by name"),
66
-                ("Programs by categories RU", "replay::categories?lang=ru","","Programs by categories RU")
67
-            ])
68
-            return content
69
-
70
-        ### programmu kategorijas ###
71
-        elif clist=="categories":
72
-            url = "http://replay.lsm.lv/lv/raidijumi/?lang=lv&type=video" if lang =="lv" else "http://replay.lsm.lv/ru/peredachi/?lang=ru&type=video"
73
-            r = self._http_request(url)
74
-            for item in re.findall(r'<a .+href="(\?lang=\w+&type=video&theme=\d+)">([^<]+)</a>\t', r):
75
-                title = item[1]
76
-                data2 = url.split("?")[0]+item[0]
77
-                data2 = data2.replace(API_URL%lang,"")
78
-                img = ""
79
-                desc = title
80
-                content.append((title,self.name+"::"+data2,img,desc))
81
-            return content
82
-
83
-        ### jaunāko raidijumu kategorijas ###
84
-        elif clist=="kategorijas":
85
-            url = "http://replay.lsm.lv/lv/" if lang =="lv" else "http://replay.lsm.lv/ru/"
86
-            r = self._http_request(url)
87
-            for item in re.findall(r'<a href="/(lv|ru)/kategorija/(\w+)/">.+?<i class="[^"]+"></i>.+?<span>([^<]+)</span>', r, re.DOTALL):
88
-                title = item[2]
89
-                data2 = "kategorija/%s/?lang=%s"%(item[1],item[0])
90
-                img = ""
91
-                desc = title
92
-                content.append((title,self.name+"::"+data2,img,desc))
93
-            return content
94
-
95
-        ### Tiešraides kanānālu saraksts
96
-        elif path=="tiesraide":
97
-            url = "http://replay.lsm.lv/styles/main.css"
98
-            r= self._http_request(url)
99
-            for item in re.findall(r'channel-logo--(\w+)\{background-image:url\("([^"]+\.png)"', r):
100
-                ch = item[0]
101
-                title = ch.upper()
102
-                data2 = "tiesraide/%s/"%ch
103
-                img = "http://replay.lsm.lv"+item[1]
104
-                veids = "video "if "tv" in ch else "audio"
105
-                desc = title+" tiesraide (%s)"%veids
106
-                content.append((title,self.name+"::"+data2,img,desc))
107
-            return content
108
-
109
-        ### Kanāla tiesraide
110
-        elif clist == "tiesraide" and "/" in data:
111
-            ch = data.split('/')[1]
112
-            veids = "video" if "tv" in ch else "audio"
113
-            #url = "http://replay.lsm.lv/lv/tiesraide/ltv7/"
114
-            url = "http://replay.lsm.lv/lv/tiesraide/%s/"%ch
115
-            r= self._http_request(url)
116
-
117
-            m = re.search('%s/">.+?<h5>([^<]+)+</h5>.*?<time>([^<]+)</time>'%ch, r, re.DOTALL)
118
-            tagad = m.group(1).strip() if m else ""
119
-            laiks = m.group(2).strip() if m else ""
120
-            laiks = h.unescape(laiks).encode("utf8")
121
-            m = re.search("<h1>([^<]+)</h1>", r)
122
-            title = m.group(1).strip() if m else path.split("/")[1].upper()
123
-            title = "%s - %s (%s)"%(title,tagad,laiks)
124
-
125
-            if veids == "video":
126
-                m = re.search('<div class="video"><iframe.+src="([^"]+)"', r)
127
-                if not m:
128
-                    content=("No stream found %s"%data,"","","No stream found")
129
-                    return content
130
-                url = m.group(1)
131
-                headers = headers2dict("""
132
-            User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
133
-            Referer: http://replay.lsm.lv/lv/ieraksts/ltv/70398/tiesa-runa.-lielbritanija-gatavojas-referendumam-par-tu/
134
-                    """)
135
-                r = self._http_request(url,headers=headers)
136
-
137
-                m = re.search('<div class="video-player"><iframe.+src="([^"]+)"', r)
138
-                if not m:
139
-                    content=("No stream found %s"%data,"","","No stream found")
140
-                    return content
141
-                url = m.group(1)
142
-
143
-                r = self._http_request(url,headers=headers)
144
-                m = re.search('"([^"]+m3u8[^"]+)"', r)
145
-                if not m:
146
-                    content=("No stream found %s"%data,"","","No stream found")
147
-                    return content
148
-                data2 = m.group(1).replace("\\","")
149
-
150
-            else: # audio
151
-                lrn = ch.replace("lr","")
152
-                url = "http://www.latvijasradio.lsm.lv/lv/tiesraide/?channel=%s"%lrn
153
-                r = self._http_request(url)
154
-                m = re.search('"file":"([^"]+?m3u8.*?)"', r)
155
-                if not m:
156
-                    content=("No stream found %s"%data,"","","No stream found")
157
-                    return content
158
-                data2 = m.group(1).replace("\\","")
159
-
160
-            img = ""
161
-            desc = ""
162
-            content =(title,data2,img,desc)
163
-            return content
164
-
165
-        #m = re.search(r'(\?page=\d+)" class=" paging__prev', r, re.IGNORECASE)
166
-        #if m:
167
-        #    data = re.sub("\?page=\d+", "", data)
168
-        #    data2 = data+m.group(1)
169
-        #    content.append(("Previous page",self.name+"::"+data2,"","Previous page"))
170
-
171
-        r = self.call(data, lang=lang)
172
-        if not r:
173
-            return content
174
-
175
-        if clist == "search":
176
-            #for r2 in re.findall('<article itemtype="http://schema.org/Article" itemscope class="thumbnail thumbnail--default ">(.+?)</article>', r2, re.DOTALL):
177
-            for item in re.findall('itemprop="image" data-image="([^"]+)".+?<figcaption><h5 itemprop="name"><a itemprop="url" href="([^<]+)">([^<]+)</a></h5></figcaption>', r):
178
-                title = item[2]
179
-                data2 = item[1].replace("/%s/"%lang,"")+"?lang=%s"%lang
180
-                img = "http://replay.lsm.lv" + item[0]
181
-                desc  = title
182
-                content.append((title,self.name+"::"+data2,img,desc))
183
-
184
-            #for item in re.findall('itemprop="image" data-image="([^"]+)".+?<figcaption><h4 itemprop="about"><a href="([^"]+)">([^<]+)</a></h4>.*?<h5 itemprop="name"><a itemprop="url" href="([^"]+)">([^<]+)</a></h5>.+?datetime="([^"]+)" class="thumbnail__date ">([^<]+)</time>', r2):
185
-            for item in re.findall('itemprop="image" data-image="([^"]+)".+? class="icon-(ltv|lr).+?<figcaption><h4 itemprop="about"><a href="([^"]+)">([^<]+)</a></h4>.*?<h5 itemprop="name"><a itemprop="url" href="([^"]+)">([^<]+)</a></h5>.+?datetime="([^"]+)" class="thumbnail__date ">([^<]+)</time>', r):
186
-                if item[1]=="lr":continue
187
-                title = "%s - %s (%s)"%(item[3],item[5],item[7])
188
-                data2 = item[4].replace("/%s/"%lang,"")+"?lang=%s"%lang
189
-                img = item[0].replace("https:","http:")
190
-                desc = title
191
-                content.append((title,self.name+"::"+data2,img,desc))
192
-
193
-        ### Raidijumi (programmas) ###
194
-        elif clist in ( "raidijumi","peredachi"):
195
-            for item in re.findall('<li itemprop="name"><a href="([^"]+)" itemprop="url">([^<]+)', r):
196
-            #for item in re.findall('<li itemprop="name"><a href="([^"]+)" itemprop="url">([^<]+)</a></li>', r):
197
-                title = item[1]
198
-                data2 = item[0].replace("/%s/"%lang,"")+"?lang=%s"%lang
199
-                img = ""
200
-                desc  = ""
201
-                content.append((title,self.name+"::"+data2,img,desc))
202
-
203
-        ### Raidijuma ieraksti speciālie###
204
-        elif clist in ( "visi","vse",):
205
-            for item in re.findall('(?i)<figure><a href="([^"]+)" itemprop="image" data-image="([^"]+)".+class="thumbnail__duration">([^<]+)</time></figure><figcaption><h4 itemprop="about"><a href="[^"]+">([^<]+)</a></h4>.+>([^<]+).*</h5>.+>([^<]+)</time></figcaption>', r):
206
-                title = item[3]
207
-                data2 = item[0].replace("/%s/"%lang,"")+"?lang=%s"%lang
208
-                img = item[1].replace("https:","http:")
209
-                desc  = "%s - %s\n%s"%(item[5],item[2],item[4])
210
-                content.append((title,self.name+"::"+data2,img,desc))
211
-
212
-        ### Raidijuma ieraksti (videos)
213
-        elif clist in ("raidijums","peredacha","kategorija"):
214
-            for item in re.findall('<article .+ href="([^"]+)".+image="([^"]+)".+class="thumbnail__duration">([^<]+).+">([^<]+).+class="thumbnail__date ">([^"]+)</time></figcaption></article>', r):
215
-                title = item[3]
216
-                data2 = item[0].replace("/%s/"%lang,"")+"?lang=%s"%lang
217
-                img = item[1].replace("https:","http:")
218
-                desc = "%s - %s"%(item[4],item[2])
219
-                content.append((title,self.name+"::"+data2,img,desc))
220
-
221
-        ### Ieraksts (video) ###
222
-        elif clist in ("ieraksts","statja"):
223
-            m = re.search('src="([^"]+)"></iframe>', r)
224
-            if m:
225
-                url2 = m.group(1)
226
-                headers = headers2dict("""
227
-User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
228
-Referer: http://replay.lsm.lv/lv/ieraksts/ltv/70398/tiesa-runa.-lielbritanija-gatavojas-referendumam-par-tu/
229
-            """)
230
-                r2 = self._http_request(url2,headers=headers)
231
-                m = re.search('"file":"([^"]+)', r2)
232
-                if m:
233
-                    data2 = m.group(1).replace("\\","")
234
-                    m = re.search('"idstring":"([^"]+)', r2)
235
-                    title = m.group(1) if m else ""
236
-                    title = title.decode("unicode-escape").encode("utf8")
237
-                    title = title.replace("\n","")
238
-                    img = ""
239
-                    desc = ""
240
-                    if "youtube" in data2:
241
-                        video_id = re.search(r"/watch\?v=([^&]+)",data2).group(1)
242
-                        data2 = YouTubeVideoUrl().extract(video_id)
243
-                        if not data2:
244
-                            content=("No stream found %s"%data,"","","No stream found")
245
-                            return content
246
-                    content =(title,data2,img,desc)
247
-                    return content
248
-            content=("No stream found %s"%data,"","","No stream found")
249
-            return content
250
-
251
-        m = re.search(r'href="\?([^"]+)" class=" paging__next', r)
252
-        if m:
253
-            page = int(re.search("page=(\d+)",m.group(1)).group(1))
254
-            if "page="in data:
255
-                data2 = re.sub("page=\d+","page=%i"%page,data)
256
-            else:
257
-                if "?" in data:
258
-                    data2 =data+"&page=%i"%page
259
-                else:
260
-                    data2 =data+"?page=%i"%page
261
-            content.append(("Next page",self.name+"::"+data2,"","Next page"))
262
-
263
-        return content
264
-
265
-    def is_video(self,data):
266
-        if "::" in data:
267
-            data = data.split("::")[1]
268
-        cmd = data.split("/")
269
-        if cmd[0] in ("ieraksts","statja"):
270
-            return True
271
-        elif cmd[0]=="tiesraide" and len(cmd)>1:
272
-            return True
273
-        else:
274
-            return False
275
-
276
-    def call(self, data,headers=headers0,lang=""):
277
-        if not lang: lang = self.country
278
-        url = API_URL%lang + data
279
-        #print "[TVPlay Api] url: ",url
280
-        result = []
281
-        content = self._http_request(url,headers=headers0)
282
-        return content
283
-
284
-
285
-if __name__ == "__main__":
286
-    country= "lv"
287
-    c = Source(country)
288
-    if len(sys.argv)>1:
289
-        data= sys.argv[1]
290
-    else:
291
-        data = "home"
292
-    content = c.get_content(data)
293
-    for item in content:
294
-        print item
295
-    #cat = api.get_categories(country)
296
-    #chan = api.get_channels("lv")
297
-    #prog = api.get_programs(channel=6400)
298
-    #prog = api.get_programs(category=55)
299
-    #seas = api.get_seasons(program=6453)
300
-    #str = api.get_streams(660243)
301
-    #res = api.get_videos(802)
302
-    #formats = api.getAllFormats()
303
-    #det = api.detailed("1516")
304
-    #vid = api.getVideos("13170")
305
-    pass

+ 0
- 230
resources/lib/sources/serialguru.py View File

@@ -1,230 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys,os
15
-import ConfigParser
16
-from SourceBase import SourceBase
17
-
18
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
19
-import HTMLParser
20
-h = HTMLParser.HTMLParser()
21
-
22
-class Source(SourceBase):
23
-
24
-    def __init__(self,country=""):
25
-        self.name = "serialguru"
26
-        self.title = "SerialGURU.ru"
27
-        self.img = "http://serialguru.ru/images/xlogo_new.png.pagespeed.ic.0sre2_2OJN.png"
28
-        self.desc = "Serialguru.ru portāla satura skatīšanās"
29
-        self.country=country
30
-        self.headers = headers2dict("""
31
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36
32
-Referer: http://serialguru.ru/
33
-""")
34
-        self.headers2 = headers2dict("""
35
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36
36
-X-Requested-With: XMLHttpRequest
37
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
38
-Referer: http://serialguru.ru/
39
-""")
40
-        self.url = "http://serialguru.ru/"
41
-        #self.login()
42
-
43
-    def login(self,user="",password=""):
44
-        return True
45
-
46
-    def get_content(self, data):
47
-        print "[tvdom] get_content:", data
48
-        if "::" in data:
49
-            data = data.split("::")[1]
50
-        path = data.split("?")[0]
51
-        clist = path.split("/")[0]
52
-        params = data[data.find("?"):] if "?" in data else ""
53
-        qs = dict(map(lambda x:x.split("="),re.findall("[%\w]+=\w+",params)))
54
-        lang = qs["lang"] if "lang" in qs else self.country
55
-
56
-        content=[]
57
-        content.append(("..return", "back","","Return back"))
58
-
59
-        if clist=="home":
60
-            content.extend([
61
-                ("Search", "serialguru::search/{0}","","Search content"),
62
-                ("Last", "serialguru::last","","Last series"),
63
-                ("Series", "serialguru::serials","","TV Series"),
64
-                ("Shows", "serialguru::tv","","TV Shows"),
65
-                ("Animations", "serialguru::mult","","Animation series"),
66
-
67
-                #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
68
-            ])
69
-            return content
70
-
71
-        elif data == "last":
72
-            r = self.call("")
73
-            for item in re.findall(r'<li><a href="(http://serialguru\.ru/[^"]+)"><i>([^<]+)</i>  <i>([^<]+)</i> <b>([^<]+)</b></a></li>', r, re.DOTALL):
74
-                title = item[1] + " - " + item[2]+"/"+item[3]
75
-                img = ""
76
-                data2 = item[0].replace(self.url, "")
77
-                desc = title
78
-                content.append((title, self.name+"::"+data2, img, desc))
79
-            return content
80
-
81
-        elif data=="serials":
82
-            content.extend([
83
-                ("All", "serialguru::serials?o=0&t=S","","All series"),
84
-                ("Russian", "serialguru::serials?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=S","","Russian countries series"),
85
-                ("English", "serialguru::serials?c%5B%5D=27&c%5B%5D=26&c%5B%5D=43&c%5B%5D=30&c%5B%5D=34&c%5B%5D=25&o=0&t=S","","English countries series"),
86
-                ("Europe", "serialguru::serials?c%5B%5D=29&c%5B%5D=66&c%5B%5D=44&c%5B%5D=28&c%5B%5D=51&c%5B%5D=65&c%5B%5D=62&c%5B%5D=40&c%5B%5D=45&c%5B%5D=68&c%5B%5D=59&c%5B%5D=39&c%5B%5D=35&c%5B%5D=47&o=0&t=S","","European countries series"),
87
-                ("Other", "serialguru::serials?c%5B%5D=36&c%5B%5D=32&c%5B%5D=67&c%5B%5D=63&c%5B%5D=60&c%5B%5D=64&c%5B%5D=38&c%5B%5D=52&c%5B%5D=41&c%5B%5D=58&c%5B%5D=57&c%5B%5D=37&c%5B%5D=50&c%5B%5D=46&o=0&t=S","","Other countries series"),
88
-                #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
89
-            ])
90
-            return content
91
-
92
-        elif data=="tv":
93
-            content.extend([
94
-                ("All", "serialguru::tv?o=0&t=S","","All series"),
95
-                ("Russian", "serialguru::tv?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=P","","Russian countries TV shows"),
96
-                ("English", "serialguru::tv?c%5B%5D=27&c%5B%5D=26&c%5B%5D=43&c%5B%5D=30&c%5B%5D=34&c%5B%5D=25&o=0&t=P","","English countries TV shows"),
97
-                ("Europe", "serialguru::tv?c%5B%5D=29&c%5B%5D=66&c%5B%5D=44&c%5B%5D=28&c%5B%5D=51&c%5B%5D=65&c%5B%5D=62&c%5B%5D=40&c%5B%5D=45&c%5B%5D=68&c%5B%5D=59&c%5B%5D=39&c%5B%5D=35&c%5B%5D=47&o=0&t=P","","European countries TV shows series"),
98
-                ("Other", "serialguru::tv?c%5B%5D=36&c%5B%5D=32&c%5B%5D=67&c%5B%5D=63&c%5B%5D=60&c%5B%5D=64&c%5B%5D=38&c%5B%5D=52&c%5B%5D=41&c%5B%5D=58&c%5B%5D=57&c%5B%5D=37&c%5B%5D=50&c%5B%5D=46&o=0&t=P","","Other countries TV shows"),
99
-                #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
100
-            ])
101
-            return content
102
-
103
-        elif data=="mult":
104
-            content.extend([
105
-                ("All", "serialguru::mult?o=0&t=S","","All series"),
106
-                ("Russian", "serialguru::mult?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=M","","Russian countries animantions"),
107
-                ("English", "serialguru::mult?c%5B%5D=27&c%5B%5D=26&c%5B%5D=43&c%5B%5D=30&c%5B%5D=34&c%5B%5D=25&o=0&t=M","","English countries animantions"),
108
-                ("Europe", "serialguru::mult?c%5B%5D=29&c%5B%5D=66&c%5B%5D=44&c%5B%5D=28&c%5B%5D=51&c%5B%5D=65&c%5B%5D=62&c%5B%5D=40&c%5B%5D=45&c%5B%5D=68&c%5B%5D=59&c%5B%5D=39&c%5B%5D=35&c%5B%5D=47&o=0&t=M","","European countries animantions"),
109
-                ("Other", "serialguru::mult?c%5B%5D=36&c%5B%5D=32&c%5B%5D=67&c%5B%5D=63&c%5B%5D=60&c%5B%5D=64&c%5B%5D=38&c%5B%5D=52&c%5B%5D=41&c%5B%5D=58&c%5B%5D=57&c%5B%5D=37&c%5B%5D=50&c%5B%5D=46&o=0&t=M","","Other countries animantions"),
110
-                #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
111
-            ])
112
-            return content
113
-
114
-        elif clist=="search":
115
-            if data.split("/")>1:
116
-                term = data.split("/")[1]
117
-            else:
118
-                return content
119
-            r = self.call("main/autocomplete?term=%s"%(term))
120
-            if r=="null":
121
-                return content
122
-            js = json.loads(r)
123
-            for item in js:
124
-                title = item["name"].encode("utf8")
125
-                data2 = item["url"].encode("utf8")
126
-                img = "http://serialguru.ru/uploads/cover/"+item["image_s"].replace("_s","")+".jpg"
127
-                rating = item["rating"].encode("utf8") if item["rating"] else ""
128
-                desc = title +"\nRating:%s (%s+/%s-)"%(rating,item["plus_cnt"].encode("utf8"),item["minus_cnt"].encode("utf8"))
129
-                content.append((title,self.name+"::"+data2,img,desc))
130
-            return content
131
-
132
-        elif path=="serials" or path=="tv" or path=="mult":
133
-            if path=="serials" and not "cat%5B%5D" in data:
134
-                #content.append(("All", "serialguru::"+data+"&cat%5B%5D=","","All series"))
135
-                categories = self.get_categories(path)
136
-                for c in categories:
137
-                    content.append((c[1], "serialguru::"+data+"&cat%5B%5D="+c[0],"",c[1]))
138
-                return content
139
-            else:
140
-                r = self.call("main/load", params[1:], headers=self.headers2)
141
-                for item in re.findall('<li><a href="([^"]+)"><div>.*?<img src="([^"]+)" alt="([^"]+)"[^<]*?><p>([^<]+)<i><span class="r">([^<]+)</span> <span class="plus">([^<]+)</span> <span class="minus">([^<]+)</span></i></p></div>([^<]+)</a></li>', r, re.DOTALL):
142
-                    title = "%s (%s)"%(item[2],item[3])
143
-                    img = item[1].replace("_s.jpg","_l.jpg")
144
-                    data2 = item[0].replace(self.url,"")
145
-                    desc = title +"\nRating:%s (%s+/%s-)"%(item[4],item[5],item[6])
146
-                    content.append((title,self.name+"::"+data2,img,desc))
147
-                page=int(re.search("o=(\d+)",data).group(1))
148
-                data2 = re.sub("o=(\d+)","o=%s"%(page+15),data)
149
-                content.append(("Next page",self.name+"::"+data2,"","Go to next page"))
150
-                return content
151
-
152
-
153
-        ### Pārraide
154
-        else:
155
-            r = self.call(clist)
156
-            title0=re.search('<h2>(.+?)</h2>',r,re.DOTALL).group(1)
157
-            m=re.search('<div class="description">(.+?)</div>',r,re.DOTALL)
158
-            desc0=m.group(1) if m else ""
159
-            desc0=desc0.replace("<p>","").replace("</p>","\n").replace('<a href="#">ПОКАЗАТЬ ПОЛНОСТЬЮ</a>',"")
160
-            desc0=title0+"\n"+desc0.strip()
161
-            img0=""
162
-            m = re.search("http://serialguru.ru/main/playlist/\d+",r)
163
-            if m:
164
-                url = m.group()
165
-            else:
166
-                raise Exception ("No stream found")
167
-            r = self._http_request(url)
168
-            js = json.loads(r,"utf8")
169
-            if not "/" in data: # sezonas
170
-                for i,item in enumerate(js["playlist"]):
171
-                    title = title0 + " - " + item["comment"].encode("utf8")
172
-                    img = img0
173
-                    data2 = "%s/%s"%(data,i)
174
-                    desc = desc0
175
-                    content.append((title,self.name+"::"+data2,img,desc))
176
-            else:
177
-                snum = int(data.split("/")[1])
178
-                title1 = js["playlist"][snum]["comment"].encode('utf8')
179
-                for i,item in enumerate(js["playlist"][snum]["playlist"]):
180
-                    title = title0 + " - " + title1+"/"+item["comment"].encode("utf8")
181
-                    img = img0
182
-                    data2 = item["file"].encode("utf8")
183
-                    desc = desc0
184
-                    content.append((title,data2,img,desc))
185
-            return content
186
-
187
-
188
-    def is_video(self,data):
189
-        if "::" in data:
190
-            data = data.split("::")[1]
191
-        if "live/view" in data:
192
-            return True
193
-        else:
194
-            return False
195
-
196
-    def get_categories(self,data):
197
-        r = self.call(data)
198
-        r2 = re.search('<td class="category">(.+?)</td>', r, re.DOTALL).group(1)
199
-        items = re.findall(r'<a href="#" data-id="(\d+)">([^<]+)</a>', r2, re.DOTALL)
200
-        return items
201
-
202
-
203
-    def call(self, data,params = None, headers=None):
204
-        if not headers: headers = self.headers
205
-        #if not lang: lang = self.country
206
-        url = self.url + data
207
-        content = self._http_request(url,params, headers)
208
-        return content
209
-
210
-if __name__ == "__main__":
211
-    country= "lv"
212
-    c = Source(country)
213
-    if len(sys.argv)>1:
214
-        data= sys.argv[1]
215
-    else:
216
-        data = "home"
217
-    content = c.get_content(data)
218
-    for item in content:
219
-        print item
220
-    #cat = api.get_categories(country)
221
-    #chan = api.get_channels("lv")
222
-    #prog = api.get_programs(channel=6400)
223
-    #prog = api.get_programs(category=55)
224
-    #seas = api.get_seasons(program=6453)
225
-    #str = api.get_streams(660243)
226
-    #res = api.get_videos(802)
227
-    #formats = api.getAllFormats()
228
-    #det = api.detailed("1516")
229
-    #vid = api.getVideos("13170")
230
-    pass

+ 0
- 117
resources/lib/sources/streams.cfg View File

@@ -1,117 +0,0 @@
1
-[home]
2
-Home
3
-My TV|config::my_tv|default|Mani TV kanāli (tiešraide)
4
-My TV archive|config::my_archive|default|Mani TV arhīvu video
5
-My Video|config::my_video||Mani video
6
-My Kids|config::my_kids||Mani bērnu video
7
-My Radio|config::my_radio||Mani radio kanāli
8
-Replay.lv (LTV)|replay::home|http://replay.lsm.lv/apple-touch-icon.png|Latvijas TV tiešraides un arhīvs
9
-Skaties.lv (TV3)|mtgplay::home|http://skaties.lv/touch-icon-192x192.png|MTG kanālu (LNT,TV3, TV6 u.c.) arhīvs
10
-Shortcut (lattelecom.tv)|ltc::home|https://kursors.lv/wp-content/uploads/2016/07/Shortcut-logo.png|lattelecom TV, arhīves un video
11
-Play24.lv (Riga24TV)|play24::home|http://play24.lv/images/play24-logo-black.png|play24.lv (Riga24TV)tiešraide un arhīvs
12
-viaplay.lv|viaplay::home|https://yt3.ggpht.com/-noVdjbNR-V8/AAAAAAAAAAI/AAAAAAAAAAA/yZ9XNP5urLY/s900-c-k-no-mo-rj-c0xffffff/photo.jpg|Viaplay.lv - filmas latviešu, krievu u.c. valodās
13
-TVDom.tv|tvdom::home|https://tvdom.tv/front/assets/images/logo.png|PBK tiešraides un arhīvs
14
-BBC iPlayer|iplayer::home|http://www.userlogos.org/files/logos/inductiveload/BBC_iPlayer_logo.png|BBC live streams and arhive
15
-Euronews|euronews::home|http://pbs.twimg.com/profile_images/732665354242150400/tZsCnjuh_400x400.jpg|Euronews live streams and archive
16
-cinemalive.tv|cinemalive::home|https://cinemalive.tv/assets/img/filmas-online-latviski.jpg|cinemalive.tv - flmas  latvišu valodā
17
-MoviePlace.lv|movieplace::home||Movieplace.lv - filmas latviesu valodā
18
-Filmix.net|filmix::home|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Filmix.net - filmas krievu valodā
19
-SerialGURU.ru|serialguru::home|http://serialguru.ru/images/xlogo_new.png.pagespeed.ic.0sre2_2OJN.png|Serialguru.ru - filmas krievu valodā
20
-USTVNow|ustvnow::home|http://watch.ustvnow.com/assets/ustvnow/img/ustvnow_og_image.png|USTVNow kanālu tiešraide
21
-FilmOn|filmon::home|http://behindthegloves.com/wp-content/uploads/2016/01/FilmOn-logo1.jpg|FilmOn - tiešraides un video (dažādās valodās)
22
-MTGPlay|config::mtg|https://www.mtg.com/wp-content/uploads/2015/11/MTG-Logo-Medium-Red-PNG.png|Other countries MTG media portals content
23
-Filmas.lv|filmas::home|https://www.filmas.lv/wp-content/uploads/2013/06/LVfilmas-logo-jauns21.png|Filmas.lv - Latvijas filmas
24
-
25
-[my_tv]
26
-My Tv
27
-..return|back|default|Atgriezties atpakaļ
28
-LTV1|replay::tiesraide/ltv1/|http://replay.lsm.lv/resources/logo/large_ltv1.png|LTV1 tiesraide (video )
29
-LTV7|replay::tiesraide/ltv7/|http://replay.lsm.lv/resources/logo/large_ltv7.png|LTV7 tiesraide (video )
30
-TV3|http://wpc.11eb4.teliasoneracdn.net/8011EB4/origin1/tvplay/mtgstream2_high.stream/playlist.m3u8|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/TV3_logo.png|TV3
31
-TV3 (ltc)|ltc::content/live-streams/103?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/TV3_logo.png|TV3
32
-LNT (ltc)|ltc::content/live-streams/104?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/LNT_logo.png|LNT
33
-TV6|ltc::content/live-streams/106?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/TV6_logo.png|TV6
34
-Kanāls 2|ltc::content/live-streams/608?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/Kanals2_logo.png|Kanāls 2
35
-3+|ltc::content/live-streams/107?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/3_logo.png|3+
36
-360TV|ltc::content/live-streams/1051?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/360TV_new.png|360TV
37
-STV Pirmā!|ltc::content/live-streams/1069?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/STV.png|STV Pirmā!
38
-TVRiga24|play24::tiesraide||TV live streams
39
-Re:TV|ltc::content/live-streams/924?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/RE_TV.png|Re:TV
40
-RU live|tvdom::tiesraides||RU live streams from TVDom
41
-BBC live (iPlayer)|iplayer::live||BBC live streams from iPlayer
42
-UK live (FilmOn) TV|filmon::group?id=5|https://static.filmon.com/assets/groups/5/big_logo.png|UK live streams from FilmOn
43
-US live (FilmOn)|ustvnow::tvlive||US live streams from FilmOn
44
-Canadian live (FilmOn)|filmon::group?id=44|https://static.filmon.com/assets/groups/44/big_logo.png|Canada live streams from FilmOn
45
-Sport stream|rtmp://184.172.124.216/live/test111||
46
-
47
-[my_archive]
48
-My Archive
49
-..return|back||Atgriezties atpakaļ
50
-LTV arhīvs LV|replay::visi/jaunakie/?source=ltv&lang=lv|http://replay.lsm.lv/apple-touch-icon.png|LTV1, LTV2 pārraižu arhīvs LV
51
-LTV arhīvs RU|replay::vse/novie/?source=ltv&lang=ru|http://replay.lsm.lv/apple-touch-icon.png|LTV1, LTV2 pārraižu arhīvs RU
52
-skaties.lv arhīvs|mtgplay::videos?country=lv&order=-airdate|http://skaties.lv/touch-icon-192x192.png|MTG (LNT, TV3, TV6 u.c.) pārraižu arhīvs
53
-Lattelecom.tv arhīvs - categories|ltc::archive/categories|http://www.lattelecom.tv/images/default-social-icon_free.png|Lattelecom.tv pārraižu arhīvs
54
-TVRiga24 arhīvs|play24::kategorija/raidijumi|http://play24.lv/images/play24-logo-black.png|TVRiga24.tv pārraižu arhīvs
55
-TVDom arhīvs - categories|tvdom::arhivs|https://tvdom.tv/front/assets/images/logo.png|TVDom(PBK, NTV, REN u.c.) pārraižu arhīvs RU
56
-BBC (iPlayer) arhīvs|iplayer::categories||BBC programmes by categories
57
-Category - News|euronews::content/getVertical?lang=en&byPage=40&page=1&vId=1|http://pbs.twimg.com/profile_images/732665354242150400/tZsCnjuh_400x400.jpg|Category - News
58
-Latest programs|euronews::content/getLatestPrograms?lang=en&byPage=40&page=1|http://pbs.twimg.com/profile_images/732665354242150400/tZsCnjuh_400x400.jpg|Latest programs
59
-
60
-[my_video]
61
-My Video
62
-..return|back||Atgriezties atpakaļ
63
-Все фильмы|filmix::films|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Все фильмы
64
-Все сериалы|filmix::serialy|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Все сериалы
65
-
66
-[my_kids]
67
-My Kids
68
-..return|back|default|Atgriezties atpakaļ
69
-Bērnu TV|config::my_kids_tv||Bērnu TV kanāli
70
-Bērnu video|config::my_kids_video||Saglabātie bērnu video
71
-LTV bērnu TV arhīvs|replay::raidijumi/?lang=lv&type=video&theme=5||LTV bērnu TV arhīvs
72
-Skaties.lv bērnu TV arhīvs|mtgplay::formats?category=51&country=lv&order=title|http://mtgonline.lv/tv3play/categories/berni-new.jpg|Skaties.lv bērnu TV arhīvs
73
-Shortcut.lv video bērniem - latviski|ltc::videonoma?page=0&genre=3&sorts=title&cnt=40&clear=true&filter={"valoda":["lv"]}|https://www.lattelecom.tv/images/redesign/videonoma_dropdown_berniem.png|Shortuc.lv (Lattelecom) bērnu video latviski
74
-CBeebies video|iplayer::categories/cbeebies|http://www.userlogos.org/files/logos/inductiveload/BBC_iPlayer_logo.png|CBeebies videos from iPlayer
75
-CBBC video|iplayer::categories/cbbc|http://www.userlogos.org/files/logos/inductiveload/BBC_iPlayer_logo.png|CBBC videos from iPlayer
76
-TVDom bērnu video|tvdom::arhivs/bernu||TVDom bērnu video RU
77
-Filmix bērnu filmas|filmix::detskij|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Filmix bērnu filmas
78
-Filmix bērnu seriāli|filmix::detskij/s7|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Filmix bērnu seriāli
79
-SerialGURU multenes|serialguru::mult||SerialGURU multenes
80
-
81
-[my_kids_tv]
82
-My Kids TV
83
-..return|back|default|Atgriezties atpakaļ
84
-Kidzone|ltc::content/live-streams/951?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/kidzone2_new.png|Kidzone
85
-Nickelodeon|ltc::content/live-streams/302?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/Nickelodeon.png|Nickelodeon
86
-Jim Jam|ltc::content/live-streams/303?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/Jim_Jam.png|Jim Jam
87
-Nick Jr|ltc::content/live-streams/1095?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/NickJR.png|Nick Jr
88
-CBeebies (iPlayer)|iplayer::live/cbeebies|http://www.lyngsat-logo.com/hires/bb/bbc_cbeebies_uk.png|CBeebies
89
-CBBC (iPlayer)|iplayer::live/cbbc|http://www.lyngsat-logo.com/hires/bb/bbc_cbbc.png|CBBC
90
-CBeebies (FilmOn)|filmon::channel?id=3191|http://static.filmon.com/assets/channels/3191/big_logo.png|CBeebies is dedicated to preschoolers. Packed full of their favourite characters, CBeebies offers 13 hours of programmes every day which encourage your child to play along and learn. It's also completely advert free and with a dedicated website and interactive service, at CBeebies it's "Playtime All the Time!"
91
-CBBC (FilmOn)|filmon::channel?id=29|http://static.filmon.com/assets/channels/29/big_logo.png|CBBC is a BBC Television channel aimed at 6 to 12 year olds.
92
-Om Nom (FilmOn)|filmon::channel?id=3824|http://static.filmon.com/assets/channels/3824/big_logo.png|The series chronicles Om Nom's adventures with a young boy named Evan, beginning  with the little monster's mysterious appearance on the boy's doorstep in Episode 1. The animation series goes on to reveal Om Nom's mischievous, yet endearing personality as he and Evan bond over day-to-day activities such as playing games, exploring house-hold items and celebrating holidays.
93
-
94
-[my_kids_video]
95
-My Kids Video
96
-..return|back|default|Atgriezties atpakaļ
97
-
98
-[my_radio]
99
-My Radio
100
-..return|back|default|Atgriezties atpakaļ
101
-LR1|replay::tiesraide/lr1/|http://replay.lsm.lv/resources/logo/lr1_logo.png|LR1 tiesraide (audio)
102
-LR2|replay::tiesraide/lr2/|http://replay.lsm.lv/resources/logo/lr2_logo.png|LR2 tiesraide (audio)
103
-LR3|replay::tiesraide/lr3/|http://replay.lsm.lv/resources/logo/lr3_logo.png|LR3 tiesraide (audio)
104
-LR4|replay::tiesraide/lr4/|http://replay.lsm.lv/resources/logo/lr4_logo.png|LR4 tiesraide (audio)
105
-LR5|replay::tiesraide/lr5/|http://replay.lsm.lv/resources/logo/lr5_logo.png|LR5 tiesraide (audio)
106
-LR6|replay::tiesraide/lr6/|http://replay.lsm.lv/resources/logo/lr6_logo.png|LR6 tiesraide (audio)
107
-
108
-[mtg]
109
-MTG
110
-..return|back|default|Atgriezties atpakaļ
111
-Estonia (tv3play.ee)|mtgplay::home?country=ee||MTG Estonia media portal content
112
-Lithuania (play.tv3.lt/)|mtgplay::home?country=lt||MTG Lithuania media portal content
113
-Sweden (tvXplay.se)|mtgplay::home?country=se||MTG Sweden media portal content
114
-Denmark (tv3play.dk)|mtgplay::home?country=dk||MTG Denmark media portal content
115
-Norway (tv3play.no)|mtgplay::home?country=no||MTG Norway media portal content
116
-Bulgaria (play.novatv.bg/)|mtgplay::home?country=bg||MTG Bulgaria media portal content
117
-

+ 0
- 828
resources/lib/sources/swfinterp.py View File

@@ -1,828 +0,0 @@
1
-# This code comes from youtube-dl: https://github.com/rg3/youtube-dl/blob/master/youtube_dl/swfinterp.py
2
-
3
-from __future__ import unicode_literals
4
-
5
-import collections
6
-import io
7
-import struct
8
-import zlib
9
-
10
-
11
-def _extract_tags(file_contents):
12
-    if file_contents[1:3] != b'WS':
13
-        print '[SWFInterpreter] Not an SWF file; header is %r' % file_contents[:3]
14
-    if file_contents[:1] == b'C':
15
-        content = zlib.decompress(file_contents[8:])
16
-    else:
17
-        raise NotImplementedError(
18
-            'Unsupported compression format %r' %
19
-            file_contents[:1])
20
-
21
-    # Determine number of bits in framesize rectangle
22
-    framesize_nbits = struct.unpack('!B', content[:1])[0] >> 3
23
-    framesize_len = (5 + 4 * framesize_nbits + 7) // 8
24
-
25
-    pos = framesize_len + 2 + 2
26
-    while pos < len(content):
27
-        header16 = struct.unpack('<H', content[pos:pos + 2])[0]
28
-        pos += 2
29
-        tag_code = header16 >> 6
30
-        tag_len = header16 & 0x3f
31
-        if tag_len == 0x3f:
32
-            tag_len = struct.unpack('<I', content[pos:pos + 4])[0]
33
-            pos += 4
34
-        assert pos + tag_len <= len(content), \
35
-            ('Tag %d ends at %d+%d - that\'s longer than the file (%d)'
36
-                % (tag_code, pos, tag_len, len(content)))
37
-        yield (tag_code, content[pos:pos + tag_len])
38
-        pos += tag_len
39
-
40
-
41
-class _AVMClass_Object(object):
42
-    def __init__(self, avm_class):
43
-        self.avm_class = avm_class
44
-
45
-    def __repr__(self):
46
-        return '%s#%x' % (self.avm_class.name, id(self))
47
-
48
-
49
-class _ScopeDict(dict):
50
-    def __init__(self, avm_class):
51
-        super(_ScopeDict, self).__init__()
52
-        self.avm_class = avm_class
53
-
54
-    def __repr__(self):
55
-        return '%s__Scope(%s)' % (
56
-            self.avm_class.name,
57
-            super(_ScopeDict, self).__repr__())
58
-
59
-
60
-class _AVMClass(object):
61
-    def __init__(self, name_idx, name, static_properties=None):
62
-        self.name_idx = name_idx
63
-        self.name = name
64
-        self.method_names = {}
65
-        self.method_idxs = {}
66
-        self.methods = {}
67
-        self.method_pyfunctions = {}
68
-        self.static_properties = static_properties if static_properties else {}
69
-
70
-        self.variables = _ScopeDict(self)
71
-        self.constants = {}
72
-
73
-    def make_object(self):
74
-        return _AVMClass_Object(self)
75
-
76
-    def __repr__(self):
77
-        return '_AVMClass(%s)' % (self.name)
78
-
79
-    def register_methods(self, methods):
80
-        self.method_names.update(methods.items())
81
-        self.method_idxs.update(dict(
82
-            (idx, name)
83
-            for name, idx in methods.items()))
84
-
85
-
86
-class _Multiname(object):
87
-    def __init__(self, kind):
88
-        self.kind = kind
89
-
90
-    def __repr__(self):
91
-        return '[MULTINAME kind: 0x%x]' % self.kind
92
-
93
-
94
-def _read_int(reader):
95
-    res = 0
96
-    shift = 0
97
-    for _ in range(5):
98
-        buf = reader.read(1)
99
-        assert len(buf) == 1
100
-        b = struct.unpack('<B', buf)[0]
101
-        res = res | ((b & 0x7f) << shift)
102
-        if b & 0x80 == 0:
103
-            break
104
-        shift += 7
105
-    return res
106
-
107
-
108
-def _u30(reader):
109
-    res = _read_int(reader)
110
-    assert res & 0xf0000000 == 0
111
-    return res
112
-_u32 = _read_int
113
-
114
-
115
-def _s32(reader):
116
-    v = _read_int(reader)
117
-    if v & 0x80000000 != 0:
118
-        v = - ((v ^ 0xffffffff) + 1)
119
-    return v
120
-
121
-
122
-def _s24(reader):
123
-    bs = reader.read(3)
124
-    assert len(bs) == 3
125
-    last_byte = b'\xff' if (ord(bs[2:3]) >= 0x80) else b'\x00'
126
-    return struct.unpack('<i', bs + last_byte)[0]
127
-
128
-
129
-def _read_string(reader):
130
-    slen = _u30(reader)
131
-    resb = reader.read(slen)
132
-    assert len(resb) == slen
133
-    return resb.decode('utf-8')
134
-
135
-
136
-def _read_bytes(count, reader):
137
-    assert count >= 0
138
-    resb = reader.read(count)
139
-    assert len(resb) == count
140
-    return resb
141
-
142
-
143
-def _read_byte(reader):
144
-    resb = _read_bytes(1, reader=reader)
145
-    res = struct.unpack('<B', resb)[0]
146
-    return res
147
-
148
-
149
-StringClass = _AVMClass('(no name idx)', 'String')
150
-ByteArrayClass = _AVMClass('(no name idx)', 'ByteArray')
151
-TimerClass = _AVMClass('(no name idx)', 'Timer')
152
-TimerEventClass = _AVMClass('(no name idx)', 'TimerEvent', {'TIMER': 'timer'})
153
-_builtin_classes = {
154
-    StringClass.name: StringClass,
155
-    ByteArrayClass.name: ByteArrayClass,
156
-    TimerClass.name: TimerClass,
157
-    TimerEventClass.name: TimerEventClass,
158
-}
159
-
160
-
161
-class _Undefined(object):
162
-    def __bool__(self):
163
-        return False
164
-    __nonzero__ = __bool__
165
-
166
-    def __hash__(self):
167
-        return 0
168
-
169
-    def __str__(self):
170
-        return 'undefined'
171
-    __repr__ = __str__
172
-
173
-undefined = _Undefined()
174
-
175
-
176
-class SWFInterpreter(object):
177
-    def __init__(self, file_contents):
178
-        self._patched_functions = {
179
-            (TimerClass, 'addEventListener'): lambda params: undefined,
180
-        }
181
-        code_tag = next(tag
182
-                        for tag_code, tag in _extract_tags(file_contents)
183
-                        if tag_code == 82)
184
-        p = code_tag.index(b'\0', 4) + 1
185
-        code_reader = io.BytesIO(code_tag[p:])
186
-
187
-        # Parse ABC (AVM2 ByteCode)
188
-
189
-        # Define a couple convenience methods
190
-        u30 = lambda *args: _u30(*args, reader=code_reader)
191
-        s32 = lambda *args: _s32(*args, reader=code_reader)
192
-        u32 = lambda *args: _u32(*args, reader=code_reader)
193
-        read_bytes = lambda *args: _read_bytes(*args, reader=code_reader)
194
-        read_byte = lambda *args: _read_byte(*args, reader=code_reader)
195
-
196
-        # minor_version + major_version
197
-        read_bytes(2 + 2)
198
-
199
-        # Constant pool
200
-        int_count = u30()
201
-        self.constant_ints = [0]
202
-        for _c in range(1, int_count):
203
-            self.constant_ints.append(s32())
204
-        self.constant_uints = [0]
205
-        uint_count = u30()
206
-        for _c in range(1, uint_count):
207
-            self.constant_uints.append(u32())
208
-        double_count = u30()
209
-        read_bytes(max(0, (double_count - 1)) * 8)
210
-        string_count = u30()
211
-        self.constant_strings = ['']
212
-        for _c in range(1, string_count):
213
-            s = _read_string(code_reader)
214
-            self.constant_strings.append(s)
215
-        namespace_count = u30()
216
-        for _c in range(1, namespace_count):
217
-            read_bytes(1)  # kind
218
-            u30()  # name
219
-        ns_set_count = u30()
220
-        for _c in range(1, ns_set_count):
221
-            count = u30()
222
-            for _c2 in range(count):
223
-                u30()
224
-        multiname_count = u30()
225
-        MULTINAME_SIZES = {
226
-            0x07: 2,  # QName
227
-            0x0d: 2,  # QNameA
228
-            0x0f: 1,  # RTQName
229
-            0x10: 1,  # RTQNameA
230
-            0x11: 0,  # RTQNameL
231
-            0x12: 0,  # RTQNameLA
232
-            0x09: 2,  # Multiname
233
-            0x0e: 2,  # MultinameA
234
-            0x1b: 1,  # MultinameL
235
-            0x1c: 1,  # MultinameLA
236
-        }
237
-        self.multinames = ['']
238
-        for _c in range(1, multiname_count):
239
-            kind = u30()
240
-            assert kind in MULTINAME_SIZES, 'Invalid multiname kind %r' % kind
241
-            if kind == 0x07:
242
-                u30()  # namespace_idx
243
-                name_idx = u30()
244
-                self.multinames.append(self.constant_strings[name_idx])
245
-            elif kind == 0x09:
246
-                name_idx = u30()
247
-                u30()
248
-                self.multinames.append(self.constant_strings[name_idx])
249
-            else:
250
-                self.multinames.append(_Multiname(kind))
251
-                for _c2 in range(MULTINAME_SIZES[kind]):
252
-                    u30()
253
-
254
-        # Methods
255
-        method_count = u30()
256
-        MethodInfo = collections.namedtuple(
257
-            'MethodInfo',
258
-            ['NEED_ARGUMENTS', 'NEED_REST'])
259
-        method_infos = []
260
-        for method_id in range(method_count):
261
-            param_count = u30()
262
-            u30()  # return type
263
-            for _ in range(param_count):
264
-                u30()  # param type
265
-            u30()  # name index (always 0 for youtube)
266
-            flags = read_byte()
267
-            if flags & 0x08 != 0:
268
-                # Options present
269
-                option_count = u30()
270
-                for c in range(option_count):
271
-                    u30()  # val
272
-                    read_bytes(1)  # kind
273
-            if flags & 0x80 != 0:
274
-                # Param names present
275
-                for _ in range(param_count):
276
-                    u30()  # param name
277
-            mi = MethodInfo(flags & 0x01 != 0, flags & 0x04 != 0)
278
-            method_infos.append(mi)
279
-
280
-        # Metadata
281
-        metadata_count = u30()
282
-        for _c in range(metadata_count):
283
-            u30()  # name
284
-            item_count = u30()
285
-            for _c2 in range(item_count):
286
-                u30()  # key
287
-                u30()  # value
288
-
289
-        def parse_traits_info():
290
-            trait_name_idx = u30()
291
-            kind_full = read_byte()
292
-            kind = kind_full & 0x0f
293
-            attrs = kind_full >> 4
294
-            methods = {}
295
-            constants = None
296
-            if kind == 0x00:  # Slot
297
-                u30()  # Slot id
298
-                u30()  # type_name_idx
299
-                vindex = u30()
300
-                if vindex != 0:
301
-                    read_byte()  # vkind
302
-            elif kind == 0x06:  # Const
303
-                u30()  # Slot id
304
-                u30()  # type_name_idx
305
-                vindex = u30()
306
-                vkind = 'any'
307
-                if vindex != 0:
308
-                    vkind = read_byte()
309
-                if vkind == 0x03:  # Constant_Int
310
-                    value = self.constant_ints[vindex]
311
-                elif vkind == 0x04:  # Constant_UInt
312
-                    value = self.constant_uints[vindex]
313
-                else:
314
-                    return {}, None  # Ignore silently for now
315
-                constants = {self.multinames[trait_name_idx]: value}
316
-            elif kind in (0x01, 0x02, 0x03):  # Method / Getter / Setter
317
-                u30()  # disp_id
318
-                method_idx = u30()
319
-                methods[self.multinames[trait_name_idx]] = method_idx
320
-            elif kind == 0x04:  # Class
321
-                u30()  # slot_id
322
-                u30()  # classi
323
-            elif kind == 0x05:  # Function
324
-                u30()  # slot_id
325
-                function_idx = u30()
326
-                methods[function_idx] = self.multinames[trait_name_idx]
327
-            else:
328
-                print '[SWFInterpreter] Unsupported trait kind %d' % kind
329
-                return None
330
-
331
-            if attrs & 0x4 != 0:  # Metadata present
332
-                metadata_count = u30()
333
-                for _c3 in range(metadata_count):
334
-                    u30()  # metadata index
335
-
336
-            return methods, constants
337
-
338
-        # Classes
339
-        class_count = u30()
340
-        classes = []
341
-        for class_id in range(class_count):
342
-            name_idx = u30()
343
-
344
-            cname = self.multinames[name_idx]
345
-            avm_class = _AVMClass(name_idx, cname)
346
-            classes.append(avm_class)
347
-
348
-            u30()  # super_name idx
349
-            flags = read_byte()
350
-            if flags & 0x08 != 0:  # Protected namespace is present
351
-                u30()  # protected_ns_idx
352
-            intrf_count = u30()
353
-            for _c2 in range(intrf_count):
354
-                u30()
355
-            u30()  # iinit
356
-            trait_count = u30()
357
-            for _c2 in range(trait_count):
358
-                trait_methods, trait_constants = parse_traits_info()
359
-                avm_class.register_methods(trait_methods)
360
-                if trait_constants:
361
-                    avm_class.constants.update(trait_constants)
362
-
363
-        assert len(classes) == class_count
364
-        self._classes_by_name = dict((c.name, c) for c in classes)
365
-
366
-        for avm_class in classes:
367
-            avm_class.cinit_idx = u30()
368
-            trait_count = u30()
369
-            for _c2 in range(trait_count):
370
-                trait_methods, trait_constants = parse_traits_info()
371
-                avm_class.register_methods(trait_methods)
372
-                if trait_constants:
373
-                    avm_class.constants.update(trait_constants)
374
-
375
-        # Scripts
376
-        script_count = u30()
377
-        for _c in range(script_count):
378
-            u30()  # init
379
-            trait_count = u30()
380
-            for _c2 in range(trait_count):
381
-                parse_traits_info()
382
-
383
-        # Method bodies
384
-        method_body_count = u30()
385
-        Method = collections.namedtuple('Method', ['code', 'local_count'])
386
-        self._all_methods = []
387
-        for _c in range(method_body_count):
388
-            method_idx = u30()
389
-            u30()  # max_stack
390
-            local_count = u30()
391
-            u30()  # init_scope_depth
392
-            u30()  # max_scope_depth
393
-            code_length = u30()
394
-            code = read_bytes(code_length)
395
-            m = Method(code, local_count)
396
-            self._all_methods.append(m)
397
-            for avm_class in classes:
398
-                if method_idx in avm_class.method_idxs:
399
-                    avm_class.methods[avm_class.method_idxs[method_idx]] = m
400
-            exception_count = u30()
401
-            for _c2 in range(exception_count):
402
-                u30()  # from
403
-                u30()  # to
404
-                u30()  # target
405
-                u30()  # exc_type
406
-                u30()  # var_name
407
-            trait_count = u30()
408
-            for _c2 in range(trait_count):
409
-                parse_traits_info()
410
-
411
-        assert p + code_reader.tell() == len(code_tag)
412
-
413
-    def patch_function(self, avm_class, func_name, f):
414
-        self._patched_functions[(avm_class, func_name)] = f
415
-
416
-    def extract_class(self, class_name, call_cinit=True):
417
-        try:
418
-            res = self._classes_by_name[class_name]
419
-        except KeyError:
420
-            print '[SWFInterpreter] Class %r not found' % class_name
421
-            return None
422
-
423
-        if call_cinit and hasattr(res, 'cinit_idx'):
424
-            res.register_methods({'$cinit': res.cinit_idx})
425
-            res.methods['$cinit'] = self._all_methods[res.cinit_idx]
426
-            cinit = self.extract_function(res, '$cinit')
427
-            cinit([])
428
-
429
-        return res
430
-
431
-    def extract_function(self, avm_class, func_name):
432
-        p = self._patched_functions.get((avm_class, func_name))
433
-        if p:
434
-            return p
435
-        if func_name in avm_class.method_pyfunctions:
436
-            return avm_class.method_pyfunctions[func_name]
437
-        if func_name in self._classes_by_name:
438
-            return self._classes_by_name[func_name].make_object()
439
-        if func_name not in avm_class.methods:
440
-            print '[SWFInterpreter] Cannot find function %s.%s' % (
441
-                avm_class.name, func_name)
442
-            return None
443
-        m = avm_class.methods[func_name]
444
-
445
-        def resfunc(args):
446
-            # Helper functions
447
-            coder = io.BytesIO(m.code)
448
-            s24 = lambda: _s24(coder)
449
-            u30 = lambda: _u30(coder)
450
-
451
-            registers = [avm_class.variables] + list(args) + [None] * m.local_count
452
-            stack = []
453
-            scopes = collections.deque([
454
-                self._classes_by_name, avm_class.constants, avm_class.variables])
455
-            while True:
456
-                opcode = _read_byte(coder)
457
-                if opcode == 9:  # label
458
-                    pass  # Spec says: "Do nothing."
459
-                elif opcode == 16:  # jump
460
-                    offset = s24()
461
-                    coder.seek(coder.tell() + offset)
462
-                elif opcode == 17:  # iftrue
463
-                    offset = s24()
464
-                    value = stack.pop()
465
-                    if value:
466
-                        coder.seek(coder.tell() + offset)
467
-                elif opcode == 18:  # iffalse
468
-                    offset = s24()
469
-                    value = stack.pop()
470
-                    if not value:
471
-                        coder.seek(coder.tell() + offset)
472
-                elif opcode == 19:  # ifeq
473
-                    offset = s24()
474
-                    value2 = stack.pop()
475
-                    value1 = stack.pop()
476
-                    if value2 == value1:
477
-                        coder.seek(coder.tell() + offset)
478
-                elif opcode == 20:  # ifne
479
-                    offset = s24()
480
-                    value2 = stack.pop()
481
-                    value1 = stack.pop()
482
-                    if value2 != value1:
483
-                        coder.seek(coder.tell() + offset)
484
-                elif opcode == 21:  # iflt
485
-                    offset = s24()
486
-                    value2 = stack.pop()
487
-                    value1 = stack.pop()
488
-                    if value1 < value2:
489
-                        coder.seek(coder.tell() + offset)
490
-                elif opcode == 32:  # pushnull
491
-                    stack.append(None)
492
-                elif opcode == 33:  # pushundefined
493
-                    stack.append(undefined)
494
-                elif opcode == 36:  # pushbyte
495
-                    v = _read_byte(coder)
496
-                    stack.append(v)
497
-                elif opcode == 37:  # pushshort
498
-                    v = u30()
499
-                    stack.append(v)
500
-                elif opcode == 38:  # pushtrue
501
-                    stack.append(True)
502
-                elif opcode == 39:  # pushfalse
503
-                    stack.append(False)
504
-                elif opcode == 40:  # pushnan
505
-                    stack.append(float('NaN'))
506
-                elif opcode == 42:  # dup
507
-                    value = stack[-1]
508
-                    stack.append(value)
509
-                elif opcode == 44:  # pushstring
510
-                    idx = u30()
511
-                    stack.append(self.constant_strings[idx])
512
-                elif opcode == 48:  # pushscope
513
-                    new_scope = stack.pop()
514
-                    scopes.append(new_scope)
515
-                elif opcode == 66:  # construct
516
-                    arg_count = u30()
517
-                    args = list(reversed(
518
-                        [stack.pop() for _ in range(arg_count)]))
519
-                    obj = stack.pop()
520
-                    res = obj.avm_class.make_object()
521
-                    stack.append(res)
522
-                elif opcode == 70:  # callproperty
523
-                    index = u30()
524
-                    mname = self.multinames[index]
525
-                    arg_count = u30()
526
-                    args = list(reversed(
527
-                        [stack.pop() for _ in range(arg_count)]))
528
-                    obj = stack.pop()
529
-
530
-                    if obj == StringClass:
531
-                        if mname == 'String':
532
-                            assert len(args) == 1
533
-                            assert isinstance(args[0], (
534
-                                int, unicode, _Undefined))
535
-                            if args[0] == undefined:
536
-                                res = 'undefined'
537
-                            else:
538
-                                res = unicode(args[0])
539
-                            stack.append(res)
540
-                            continue
541
-                        else:
542
-                            raise NotImplementedError(
543
-                                'Function String.%s is not yet implemented'
544
-                                % mname)
545
-                    elif isinstance(obj, _AVMClass_Object):
546
-                        func = self.extract_function(obj.avm_class, mname)
547
-                        res = func(args)
548
-                        stack.append(res)
549
-                        continue
550
-                    elif isinstance(obj, _AVMClass):
551
-                        func = self.extract_function(obj, mname)
552
-                        res = func(args)
553
-                        stack.append(res)
554
-                        continue
555
-                    elif isinstance(obj, _ScopeDict):
556
-                        if mname in obj.avm_class.method_names:
557
-                            func = self.extract_function(obj.avm_class, mname)
558
-                            res = func(args)
559
-                        else:
560
-                            res = obj[mname]
561
-                        stack.append(res)
562
-                        continue
563
-                    elif isinstance(obj, unicode):
564
-                        if mname == 'split':
565
-                            assert len(args) == 1
566
-                            assert isinstance(args[0], unicode)
567
-                            if args[0] == '':
568
-                                res = list(obj)
569
-                            else:
570
-                                res = obj.split(args[0])
571
-                            stack.append(res)
572
-                            continue
573
-                        elif mname == 'charCodeAt':
574
-                            assert len(args) <= 1
575
-                            idx = 0 if len(args) == 0 else args[0]
576
-                            assert isinstance(idx, int)
577
-                            res = ord(obj[idx])
578
-                            stack.append(res)
579
-                            continue
580
-                    elif isinstance(obj, list):
581
-                        if mname == 'slice':
582
-                            assert len(args) == 1
583
-                            assert isinstance(args[0], int)
584
-                            res = obj[args[0]:]
585
-                            stack.append(res)
586
-                            continue
587
-                        elif mname == 'join':
588
-                            assert len(args) == 1
589
-                            assert isinstance(args[0], unicode)
590
-                            res = args[0].join(obj)
591
-                            stack.append(res)
592
-                            continue
593
-                    raise NotImplementedError(
594
-                        'Unsupported property %r on %r'
595
-                        % (mname, obj))
596
-                elif opcode == 71:  # returnvoid
597
-                    res = undefined
598
-                    return res
599
-                elif opcode == 72:  # returnvalue
600
-                    res = stack.pop()
601
-                    return res
602
-                elif opcode == 73:  # constructsuper
603
-                    # Not yet implemented, just hope it works without it
604
-                    arg_count = u30()
605
-                    args = list(reversed(
606
-                        [stack.pop() for _ in range(arg_count)]))
607
-                    obj = stack.pop()
608
-                elif opcode == 74:  # constructproperty
609
-                    index = u30()
610
-                    arg_count = u30()
611
-                    args = list(reversed(
612
-                        [stack.pop() for _ in range(arg_count)]))
613
-                    obj = stack.pop()
614
-
615
-                    mname = self.multinames[index]
616
-                    assert isinstance(obj, _AVMClass)
617
-
618
-                    # We do not actually call the constructor for now;
619
-                    # we just pretend it does nothing
620
-                    stack.append(obj.make_object())
621
-                elif opcode == 79:  # callpropvoid
622
-                    index = u30()
623
-                    mname = self.multinames[index]
624
-                    arg_count = u30()
625
-                    args = list(reversed(
626
-                        [stack.pop() for _ in range(arg_count)]))
627
-                    obj = stack.pop()
628
-                    if isinstance(obj, _AVMClass_Object):
629
-                        func = self.extract_function(obj.avm_class, mname)
630
-                        res = func(args)
631
-                        assert res is undefined
632
-                        continue
633
-                    if isinstance(obj, _ScopeDict):
634
-                        assert mname in obj.avm_class.method_names
635
-                        func = self.extract_function(obj.avm_class, mname)
636
-                        res = func(args)
637
-                        assert res is undefined
638
-                        continue
639
-                    if mname == 'reverse':
640
-                        assert isinstance(obj, list)
641
-                        obj.reverse()
642
-                    else:
643
-                        raise NotImplementedError(
644
-                            'Unsupported (void) property %r on %r'
645
-                            % (mname, obj))
646
-                elif opcode == 86:  # newarray
647
-                    arg_count = u30()
648
-                    arr = []
649
-                    for i in range(arg_count):
650
-                        arr.append(stack.pop())
651
-                    arr = arr[::-1]
652
-                    stack.append(arr)
653
-                elif opcode == 93:  # findpropstrict
654
-                    index = u30()
655
-                    mname = self.multinames[index]
656
-                    for s in reversed(scopes):
657
-                        if mname in s:
658
-                            res = s
659
-                            break
660
-                    else:
661
-                        res = scopes[0]
662
-                    if mname not in res and mname in _builtin_classes:
663
-                        stack.append(_builtin_classes[mname])
664
-                    else:
665
-                        stack.append(res[mname])
666
-                elif opcode == 94:  # findproperty
667
-                    index = u30()
668
-                    mname = self.multinames[index]
669
-                    for s in reversed(scopes):
670
-                        if mname in s:
671
-                            res = s
672
-                            break
673
-                    else:
674
-                        res = avm_class.variables
675
-                    stack.append(res)
676
-                elif opcode == 96:  # getlex
677
-                    index = u30()
678
-                    mname = self.multinames[index]
679
-                    for s in reversed(scopes):
680
-                        if mname in s:
681
-                            scope = s
682
-                            break
683
-                    else:
684
-                        scope = avm_class.variables
685
-
686
-                    if mname in scope:
687
-                        res = scope[mname]
688
-                    elif mname in _builtin_classes:
689
-                        res = _builtin_classes[mname]
690
-                    else:
691
-                        # Assume unitialized
692
-                        # TODO warn here
693
-                        res = undefined
694
-                    stack.append(res)
695
-                elif opcode == 97:  # setproperty
696
-                    index = u30()
697
-                    value = stack.pop()
698
-                    idx = self.multinames[index]
699
-                    if isinstance(idx, _Multiname):
700
-                        idx = stack.pop()
701
-                    obj = stack.pop()
702
-                    obj[idx] = value
703
-                elif opcode == 98:  # getlocal
704
-                    index = u30()
705
-                    stack.append(registers[index])
706
-                elif opcode == 99:  # setlocal
707
-                    index = u30()
708
-                    value = stack.pop()
709
-                    registers[index] = value
710
-                elif opcode == 102:  # getproperty
711
-                    index = u30()
712
-                    pname = self.multinames[index]
713
-                    if pname == 'length':
714
-                        obj = stack.pop()
715
-                        assert isinstance(obj, (unicode, list))
716
-                        stack.append(len(obj))
717
-                    elif isinstance(pname, unicode):  # Member access
718
-                        obj = stack.pop()
719
-                        if isinstance(obj, _AVMClass):
720
-                            res = obj.static_properties[pname]
721
-                            stack.append(res)
722
-                            continue
723
-
724
-                        assert isinstance(obj, (dict, _ScopeDict)),\
725
-                            'Accessing member %r on %r' % (pname, obj)
726
-                        res = obj.get(pname, undefined)
727
-                        stack.append(res)
728
-                    else:  # Assume attribute access
729
-                        idx = stack.pop()
730
-                        assert isinstance(idx, int)
731
-                        obj = stack.pop()
732
-                        assert isinstance(obj, list)
733
-                        stack.append(obj[idx])
734
-                elif opcode == 104:  # initproperty
735
-                    index = u30()
736
-                    value = stack.pop()
737
-                    idx = self.multinames[index]
738
-                    if isinstance(idx, _Multiname):
739
-                        idx = stack.pop()
740
-                    obj = stack.pop()
741
-                    obj[idx] = value
742
-                elif opcode == 115:  # convert_
743
-                    value = stack.pop()
744
-                    intvalue = int(value)
745
-                    stack.append(intvalue)
746
-                elif opcode == 128:  # coerce
747
-                    u30()
748
-                elif opcode == 130:  # coerce_a
749
-                    value = stack.pop()
750
-                    # um, yes, it's any value
751
-                    stack.append(value)
752
-                elif opcode == 133:  # coerce_s
753
-                    assert isinstance(stack[-1], (type(None), unicode))
754
-                elif opcode == 147:  # decrement
755
-                    value = stack.pop()
756
-                    assert isinstance(value, int)
757
-                    stack.append(value - 1)
758
-                elif opcode == 149:  # typeof
759
-                    value = stack.pop()
760
-                    return {
761
-                        _Undefined: 'undefined',
762
-                        unicode: 'String',
763
-                        int: 'Number',
764
-                        float: 'Number',
765
-                    }[type(value)]
766
-                elif opcode == 160:  # add
767
-                    value2 = stack.pop()
768
-                    value1 = stack.pop()
769
-                    res = value1 + value2
770
-                    stack.append(res)
771
-                elif opcode == 161:  # subtract
772
-                    value2 = stack.pop()
773
-                    value1 = stack.pop()
774
-                    res = value1 - value2
775
-                    stack.append(res)
776
-                elif opcode == 162:  # multiply
777
-                    value2 = stack.pop()
778
-                    value1 = stack.pop()
779
-                    res = value1 * value2
780
-                    stack.append(res)
781
-                elif opcode == 164:  # modulo
782
-                    value2 = stack.pop()
783
-                    value1 = stack.pop()
784
-                    res = value1 % value2
785
-                    stack.append(res)
786
-                elif opcode == 168:  # bitand
787
-                    value2 = stack.pop()
788
-                    value1 = stack.pop()
789
-                    assert isinstance(value1, int)
790
-                    assert isinstance(value2, int)
791
-                    res = value1 & value2
792
-                    stack.append(res)
793
-                elif opcode == 171:  # equals
794
-                    value2 = stack.pop()
795
-                    value1 = stack.pop()
796
-                    result = value1 == value2
797
-                    stack.append(result)
798
-                elif opcode == 175:  # greaterequals
799
-                    value2 = stack.pop()
800
-                    value1 = stack.pop()
801
-                    result = value1 >= value2
802
-                    stack.append(result)
803
-                elif opcode == 192:  # increment_i
804
-                    value = stack.pop()
805
-                    assert isinstance(value, int)
806
-                    stack.append(value + 1)
807
-                elif opcode == 208:  # getlocal_0
808
-                    stack.append(registers[0])
809
-                elif opcode == 209:  # getlocal_1
810
-                    stack.append(registers[1])
811
-                elif opcode == 210:  # getlocal_2
812
-                    stack.append(registers[2])
813
-                elif opcode == 211:  # getlocal_3
814
-                    stack.append(registers[3])
815
-                elif opcode == 212:  # setlocal_0
816
-                    registers[0] = stack.pop()
817
-                elif opcode == 213:  # setlocal_1
818
-                    registers[1] = stack.pop()
819
-                elif opcode == 214:  # setlocal_2
820
-                    registers[2] = stack.pop()
821
-                elif opcode == 215:  # setlocal_3
822
-                    registers[3] = stack.pop()
823
-                else:
824
-                    raise NotImplementedError(
825
-                        'Unsupported opcode %d' % opcode)
826
-
827
-        avm_class.method_pyfunctions[func_name] = resfunc
828
-        return resfunc

+ 0
- 4
resources/lib/sources/tvdom.cfg View File

@@ -1,4 +0,0 @@
1
-[tvdom]
2
-user = ivars777@gmail.com
3
-password = kaskade7
4
-

+ 0
- 282
resources/lib/sources/tvdom.py View File

@@ -1,282 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys,os
15
-from collections import OrderedDict
16
-from SourceBase import SourceBase
17
-
18
-API_URL = 'http://replay.lsm.lv/'
19
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
20
-headers0 = headers2dict("""
21
-User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
22
-""")
23
-import HTMLParser
24
-h = HTMLParser.HTMLParser()
25
-
26
-class Source(SourceBase):
27
-
28
-    def __init__(self,country="lv"):
29
-        self.name = "tvdom"
30
-        self.title = "TVDom.tv"
31
-        self.img = "https://tvdom.tv/front/assets/images/logo.png"
32
-        self.desc = "TVDom.tv portāla satura skatīšanās"
33
-        self.headers = headers0
34
-
35
-        self.country=country
36
-        self.session = None
37
-        self.token = None
38
-
39
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
40
-        self.config_file = os.path.join(cur_directory,self.name+".cfg")
41
-        self.options = OrderedDict([("user","lietotajs"),("password","parole")])
42
-        self.options_read()
43
-
44
-    def login(self,user="",password=""):
45
-        self.options_read()
46
-        if not user: user=self.options["user"]
47
-        if not password: password = self.options["password"]
48
-        headers = headers2dict("""
49
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0
50
-Accept: */*
51
-Accept-Language: en-US,en;q=0.5
52
-Accept-Encoding: gzip, deflate, br
53
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
54
-X-Requested-With: XMLHttpRequest
55
-Referer: https://tvdom.tv/
56
-        """)
57
-        url = "https://tvdom.tv/infinity/on_register_user"
58
-        params = "email=%s&password=%s&remember=false&auth_type=login"%(user,password)
59
-        import requests
60
-        try:
61
-            from requests.packages.urllib3.exceptions import InsecureRequestWarning
62
-            requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
63
-        except:
64
-            pass
65
-        r = requests.post(url, data=params, headers=headers)
66
-        js = json.loads(r.content)
67
-        if 'success' in r.content:
68
-            self.token = js["access_token"]
69
-            if 'PHPSESSID' in r.cookies:
70
-                self.session = r.cookies["PHPSESSID"]
71
-            return True
72
-        else:
73
-            raise Exception(js["error"])
74
-
75
-
76
-    def get_content(self, data):
77
-        print "[tvdom] get_content:", data
78
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
79
-        lang = qs["lang"] if "lang" in qs else self.country
80
-        content=[]
81
-        content.append(("..return", "back","","Return back"))
82
-
83
-        if clist=="home":
84
-            content.extend([
85
-                ("Live stream", "tvdom::tiesraides","","TV live streams"),
86
-                ("Archive - categories", "tvdom::arhivs","","Video archive by categories"),
87
-                ("Search", "tvdom::search/?srch-term={0}","","Search archive"),
88
-
89
-                #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
90
-            ])
91
-            return content
92
-
93
-        ### Tiesraides kanalu saraksts ###
94
-        elif data=="tiesraides":
95
-            ch_name = {"49":"Дом Кино","50":"Карусель","51":"Время","52":"Музыка Первого","53":"Телекафе"}
96
-            url = "https://tvdom.tv/"
97
-            r = self._http_request(url)
98
-            #channels1 = re.findall(r'data-xprs_status="\d" data-href="/tiesraides/([^/]+)/[^"]+">.+?src="([^"]+)" alt="([^"]+)">', r, re.DOTALL)
99
-            channels2 = re.findall(r'<a class="channel-name">([^<]*)</a>\s+<div class="redirect-to-url" data-href="/tiesraides/([^/]+)/[^"]+">.+?<img style="width:100%;" src="([^"]+)".+?<h3>([^<]+)</h3>.+?<p class="unix">([^<]+)</p>', r, re.DOTALL)
100
-            channels = {}
101
-            for item in channels2:
102
-                title = item[0]
103
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
104
-                img = "https://tvdom.tv"+item[2]
105
-                data2 = "tiesraides/%s/"%item[1]
106
-                desc = "%s\n%s\n%s"%(title,item[3],item[4])
107
-                channels[item[1]]={"title":title,"img":img,"desc":desc}
108
-                #content.append((title,self.name+"::"+data2,img,desc))
109
-
110
-            for r2 in re.findall(r'<div class="thumbnail-menu pull-left updater"(.+?)</div>\s+</div>', r, re.DOTALL):
111
-                ch = re.search('data-href="/tiesraides/([^/]+)/[^"]+"', r2, re.DOTALL).group(1)
112
-                data2 = "tiesraides/"+ch
113
-                m = re.search('src="(.+?)" alt="(.+?)">', r2, re.DOTALL)
114
-                title = m.group(2)
115
-                img = m.group(1)
116
-                desc = title
117
-                if ch in channels:
118
-                    img = channels[ch]["img"]
119
-                    desc = channels[ch]["desc"]
120
-                else:
121
-                    m = re.search('<img src="([^"]+)" alt="aaaaaa([^"]+)"><h3>.+<p class="unix">([^<]+)</p>', r2, re.DOTALL)
122
-                    if m:
123
-                        desc  = "%s\n%s\n%s"%(title,m.group(1),m.group(3))
124
-                        img = m.group(2)
125
-                content.append((title,self.name+"::"+data2,img,desc))
126
-            return content
127
-
128
-        elif clist == "tiesraides":
129
-            if not self.session:
130
-                self.login()
131
-            url = "https://tvdom.tv/" + data
132
-            headers = self.headers
133
-            headers["Cookie"] = "PHPSESSID=%s; neverending_story=1;"%self.session
134
-            r = self._http_request(url,headers=headers)
135
-            m = re.search("var streamConnectionUrl = '([^']+)'", r, re.DOTALL)
136
-            if m:
137
-                data2 = m.group(1)
138
-            else:
139
-                return ("No stream found %s"%data,"","","No stream found")
140
-            m = re.search('title: "([^"]+)"', r, re.DOTALL)
141
-            title = m.group(1) if m else data2
142
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
143
-            desc = m.group(1) if m else title
144
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
145
-            desc = m.group(1) if m else title
146
-            m = re.search('var promo_image *= "([^"]+)', r, re.DOTALL)
147
-            img = m.group(1) if m else ""
148
-            return (title,data2,img,desc)
149
-
150
-        ### Search ###
151
-        elif clist=="search":
152
-            url = "https://tvdom.tv/" + data
153
-            r = self._http_request(url)
154
-            for item in re.findall(r'<li data-xprs-search="\d+" data-href="([^"]+)".*?<img class="img-responsive" src="([^"]+)".*?<h3>([^<]+)</h3>.*?<h5>([^<]+)</h5>', r, re.DOTALL):
155
-                title = item[2] + " "+ item[3]
156
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
157
-                img = "https://tvdom.tv" + item[1]
158
-                data2 = item[0][1:]
159
-                desc = title
160
-                content.append((title,self.name+"::"+data2,img,desc))
161
-            return content
162
-
163
-        ### Arhīva kategorijas ###
164
-        elif data=="arhivs":
165
-            url = "https://tvdom.tv/"+data
166
-            r = self._http_request(url)
167
-            for item in re.findall('pointer" href="/([^"]+)">([^<]+)</a>', r, re.DOTALL):
168
-                title = item[1]
169
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
170
-                img = ""
171
-                data2 = item[0]
172
-                desc = title
173
-                content.append((title,self.name+"::"+data2,img,desc))
174
-            return content
175
-
176
-        ### Arhīva kategorijas programmas ###
177
-        elif clist=="arhivs":
178
-            url = "https://tvdom.tv/"+data
179
-            r = self._http_request(url)
180
-            for item in re.findall(r"""<li><div class="thumbnail pull-left" onclick="location\.href='([^']+)'" data-toggle="popover" title="([^"]+)" data-content="([^"]*)".+?<img class="img-responsive archive-image" src="([^"]+)""", r, re.DOTALL):
181
-            #for item in re.findall(r"""<li><div class="thumbnail pull-left" onclick="location\.href='([^']+)'" data-toggle="popover" title="([^"]+)" data-content="([^"]+)".+?<img class="img-responsive archive-image" src="([^"]+)""", r, re.DOTALL):
182
-                title = item[1].replace("&lt;br&gt;"," - ")
183
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
184
-                img = "https://tvdom.tv"+item[3]
185
-                data2 = item[0][1:]
186
-                desc = item[2]
187
-                content.append((title,self.name+"::"+data2,img,desc))
188
-            return content
189
-
190
-        ### Arhīva programmas video saraksts ###
191
-        elif clist=="play_arhivs" and len(data.split("/"))==3 and not re.search("_\d+",plist[2]):
192
-            url = "https://tvdom.tv/"+data
193
-            r = self._http_request(url)
194
-            vid=re.search(r"id:(\d+), type: type", r, re.DOTALL).group(1)
195
-            data2 = data+"_"+vid
196
-            m = re.search('program_title        = "([^"]+)"', r, re.DOTALL)
197
-            title = m.group(1) if m else data2
198
-            m = re.search('<a class="episode">Pārraides laiks ēterā: <span>([^<]+)</span></a>', r, re.DOTALL)
199
-            datums = m.group(1) if m else ""
200
-            title = title + " " + datums
201
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
202
-            desc = m.group(1) if m else title
203
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
204
-            desc = m.group(1) if m else title
205
-            m = re.search('var share_image *= "([^"]+)', r, re.DOTALL)
206
-            img = m.group(1) if m else ""
207
-            content.append((title,self.name+"::"+data2,img,desc))
208
-            i = r.find('<span class="slider-top-title"')
209
-            if i>0: r = r[:i]
210
-            for item in re.findall('<div class="col-md-9 redirect-to-url same-event" data-href="/([^"]+)">.+?image" src="([^"]+)".+?<h3 class="same-title">([^<]+)</h3>.*?<h5 class="same-online">([^<]+)</h5>', r, re.DOTALL):
211
-                title = item[2] + " " + item[3]
212
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
213
-                img = "https://tvdom.tv"+item[1]
214
-                data2 = item[0]
215
-                desc = title # TODO
216
-                content.append((title,self.name+"::"+data2,img,desc))
217
-            return content
218
-
219
-        ### Arhīva video
220
-        elif clist=="play_arhivs" and len(data.split("/"))==3 and re.search("_\d+",plist[2]):
221
-            url = "https://tvdom.tv/" + data
222
-            headers = self.headers
223
-            headers["Cookie"] = "PHPSESSID=%s; neverending_story=1;"%self.session
224
-            r = self._http_request(url,headers=headers)
225
-            m = re.search('var streamConnectionUrl  = "([^"]+)"', r, re.DOTALL)
226
-            if m:
227
-                data2 = m.group(1)
228
-            else:
229
-                return ("No stream found %s"%data,"","","No stream found")
230
-            m = re.search('program_title        = "([^"]+)"', r, re.DOTALL)
231
-            title = m.group(1) if m else data2
232
-            m = re.search('<a class="episode">Pārraides laiks ēterā: <span>([^<]+)</span></a>', r, re.DOTALL)
233
-            datums = m.group(1) if m else ""
234
-            title = title + " " + datums
235
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
236
-            desc = m.group(1) if m else title
237
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
238
-            desc = m.group(1) if m else title
239
-            m = re.search('var share_image *= "([^"]+)', r, re.DOTALL)
240
-            img = m.group(1) if m else ""
241
-            return (title,data2,img,desc)
242
-
243
-
244
-    def is_video(self,data):
245
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
246
-        cmd = data.split("/")
247
-        if cmd[0] in ("tiesraides") and len(cmd)>1:
248
-            return True
249
-        elif cmd[0]=="play_arhivs" and len(cmd)==3 and re.search("_\d+",plist[2]):
250
-            return True
251
-        else:
252
-            return False
253
-
254
-    def call(self, data,headers=headers0,lang=""):
255
-        if not lang: lang = self.country
256
-        url = API_URL%lang + data
257
-        #print "[TVPlay Api] url: ",url
258
-        result = []
259
-        content = self._http_request(url)
260
-        return content
261
-
262
-if __name__ == "__main__":
263
-    country= "lv"
264
-    c = Source(country)
265
-    if len(sys.argv)>1:
266
-        data= sys.argv[1]
267
-    else:
268
-        data = "home"
269
-    content = c.get_content(data)
270
-    for item in content:
271
-        print item
272
-    #cat = api.get_categories(country)
273
-    #chan = api.get_channels("lv")
274
-    #prog = api.get_programs(channel=6400)
275
-    #prog = api.get_programs(category=55)
276
-    #seas = api.get_seasons(program=6453)
277
-    #str = api.get_streams(660243)
278
-    #res = api.get_videos(802)
279
-    #formats = api.getAllFormats()
280
-    #det = api.detailed("1516")
281
-    #vid = api.getVideos("13170")
282
-    pass

+ 0
- 4
resources/lib/sources/ustvnow.cfg View File

@@ -1,4 +0,0 @@
1
-[ustvnow]
2
-user = ivars777@gmail.com
3
-password = kaskade7
4
-

+ 0
- 181
resources/lib/sources/ustvnow.py View File

@@ -1,181 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys,os
15
-import traceback
16
-from collections import OrderedDict
17
-from SourceBase import SourceBase
18
-
19
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
20
-headers0 = headers2dict("""
21
-Host: m-api.ustvnow.com
22
-User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46
23
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
24
-DNT: 1
25
-Connection: keep-alive
26
-""")
27
-import HTMLParser
28
-h = HTMLParser.HTMLParser()
29
-
30
-class Source(SourceBase):
31
-
32
-    def __init__(self,country="lv"):
33
-        self.name = "ustvnow"
34
-        self.title = "USTVNow"
35
-        self.img = "http://watch.ustvnow.com/assets/ustvnow/img/ustvnow_og_image.png"
36
-        self.desc = "USTVNow kanālu tiešraide"
37
-        self.headers = headers0
38
-
39
-        self.country=country
40
-        self.token = ""
41
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
42
-        self.config_file = os.path.join(cur_directory,self.name+".cfg")
43
-        self.options = OrderedDict([("user","lietotajs"),("password","parole")])
44
-        self.options_read()
45
-
46
-    def login(self,user="",password=""):
47
-        self.options_read()
48
-        if not user: user=self.options["user"]
49
-        if not password: password = self.options["password"]
50
-        headers = headers2dict("""
51
-        Host: m-api.ustvnow.com
52
-        Accept-Language: en-US,en;q=0.5
53
-        User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
54
-        Accept: text/html,application/xhtml+xml,application/xml
55
-        Connection: keep-alive
56
-        """)
57
-
58
-        url = "http://m-api.ustvnow.com/iphone/1/live/login?username=%s&password=%s&device=gtv&redir=0"%(user,password)
59
-        #url = "http://m-api.ustvnow.com/gtv/1/live/login?username=%s&password=%s&device=gtv&redir=0"%(user,password)
60
-        r = self._http_request(url,headers=headers)
61
-        if 'success' in r:
62
-            self.token = re.search('"token":"([^"]+)',r).group(1)
63
-            return True
64
-        else:
65
-            return False
66
-
67
-    def get_content(self, data):
68
-        print "[ustvnow] get_content:", data
69
-        if "::" in data:
70
-            data = data.split("::")[1]
71
-        path = data.split("?")[0]
72
-        clist = path.split("/")[0]
73
-        params = data[data.find("?"):] if "?" in data else ""
74
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
75
-        lang = qs["lang"] if "lang" in qs else self.country
76
-
77
-        content=[]
78
-        content.append(("..return", "back","","Return back"))
79
-
80
-        if clist=="home":
81
-            content.extend([
82
-                ("TV live streams", "ustvnow::tvlive","","TV live streams"),
83
-                ("Movies", "ustvnow::movies","","Movies (not implemented yet"),
84
-                ("Recordings", "ustvnow::recordings","","Recordings (not implemented yet"),
85
-            ])
86
-            return content
87
-
88
-        if clist=="movies":
89
-            return content
90
-
91
-        if clist=="recordings":
92
-            return content
93
-
94
-        ### Tiesraides kanalu saraksts ###
95
-        elif data=="tvlive":
96
-            if not self.token:
97
-                if not self.login():
98
-                    raise Exception("Can not login\nPlease check USTVNow username/password in\n/usr/lib/enigma2/python/Plugins/Extensions/sources/ustvnow.cfg file")
99
-            data = "live/channelguide?token=%s"%self.token
100
-            self.r = self.call(data)
101
-            if not self.r:
102
-                return content
103
-            for item in self.r["results"]:
104
-                if item["order"] == 1:
105
-                    title = item["stream_code"]
106
-                    title =  h.unescape(title.decode("utf8")).encode("utf8")
107
-                    img = "http://m-api.ustvnow.com/"+item["prg_img"] #item["img"]
108
-                    data2 = "live/view?scode=%s&token=%s"%(item["scode"],self.token)
109
-                    desc = "%s\n%s (+%s')\n%s"%(item["title"],item["event_time"],int(item["actualremainingtime"])/60,item["description"])
110
-                    content.append((title,self.name+"::"+data2,img,desc))
111
-            return content
112
-
113
-        ### Tiesraides kanāls ###
114
-        elif path == "live/view":
115
-            url = "http://m-api.ustvnow.com/stream/1/%s"%data
116
-            r = self._http_request(url)
117
-            if not r:
118
-                return ("No stream found %s"%data,"","","No stream found")
119
-            r = json.loads(r)
120
-            if not "r" in dir(self):
121
-                if not self.token:
122
-                    self.login()
123
-                self.r = self.call("live/channelguide?token=%s"%self.token)
124
-            if self.r:
125
-                ch = qs["scode"]
126
-                for item in self.r["results"]:
127
-                    if item["order"] == 1 and item["scode"] == ch:
128
-                        title = item["stream_code"]
129
-                        title = "%s - %s (%s)"%(item["stream_code"],item["title"],item["event_time"])
130
-                        img = "http://m-api.ustvnow.com/"+item["prg_img"]
131
-                        data2 = "live/view?scode=%s&token=%s"%(item["scode"],self.token)
132
-                        desc = "%s\n%s (+%s')\n%s"%(item["title"],item["event_time"],int(item["actualremainingtime"])/60,item["description"])
133
-            else:
134
-                title = data
135
-            data2 = r["stream"]
136
-            desc = title
137
-            img = "" # img TODO
138
-            return (title,data2,img,desc)
139
-
140
-    def is_video(self,data):
141
-        if "::" in data:
142
-            data = data.split("::")[1]
143
-        if "live/view" in data:
144
-            return True
145
-        else:
146
-            return False
147
-
148
-    def call(self, data,headers=headers0,lang=""):
149
-        if not lang: lang = self.country
150
-        url = "http://m-api.ustvnow.com/gtv/1/"+data
151
-        content = self._http_request(url)
152
-        result = None
153
-        if content:
154
-            try:
155
-                result = json.loads(content)
156
-            except Exception, ex:
157
-                return None
158
-        return result
159
-
160
-
161
-if __name__ == "__main__":
162
-    country= "lv"
163
-    c = Source(country)
164
-    if len(sys.argv)>1:
165
-        data= sys.argv[1]
166
-    else:
167
-        data = "home"
168
-    content = c.get_content(data)
169
-    for item in content:
170
-        print item
171
-    #cat = api.get_categories(country)
172
-    #chan = api.get_channels("lv")
173
-    #prog = api.get_programs(channel=6400)
174
-    #prog = api.get_programs(category=55)
175
-    #seas = api.get_seasons(program=6453)
176
-    #str = api.get_streams(660243)
177
-    #res = api.get_videos(802)
178
-    #formats = api.getAllFormats()
179
-    #det = api.detailed("1516")
180
-    #vid = api.getVideos("13170")
181
-    pass

+ 0
- 5
resources/lib/sources/viaplay.cfg View File

@@ -1,5 +0,0 @@
1
-[viaplay]
2
-user = ivars777@gmail.com
3
-password = kaskade7
4
-device = 
5
-

+ 0
- 484
resources/lib/sources/viaplay.py View File

@@ -1,484 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import requests
14
-try:
15
-    from requests.packages.urllib3.exceptions import InsecureRequestWarning
16
-    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
17
-except:
18
-    pass
19
-import urlparse, urllib
20
-import datetime, time,re, sys,os
21
-from collections import OrderedDict
22
-from SourceBase import SourceBase
23
-try:
24
-    import util
25
-except:
26
-    parent = os.path.dirname(os.path.abspath(__file__))
27
-    parent = os.sep.join(parent.split(os.sep)[:-1])
28
-    sys.path.insert(0,parent)
29
-    import util
30
-
31
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
32
-
33
-class Source(SourceBase):
34
-
35
-    def __init__(self,language="en"):
36
-        self.name = "viaplay"
37
-        self.title = "viaplay.lv"
38
-        self.img = "https://yt3.ggpht.com/-noVdjbNR-V8/AAAAAAAAAAI/AAAAAAAAAAA/yZ9XNP5urLY/s900-c-k-no-mo-rj-c0xffffff/photo.jpg"
39
-        self.desc = "Viaplay.lv saturs"
40
-        self.url = "https://viaplay.lv/"
41
-        self.headers = headers2dict("""
42
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
43
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
44
-Connection: keep-alive
45
-Upgrade-Insecure-Requests: 1
46
-        """)
47
-        #self.language=language
48
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
49
-        self.config_file = os.path.join(cur_directory,self.name+".cfg")
50
-        self.options = OrderedDict([("user","change_user"),("password","change_password"),("device","")])
51
-        self.options_read()
52
-        self.device = self.options["device"]
53
-        self.r = None # requests
54
-        self.play_session = None
55
-        self.s = None
56
-
57
-    def login(self,user="",password=""):
58
-        self.options_read()
59
-        if not user: user=self.options["user"]
60
-        if not password: password = self.options["password"]
61
-        self.s = requests.Session()
62
-
63
-        ### Dabu sesijas ID ===
64
-        headers = headers2dict("""
65
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
66
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
67
-Accept-Language: en-US,en;q=0.5
68
-Accept-Encoding: gzip, deflate, br
69
-Referer: https://viaplay.lv/
70
-Cookie: ott_cookies_confirmed=1;
71
-DNT: 1
72
-Connection: keep-alive
73
-Upgrade-Insecure-Requests: 1
74
-""")
75
-        r = requests.get(self.url,headers=headers)
76
-        if not "PLAY_SESSION" in r.cookies:
77
-            return False
78
-        self.play_session = r.cookies["PLAY_SESSION"]
79
-        self.csrfToken = re.search("csrfToken=(.+)",self.play_session).group(1)
80
-
81
-        ### Ielogojamies ###
82
-        headers = headers2dict("""
83
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
84
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
85
-Accept-Language: en-US,en;q=0.5
86
-Accept-Encoding: gzip, deflate, br
87
-Referer: https://viaplay.lv/
88
-Cookie: ott_cookies_confirmed=1; PLAY_SESSION=e618c42b377a65021298ff63309d5a907988ed1b-PSESSIONID=b010ea1b-fc5e-4a18-aa15-ebbe8b57b3f0&csrfToken=b4eb35263d9be16ef9f7b2f5d10a8ee99dfe75a8-1478051634814-63682b20f1e7e5579de6d056
89
-DNT: 1
90
-Connection: keep-alive
91
-Upgrade-Insecure-Requests: 1
92
-Content-Type: application/x-www-form-urlencoded
93
-""")
94
-        url = "https://viaplay.lv/tdi/login/nav/formular?csrfToken=%s"%self.csrfToken
95
-        params = "nav_redirectUri=https%3A%2F%2Fviaplay.lv%2F&nav_email={}&nav_password={}".format(urllib.quote(user),urllib.quote(password))
96
-        headers["Cookie"] = "ott_cookies_confirmed=1; PLAY_SESSION=%s;"%self.play_session
97
-        if self.device:
98
-            headers["Cookie"] += "ott_dids=%s"%self.device
99
-        #cookie = dict(PLAY_SESSION=self.play_session,_hjIncludedInSample=1, mobileAppPromo="shown")
100
-        r = requests.post(url,params,headers=headers,allow_redirects=False)
101
-        if not "Set-Cookie" in r.headers:
102
-            self.play_session = None
103
-            return False
104
-        self.ott = r.cookies["ott_web_sac"]
105
-
106
-        ### Dabu iekārtas ID ###
107
-        if not self.device:
108
-            headers = headers2dict("""
109
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
110
-Accept: application/xml, text/xml, */*; q=0.01
111
-Accept-Language: en-US,en;q=0.5
112
-Accept-Encoding: gzip, deflate, br
113
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
114
-X-Requested-With: XMLHttpRequest
115
-Referer: https://viaplay.lv/movies/me-and-earl-and-the-dying-girl
116
-DNT: 1
117
-Connection: keep-alive    """)
118
-            url = "https://viaplay.lv/tdi/account/device/create?_infuse=1&csrfToken=%s"%self.csrfToken
119
-            params = "successRedirectUri=https%3A%2F%2Fviaplay.lv%2Fmovies%2F&slotId=&title=Enigma2"
120
-            headers["Cookie"] = "PLAY_SESSION=%s; ott_cookies_confirmed=1; ott_web_sac=%s;"%(self.play_session,self.ott)
121
-            #cookie = dict(PLAY_SESSION=self.play_session,_hjIncludedInSample=1, mobileAppPromo="shown")
122
-            r = requests.post(url,params,headers=headers,allow_redirects=False)
123
-            if not ("Set-Cookie" in r.headers and "ott_dids" in r.headers["Set-Cookie"]):
124
-                self.play_session = None
125
-                return False
126
-            self.device =  r.cookies["ott_dids"]
127
-            self.options["device"] = self.device
128
-            self.options_write(self.options)
129
-        return True
130
-
131
-    def logout(self):
132
-        return True
133
-
134
-    def is_logedin(self):
135
-        if self.play_session:
136
-            return True
137
-        else:
138
-            return False
139
-
140
-    def get_video_info(self,vid):
141
-        import demjson
142
-        ### Dabu strimus ###
143
-        headers = headers2dict("""
144
-Host: viaplay.lv
145
-User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46
146
-Accept: application/xml, text/xml, */*; q=0.01
147
-Accept-Language: en-US,en;q=0.5
148
-Accept-Encoding: gzip, deflate, br
149
-X-Requested-With: XMLHttpRequest
150
-DNT: 1
151
-Connection: keep-alive
152
-Referer: https://viaplay.lv/
153
-""")
154
-        url = "https://viaplay.lv/prehravac/init?_infuse=1&productId=%s"%vid #t110623
155
-        headers["Cookie"] = "ott_cookies_confirmed=1; ott_dids=%s; PLAY_SESSION=%s"%(self.device,self.play_session)
156
-        r = requests.get(url,headers=headers,allow_redirects=False)
157
-        statuss = re.search("<status>(.+?)</status>", r.content).group(1)
158
-        if statuss.lower() <> "ok":
159
-            raise Exception(statuss)
160
-        #print r.content
161
-        m = re.search(r"<!\[CDATA\[\s+var TDIPlayerOptions = (.+?);[\n\t\s]+\]\]>\s+</script>", r.content, re.DOTALL)
162
-        if not m:
163
-            raise "Can not find stream info"
164
-        txt = m.group(1)
165
-        txt = re.sub("// .+$", "", txt, flags=re.MULTILINE)
166
-        #print txt
167
-        #for m in re.finditer("// .+$", txt, re.MULTILINE):
168
-        #    txt = txt[:m.start()] + txt[m.end():]
169
-        #print txt
170
-        js = demjson.decode(txt)
171
-        return js
172
-        #return txt
173
-
174
-
175
-    def get_content(self, data):
176
-        print "[%s] get_content:"%self.name, data
177
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
178
-        content=[]
179
-        content.append(("..return", "back","","Return back"))
180
-
181
-        if clist=="home":
182
-            content.extend([
183
-                ("Search", "viaplay::search-results-all?query={0}",self.img,"Meklēt"),
184
-                ("Filmas", "viaplay::movies",self.img,"Filmas"),
185
-                ("Seriāli", "viaplay::series",self.img,"Seriāli"),
186
-                ("Bērniem", "viaplay::kids",self.img,"Bērniem"),
187
-                ("Dokumentalās filmas", "viaplay::documentary",self.img,"Dokumentalās filmas"),
188
-                ("Sports", "viaplay::live",self.img,"Sports"),
189
-             ])
190
-            return content
191
-
192
-        ### Meklēt ###
193
-        elif clist=="search-results-all":
194
-            url = "https://viaplay.lv/"+data
195
-            r = self._http_request(url)
196
-            result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<h3 class="is-size-h6">([^<]+)</h3>.*?<p>([^<]+).+?</p>.+?<p class="promo-notice">([^<]+)</p>.+?<p class="info">([^<]+)</p>', r, re.DOTALL)
197
-            for item in result:
198
-                vid = item[0]
199
-                data2 = item[1].replace("https://viaplay.lv/","")
200
-                img = item[2]
201
-                ep = item[3]
202
-                title= item[4]
203
-                seas = item[5].replace("\n","").replace("\t","")
204
-                desc = item[6]
205
-                desc2 = item[7]
206
-                if ep==title:
207
-                    title = "%s (%s)"%(title,seas)
208
-                else:
209
-                    title = "%s - %s%s"%(title,seas,ep)
210
-                desc = "%s\n%s\n%s"%(title,desc2,desc)
211
-                content.append((title,self.name+"::"+data2,img,desc))
212
-            return content
213
-
214
-        ### Sadalas ##
215
-        elif data in ["movies","series","kids","documentary"]:
216
-            r = self._http_request(self.url+data)
217
-            # https://viaplay.lv/tdi/movies/next?sections[]=MOVIES&genres[]=a3591&sort[]=latest&offset=0
218
-            # https://viaplay.lv/tdi/series/next?sections[]=SERIES&sort[]=latest&offset=0
219
-            # https://viaplay.lv/tdi/kids/next?sections[]=KIDS&cat[]=SERIES&cat[]=MOVIE&sort[]=latest&offset=18
220
-            # https://viaplay.lv/kids?sections[]=KIDS&cat[]=SERIES&sort[]=latest
221
-            sections =  {"movies":"MOVIES","series":"SERIES","kids":"KIDS","documentary":"DOCUMENTS"}
222
-            nosaukums = {"movies":"Flmas","series":"Seriāli","kids":"Bērnu","documentary":"Dokumentalās"}
223
-            #availability = {"new":"jaunākās","last":"pēdējā iespēja"}
224
-            sort = OrderedDict([("latest","jaunākais"),("title","pēc nosaukuma"),("popular","pēc popularitātes"),("year","pēc gada")])
225
-            for s in sort:
226
-                if data in ("movies","series"):
227
-                    title = "%s - %s"%(nosaukums[data],sort[s])
228
-                    data2 = "%s/next?sections[]=%s&sort[]=%s"%(data,sections[data],s)
229
-                    content.append((title,self.name+"::"+data2,self.img,title))
230
-                else:
231
-                    title = "%s filmas - %s"%(nosaukums[data],sort[s])
232
-                    data2 = "%s/next?sections[]=%s&cat[]=MOVIE&sort[]=%s"%(data,sections[data],s)
233
-                    content.append((title,self.name+"::"+data2,self.img,title))
234
-                    title = "%s seriāli - %s"%(nosaukums[data],sort[s])
235
-                    data2 = "%s/next?sections[]=%s&cat[]=SERIES&sort[]=%s"%(data,sections[data],s)
236
-                    content.append((title,self.name+"::"+data2,self.img,title))
237
-
238
-            # Pievienojam žanru sarakstu
239
-            result = re.findall(r'name="genres\[\]" value="([^"]+)">.+?class="">([^<]+)</label>', r, re.DOTALL)
240
-            for item in result:
241
-                s = "latest"
242
-                genre = item[1].replace("&amp;","&")
243
-                title = "%s: %s"%(nosaukums[data],genre)
244
-                data2 = "%s/next?sections[]=%s&genres[]=%s&sort[]=%s"%(data,sections[data],item[0],s)
245
-                content.append((title,self.name+"::"+data2,self.img,title))
246
-
247
-            return content
248
-
249
-        ### Filmu/seriālu/sēriju saraksts ###
250
-        elif clist in ("movies","series","kids","documentary") and plist[1] == "next":
251
-            url = "https://viaplay.lv/tdi/"+data
252
-            r = self._http_request(url)
253
-            if clist == "series" and "season" in qs:
254
-                result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<h3 class="is-size-h6">([^<]+)</h3>.*?<p>([^<]+).+?</p>.+?<p class="promo-notice">([^<]+)</p>.+?<p class="info">([^<]+)</p>', r, re.DOTALL)
255
-                for item in result:
256
-                    vid = item[0]
257
-                    data2 = item[1].replace("https://viaplay.lv/","")
258
-                    img = item[2]
259
-                    ep = item[3]
260
-                    title= item[4]
261
-                    seas = item[5]
262
-                    desc = item[6]
263
-                    desc2 = item[7]
264
-                    title = "%s - %s%s"%(title,seas,ep)
265
-                    desc = "%s\n%s\n%s"%(title,desc2,desc)
266
-                    content.append((title,self.name+"::"+data2,img,desc))
267
-            else: # filmas
268
-                result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<p>([^<]+)</p>.+?<p class="promo-notice">([^<]+).+?<p class="is-strong detail">(.+?)</p>.+?<p class="info">([^<]+)</p>', r, re.DOTALL)
269
-                for item in result:
270
-                    vid = item[0]
271
-                    data2 = item[1].replace("https://viaplay.lv/","")
272
-                    img = item[2]
273
-                    title = item[3]
274
-                    year = item[4]
275
-                    year  = year.replace("\n","").replace("\t","")
276
-                    title = title +"(%s)"%year
277
-                    desc= item[5]
278
-                    genre = re.findall(">([^<]+)<", item[6], re.DOTALL)
279
-                    genre = ("".join(genre)).replace("&amp;","&")
280
-                    desc2 = item[7]
281
-                    desc = "%s\n%s\n%s"%(genre,desc2,desc)
282
-                    content.append((title,self.name+"::"+data2, img,desc))
283
-            m = re.search(r"data\('href', 'https://viaplay\.lv/tdi/([^']+)'\)", r, re.DOTALL)
284
-            if m:
285
-                data2 = m.group(1)
286
-                content.append(("Next page",self.name+"::"+data2,img,"Next page"))
287
-            return content
288
-
289
-        ### Seriāls ###
290
-        elif clist == "series" and len(plist)==2:
291
-            url = "https://viaplay.lv/"+data
292
-            r = self._http_request(url)
293
-            result = re.findall(r'<li>.*?<a class="tdi" href="https://viaplay\.lv/([^"]+)" data-related-ancestor="\.js-tdi-items-filter-and-items">([^<]+)</a>.*?</li>', r, re.DOTALL)
294
-            for item in result:
295
-                title = item[1]
296
-                data2 = item[0]
297
-                data2 = data2.replace("series/","series/next/")
298
-                data2 = data2+"&sort[]=ord"
299
-                #series/littlest-pet-shop?season=t6821
300
-                #series/next/peppa-pig?season=t8430
301
-                # &sort[]=ord
302
-                if "availability=" in data2: continue
303
-                content.append((title,self.name+"::"+data2,self.img,title)) #TODO bilde
304
-            return content
305
-
306
-    def is_video(self,data):
307
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
308
-        if clist in ("movies","documentary","kids") and len(plist)>1 and plist[1]<>"next":
309
-            return True
310
-        elif clist == "series"  and len(plist)>1 and plist[1] == "episode":
311
-            return True
312
-        else:
313
-            return False
314
-
315
-    def get_streams(self, data):
316
-        print "[viaplay] get_streams:", data
317
-        if not self.is_video(data):
318
-            return []
319
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
320
-        if not self.is_logedin():
321
-            self.login()
322
-        if not self.is_logedin():
323
-            raise Exception("Could not login to viaplay.lv, check username/password in options")
324
-
325
-        streams = []
326
-        url = "https://viaplay.lv/"+data
327
-        r = self._http_request(url)
328
-        if clist=="series":
329
-            m = re.search(r'<h1 class="is-bottom-sticked is-size-h2">(.+?)</h1>.*?<h2 class="is-size-h4">.*?<p class="is-size-h6 is-strong is-bottom-sticked">(.+?)<div class="toggler-content">\s+<p>(.+?)</p>', r, re.DOTALL)
330
-            if not m:
331
-                raise Exception("Problem getting video information")
332
-            title = m.group(1).replace("\n"," ").replace("\t","").strip()
333
-            title = re.sub("<[^>]+>","",title).strip()
334
-            desc2 = m.group(2).replace("\n"," ").replace("\t","").strip()
335
-            desc2 = re.sub("<[^>]+>","",desc2).strip()
336
-            desc = m.group(3)
337
-            desc = "%s\n%s"%(desc2,desc)
338
-            vid = re.search('data-productid="(\w+)"',r).group(1)
339
-        else:
340
-            m = re.search(r'<h1 class="is-strong is-bottom-sticked is-size-h2" jnp-id="(\w+)">([^<]+)</h1>.*?<h2 class="is-strong is-size-h4">([^<]+)</h2>.*?<p class="is-size-h6 is-strong is-bottom-sticked">(.+?)<div class="toggler-content">\s+<p>(.+?)</p>', r, re.DOTALL)
341
-            if not m:
342
-                raise Exception("Problem getting video information")
343
-            title = m.group(2).strip()
344
-            title2 = m.group(3).strip()
345
-            title = "%s | %s"%(title,title2)
346
-            desc = m.group(5).strip()
347
-            desc2 = m.group(4).strip()
348
-            desc2 = re.sub("<[^>]+>","",desc2)
349
-            desc2 = desc2.replace("\n"," ").replace("\t","")
350
-            desc = "%s\n%s"%(desc2,desc)
351
-            vid = m.group(1)
352
-
353
-        js = self.get_video_info(vid)
354
-        #for m in re.finditer(r"lang: '(?P<lang>\w+)',\s+src: '(?P<url>[^']+)',\s+type: '(?P<mime>[^']+)',\s+drm: \[(?P<drm>.+?)\]\s*\}", r, re.DOTALL):
355
-        if not js:
356
-            return []
357
-        tracks = js["tracks"]
358
-        #if not tracks["HLS"]:
359
-        #    raise Exception("Encrypted DASH playing not yet implemented")
360
-
361
-        captions = []
362
-        llist = ["fr","en","ru","lv"]
363
-        for st in js["plugins"]["settings"]["subtitles"]:
364
-            sub = {}
365
-            sub["url"] = st["src"]
366
-            sub["lang"] = st["srclang"]
367
-            sub["name"] = st["label"]
368
-            sub["type"] = "vtt"
369
-            sub["order"] = llist.index(sub["lang"])*10 if sub["lang"] in llist else 0
370
-            captions.append(sub)
371
-        captions = sorted(captions,key=lambda item: item["order"],reverse=True)
372
-
373
-        for s in tracks["HLS"] if tracks["HLS"]  else tracks["DASH"] :
374
-            stype = "DASH" if "dash" in s["type"] else "HLS"
375
-            if "drm" in s: ###
376
-                # TODO, encrypted stream
377
-                continue
378
-            url = s["src"]
379
-            #urlp = util.streamproxy_encode(s["src"])
380
-            stream = util.item()
381
-            stream["url"]=url
382
-            stream["resolver"] = "viaplay"
383
-            stream["lang"]=s["lang"]
384
-            stream["quality"]="variant"
385
-            stream["bitrate"]= "1000000"
386
-            stream["name"]= title
387
-            stream["desc"]=desc
388
-            stream["type"]=stype
389
-            stream["subs"] = captions
390
-            print url
391
-            if stype=="DASH": streams.append(stream)
392
-
393
-            if stype == "HLS": # izvelkam individuālos strimus
394
-                r = requests.get(url)
395
-                result = re.findall("#EXT-X-STREAM-INF:BANDWIDTH=(\d+),RESOLUTION=(\d+x\d+)\n(\w+.m3u8)", r.content)
396
-                if not result:
397
-                    continue
398
-                for s2 in result:
399
-                    ### TODO vajag lietot cookie ar tokenu no playlista requesta
400
-                    if "set-cookie" in r.headers:
401
-                        headers = {"Cookie":r.headers["set-cookie"]}
402
-                    else:
403
-                        headers={}
404
-                    #url2 = re.sub(r"(http.*://.+/)\w+.m3u8", r"\1"+s2[2], url)
405
-                    url2 = "/".join(url.split("/")[:-1])+"/"+s2[2]
406
-                    #r2 = requests.get(url2,headers=headers)
407
-                    #if "set-cookie" in r2.headers:
408
-                        #headers = {"Cookie":r2.headers["set-cookie"]}
409
-                    #else:
410
-                        #headers={}
411
-                    url2p=util.streamproxy_encode(url2,headers)
412
-                    stream = util.item()
413
-                    stream["url"]=url2p
414
-                    stream["lang"]=s["lang"]
415
-                    stream["quality"]="%s"%(s2[1])
416
-                    stream["name"]= title
417
-                    stream["desc"]=desc
418
-                    stream["bitrate"]=s2[0]
419
-                    stream["type"]="DASH" if "dash" in s["type"] else "HLS"
420
-                    streams.append(stream)
421
-
422
-        ### TODO - sakārtot sarakstu, lai pirmais ir labakais video
423
-        qlist = ["","512","640","758","1024","variant"]
424
-        llist = ["lt","et","fr","en","ru","lv"]
425
-        for s in streams:
426
-            lv = llist.index(s["lang"])*10000000 if s["lang"] in llist else 0
427
-            #qv=qlist.index(s["quality"]) if s["quality"] in qlist else 0
428
-            qv = int(s["bitrate"]) if s["bitrate"] else 0
429
-            s["order"] = lv+qv
430
-            #print s["lang"],s["quality"],s["bitrate"],s["order"]
431
-
432
-        streams = sorted(streams,key=lambda item: item["order"],reverse=True)
433
-        return streams
434
-
435
-    def call(self, data,params = None, headers=None):
436
-        if not headers: headers = self.headers
437
-        #if not lang: lang = self.country
438
-        url = "https://viaplay.lv/tdi/" + data
439
-        content = self._http_request(url, params, headers)
440
-        return content
441
-
442
-if __name__ == "__main__":
443
-    if len(sys.argv)>1:
444
-        data= sys.argv[1]
445
-    else:
446
-        data = "kids/child-and-karlson"
447
-    c = Source()
448
-    print "login: %s"%c.login()
449
-    if "/" in data:
450
-        streams = c.get_streams(data)
451
-        util.play_video(streams)
452
-    else:
453
-        vinfo = c.get_video_info(data)
454
-        if "HLS" in vinfo["tracks"] and vinfo["tracks"]["HLS"]:
455
-            url = vinfo["tracks"]["HLS"][0]["src"]
456
-            urlp = util.streamproxy_encode(url)
457
-            util.player(urlp)
458
-        else:
459
-            print "No HLS stream"
460
-    sys.exit()
461
-
462
-    r = requests.get("https://viaplay.lv/movies?sections[]=MOVIES")
463
-    result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<p class="promo-notice">([^<]+)<', r.content, re.DOTALL)
464
-    for item in result:
465
-        vid = item[0]
466
-        url = item[1]
467
-        img = item[2]
468
-        title = item[3]
469
-        desc= item[4]
470
-        print "\n%s (%s):"%(title,vid)
471
-        vinfo = c.get_video_info(vid)
472
-        if "HLS" in vinfo["tracks"]:
473
-            for s in vinfo["tracks"]["HLS"]:
474
-                print "HLS %s: \n%s"%(s["lang"],s["src"])
475
-
476
-        if "DASH" in vinfo["tracks"]:
477
-            for s in vinfo["tracks"]["DASH"]:
478
-                print "DASH %s: \n%s"%(s["lang"],s["src"])
479
-        #except Exception,ex:
480
-            #print ex.message
481
-    #content = c.get_content(data)
482
-    #for item in content:
483
-    #    print item
484
-    pass

+ 0
- 149
resources/lib/sources0/SourceBase.py View File

@@ -1,149 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-
9
-import urllib2, urllib
10
-import datetime, re, sys,os
11
-import requests
12
-from collections import OrderedDict
13
-import ConfigParser
14
-try:
15
-    import util
16
-except:
17
-    parent = os.path.dirname(os.path.abspath(__file__))
18
-    parent = os.sep.join(parent.split(os.sep)[:-1])
19
-    sys.path.insert(0,parent)
20
-    import util
21
-
22
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
23
-
24
-class SourceBase(object):
25
-    """Stream source base class"""
26
-
27
-    def __init__(self,country="lv"):
28
-        self.name = "name"
29
-        self.title = "Title"
30
-        self.img = ""
31
-        self.desc = ""
32
-        self.options = OrderedDict()
33
-        self.config_file = ""
34
-        self.url = "http://www.bbb.com/"
35
-        self.headers = headers2dict("""
36
-User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
37
-""")
38
-
39
-    def login(self,user="",password=""):
40
-        return False
41
-
42
-    def logout(self):
43
-        return True
44
-
45
-    def get_content(self,data):
46
-        ### To be overriden in child class
47
-        return [("..atpakaļ","back",None,"Kļūda, atgriezties atpakaļ")]
48
-
49
-    def is_video(self,data):
50
-        ### To be overriden in child class
51
-        return False
52
-
53
-    def get_streams(self,data):
54
-        ### Normally to be overrided in child class
55
-
56
-        if not self.is_video(data):
57
-            return []
58
-        content = self.get_content(data)
59
-        stream = util.item()
60
-        stream["name"] = content[0].encode("utf8") if isinstance(content[0],unicode) else content[0]
61
-        stream["url"] = content[1].encode("utf8") if isinstance(content[1],unicode) else content[1]
62
-        stream["img"] = content[2].encode("utf8") if isinstance(content[2],unicode) else content[2]
63
-        stream["desc"] = content[3].encode("utf8") if isinstance(content[3],unicode) else content[3]
64
-        stream["type"] = stream_type(content[1]).encode("utf8")
65
-        return[stream]
66
-
67
-    def options_read(self):
68
-        if not ("options" in dir(self) and self.options): # process options only if self.options defined, self.config_file should be defined too
69
-            return None
70
-        config = ConfigParser.ConfigParser()
71
-        if os.path.exists(self.config_file):
72
-            config.read(self.config_file)
73
-            self.options = OrderedDict(config.items(self.name))
74
-        else:
75
-            self.options_write(self.options)
76
-        return self.options
77
-
78
-    def options_write(self,options):
79
-        config = ConfigParser.ConfigParser()
80
-        config.add_section(self.name)
81
-        for k in options.keys():
82
-            config.set(self.name, k,options[k])
83
-        with open(self.config_file,"w") as f:
84
-            config.write(f)
85
-        self.options = OrderedDict(config.items(self.name))
86
-
87
-    def call(self, data,params=None,headers=None,lang=""):
88
-        if not headers: headers = self.headers
89
-        url = self.url+data
90
-        result = self._http_request(url,params,headers=headers)
91
-        return result
92
-
93
-    def call_json(self, data,params=None,headers=None,lang=""):
94
-        result = self.call(url,params,headers=headers)
95
-        if result:
96
-            result = json.loads(content)
97
-            return result
98
-        else:
99
-            raise "No data returned"
100
-
101
-    def _http_request(self, url,params = None, headers=None):
102
-        if not headers:
103
-            headers = self.headers if "headers" in dir(self) else headers2dict("User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0")
104
-        try:
105
-            if params:
106
-                r = requests.post(url, data=params, headers=headers)
107
-            else:
108
-                r = requests.get(url, headers=headers)
109
-            return r.content
110
-        except Exception as ex:
111
-            if "read" in ex:
112
-                content = ex.read()
113
-            else:
114
-                content = None
115
-            return content
116
-
117
-    @staticmethod
118
-    def stream_type(data):
119
-        return stream_type(data)
120
-
121
-    @staticmethod
122
-    def parse_data(data):
123
-        if "::" in data:
124
-            source = data.split("::")[0]
125
-            data = data.split("::")[1]
126
-        else:
127
-            source = ""
128
-        path = data.split("?")[0]
129
-        plist = path.split("/")
130
-        clist = plist[0]
131
-        params = data[data.find("?"):] if "?" in data else ""
132
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
133
-        return source,data,path,plist,clist,params,qs
134
-
135
-def stream_type(data):
136
-    if "::" in data:
137
-        data = data.split("::")[1]
138
-    data = data.lower()
139
-    m = re.search(r"^(\w+)://", data)
140
-    prefix = m.group(1) if m else ""
141
-    if prefix in ("http","https") and "m3u8" in data:
142
-        return "hls"
143
-    elif prefix == "http":
144
-        return "http"
145
-    else:
146
-        return prefix
147
-
148
-if __name__ == "__main__":
149
-    pass

+ 0
- 404
resources/lib/sources0/YouTubeVideoUrl.py View File

@@ -1,404 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# This video extraction code based on youtube-dl: https://github.com/rg3/youtube-dl
3
-
4
-import codecs
5
-import json
6
-import re
7
-
8
-from urllib import urlencode
9
-from urllib2 import urlopen, URLError
10
-import sys
11
-
12
-#from Components.config import config
13
-
14
-#from . import sslContext
15
-sslContext = None
16
-if sys.version_info >= (2, 7, 9):
17
-	try:
18
-		import ssl
19
-		sslContext = ssl._create_unverified_context()
20
-	except:
21
-		pass 
22
-from jsinterp import JSInterpreter
23
-from swfinterp import SWFInterpreter
24
-
25
-
26
-PRIORITY_VIDEO_FORMAT = []
27
-maxResolution =  '22'
28
-
29
-
30
-def createPriorityFormats():
31
-	global PRIORITY_VIDEO_FORMAT,maxResolution
32
-	PRIORITY_VIDEO_FORMAT = []
33
-	use_format = False
34
-	for itag_value in ['38', '37', '96', '22', '95', '120',
35
-		'35', '94', '18', '93', '5', '92', '132', '17']:
36
-		if itag_value == maxResolution: #config.plugins.YouTube.maxResolution.value:
37
-			use_format = True
38
-		if use_format:
39
-			PRIORITY_VIDEO_FORMAT.append(itag_value)
40
-
41
-createPriorityFormats()
42
-
43
-IGNORE_VIDEO_FORMAT = [
44
-		'43',  # webm
45
-		'44',  # webm
46
-		'45',  # webm
47
-		'46',  # webm
48
-		'100',  # webm
49
-		'101',  # webm
50
-		'102'  # webm
51
-	]
52
-
53
-
54
-def uppercase_escape(s):
55
-	unicode_escape = codecs.getdecoder('unicode_escape')
56
-	return re.sub(
57
-		r'\\U[0-9a-fA-F]{8}',
58
-		lambda m: unicode_escape(m.group(0))[0],
59
-		s)
60
-
61
-
62
-def compat_urllib_parse_unquote(string, encoding='utf-8', errors='replace'):
63
-	if string == '':
64
-		return string
65
-	res = string.split('%')
66
-	if len(res) == 1:
67
-		return string
68
-	if encoding is None:
69
-		encoding = 'utf-8'
70
-	if errors is None:
71
-		errors = 'replace'
72
-	# pct_sequence: contiguous sequence of percent-encoded bytes, decoded
73
-	pct_sequence = b''
74
-	string = res[0]
75
-	for item in res[1:]:
76
-		try:
77
-			if not item:
78
-				raise ValueError
79
-			pct_sequence += item[:2].decode('hex')
80
-			rest = item[2:]
81
-			if not rest:
82
-				# This segment was just a single percent-encoded character.
83
-				# May be part of a sequence of code units, so delay decoding.
84
-				# (Stored in pct_sequence).
85
-				continue
86
-		except ValueError:
87
-			rest = '%' + item
88
-		# Encountered non-percent-encoded characters. Flush the current
89
-		# pct_sequence.
90
-		string += pct_sequence.decode(encoding, errors) + rest
91
-		pct_sequence = b''
92
-	if pct_sequence:
93
-		# Flush the final pct_sequence
94
-		string += pct_sequence.decode(encoding, errors)
95
-	return string
96
-
97
-
98
-def _parse_qsl(qs, keep_blank_values=False, strict_parsing=False,
99
-			encoding='utf-8', errors='replace'):
100
-	qs, _coerce_result = qs, unicode
101
-	pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
102
-	r = []
103
-	for name_value in pairs:
104
-		if not name_value and not strict_parsing:
105
-			continue
106
-		nv = name_value.split('=', 1)
107
-		if len(nv) != 2:
108
-			if strict_parsing:
109
-				raise ValueError("bad query field: %r" % (name_value,))
110
-			# Handle case of a control-name with no equal sign
111
-			if keep_blank_values:
112
-				nv.append('')
113
-			else:
114
-				continue
115
-		if len(nv[1]) or keep_blank_values:
116
-			name = nv[0].replace('+', ' ')
117
-			name = compat_urllib_parse_unquote(
118
-				name, encoding=encoding, errors=errors)
119
-			name = _coerce_result(name)
120
-			value = nv[1].replace('+', ' ')
121
-			value = compat_urllib_parse_unquote(
122
-				value, encoding=encoding, errors=errors)
123
-			value = _coerce_result(value)
124
-			r.append((name, value))
125
-	return r
126
-
127
-
128
-def compat_parse_qs(qs, keep_blank_values=False, strict_parsing=False,
129
-					encoding='utf-8', errors='replace'):
130
-	parsed_result = {}
131
-	pairs = _parse_qsl(qs, keep_blank_values, strict_parsing,
132
-					encoding=encoding, errors=errors)
133
-	for name, value in pairs:
134
-		if name in parsed_result:
135
-			parsed_result[name].append(value)
136
-		else:
137
-			parsed_result[name] = [value]
138
-	return parsed_result
139
-
140
-
141
-class YouTubeVideoUrl():
142
-
143
-	def _download_webpage(self, url):
144
-		""" Returns a tuple (page content as string, URL handle) """
145
-		try:
146
-			if sslContext:
147
-				urlh = urlopen(url, context = sslContext)
148
-			else:
149
-				urlh = urlopen(url)
150
-		except URLError, e:
151
-			#raise Exception(e.reason)
152
-			return ""
153
-		return urlh.read()
154
-
155
-	def _search_regex(self, pattern, string):
156
-		"""
157
-		Perform a regex search on the given string, using a single or a list of
158
-		patterns returning the first matching group.
159
-		"""
160
-		mobj = re.search(pattern, string, 0)
161
-		if mobj:
162
-			# return the first matching group
163
-			return next(g for g in mobj.groups() if g is not None)
164
-		else:
165
-			raise Exception('Unable extract pattern from string!')
166
-
167
-	def _decrypt_signature(self, s, player_url):
168
-		"""Turn the encrypted s field into a working signature"""
169
-
170
-		if player_url is None:
171
-			raise Exception('Cannot decrypt signature without player_url!')
172
-
173
-		if player_url[:2] == '//':
174
-			player_url = 'https:' + player_url
175
-		try:
176
-			func = self._extract_signature_function(player_url)
177
-			return func(s)
178
-		except:
179
-			raise Exception('Signature extraction failed!')
180
-
181
-	def _extract_signature_function(self, player_url):
182
-		id_m = re.match(
183
-			r'.*?-(?P<id>[a-zA-Z0-9_-]+)(?:/watch_as3|/html5player(?:-new)?|/base)?\.(?P<ext>[a-z]+)$',
184
-			player_url)
185
-		if not id_m:
186
-			raise Exception('Cannot identify player %r!' % player_url)
187
-		player_type = id_m.group('ext')
188
-		code = self._download_webpage(player_url)
189
-		if player_type == 'js':
190
-			return self._parse_sig_js(code)
191
-		elif player_type == 'swf':
192
-			return self._parse_sig_swf(code)
193
-		else:
194
-			raise Exception('Invalid player type %r!' % player_type)
195
-
196
-	def _parse_sig_js(self, jscode):
197
-		funcname = self._search_regex(r'\.sig\|\|([a-zA-Z0-9$]+)\(', jscode)
198
-		jsi = JSInterpreter(jscode)
199
-		initial_function = jsi.extract_function(funcname)
200
-		return lambda s: initial_function([s])
201
-
202
-	def _parse_sig_swf(self, file_contents):
203
-		swfi = SWFInterpreter(file_contents)
204
-		TARGET_CLASSNAME = 'SignatureDecipher'
205
-		searched_class = swfi.extract_class(TARGET_CLASSNAME)
206
-		initial_function = swfi.extract_function(searched_class, 'decipher')
207
-		return lambda s: initial_function([s])
208
-
209
-	def _extract_from_m3u8(self, manifest_url):
210
-		url_map = {}
211
-
212
-		def _get_urls(_manifest):
213
-			lines = _manifest.split('\n')
214
-			urls = filter(lambda l: l and not l.startswith('#'), lines)
215
-			return urls
216
-
217
-		manifest = self._download_webpage(manifest_url)
218
-		formats_urls = _get_urls(manifest)
219
-		for format_url in formats_urls:
220
-			itag = self._search_regex(r'itag/(\d+?)/', format_url)
221
-			url_map[itag] = format_url
222
-		return url_map
223
-
224
-	def _get_ytplayer_config(self, webpage):
225
-		# User data may contain arbitrary character sequences that may affect
226
-		# JSON extraction with regex, e.g. when '};' is contained the second
227
-		# regex won't capture the whole JSON. Yet working around by trying more
228
-		# concrete regex first keeping in mind proper quoted string handling
229
-		# to be implemented in future that will replace this workaround (see
230
-		# https://github.com/rg3/youtube-dl/issues/7468,
231
-		# https://github.com/rg3/youtube-dl/pull/7599)
232
-		patterns = [
233
-			r';ytplayer\.config\s*=\s*({.+?});ytplayer',
234
-			r';ytplayer\.config\s*=\s*({.+?});',
235
-		]
236
-		for pattern in patterns:
237
-			config = self._search_regex(pattern, webpage)
238
-			if config:
239
-				return json.loads(uppercase_escape(config))
240
-
241
-	def extract(self, video_id):
242
-		url = 'https://www.youtube.com/watch?v=%s&gl=US&hl=en&has_verified=1&bpctr=9999999999' % video_id
243
-
244
-		# Get video webpage
245
-		video_webpage = self._download_webpage(url)
246
-		if not video_webpage:
247
-			#raise Exception('Video webpage not found!')
248
-			return ""
249
-
250
-		# Attempt to extract SWF player URL
251
-		mobj = re.search(r'swfConfig.*?"(https?:\\/\\/.*?watch.*?-.*?\.swf)"', video_webpage)
252
-		if mobj is not None:
253
-			player_url = re.sub(r'\\(.)', r'\1', mobj.group(1))
254
-		else:
255
-			player_url = None
256
-
257
-		# Get video info
258
-		embed_webpage = None
259
-		if re.search(r'player-age-gate-content">', video_webpage) is not None:
260
-			age_gate = True
261
-			# We simulate the access to the video from www.youtube.com/v/{video_id}
262
-			# this can be viewed without login into Youtube
263
-			url = 'https://www.youtube.com/embed/%s' % video_id
264
-			embed_webpage = self._download_webpage(url)
265
-			data = urlencode({
266
-				'video_id': video_id,
267
-				'eurl': 'https://youtube.googleapis.com/v/' + video_id,
268
-				'sts': self._search_regex(r'"sts"\s*:\s*(\d+)', embed_webpage),
269
-			})
270
-			video_info_url = 'https://www.youtube.com/get_video_info?' + data
271
-			video_info_webpage = self._download_webpage(video_info_url)
272
-			video_info = compat_parse_qs(video_info_webpage)
273
-		else:
274
-			age_gate = False
275
-			video_info = None
276
-			# Try looking directly into the video webpage
277
-			ytplayer_config = self._get_ytplayer_config(video_webpage)
278
-			if ytplayer_config:
279
-				args = ytplayer_config['args']
280
-				if args.get('url_encoded_fmt_stream_map'):
281
-					# Convert to the same format returned by compat_parse_qs
282
-					video_info = dict((k, [v]) for k, v in args.items())
283
-
284
-			if not video_info:
285
-				# We also try looking in get_video_info since it may contain different dashmpd
286
-				# URL that points to a DASH manifest with possibly different itag set (some itags
287
-				# are missing from DASH manifest pointed by webpage's dashmpd, some - from DASH
288
-				# manifest pointed by get_video_info's dashmpd).
289
-				# The general idea is to take a union of itags of both DASH manifests (for example
290
-				# video with such 'manifest behavior' see https://github.com/rg3/youtube-dl/issues/6093)
291
-				for el_type in ['&el=info', '&el=embedded', '&el=detailpage', '&el=vevo', '']:
292
-					video_info_url = (
293
-						'https://www.youtube.com/get_video_info?&video_id=%s%s&ps=default&eurl=&gl=US&hl=en'
294
-						% (video_id, el_type))
295
-					video_info_webpage = self._download_webpage(video_info_url)
296
-					video_info = compat_parse_qs(video_info_webpage)
297
-					if 'token' in video_info:
298
-						break
299
-		if 'token' not in video_info:
300
-			if 'reason' in video_info:
301
-				print '[YouTubeVideoUrl] %s' % video_info['reason'][0]
302
-			else:
303
-				print '[YouTubeVideoUrl] "token" parameter not in video info for unknown reason'
304
-
305
-		# Start extracting information
306
-		if 'conn' in video_info and video_info['conn'][0][:4] == 'rtmp':
307
-			url = video_info['conn'][0]
308
-		elif len(video_info.get('url_encoded_fmt_stream_map', [''])[0]) >= 1 or \
309
-			len(video_info.get('adaptive_fmts', [''])[0]) >= 1:
310
-			encoded_url_map = video_info.get('url_encoded_fmt_stream_map', [''])[0] + \
311
-				',' + video_info.get('adaptive_fmts', [''])[0]
312
-			if 'rtmpe%3Dyes' in encoded_url_map:
313
-				raise Exception('rtmpe downloads are not supported, see https://github.com/rg3/youtube-dl/issues/343')
314
-
315
-			# Find the best format from our format priority map
316
-			encoded_url_map = encoded_url_map.split(',')
317
-			url_map_str = None
318
-			# If format changed in config, recreate priority list
319
-			if PRIORITY_VIDEO_FORMAT[0] != maxResolution: #config.plugins.YouTube.maxResolution.value:
320
-				createPriorityFormats()
321
-			for our_format in PRIORITY_VIDEO_FORMAT:
322
-				our_format = 'itag=' + our_format
323
-				for encoded_url in encoded_url_map:
324
-					if our_format in encoded_url and 'url=' in encoded_url:
325
-						url_map_str = encoded_url
326
-						break
327
-				if url_map_str:
328
-					break
329
-			# If anything not found, used first in the list if it not in ignore map
330
-			if not url_map_str:
331
-				for encoded_url in encoded_url_map:
332
-					if 'url=' in encoded_url:
333
-						url_map_str = encoded_url
334
-						for ignore_format in IGNORE_VIDEO_FORMAT:
335
-							ignore_format = 'itag=' + ignore_format
336
-							if ignore_format in encoded_url:
337
-								url_map_str = None
338
-								break
339
-					if url_map_str:
340
-						break
341
-			if not url_map_str:
342
-				url_map_str = encoded_url_map[0]
343
-
344
-			url_data = compat_parse_qs(url_map_str)
345
-			url = url_data['url'][0]
346
-			if 'sig' in url_data:
347
-				url += '&signature=' + url_data['sig'][0]
348
-			elif 's' in url_data:
349
-				encrypted_sig = url_data['s'][0]
350
-				ASSETS_RE = r'"assets":.+?"js":\s*("[^"]+")'
351
-
352
-				jsplayer_url_json = self._search_regex(ASSETS_RE,
353
-					embed_webpage if age_gate else video_webpage)
354
-				if not jsplayer_url_json and not age_gate:
355
-					# We need the embed website after all
356
-					if embed_webpage is None:
357
-						embed_url = 'https://www.youtube.com/embed/%s' % video_id
358
-						embed_webpage = self._download_webpage(embed_url)
359
-					jsplayer_url_json = self._search_regex(ASSETS_RE, embed_webpage)
360
-
361
-				player_url = json.loads(jsplayer_url_json)
362
-				if player_url is None:
363
-					player_url_json = self._search_regex(
364
-						r'ytplayer\.config.*?"url"\s*:\s*("[^"]+")',
365
-						video_webpage)
366
-					player_url = json.loads(player_url_json)
367
-
368
-				signature = self._decrypt_signature(encrypted_sig, player_url)
369
-				url += '&signature=' + signature
370
-			if 'ratebypass' not in url:
371
-				url += '&ratebypass=yes'
372
-		elif video_info.get('hlsvp'):
373
-			url = None
374
-			manifest_url = video_info['hlsvp'][0]
375
-			url_map = self._extract_from_m3u8(manifest_url)
376
-
377
-			# Find the best format from our format priority map
378
-			for our_format in PRIORITY_VIDEO_FORMAT:
379
-				if url_map.get(our_format):
380
-					url = url_map[our_format]
381
-					break
382
-			# If anything not found, used first in the list if it not in ignore map
383
-			if not url:
384
-				for url_map_key in url_map.keys():
385
-					if url_map_key not in IGNORE_VIDEO_FORMAT:
386
-						url = url_map[url_map_key]
387
-						break
388
-			if not url:
389
-				url = url_map.values()[0]
390
-		else:
391
-			#raise Exception('No supported formats found in video info!')
392
-			return ""
393
-
394
-		return str(url)
395
-
396
-if __name__ == "__main__":
397
-
398
-	#yt = YouTubeVideoUrl()
399
-	if len(sys.argv)>1:
400
-		video_id= sys.argv[1]
401
-	else:
402
-		video_id = "2rlTF6HiMGg"
403
-	e = YouTubeVideoUrl().extract(video_id)
404
-	print e

+ 0
- 0
resources/lib/sources0/__init__.py View File


+ 0
- 209
resources/lib/sources0/cinemalive.py View File

@@ -1,209 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-import urllib2, urllib
13
-import datetime, re, sys,os
14
-import ConfigParser
15
-from SourceBase import SourceBase
16
-#from collections import OrderedDict
17
-import os
18
-
19
-#sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 
20
-from resolver import resolve
21
-import util
22
-
23
-
24
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
25
-import HTMLParser
26
-h = HTMLParser.HTMLParser()
27
-    
28
-class Source(SourceBase):
29
-    
30
-    def __init__(self,country=""):
31
-        self.name = "cinemalive"
32
-        self.title = "cinemalive.tv"
33
-        self.img = "picons/cinemalive.png" #"https://cinemalive.tv/assets/img/logo.png"
34
-        self.desc = "cinemalive.tv satura skatīšanās"
35
-        self.country=country
36
-        self.headers = headers2dict("""
37
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
38
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
39
-""")
40
-        self.headers2 = headers2dict("""
41
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
42
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
43
-Accept-Language: en-US,en;q=0.8
44
-""")
45
-        self.url = "https://cinemalive.tv/"
46
-        #self.login()
47
-        
48
-            
49
-    ######### Entry point ########
50
-    def get_content(self, data):
51
-        print "[cinemalive] get_content:", data
52
-        source,data,path,plist,clist,params,qs = self.parse_data(data)     
53
-        content=[]
54
-        content.append(("..return", "back","","Return back"))
55
-        
56
-        if clist=="home":
57
-            content.extend([
58
-                ("Search", "cinemalive::scripts/search.php?search={0}","","Search"),            
59
-                ("Filmas latviski - visas", "cinemalive::filmaslatviski/visas/lapa/1","","Filmas latviski - visas"),
60
-                ("Filmas angliski", "cinemalive::home_en","","Filmas angliski"),
61
-                ("Filmas latviski - jaunākās", "cinemalive::filmaslatviski/jaunakas/lapa/1","","Filmas latviski - jaunākās"),
62
-                ("Filmas latviski - vertētākās", "cinemalive::filmaslatviski/vertetakas/lapa/1","","Filmas latviski - vērtētākās"),
63
-                ("Filmas latviski - skatitakās", "cinemalive::filmaslatviski/skatitakas/lapa/1","","Filmas latviski - skatītākās"),
64
-            ])
65
-            r = self.call("filmaslatviski")
66
-            for item in re.findall(r'<li class="nav-submenu-item"><a href="/([\w/]+)">(.+?)</a></li>', r):
67
-                title = "Filmas latviski - "+item[1]
68
-                data2 = item[0]+"/lapa/1"
69
-                img = self.img
70
-                desc = title
71
-                content.append((title,self.name+"::"+data2,img,desc))      
72
-            return content
73
-
74
-        elif clist=="home_en":
75
-            content.extend([
76
-                ("Search", "cinemalive::scripts/search.php?search={0}","","Search"),            
77
-                ("Movies English - all", "cinemalive::moviesenglish/all/page/1","","Movies English - all"),
78
-                ("Movies Latvian", "cinemalive::home","","Filmas latviski"),
79
-                ("Movies English - newest", "cinemalive::moviesenglish/newestmovies/page/1","","Movies English - newest"),
80
-                ("Movies English - top rated", "cinemalive::moviesenglish/toprated/page/1","","Movies English - top rated"),
81
-                ("Movies English - most watched", "cinemalive::moviesenglish/mostwatched/page/1","","Movies English - most watched"),
82
-            ])
83
-            r = self.call("moviesenglish")
84
-            for item in re.findall(r'<li class="nav-submenu-item"><a href="/([\w/]+)">(.+?)</a></li>', r):
85
-                title = "Movies English - "+item[1]
86
-                data2 = item[0]+"/page/1"
87
-                img = self.img
88
-                desc = title
89
-                content.append((title,self.name+"::"+data2,img,desc))      
90
-            return content
91
-
92
-    
93
-        elif "search.php" in data:
94
-            
95
-            r=self.call(path,params=params[1:],headers=self.headers2)
96
-            result = re.findall(r'<div class="results.+?<a href="https://cinemalive\.tv/(.+?)">.+?<img src="(.+?)".+?<span style="color:#bcbcbc">([^<]+)</span> <span style="color:#5a606d;font-size:12px;">([^<]+)</span><br/>.+?<p class="dec" style="font-size:12px; color:#777;line-height:14px;">([^<]+)</p>', r, re.DOTALL)            
97
-            for item in result:
98
-                title = item[2]
99
-                title0 = re.sub(" \(\d+\)","",title)
100
-                if title0 == item[3]:
101
-                    title = title+" [EN]"
102
-                else:
103
-                    title = title + "/"+ item[3]+" [LV]"
104
-                title = util.unescape(title)
105
-                data2 = item[0]
106
-                img = item[1].replace("xs.","sm.")
107
-                desc = util.unescape(item[4])
108
-                content.append((title,self.name+"::"+data2,img,desc))            
109
-            return content
110
-
111
-        elif clist in ("filmaslatviski","moviesenglish"):
112
-            r = self.call(data)
113
-            if not r:
114
-                return content
115
-            result = re.findall(r'<div class="base-used">.+?<a href="https://cinemalive.tv/([^"]+)">.+?<img class="img-thumbnail" src="/([^"]+)" alt="([^"]+)"/>.+?<p class="year">(\d+)</p>', r, re.DOTALL)
116
-            for item in result:
117
-                title = item[2] + " (%s)"%item[3]
118
-                data2 = item[0]
119
-                img = "https://cinemalive.tv/"+item[1]
120
-                title = util.unescape(title)
121
-                desc = title
122
-                content.append((title,self.name+"::"+data2,img,desc)) 
123
-            m = re.search(r"""<a href='https://cinemalive\.tv/([^']+)' style="border-right:none;">»</a>""", r, re.DOTALL)
124
-            if m:
125
-                data2 = m.group(1)
126
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))                                  
127
-            return content      
128
-         
129
-        else:
130
-            return content                            
131
-              
132
-    def is_video(self,data):
133
-        source,data,path,plist,clist,params,qs = self.parse_data(data)        
134
-        if clist=="movie":
135
-            return True
136
-        else:
137
-            return False
138
-                        
139
-    def get_streams(self, data):
140
-        print "[cinemalive] get_streams:", data
141
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
142
-        r = self.call(path)
143
-        if not r:
144
-            return []
145
-        streams = []
146
-        title0 = re.search("<title>([^<]+)</title>", r).group(1)
147
-        lang = "LV" if "Filma Online Latviski" in title0 else "EN"
148
-        title = title0.replace(" - Filma Online Latviski","").replace(" - Movie Online English HD","")
149
-        desc = re.search('<p class="plot">(.+?)</p>', r).group(1)
150
-        img = "http://cinemalive.tv"+re.search('<img src="(.+?)" class="img-thumbnail"', r).group(1)
151
-        
152
-        m = re.search(r'<video id=.+?<source src="([^"]+\.mp4)"', r, re.DOTALL)
153
-        if m:
154
-            s = util.item()
155
-            s["url"] = m.group(1)
156
-            s["name"] = util.unescape(title)
157
-            s["desc"] = util.unescape(desc)
158
-            s["img"] = img
159
-            s["type"] = self.stream_type(s["url"])
160
-            s["lang"] = lang 
161
-            return [s]
162
-        
163
-        #m = re.search('<div class="viboom-overroll"><iframe src="([^"]+)"', r)
164
-        #if m:
165
-        result = re.findall('<div id="video_container"><iframe src="(.+?)"', r)
166
-        if result:
167
-            streams = resolve(result[0])
168
-            for s in streams:
169
-                s["name"] = util.unescape(title)
170
-                s["desc"] = util.unescape(desc)
171
-                s["img"] = img
172
-                s["type"] = self.stream_type(s["url"])
173
-                s["lang"] = lang
174
-            if len(result)>1:
175
-                lang2 = "EN" if lang=="LV" else "LV"
176
-                streams2 = resolve(result[1])
177
-                for s in streams2:
178
-                    s["name"] = util.unescape(title)
179
-                    s["desc"] = util.unescape(desc)
180
-                    s["img"] = img
181
-                    s["type"]= self.stream_type(s["url"])
182
-                    s["lang"] = lang2
183
-                    streams.append(s)  
184
-            return streams
185
-        else:
186
-            return []
187
-
188
-                    
189
-if __name__ == "__main__":
190
-    country= "lv"
191
-    c = Source(country)
192
-    if len(sys.argv)>1:
193
-        data= sys.argv[1]
194
-    else:
195
-        data = "home"
196
-    content = c.get_content(data)
197
-    for item in content:
198
-        print item
199
-    #cat = api.get_categories(country)
200
-    #chan = api.get_channels("lv")
201
-    #prog = api.get_programs(channel=6400)
202
-    #prog = api.get_programs(category=55)
203
-    #seas = api.get_seasons(program=6453)
204
-    #str = api.get_streams(660243)
205
-    #res = api.get_videos(802)
206
-    #formats = api.getAllFormats()
207
-    #det = api.detailed("1516")
208
-    #vid = api.getVideos("13170")
209
-    pass

+ 0
- 99
resources/lib/sources0/config.py View File

@@ -1,99 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-import os.path,re
9
-import collections
10
-from SourceBase import SourceBase
11
-
12
-os.path.dirname(os.path.abspath(__file__))
13
-class Source(SourceBase):
14
-    
15
-    def __init__(self,country="lv"):
16
-        self.name = "config"
17
-        self.country=country
18
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
19
-        self.streams_file = os.path.join(cur_directory,"streams.cfg")
20
-        self.lists = collections.OrderedDict()
21
-        self.read_streams()
22
-         
23
-    def get_content(self, data):
24
-        self.read_streams()
25
-        if "::" in data:
26
-            data = data.split("::")[1]
27
-        if not data in self.lists:
28
-            return []
29
-        return self.lists[data]
30
-
31
-    def is_video(self,data):
32
-        return False
33
-    
34
-    def read_streams(self):
35
-        for line in open(self.streams_file,"r"):
36
-            r = re.search("^\[(\w+)\]", line)
37
-            if r:
38
-                name = r.group(1)
39
-                self.lists[name] = []
40
-            else:
41
-                if len(line)<10 or line[0] in ("#"): continue
42
-                items = tuple(line.strip().split("|"))
43
-                if len(items)<2:
44
-                    continue
45
-                self.lists[name].append(items)
46
-                
47
-    def write_streams(self):
48
-        f = open(self.streams_file,"w")
49
-        for l in self.lists.keys():
50
-            f.write("[%s]\n"%l)
51
-            for item in self.lists[l]:
52
-                f.write("%s|%s|%s|%s\n"%(item[0],item[1],item[2],item[3]))
53
-            f.write("\n")
54
-        f.close()
55
-    
56
-    def get_lists(self):
57
-        return self.lists.keys()
58
-    
59
-    def get_list_items(self,name):
60
-        return self.lists[name]
61
-    
62
-    def add_list(self,name):
63
-        if not name in self.lists.keys():
64
-            self.lists[name] = []
65
-            
66
-    def del_list(self,name):
67
-        if name in self.lists.keys():
68
-            del self.lists[name]
69
-            
70
-    def add_item(self,name,item,pos=None):
71
-        if name in self.lists.keys():
72
-            if pos==None:
73
-                self.lists[name].append(item)
74
-            else:
75
-                self.lists[name].insert(pos,item)
76
-                
77
-    def del_item(self,name,pos):
78
-        self.lists[name].pop(pos)
79
-    
80
-    def replace_item(self,name,item,pos):
81
-        self.lists[name][pos]=item
82
-            
83
-                           
84
-if __name__ == "__main__":
85
-    c = Source()
86
-    content = c.get_content("home")
87
-    for item in content: print item
88
-    #c.del_item("home",0)
89
-    #c.del_list("favorites")
90
-    
91
-    #c.add_item("home",("My Streams","config::favorites","","Mani saglabātie TV kanāli un video"),0)
92
-    c.replace_item("home",("My Streams","config::my_streams","default","Mani saglabātie TV kanāli un video"),0)
93
-    #c.add_list("favorites")
94
-    #c.add_item("favorites",("..return","back","","Atgriezties atpakaļ"))    
95
-    #c.add_item("favorites",("LTV1","http://streamltv.cloudy.services/ltv/LTV02.smil/playlist.m3u8","picons/latvia1.png", "Latvijas televīzijas 1.kanāls"))
96
-    
97
-    c.write_streams()
98
-    for item in content: print item
99
-    

+ 0
- 3
resources/lib/sources0/euronews.cfg View File

@@ -1,3 +0,0 @@
1
-[euronews]
2
-language = en
3
-

+ 0
- 287
resources/lib/sources0/euronews.py View File

@@ -1,287 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, time,re, sys,os
15
-from collections import OrderedDict
16
-from SourceBase import SourceBase
17
-import util
18
-
19
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
20
-import HTMLParser
21
-h = HTMLParser.HTMLParser()
22
-
23
-class Source(SourceBase):
24
-
25
-    def __init__(self,language="en"):
26
-        self.name = "euronews"
27
-        self.title = "Euronews"
28
-        self.img = "http://pbs.twimg.com/profile_images/732665354242150400/tZsCnjuh_400x400.jpg"
29
-        self.desc = "Euronews live and archive"
30
-        self.headers = headers2dict("""
31
-User-Agent: Euronews/4.0.126
32
-Content-Type: application/json
33
-Connection: keep-alive
34
-        """)
35
-        #self.language=language
36
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
37
-        self.config_file = os.path.join(cur_directory,self.name+".cfg")
38
-        self.options = OrderedDict([("language","en")])
39
-        self.options_read()
40
-        self.vid={"1": "News", "2": "European Affairs", "3": "Lifestyle", "4": "Knowledge"}
41
-        self.languages = []
42
-        try:
43
-            self.get_languages()
44
-        except:
45
-            pass
46
-
47
-    def login(self,user="",password=""):
48
-        return True
49
-
50
-    def get_content(self, data):
51
-        print "[%s] get_content:"%self.name, data
52
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
53
-        #lang = qs["lang"] if "lang" in qs else self.language
54
-        lang = self.options["language"]
55
-        if not lang in self.get_languages():
56
-            raise Exception("Not valid default language - '%s'"%lang)
57
-
58
-        content=[]
59
-        content.append(("..return", "back","","Return back"))
60
-
61
-        if clist=="home":
62
-            content.extend([
63
-                ("Search", "euronews::content/getSearch?lang=%s&byPage=40&page=1&text={0}"%lang,self.img,"Top stories timeline"),
64
-                ("Live stream", "euronews::live?lang=%s"%lang,self.img,"Euronews live stream"),
65
-                ("Just in", "euronews::content/getTimeline?lang=%s&byPage=40&page=1"%lang,self.img,"News timeline"),
66
-                ("Top stories", "euronews::content/getTopStories?lang=%s"%lang,self.img,"Top stories timeline"),
67
-                ("Category - News", "euronews::content/getVertical?lang=%s&byPage=40&page=1&vId=1"%lang,self.img,"Category - News"),
68
-                ("Category - European Affairs", "euronews::content/getVertical?lang=%s&byPage=40&page=1&vId=2"%lang,self.img,"Category - European Affairs"),
69
-                ("Category - Lifestyle", "euronews::content/getVertical?lang=%s&byPage=40&page=1&vId=3"%lang,self.img,"Category - Lifestyle"),
70
-                ("Category - Knowledge", "euronews::content/getVertical?lang=%s&byPage=40&page=1&vId=4"%lang,self.img,"Category - Knowledge"),
71
-                ("Latest programs", "euronews::content/getLatestPrograms?lang=%s&byPage=40&page=1"%lang,self.img,"Latest programs"),
72
-                ("Programs list", "euronews::content/getPrograms?lang=%s"%lang,self.img,"Programs list"),
73
-             ])
74
-            return content
75
-
76
-
77
-        ### Video arhīvs ###
78
-        elif clist=="content":
79
-            if "lang" in qs:
80
-                del qs["lang"]
81
-            params = json.dumps(qs)
82
-
83
-            req = '{"methodName":"content.%s","apiKey":"androidPhoneEuronews-1.0","params":%s,"language":"%s"}'%(plist[1],params,lang)
84
-            r = self.call(req)
85
-            if not r:
86
-                return content
87
-            lst = r["timeline"] if "timeline" in r else\
88
-                r["topstorieslist"] if "topstorieslist" in r else\
89
-                r["programs"] if "programs" in r else\
90
-                r["programDetailsList"] if "programDetailsList" in r else\
91
-                r["programlist"] if "programlist" in r else\
92
-                r["articlelist"] if "articlelist" in r else\
93
-                r["verticals"] if "verticals" in r else\
94
-                []
95
-            if not lst:
96
-                return content
97
-
98
-            for item in lst:
99
-                if plist[1] in ("getTimeline"):
100
-                    article = item["article"]
101
-                    atype = item["type"]
102
-                    #if item["type"] == "wire":
103
-                        #continue # TODO
104
-                else:
105
-                    article = item
106
-                    atype = "article"
107
-                if plist[1]=="getPrograms":
108
-                    title = article["title"]
109
-                    id = article["pId"]
110
-                    desc = title
111
-                    img = "http://static.euronews.com/articles/programs/533x360_%s"%article["img"]
112
-                    data2 = "content/getProgramDetails?lang=%s&byPage=40&page=1&pId=%s"%(lang,id)
113
-                    content.append((title,self.name+"::"+data2,img,desc))
114
-                else:
115
-                    title = article["title"] if "title" in article else article["text"] if "text" in article else "No title"
116
-                    if atype <> "article":
117
-                        title = "[%s] %s"%(atype,title)
118
-                    atime = datetime.datetime.fromtimestamp(int(article["uts"]))
119
-                    #atime = datetime.datetime.fromtimestamp(int(article["uts"])-time.altzone)
120
-                    atime = atime.strftime("%Y-%m-%d %H:%M")
121
-                    vert = self.vid[article["vId"]] if "vId" in article else ""
122
-                    ptitle = article["pTitle"] if "pTitle" in article else ""
123
-                    id = article["id"]
124
-                    desc = "%s\n%s\n%s %s"%(title,atime,vert,ptitle)
125
-                    img = "http://static.euronews.com/articles/%s/399x225_%s.jpg"%(id,id)
126
-                    if not atype in ("breakingnews","wire"):
127
-                        data2 = "content/getArticle?lang=%s&id=%s"%(lang,id)
128
-                    else:
129
-                        data2 = ""
130
-                    content.append((title,self.name+"::"+data2,img,desc))
131
-            if "page=" in data:
132
-                data2 = re.sub("page=\d+","page=%s"%(int(qs["page"])+1),data)
133
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
134
-            return content
135
-
136
-
137
-    def is_video(self,data):
138
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
139
-        if path == "live":
140
-            return True
141
-        elif clist=="content" and plist[1]=="getArticle":
142
-            return True
143
-        else:
144
-            return False
145
-
146
-    def get_streams(self, data):
147
-        print "[euronews] get_streams:", data
148
-        if not self.is_video(data):
149
-            return []
150
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
151
-        #lang = qs["lang"] if "lang" in qs else self.language
152
-        lang = self.options["language"]
153
-        if not lang in self.get_languages():
154
-            raise Exception("Not valid default language - '%s'"%lang)
155
-
156
-        streams = []
157
-
158
-        if path == "live":
159
-            url = "http://www.euronews.com/api/watchlive.json"
160
-            r = self._http_request(url)
161
-            try:
162
-                js = json.loads(r)
163
-                url = js["url"]
164
-            except:
165
-                raise Exception("No live stream found")
166
-            r = self._http_request(url)
167
-            try:
168
-                js = json.loads(r)
169
-                if not js["status"]=="ok":
170
-                    raise Exception("No live stream found")
171
-            except:
172
-                raise Exception("No live stream found")
173
-
174
-            slist = js["primary"]
175
-
176
-            for l in slist:
177
-                stream = util.item()
178
-                stream["url"]=slist[l]["hls"]
179
-                stream["lang"]=l
180
-                stream["quality"]="variant"
181
-                stream["name"]="Euronews live [%s]"%l
182
-                stream["desc"]=stream["name"]
183
-                stream["type"]="hls" #stream_type(url)
184
-                streams.append(stream)
185
-
186
-        elif clist=="content" and plist[1] == "getArticle":
187
-            if "lang" in qs:
188
-                del qs["lang"]
189
-            languages = self.get_languages()
190
-            for lang in languages:
191
-                id = qs["id"]
192
-                req = '{"methodName":"content.getArticle","apiKey":"androidPhoneEuronews-1.0","params":{"id":"%s"},"language":"%s"}'%(id,lang)
193
-                r = self.call(req)
194
-                if not r:
195
-                    raise Exception("No live stream found")
196
-                if not "articlelist" in r:
197
-                    msg = r["label"] if "label" in r else "No article finde"
198
-                    raise Exception(msg)
199
-                article = r["articlelist"]
200
-                stream = util.item()
201
-                stream["url"]=article["videoUri"] if "videoUri" in article else ""
202
-                if not stream["url"]:
203
-                    return []
204
-                stream["lang"]=lang
205
-                stream["quality"]="?"
206
-                stream["name"]= article["title"]
207
-                stream["desc"]=article["text"] if "text" in article else article["title"]
208
-                stream["type"]="http" #stream_type(url)
209
-                streams.append(stream)
210
-
211
-        else:
212
-            raise Exception("No live stream found")
213
-
214
-        ### TODO - sakārtot sarakstu, lai pirmais ir labakais video
215
-        qlist = ["???","lq","mq","hq","hd","variant"]
216
-        llist = ["fr","en","ru","lv"]
217
-        for s in streams:
218
-            if s["lang"]==self.options["language"]:
219
-                s["order"] = 10000
220
-                continue
221
-            lv = llist.index(s["lang"])*10 if s["lang"] in llist else 0
222
-            qv=qlist.index(s["quality"]) if s["quality"] in qlist else 0
223
-            s["order"] = lv+qv
224
-        streams = sorted(streams,key=lambda item: item["order"],reverse=True)
225
-        return streams
226
-    def get_languages(self):
227
-        if self.languages: return self.languages
228
-        url = "http://www.euronews.com/api/watchlive.json"
229
-        r = self._http_request(url)
230
-        try:
231
-            js = json.loads(r)
232
-            url = js["url"]
233
-        except:
234
-            raise Exception("Can not get languages list")
235
-        r = self._http_request(url)
236
-        try:
237
-            js = json.loads(r)
238
-            if not js["status"]=="ok":
239
-                raise Exception("Can not get languages list")
240
-        except:
241
-            raise Exception("Can not get languages list")
242
-
243
-        slist = js["primary"]
244
-        self.languages=slist.keys()
245
-        return self.languages
246
-
247
-    def call(self, data,params = None, headers=None):
248
-        if not headers: headers = self.headers
249
-        #if not lang: lang = self.country
250
-        url = "http://api.euronews.com/ipad/"
251
-        headers = headers2dict("""
252
-User-Agent: Euronews/4.0.126
253
-Content-Type: multipart/form-data, boundary=AaB03xBounDaRy; charset=UTF-8
254
-Host: api.euronews.com
255
-Connection: Keep-Alive
256
-        """)
257
-        params = """
258
---AaB03xBounDaRy
259
-content-disposition: form-data; name=request
260
-
261
-%s
262
---AaB03xBounDaRy--
263
-"""%data
264
-        content = self._http_request(url, params, headers)
265
-        if content:
266
-            try:
267
-                result = json.loads(content)
268
-                return result
269
-            except Exception, ex:
270
-                return None
271
-        else:
272
-            return None
273
-
274
-
275
-if __name__ == "__main__":
276
-    language= "en"
277
-    c = Source(language)
278
-    data = '{"methodName":"content.getTimeline","apiKey":"androidPhoneEuronews-1.0","params":{"page":"1","byPage":"30"},"language":"en"}'
279
-    r = c.call(data)
280
-    if len(sys.argv)>1:
281
-        data= sys.argv[1]
282
-    else:
283
-        data = "home"
284
-    content = c.get_content(data)
285
-    for item in content:
286
-        print item
287
-    pass

+ 0
- 336
resources/lib/sources0/filmix.py View File

@@ -1,336 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys,os
15
-import ConfigParser
16
-from SourceBase import SourceBase
17
-import base64
18
-from collections import OrderedDict
19
-import sys
20
-try:
21
-    import util
22
-except:
23
-    sys.path.insert(0,'..')
24
-    import util
25
-
26
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
27
-
28
-class Source(SourceBase):
29
-
30
-    def __init__(self,country=""):
31
-        self.name = "filmix"
32
-        self.title = "filmix.me"
33
-        self.img = "http://cs5324.vk.me/g33668783/a_903fcc63.jpg"
34
-        self.desc = "filmix.me satura skatīšanās"
35
-        self.country=country
36
-        self.headers = headers2dict("""
37
-Host: filmix.me
38
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
39
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
40
-Accept-Language: en-US,en;q=0.5
41
-""")
42
-        self.headers2 = headers2dict("""
43
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
44
-X-Requested-With: XMLHttpRequest
45
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
46
-""")
47
-        self.url = "https://filmix.me/"
48
-        #self.login()
49
-
50
-    def login(self,user="",password=""):
51
-        return True
52
-
53
-    def get_content(self, data):
54
-        print "[filmix] get_content:", data
55
-        source, data, path, plist, clist, params, qs = self.parse_data(data)
56
-        content=[]
57
-        content.append(("..return", "back","","Return back"))
58
-
59
-        if clist=="home":
60
-            content.extend([
61
-                ("Search", "filmix::search/{0}","","Search"),
62
-                ("Movies", "filmix::movies","","Movies"),
63
-                ("Series", "filmix::series","","TV Series"),
64
-                ("Cartoons", "filmix::cartoons","","Cartoons"),
65
-            ])
66
-            return content
67
-
68
-        #elif clist=="search":
69
-            # TODO
70
-            #return content
71
-
72
-        elif data in ("movies","series","cartoons"):
73
-            r = self.call("")
74
-            r = r.decode("cp1251").encode("utf8")
75
-            if data == "movies":
76
-                sname = "Фильмы"
77
-            elif data=="series":
78
-                sname = "Сериалы"
79
-            else:
80
-                sname = "Мультфильмы"
81
-            # <span class="menu-title">Фильмы</span>
82
-            m = re.search('<span class="menu-title">%s</span>(.+?)<li>\s+?<span'%sname, r, re.DOTALL|re.UNICODE)
83
-            if not m: return content
84
-            r2 = m.group(1)
85
-            result = re.findall(r'<a .*?href="https://filmix\.me/([^"]+)".*?>([^<]+)</', r2, re.DOTALL)
86
-            for item in result:
87
-                if "catalog" in item[0]: continue
88
-                title = item[1]
89
-                data2 = item[0]
90
-                img = self.img
91
-                desc = title
92
-                content.append((title,self.name+"::"+data2,img,desc))
93
-            return content
94
-
95
-        ## Seriāls
96
-        elif clist=="play":
97
-            r = self.call(path)
98
-            r = r.decode("cp1251").encode("utf8")
99
-            title = title0 = util.unescape(re.search("titlePlayer = '([^']+)'", r, re.DOTALL).group(1))
100
-            m = re.search('<meta itemprop="thumbnailUrl" content="([^"]+)',r,re.DOTALL)
101
-            img = m.group(1) if m else self.img
102
-            m = re.search('<meta itemprop="duration" content="([^"]+)" />', r, re.DOTALL)
103
-            duration = "(%s)"%m.group(1) if m else ""
104
-            m = re.search('<p itemprop="description"[^>]+>([^<]+)<', r, re.DOTALL)
105
-            desc = desc0 =  util.unescape(m.group(1).strip()) if m else ""
106
-            vid = plist[-1]
107
-            js = self.get_movie_info(vid)
108
-            pl_link = js["message"]["translations"]["flash"].values()[0] # TODO process several players
109
-            pl_link = self.decode_uppod_text(pl_link)
110
-            js = self._http_request(pl_link)
111
-            js = self.decode_uppod_text(js)
112
-            js = json.loads(js)
113
-            if "s" in qs:
114
-                s = int(qs["s"])
115
-                for i,ep in enumerate(js["playlist"][s-1]["playlist"]):
116
-                    title = title0+" - "+js["playlist"][s-1]["playlist"][i]["comment"].encode("utf8")
117
-                    serie = js["playlist"][s-1]["playlist"][i]["comment"].encode("utf8")
118
-                    data2 = data+"&e=%s"%(i+1)
119
-                    desc = serie +"\n"+desc0
120
-                    content.append((title,self.name+"::"+data2,img,desc))
121
-            else:
122
-                for i,ep in enumerate(js["playlist"]):
123
-                    title = title0 +" - "+js["playlist"][i]["comment"].encode("utf8")
124
-                    serie = js["playlist"][i]["comment"].encode("utf8")
125
-                    data2 = data+"?s=%s"%(i+1)
126
-                    desc = serie +"\n"+desc0
127
-                    content.append((title,self.name+"::"+data2,img,desc))
128
-            return content
129
-            #r = self._http_request(url)
130
-
131
-
132
-        ### saraksts ###
133
-        else:
134
-            r = self.call(data)
135
-            r = r.decode("cp1251").encode("utf8")
136
-            for r2 in re.findall('<article class="shortstory line".+?</article>', r, re.DOTALL):
137
-                m = re.search(r'<a href="https://filmix\.me/play/(\d+)" class="watch icon-play">', r2, re.DOTALL)
138
-                if not m: continue
139
-                vid = m.group(1)
140
-                data2 = "play/%s"%vid
141
-                #title = re.search('itemprop="name">([^<]+)</div>', r2, re.DOTALL).group(1)
142
-                title = re.search('itemprop="name" content="([^"]+)"', r2, re.DOTALL).group(1)
143
-                m = re.search('itemprop="alternativeHeadline" content="([^"]+)"', r2, re.DOTALL)
144
-                if m:
145
-                    title = title + "/"+m.group(1)
146
-                m = re.search('<img src="([^"]+.jpg)"', r2, re.DOTALL)
147
-                img = "http://filmix.me"+m.group(1) if m else self.img
148
-                m = re.search(r'<a itemprop="copyrightYear".+?>(\d+)<', r2, re.DOTALL)
149
-                if m:
150
-                    year = m.group(1) if m else ""
151
-                    title = "%s (%s)"%(title,year)
152
-                title = util.unescape(title)
153
-                genre = re.findall('<a itemprop="genre"[^>]+?">([^<]+)</a>', r2, re.DOTALL)
154
-                genre = ",".join(genre)
155
-                m = re.search('<p itemprop="description">([^<]+)</p>', r2, re.DOTALL)
156
-                desc0 = util.unescape(m.group(1)) if m else ""
157
-                m = re.search('<div class="quality">([^<]+)</div>', r2, re.DOTALL)
158
-                quality = m.group(1) if m else ""
159
-                actors = re.findall('itemprop="actor">([^<]+)<', r2, re.DOTALL)
160
-                actors = ",".join(actors)
161
-                desc="%s\n%s\n%s\n%s\n%s"%(title,genre,desc0,actors,quality)
162
-                content.append((title,self.name+"::"+data2,img,desc))
163
-            if '<div class="navigation">' in r:
164
-                m = re.search(r'href="https://filmix\.me/([^"]+)" class="next icon-arowRight btn-tooltip"', r, re.DOTALL)
165
-                if m:
166
-                    data2 = m.group(1)
167
-                else:
168
-                    m = re.search("/page/(\d)+",data)
169
-                    if m:
170
-                        page = int(m.group(1))+1
171
-                        data2 = re.sub("/page/(\d)+", "/page/%s"%page, data)
172
-                    else:
173
-                        data2 = data + "/page/2"
174
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
175
-
176
-            return content
177
-
178
-    def is_video(self,data):
179
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
180
-        if clist == "play" and "s=" in data and "e=" in data:
181
-            return True
182
-        elif clist=="play" and not params:
183
-            r = self.call(path)
184
-            #r = r.decode("cp1251").encode("utf8")
185
-            m = re.search('itemprop="contentUrl" content="(.+?)"', r, re.IGNORECASE | re.DOTALL)
186
-            if not m:
187
-                raise Exception("Can not find video link")
188
-                #return False
189
-            video_link = m.group(1)
190
-            if video_link=='{video-link}':
191
-                return False
192
-            else:
193
-                return True
194
-        else:
195
-            return False
196
-
197
-    def get_streams(self, data):
198
-        print "[filmix] get_streams:", data
199
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
200
-
201
-        r = self.call(path)
202
-        if not r:
203
-            return []
204
-        streams = []
205
-        r = r.decode("cp1251").encode("utf8")
206
-        title = title0 = util.unescape(re.search("titlePlayer = '([^']+)'", r, re.DOTALL).group(1))
207
-        m = re.search('<meta itemprop="thumbnailUrl" content="([^"]+)',r,re.DOTALL)
208
-        img = m.group(1) if m else self.img
209
-        m = re.search('<meta itemprop="duration" content="([^"]+)" />', r, re.DOTALL)
210
-        duration = "(%s)"%m.group(1) if m else ""
211
-        m = re.search('<p itemprop="description"[^>]+>([^<]+)<', r, re.DOTALL)
212
-        desc = desc0 =  util.unescape(m.group(1).strip()) if m else ""
213
-        m = re.search('itemprop="contentUrl" content="(.+?)"', r, re.IGNORECASE | re.DOTALL)
214
-        if not m:
215
-        #    #raise Exception("Can not find video link")
216
-            return []
217
-        video_link = m.group(1)
218
-        series = True if video_link == '{video-link}' else False
219
-        vid = plist[1]
220
-        js = self.get_movie_info(vid)
221
-        if js["message"]["translations"]["flash"]:
222
-            video_link = js["message"]["translations"]["flash"].values()[0].encode("utf8")
223
-            video_link = self.decode_uppod_text(video_link)
224
-            lang = js["message"]["translations"]["flash"].keys()[0].encode("utf8") # TODO process several players/streams
225
-        else:
226
-            return []
227
-
228
-        if not series : # Filma
229
-            url0 = video_link
230
-            streams2 = self.get_streams2(url0)
231
-            for st in streams2:
232
-                stream = util.item()
233
-                stream["url"]=st[1]
234
-                stream["lang"]=lang
235
-                stream["quality"]=st[0]
236
-                stream["name"]= title
237
-                stream["desc"]=desc
238
-                streams.append(stream)
239
-            return streams
240
-
241
-        else: # Seriāls
242
-            pl_link = video_link
243
-            js = self._http_request(pl_link)
244
-            js = self.decode_uppod_text(js)
245
-            js = json.loads(js)
246
-            if "s" in qs and "e" in qs:
247
-                s = int(qs["s"])
248
-                e = int(qs["e"])
249
-                serie = js["playlist"][s-1]["playlist"][e-1]["comment"].encode("utf8")
250
-                title = title0+" - "+ serie
251
-                url0 = js["playlist"][s-1]["playlist"][e-1]["file"].encode("utf8")
252
-                streams2 = self.get_streams2(url0)
253
-                for st in streams2:
254
-                    stream = util.item()
255
-                    stream["url"]=st[1]
256
-                    stream["lang"]=lang
257
-                    stream["quality"]=st[0]
258
-                    stream["name"]= title
259
-                    stream["desc"]=desc
260
-                    streams.append(stream)
261
-                return streams
262
-
263
-    def call(self, data,params=None,headers=None,lang=""):
264
-        if not headers: headers = self.headers
265
-        url = self.url+data
266
-        result = self._http_request(url,params,headers=headers)
267
-        return result
268
-
269
-    def get_movie_info(self,vid):
270
-        headers = headers2dict("""
271
-    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
272
-    Accept: application/json, text/javascript, */*; q=0.01
273
-    Accept-Language: en-US,en;q=0.5
274
-    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
275
-    X-Requested-With: XMLHttpRequest
276
-    Referer: https://filmix.me/play/%s
277
-    """%vid )
278
-        post_data = {"post_id":vid}
279
-        r = util.post("https://filmix.me/api/movies/player_data", data=post_data, headers = headers)
280
-        if not r:
281
-            raise Exception("Can not get movie info")
282
-            #return []
283
-        js = json.loads(r)
284
-        return js
285
-
286
-    def decode_uppod_text(self, text):
287
-        Client_codec_a = ["l", "u", "T", "D", "Q", "H", "0", "3", "G", "1", "f", "M", "p", "U", "a", "I", "6", "k", "d", "s", "b", "W", "5", "e", "y", "="]
288
-        Client_codec_b = ["w", "g", "i", "Z", "c", "R", "z", "v", "x", "n", "N", "2", "8", "J", "X", "t", "9", "V", "7", "4", "B", "m", "Y", "o", "L", "h"]
289
-        text = text.replace("\n", "").strip()
290
-        for i in range(len(Client_codec_a)):
291
-            char1 = Client_codec_b[i]
292
-            char2 = Client_codec_a[i]
293
-            text = text.replace(char1, "___")
294
-            text = text.replace(char2, char1)
295
-            text = text.replace("___", char2)
296
-        result = base64.b64decode(text)
297
-        print result
298
-        return result
299
-
300
-    def get_streams2(self,url0):
301
-        m = re.search("\[([\d,]+)]",url0)
302
-        if not m:
303
-            return [("?",url0)]
304
-        res = m.group(1)
305
-        streams=[]
306
-        for res in res.split(","):
307
-            if not res: continue
308
-            url=re.sub("\[[\d,]+]",res,url0)
309
-            streams.append((res,url))
310
-        return streams
311
-
312
-
313
-if __name__ == "__main__":
314
-
315
-    c = Source()
316
-    #s = "ZnVuY3Rpb24gc2VuZE1lc3NhZ2U2MDc3ODkoZSl7dmFyIGg9bWdfd3M2MDc3ODkub25tZXNzYWdlOyBtZ193czYwNzc4OS5yZWFkeVN0YXRlPT1tZ193czYwNzc4OS5DTE9TRUQmJihtZ193czYwNzc4OT1uZXcgV2ViU29ja2V0KG1nX3dzNjA3Nzg5X2xvY2F0aW9uKSksbWdfd3M2MDc3ODkub25tZXNzYWdlPWgsd2FpdEZvclNvY2tldENvbm5lY3Rpb242MDc3ODkobWdfd3M2MDc3ODksZnVuY3Rpb24oKXttZ193czYwNzc4OS5zZW5kKGUpfSl9ZnVuY3Rpb24gd2FpdEZvclNvY2tldENvbm5lY3Rpb242MDc3ODkoZSx0KXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7cmV0dXJuIDE9PT1lLnJlYWR5U3RhdGU/dm9pZChudWxsIT10JiZ0KCkpOnZvaWQgd2FpdEZvclNvY2tldENvbm5lY3Rpb242MDc3ODkoZSx0KX0sNSl9OyB2YXIgbWdfd3M2MDc3ODlfbG9jYXRpb24gPSAid3NzOi8vd3NwLm1hcmtldGdpZC5jb20vd3MiOyBtZ193czYwNzc4OSA9IG5ldyBXZWJTb2NrZXQobWdfd3M2MDc3ODlfbG9jYXRpb24pLCBtZ193czYwNzc4OS5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAodCkge3Bvc3RNZXNzYWdlKHQuZGF0YSk7fSwgb25tZXNzYWdlID0gZnVuY3Rpb24oZSl7c2VuZE1lc3NhZ2U2MDc3ODkoZS5kYXRhKX0="
317
-
318
-    #txt = c.decode_uppod_text(s)
319
-    if len(sys.argv)>1:
320
-        data= sys.argv[1]
321
-    else:
322
-        data = "home"
323
-    content = c.get_content(data)
324
-    for item in content:
325
-        print item
326
-    #cat = api.get_categories(country)
327
-    #chan = api.get_channels("lv")
328
-    #prog = api.get_programs(channel=6400)
329
-    #prog = api.get_programs(category=55)
330
-    #seas = api.get_seasons(program=6453)
331
-    #str = api.get_streams(660243)
332
-    #res = api.get_videos(802)
333
-    #formats = api.getAllFormats()
334
-    #det = api.detailed("1516")
335
-    #vid = api.getVideos("13170")
336
-    pass

+ 0
- 272
resources/lib/sources0/filmon.py View File

@@ -1,272 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys
15
-from SourceBase import SourceBase
16
-
17
-API_URL = 'http://www.filmon.com/'
18
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
19
-#User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
20
-headers0 = headers2dict("""
21
-User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46
22
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
23
-Accept-Language: en-US,en;q=0.5
24
-Accept-Encoding: deflate
25
-Connection: keep-alive
26
-""")
27
-import HTMLParser
28
-h = HTMLParser.HTMLParser()
29
-
30
-class Source(SourceBase):
31
-
32
-    def __init__(self,country="lv"):
33
-        self.name = "filmon"
34
-        self.title = "FilmOn"
35
-        self.img = "http://behindthegloves.com/wp-content/uploads/2016/01/FilmOn-logo1.jpg"
36
-        self.desc = "FilmOn portāla satura skatīšanās"
37
-        self.headers = headers0
38
-
39
-        self.country=country
40
-        self.jstv = None
41
-        self.session_key = None
42
-        self.cookie = None
43
-
44
-    def get_content(self, data):
45
-        print "[filmon] get_content:", data
46
-        if "::" in data:
47
-            data = data.split("::")[1] 
48
-        path = data.split("?")[0]
49
-        clist = path.split("/")[0]
50
-        params = data[data.find("?"):] if "?" in data else ""
51
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
52
-        lang = qs["lang"] if "lang" in qs else self.country
53
-
54
-        if not self.jstv:
55
-            self.jstv = self.get_tv_channels()
56
-        #if not self.session_key: # TODO izskatās, ka strādā bez, vismaz ja nelogojas iekšā,  jānočeko
57
-        #    html = self._http_request("http://www.filmon.com/api/init")
58
-        #    js = json.loads(html)
59
-        #    self.session_key = js["session_key"]
60
-
61
-        content=[]
62
-        content.append(("..return", "back","","Return back"))
63
-
64
-        if clist=="home":
65
-            content.extend([
66
-                ("Live streams", "filmon::tv","","TV live streams"),
67
-                ("Video on demand", "filmon::vod","","Last videos"),
68
-            ])
69
-            return content
70
-
71
-        ### TV Groups ###
72
-        elif clist in ("tv","home"):
73
-            for gr in self.jstv:
74
-                title = gr["name"].encode("utf8")
75
-                data2 = "group?id=%s"%gr["id"]
76
-                img = gr["logo_148x148_uri"].encode("utf8")
77
-                desc = gr["description"].encode("utf8")
78
-                content.append((title,self.name+"::"+data2,img,desc))
79
-            return content
80
-
81
-        ### TV group channels ###
82
-        elif clist=="group":
83
-            if "id" in qs:
84
-                group_id = qs["id"] 
85
-            else:
86
-                return content
87
-            group = None
88
-            for gr in self.jstv:
89
-                if gr["id"]==group_id:
90
-                    group = gr
91
-                    break
92
-            if not group:
93
-                return content
94
-            for ch in group["channels"]:
95
-                title = ch["title"].encode("utf8")
96
-                data2 = "channel?id=%s"%ch["id"]
97
-                img = ch["big_logo"].encode("utf8")
98
-                desc = ch["description"].encode("utf8") if ch["description"] else title
99
-                content.append((title,self.name+"::"+data2,img,desc))
100
-            return content
101
-
102
-        ### TV Channel ###
103
-        elif clist == "channel" or clist == "video":
104
-            if "id" in qs:
105
-                ch_id = qs["id"] 
106
-            else:
107
-                return ("No stream found %s"%data,"","","No stream found")
108
-            ch = self.get_tv_channel_info(ch_id)
109
-            if ch["now_playing"]:
110
-                current_event = ch["now_playing"]["programme_name"] if "programme_name" in ch["now_playing"] else ""
111
-            else:
112
-                current_event = ""
113
-            title = u"%s - %s"%(ch["title"],current_event)
114
-            title = title.encode("utf8")
115
-            if current_event:
116
-                desc = ch["now_playing"]["programme_description"].encode("utf8")
117
-            else:
118
-                desc = title
119
-            data2 = ""
120
-            for t in ("SD","HD"):
121
-                for s in ch["streams"]:
122
-                    if s["name"]==t:
123
-                        data2 = s["url"].encode("utf8")
124
-                        break
125
-                if data2: break
126
-            return (title,data2,"",desc)
127
-
128
-        ### VOD genres ###
129
-        elif path in ("vod","vod/genres"):
130
-            data = "vod/genres"
131
-            js = self.call(data)
132
-            for gr in js["response"]:
133
-                title = gr["name"].encode("utf8")
134
-                data2 = "vod/search?genre=%s&max_results=30&no_episode=true&start_index=0"%(gr["slug"].encode("utf8"))
135
-                img = gr["images"][0]["url"].encode("utf8")
136
-                desc = gr["description"].encode("utf8") if gr["description"] else title
137
-                content.append((title,self.name+"::"+data2,img,desc))
138
-            return content           
139
-
140
-        ### VOD genre videos ###
141
-        elif path == "vod/search":
142
-            js = self.call(data)
143
-            for vid in js["response"]:
144
-                title = vid["title"].encode("utf8")
145
-                if vid["type"]=="series":
146
-                    title = "[Series] "+title
147
-                data2 = "vod/movie?id=%s&type=%s"%(vid["id"],vid["type"].encode("utf8"))
148
-                img = "http://static.filmon.com/assets/"+vid["poster"]["couchdb_url"].encode("utf8")
149
-                desc = vid["description"].encode("utf8") if vid["description"] else title
150
-                content.append((title,self.name+"::"+data2,img,desc))
151
-            start_index = int(qs["start_index"]) if "start_index" in qs else 0
152
-            if start_index+js["total"]<js["total_found"]:
153
-                start_index += 30
154
-                data2 = re.sub("start_index=\d+","start_index=%s"%start_index,data) if "start_index" in qs else data +"&start_index=30"
155
-                content.append(("Next page",self.name+"::"+data2,"","Next page"))                                            
156
-            return content
157
-
158
-        ### VOD video sigle/series ###
159
-        elif path == "vod/movie":
160
-            js = self.call(data)
161
-            if js["response"]["type"] == "series":
162
-                ids = ",".join(js["response"]["episodes"])
163
-                data2 = "vod/movies?ids=%s"%ids
164
-                js2 = self.call(data2)
165
-                for vid in js2["response"]:
166
-                    title = vid["title"].encode("utf8")
167
-                    if vid["type"]=="series":
168
-                        title = "[Series] "+title
169
-                    data2 = "vod/movie?id=%s&type=%s"%(vid["id"],vid["type"].encode("utf8"))
170
-                    img = "http://static.filmon.com/assets/"+vid["poster"]["couchdb_url"].encode("utf8")
171
-                    desc = vid["description"].encode("utf8") if vid["description"] else title
172
-                    content.append((title,self.name+"::"+data2,img,desc))
173
-                return content
174
-            else:
175
-                title = js["response"]["title"].encode("utf8")
176
-                desc = js["response"]["description"].encode("utf8") if js["response"]["description"] else title
177
-                data2 = js["response"]["streams"]["low"]["url"].encode("utf8")
178
-                return (title,data2,"",desc)
179
-
180
-    def is_video(self,data):
181
-        if "::" in data:
182
-            data = data.split("::")[1]
183
-        cmd = data.split("?")
184
-        if cmd[0] in ("video","channel"):
185
-            return True
186
-        elif cmd[0] == "vod/movie" and "type=movie" in data:
187
-            return True
188
-        else:
189
-            return False
190
-
191
-    def call(self, data,headers=headers0,lang=""):
192
-        if not lang: lang = self.country
193
-        url = "http://www.filmon.com/api/" + data
194
-        #if not "?" in url: url += "?session_key=%s"%self.session_key
195
-        #if not "session_key=" in url: url += "&session_key=%s"%self.session_key
196
-        #print "[TVPlay Api] url: ",url
197
-        result = []
198
-        content = self._http_request(url)
199
-        if content:
200
-            try:
201
-                result = json.loads(content)
202
-            except Exception, ex:
203
-                return None
204
-        return result
205
-
206
-    #----------------------------------------------------------------------
207
-    def get_tv_channel_info(self,id):
208
-        url = "http://www.filmon.com/ajax/getChannelInfo"
209
-        headers = headers2dict("""
210
-Host: www.filmon.com
211
-User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0
212
-Accept: application/json, text/javascript, */*; q=0.01
213
-Accept-Language: en-US,en;q=0.5
214
-Accept-Encoding: deflate
215
-DNT: 1
216
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
217
-X-Requested-With: XMLHttpRequest
218
-Referer: http://www.filmon.com/tv/live
219
-Connection: keep-alive
220
-Pragma: no-cache
221
-Cache-Control: no-cache
222
-""")
223
-        headers["Cookie"] = self.cookie
224
-        data = "channel_id=%s&quality=low"%id
225
-        response = urllib2.urlopen(urllib2.Request(url, headers=headers,data=data))
226
-        html =  response.read()
227
-        js = json.loads(html)
228
-        return js
229
-
230
-    #----------------------------------------------------------------------
231
-    def get_tv_channels(self):
232
-        """Get tv channels list"""
233
-        headers = headers2dict("""
234
-Host: www.filmon.com
235
-User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0
236
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
237
-Accept-Language: en-US,en;q=0.5
238
-Accept-Encoding: deflate
239
-DNT: 1
240
-Connection: keep-alive
241
-    """)
242
-
243
-        url = "http://www.filmon.com/tv"
244
-        response = urllib2.urlopen(urllib2.Request(url, headers=headers))
245
-        if "set-cookie" in response.headers:
246
-            self.cookie = response.headers["set-cookie"]
247
-        html =  response.read()
248
-        s = re.search("(?i)var groups = (.*);", html).groups(1)[0]
249
-        js = json.loads(s)
250
-        return js
251
-
252
-if __name__ == "__main__":
253
-    country= "lv"
254
-    c = Source(country)
255
-    if len(sys.argv)>1:
256
-        data= sys.argv[1]
257
-    else:
258
-        data = "home"
259
-    content = c.get_content(data)
260
-    for item in content:
261
-        print item
262
-    #cat = api.get_categories(country)
263
-    #chan = api.get_channels("lv")
264
-    #prog = api.get_programs(channel=6400)
265
-    #prog = api.get_programs(category=55)
266
-    #seas = api.get_seasons(program=6453)
267
-    #str = api.get_streams(660243)
268
-    #res = api.get_videos(802)
269
-    #formats = api.getAllFormats()
270
-    #det = api.detailed("1516")
271
-    #vid = api.getVideos("13170")
272
-    pass

+ 0
- 4
resources/lib/sources0/iplayer.cfg View File

@@ -1,4 +0,0 @@
1
-[iplayer]
2
-user = lietotajs
3
-password = parole
4
-

+ 0
- 524
resources/lib/sources0/iplayer.py View File

@@ -1,524 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-import sys, os, os.path, re, sys
9
-import urllib,urllib2
10
-from xml.sax.saxutils import unescape,escape
11
-from urllib import quote, unquote
12
-import datetime
13
-import HTMLParser
14
-import json
15
-import datetime,time
16
-from SourceBase import SourceBase, stream_type
17
-import util
18
-from collections import OrderedDict
19
-
20
-API_URL = 'https://m.lattelecom.tv/'
21
-user_agent = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; da-dk) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3"
22
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
23
-h = HTMLParser.HTMLParser()
24
-
25
-class Source(SourceBase):
26
-
27
-    def __init__(self):
28
-        self.name = "iplayer"
29
-        self.title = "BBC iPlayer"
30
-        self.img = "http://www.userlogos.org/files/logos/inductiveload/BBC_iPlayer_logo.png"
31
-        self.desc = "BBC iPlayer portal content"
32
-
33
-        self.api_url = "http://ibl.api.bbci.co.uk/ibl/v1/"
34
-        self.headers = headers2dict("""
35
-User-Agent: BBCiPlayer/4.19.0.3021 (SM-G900FD; Android 4.4.2)
36
-Connection: Keep-Alive
37
-        """)
38
-        self.headers2 = headers2dict("""
39
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
40
-Connection: Keep-Alive
41
-        """)
42
-
43
-        self.ch = []
44
-        self.ch_id={}
45
-        self.ch_id2={}
46
-        self.ch_name={}
47
-        self.logos ={
48
-            "bbc_one_london":"http://www.lyngsat-logo.com/hires/bb/bbc_one.png",
49
-            "bbc_two_england":"http://www.lyngsat-logo.com/hires/bb/bbc_two_uk.png",
50
-            "bbc_three":"http://www.lyngsat-logo.com/hires/bb/bbc_three_uk.png",
51
-            "bbc_four":"http://www.lyngsat-logo.com/hires/bb/bbc_four_uk.png",
52
-            "bbc_radio_one":"http://www.lyngsat-logo.com/hires/bb/bbc_radio1.png",
53
-            "cbbc":"http://www.lyngsat-logo.com/hires/bb/bbc_cbbc.png",
54
-            "cbeebies":"http://www.lyngsat-logo.com/hires/bb/bbc_cbeebies_uk.png",
55
-            "bbc_news24":"http://www.lyngsat-logo.com/hires/bb/bbc_news.png",
56
-            "bbc_parliament":"http://www.lyngsat-logo.com/hires/bb/bbc_parliament.png",
57
-            "bbc_alba":"http://www.lyngsat-logo.com/hires/bb/bbc_alba.png",
58
-            "s4cpbs":"http://www.lyngsat-logo.com/hires/ss/s4c_uk.png"
59
-        }
60
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
61
-        self.config_file = os.path.join(cur_directory,self.name+".cfg")
62
-        self.options = OrderedDict([("user","lietotajs"),("password","parole")])
63
-        self.options_read()
64
-
65
-    def get_content(self, data):
66
-        print "[iplayer] get_content:", data
67
-        if "::" in data:
68
-            data = data.split("::")[1]
69
-        path = data.split("?")[0]
70
-        clist = path.split("/")[0]
71
-        params = data[data.find("?"):] if "?" in data else ""
72
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=[\w-]+",params)))
73
-        #lang = qs["lang"] if "lang" in qs else self.country
74
-
75
-        content=[]
76
-        content.append(("..return", "back","","Return back"))
77
-
78
-        ### Home ###
79
-        if data=="home":
80
-            content.extend([
81
-                ("Search TV", "iplayer::search/{0}","","Search in iPlayer"),
82
-                ("Live streams", "iplayer::live","","TV live streams"),
83
-                ("Channels", "iplayer::channels","","Programmes by channel/date"),
84
-                ("Categories", "iplayer::categories","","Programmes by categories"),
85
-                ("A-Z", "iplayer::a-z","","All programmes by name"),
86
-                ("Highlights", "iplayer::home/highlights","","Current highlights"),
87
-                ("Most popular", "iplayer::groups/popular/episodes?per_page=40&page=1","","Most popular programmes")
88
-            ])
89
-            return content
90
-
91
-        ### Search ###
92
-        elif clist=="search":
93
-            data_ = "search-suggest/?q=%s&rights=mobile&initial_child_count=1"%data.split("/")[1]
94
-            r = self.call(data_)
95
-            for item in r["search_suggest"]["results"]:
96
-                title,data2,img,desc = self.get_data_element(item)
97
-                content.append((title,self.name+"::"+data2,img,desc))
98
-            return content
99
-
100
-
101
-        ### Live main ###
102
-        elif data=="live":
103
-            for ch in self.get_channels():
104
-                title = ch["title"]
105
-                img = self.logos[ch["id"]] if ch["id"] in self.logos else  "http://static.bbci.co.uk/mobileiplayerappbranding/1.9/android/images/channels/tv-guide-wide-logo/layout_normal/xxhdpi/%s_tv-guide-wide-logo.png"%ch["id"]
106
-                desc = title
107
-                data2 = "live/%s"%ch["id"]
108
-                ee = self.get_epg_live(ch["id"])
109
-                desc = ee[2]
110
-                content.append((title,self.name+"::"+data2,img,desc))
111
-            return content
112
-
113
-        ### Categories ###
114
-        elif data == "categories":
115
-            r = self.call(data)
116
-            if not "categories":
117
-                raise Exception("Error reading categories")
118
-            for item in r["categories"]:
119
-                data2 = "categories/%s"%(item["id"])
120
-                title = item["title"]
121
-                desc = title
122
-                img = self.img
123
-                content.append((title,self.name+"::"+data2,img,desc))
124
-            return content
125
-
126
-        ### Catetory root ###
127
-        elif clist == "categories" and len(data.split("/"))==2:
128
-            r = self.call(data)
129
-            title = "%s - highlights"%r["category"]["title"]
130
-            content.append((title,self.name+"::"+data+"/highlights?lang=en&rights=mobile&availability=available",self.img,title))
131
-            title = "%s - recent (%s programmes, %s episodes)"%(r["category"]["title"],r["category"]["child_programme_count"],r["category"]["child_episode_count"])
132
-            content.append((title,self.name+"::"+data+"/programmes?rights=mobile&page=1&per_page=40&sort=recent&sort_direction=asc&initial_child_count=1&availability=available",self.img,title))
133
-            title = "%s - a-z (%s programmes, %s episodes)"%(r["category"]["title"],r["category"]["child_programme_count"],r["category"]["child_episode_count"])
134
-            content.append((title,self.name+"::"+data+"/programmes?rights=mobile&page=1&per_page=40&sort=title&sort_direction=asc&initial_child_count=1&availability=available",self.img,title))
135
-            return content
136
-
137
-        ### Program/episodes list ###
138
-        elif   re.search("categories/([\w\-]+)/(highlights|programmes).+",data) or\
139
-               re.search("programmes/(\w+)/episodes.+",data) or\
140
-               re.search("groups/(\w+)/episodes.+",data) or\
141
-               re.search("atoz/([\w]+)/programmes.+",data) or\
142
-               re.search("channels/(\w+)/schedule/[\d\-].+",data) or\
143
-               re.search("channels/(\w+)/programmes.+",data) or\
144
-               re.search("channels/(\w+)/highlights.+",data) or\
145
-               data == "home/highlights":
146
-            r = self.call(data)
147
-            lst = r["category_highlights"] if "category_highlights" in r else\
148
-                  r["category_programmes"] if "category_programmes" in r else\
149
-                  r["programme_episodes"] if "programme_episodes" in r else\
150
-                  r["atoz_programmes"] if "atoz_programmes" in r else\
151
-                  r["group_episodes"] if "group_episodes" in r else\
152
-                  r["schedule"] if "schedule" in r else\
153
-                  r["channel_highlights"] if "channel_highlights" in r else\
154
-                  r["channel_programmes"] if "channel_programmes" in r else\
155
-                  r["home_highlights"] if "home_highlights" in r else\
156
-                  []
157
-            if not lst:
158
-                return content
159
-            for el in lst["elements"]:
160
-                if el["type"] == "broadcast":
161
-                    if not len(el["episode"]["versions"]):continue
162
-                    title,data2,img,desc = self.get_data_element(el["episode"])
163
-                    t1 = gt(el['scheduled_start'])
164
-                    t2 = gt(el['scheduled_end'])
165
-                    title = "[%s-%s]%s"%(t1.strftime("%d.%m.%Y %H:%M"),t2.strftime("%H:%M"),title)
166
-                else:
167
-                    title,data2,img,desc = self.get_data_element(el)
168
-                content.append((title,self.name+"::"+data2,img,desc))
169
-
170
-            if "&page=" in data and lst["page"]*lst["per_page"]<lst["count"]:
171
-                data2 = re.sub("&page=\d+","&page=%s"%(lst["page"]+1),data)
172
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
173
-            return content
174
-
175
-        ### A-z root ###
176
-        elif data=="a-z":
177
-            url = "http://www.bbc.co.uk/programmes/a-z/by/x/all.json?page=1"
178
-            r = self._http_request(url)
179
-            if not r:
180
-                raise Exception("Can not read %s"%s)
181
-            js = json.loads(r)
182
-            for ch in js["atoz"]["letters"]:
183
-                title = ch.upper()
184
-                desc = "Programmes beginning with %s"%title
185
-                img = self.img
186
-                data2 = "atoz/%s/programmes?rights=mobile&page=1&per_page=40&initial_child_count=1&sort=title&sort_direction=asc&availability=available"%ch
187
-                content.append((title,self.name+"::"+data2,img,desc))
188
-            return content
189
-
190
-        ###  Channels home ###
191
-        elif data=="channels":
192
-            for ch in self.get_channels():
193
-                title = ch["title"]
194
-                img = self.logos[ch["id"]] if ch["id"] in self.logos else  "http://static.bbci.co.uk/mobileiplayerappbranding/1.9/android/images/channels/tv-guide-wide-logo/layout_normal/xxhdpi/%s_tv-guide-wide-logo.png"%ch["id"]
195
-                desc = title
196
-                data2 = "channels/%s"%ch["id"]
197
-                #ee = self.get_epg_live(ch["id"])
198
-                desc = title
199
-                content.append((title,self.name+"::"+data2,img,desc))
200
-            return content
201
-
202
-        ### Channel higlihts/progrmmes/days ###
203
-        elif clist=="channels" and len(data.split("/"))==2:
204
-            r = self.call(data)
205
-            chid = data.split("/")[1]
206
-            ch = self.get_channel_by_id(chid)
207
-
208
-            # Highlights
209
-            title = ch["title"] + " - highlights"
210
-            img = "http://static.bbci.co.uk/mobileiplayerappbranding/1.9/android/images/channels/tv-guide-wide-logo/layout_normal/xxhdpi/%s_tv-guide-wide-logo.png"%ch["id"]
211
-            data2 = "channels/%s/highlights?lang=en&rights=mobile&availability=available"%ch["id"]
212
-            desc = title
213
-            content.append((title,self.name+"::"+data2,img,desc))
214
-
215
-            #AtoZ
216
-            title = ch["title"] + " - programmes AtoZ"
217
-            data2 = "channels/%s/programmes?rights=mobile&page=1&per_page=40&sort=recent&sort_direction=asc&initial_child_count=1&availability=available"%ch["id"]
218
-            desc = title
219
-            content.append((title,self.name+"::"+data2,img,desc))
220
-
221
-            day0 = datetime.date.today()
222
-            for i in range(10):
223
-                day = day0-datetime.timedelta(days=i)
224
-                days = day.strftime("%Y-%m-%d")
225
-                title = ch["title"] + " - " + days
226
-                img = "http://static.bbci.co.uk/mobileiplayerappbranding/1.9/android/images/channels/tv-guide-wide-logo/layout_normal/xxhdpi/%s_tv-guide-wide-logo.png"%ch["id"]
227
-                data2 = "channels/%s/schedule/%s?availability=available"%(ch["id"],days)
228
-                #ee = self.get_epg_live(ch["id"])
229
-                desc = title
230
-                content.append((title,self.name+"::"+data2,img,desc))
231
-            return content
232
-
233
-
234
-    def get_streams(self, data):
235
-        print "[iplayer] get_streams:", data
236
-        if "::" in data: data = data.split("::")[1]
237
-        if not self.is_video(data):
238
-            return []
239
-        cmd = data.split("/")
240
-        vid = cmd[1].split("?")[0]
241
-        if cmd[0] == "live":
242
-            title,img,desc = self.get_epg_live(vid)
243
-        else:
244
-            data_ = "episodes/%s"%vid
245
-            r = self.call(data_)
246
-            title,img,desc,vid = self.get_epg_video(vid)
247
-        url = "http://open.live.bbc.co.uk/mediaselector/5/select/version/2.0/format/json/mediaset/iptv-all/vpid/%s"%vid
248
-        print "vid=%s"%vid
249
-        print url
250
-        r = self._http_request(url) #,headers=self.headers2
251
-        if not r:
252
-            raise Exception("No streams found")
253
-        js = json.loads(r)
254
-        if "result" in js and js["result"]=="geolocation":
255
-            raise Exception("BBC iPlayer service available only from UK")
256
-        if not "media" in js:
257
-            raise Exception("No streams found")
258
-        streams = []
259
-        captions = []
260
-        for s in js["media"]:
261
-            if s["kind"] == "captions":
262
-                if s["connection"][0]["href"]:
263
-                    sub = {}
264
-                    sub["url"] = s["connection"][0]["href"].encode('utf8')
265
-                    sub["type"] = s["type"]
266
-                    sub["name"] = s["service"] if "service" in s else "captions (taff)"
267
-                    sub["lang"] = "en"
268
-                    captions.append(sub)
269
-
270
-            if s["kind"] <> "video":
271
-                continue
272
-            for c in s["connection"]:
273
-                if c["transferFormat"] <> "hls": continue
274
-                #if not (c["supplier"].startswith("mf_") or c["supplier"].startswith("ll_")) : continue # TODO ir kaut kādas VPN problēmas ar akamaihd
275
-                #if c["priority"] <> "1": continue
276
-                url=c["href"].encode("utf8")
277
-                r2 = self._http_request(url)
278
-                if not r2: continue
279
-                slist = re.findall("#EXT-X-STREAM-INF:([^\n]+)\n([^\n]+)", r2, re.DOTALL)
280
-                if not slist:
281
-                    stream = util.item()
282
-                    stream["url"]=url
283
-                    stream["name"]=title
284
-                    stream["desc"]=desc
285
-                    stream["img"]=img
286
-                    stream["type"]="hls"
287
-                    stream["quality"]=("%s %sx%s %s,%s"%(s["bitrate"],s["width"],s["height"],c["supplier"],c["priority"])).encode("utf8")
288
-                    stream["lang"]="en"
289
-                    stream["subs"]=captions
290
-                    stream["order"]=int(s["bitrate"])
291
-                    streams.append(stream)
292
-                else:
293
-                    for cc in slist:
294
-                        m = re.search("RESOLUTION=([\dx]+)",cc[0])
295
-                        resolution = m.group(1) if m else "%sx%s"%(s["width"],s["height"])
296
-                        m = re.search("BANDWIDTH=([\d]+)",cc[0])
297
-                        bitrate = m.group(1) if m else s["bitrate"]
298
-                        url2 = cc[1].encode("utf8")
299
-                        if not url2.startswith("http"):
300
-                            uu = url.split("/")[:-1]
301
-                            uu.append(url2)
302
-                            url2 = "/".join(uu)
303
-                        stream = util.item()
304
-                        stream["url"]=url2
305
-                        stream["name"]=title
306
-                        stream["desc"]=desc
307
-                        stream["img"]=img
308
-                        stream["type"]="hls"
309
-                        stream["quality"]=("%s %s %s,%s"%(bitrate,resolution,c["supplier"],c["priority"])).encode("utf8")
310
-                        stream["lang"]="en"
311
-                        stream["subs"]=captions
312
-                        stream["order"]=int(bitrate)
313
-                        streams.append(stream)
314
-        if captions:
315
-            for s in streams:
316
-                s["subs"]=captions
317
-        streams = sorted(streams,key=lambda item: item["order"],reverse=True)
318
-        return streams
319
-
320
-    def is_video(self,data):
321
-        if "::" in data:
322
-            data = data.split("::")[1]
323
-        cmd = data.split("/")
324
-        if cmd[0]=="live" and  len(cmd)==2:
325
-            return True
326
-        elif cmd[0]=="episodes" and len(cmd)==2:
327
-            return True
328
-        else:
329
-            return False
330
-
331
-    def get_data_element(self,item):
332
-        if ("programme" in item["type"] or "group" in item["type"]) and item["count"]>1:
333
-            ep = item.copy()
334
-        elif ("programme" in item["type"] or "group" in item["type"]) and item["count"]==1:
335
-            ep = item["initial_children"][0].copy()
336
-        elif item["type"] == "episode":
337
-            ep = item.copy()
338
-        elif item["type"] == "broadcast":
339
-            ep = item["episode"].copy()
340
-        else:
341
-            ep = item.copy()
342
-        title = ep["title"]
343
-        if "subtitle" in ep and ep["subtitle"]:
344
-            title = title+". "+ ep["subtitle"]
345
-        desc = ep["synopses"]["large"] if "large" in ep["synopses"] else ep["synopses"]["medium"] if "medium" in ep["synopses"] else ep["synopses"]["small"]
346
-        #TODO papildus info pie apraksta
347
-        img = ep["images"]["standard"].replace("{recipe}","512x288") if "images" in ep else self.img
348
-        if ep["type"] == "episode":
349
-            data2 = "episodes/%s"%ep["id"]
350
-        elif "programme" in ep["type"]:
351
-            data2 = "programmes/%s/episodes?per_page=40&page=1"%ep["id"]
352
-            title = "%s [%s episodes]"%(title,ep["count"])
353
-        elif "group" in ep["type"]:
354
-            data2 = "groups/%s/episodes?per_page=40&page=1"%ep["id"]
355
-            title = "%s [%s episodes]"%(title,ep["count"])
356
-        else:
357
-            data2 = "programmes/%s/episodes?per_page=40&page=1"%ep["id"]
358
-            title = "%s [%s episodes]"%(title,ep["count"])
359
-        return title,data2,img,desc
360
-
361
-    def get_epg_video(self,vid):
362
-        data = "episodes/%s"%vid
363
-        r = self.call(data)
364
-        if "episodes" in r :
365
-            ep = r["episodes"][0]
366
-            title = ep["title"]
367
-            if "subtitle" in ep:
368
-                title = title +". "+ ep["subtitle"]
369
-            title = title
370
-            desc = ep["synopses"]["medium"] if "medium" in ep["synopses"] else p["synopses"]["small"] if "small" in ep["synopses"] else title
371
-            desc = desc
372
-            ver = ep["versions"][0]
373
-            vid = ver["id"]
374
-            remaining = ver["availability"]["remaining"]["text"]
375
-            duration = ver["duration"]
376
-            first_broadcast = ver["first_broadcast"]
377
-            desc =u"%s\n%s\%s\n%s\n%s"%(title,duration,remaining,first_broadcast,desc)
378
-            img = ep["images"]["standard"].replace("{recipe}","512x288")
379
-            return title.encode("utf8"),img.encode("utf8"),desc.encode("utf8"),vid.encode("utf8")
380
-        else:
381
-            raise Exception("No video info")
382
-
383
-    def get_epg_live(self,channelid):
384
-        data = "channels/%s/highlights?live=true"%channelid
385
-        r = self.call(data)
386
-        if "channel_highlights" in r and r["channel_highlights"]["elements"][0]["id"] == "live":
387
-            epg = r["channel_highlights"]["elements"][0]["initial_children"][0].copy()
388
-            t1 = gt(epg['scheduled_start'])
389
-            t2 = gt(epg['scheduled_end'])
390
-            ep = epg["episode"]
391
-            title = ep["title"]
392
-            if "subtitle" in ep:
393
-                title = title +". "+ ep["subtitle"]
394
-            title = "%s (%s-%s)"%(title,t1.strftime("%H:%M"),t2.strftime("%H:%M"))
395
-            title = title
396
-            desc = ep["synopses"]["medium"] if "medium" in ep["synopses"] else p["synopses"]["small"] if "small" in ep["synopses"] else title
397
-            desc = desc
398
-            desc ="%s\n%s"%(title,desc)
399
-            img = ep["images"]["standard"].replace("{recipe}","512x288")
400
-            #return title,img,desc
401
-        else:
402
-            title = r["channel_highlights"]["channel"]["title"]
403
-            img = ""
404
-            desc = title
405
-
406
-        return title.encode("utf8"),img.encode("utf8"),desc.encode("utf8")
407
-
408
-    def get_channels(self):
409
-        if self.ch:
410
-            return self.ch
411
-        r= self.call("channels")
412
-        self.ch=[]
413
-        for i,item in enumerate(r["channels"]):
414
-            self.ch.append(item)
415
-            self.ch_id[item["id"]]=i
416
-            self.ch_id2[item["master_brand_id"]]=i
417
-            self.ch_name[item["title"]]=i
418
-        return self.ch
419
-
420
-    def get_channel_by_id(self,chid):
421
-        if not self.ch:
422
-            self.get_channels()
423
-        if not self.ch:
424
-            return None
425
-        return self.ch[self.ch_id[chid]] if self.ch_id.has_key(chid) else None
426
-
427
-    def get_channel_by_id2(self,chid):
428
-        if not self.ch:
429
-            self.get_channels()
430
-        if not self.ch:
431
-            return None
432
-        return self.ch[self.ch_id2[chid]] if self.ch_id2.has_key(chid) else None
433
-
434
-    def get_channel_by_name(self,name):
435
-        if not self.ch:
436
-            self.get_channels()
437
-        ch2 = self.get_channel_by_name2(name)
438
-        if not ch2:
439
-            return None
440
-        ch = self.get_channel_by_id2(ch2["id2"])
441
-        return ch
442
-
443
-
444
-    def call(self, data,params = None, headers=None):
445
-        if not headers: headers = self.headers
446
-        #if not lang: lang = self.country
447
-        url = self.api_url + data
448
-        content = self._http_request(url,params, headers)
449
-        if content:
450
-            try:
451
-                result = json.loads(content)
452
-                return result
453
-            except Exception, ex:
454
-                return None
455
-        else:
456
-            return None
457
-
458
-    def call2(self, data,params = None, headers=None):
459
-        if not headers: headers = self.headers2
460
-        #if not lang: lang = self.country
461
-        url = self.api_url2 + data
462
-        content = self._http_request(url,params, headers)
463
-        return content
464
-
465
-    def _http_request(self, url,params = None, headers=None):
466
-        if not headers: headers = self.headers
467
-        import requests
468
-        try:
469
-            r = requests.get(url, headers=headers)
470
-            return r.content
471
-
472
-        except Exception as ex:
473
-            if ex.code==403:
474
-                return ex.read()
475
-            else:
476
-                return None
477
-
478
-def gt(dt_str):
479
-    dt, _, us= dt_str.partition(".")
480
-    dt= datetime.datetime.strptime(dt, "%Y-%m-%dT%H:%M:%S")
481
-    dt = dt - datetime.timedelta(seconds=time.altzone)
482
-    #us= int(us.rstrip("Z"), 10)
483
-    #r = dt + datetime.timedelta(microseconds=us)a
484
-    return dt
485
-
486
-if __name__ == "__main__":
487
-    c = Source()
488
-    from subprocess import call
489
-    #ch = c.get_channels()
490
-    #c.get_epg_live("bbc_two_england")
491
-
492
-    if len(sys.argv)>1 and  not "iplayer::" in sys.argv[1]:
493
-
494
-        vid = sys.argv[1]
495
-        print "login - %s"%c.login("ivars777","xxx")
496
-        vid = "1069"
497
-        vid = "1462566072086"
498
-        channelid="101"
499
-        vid = "1350462656767"
500
-        #data = c.get_stream_url(vid,"vod")
501
-        #call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",data["stream"]])
502
-        pass
503
-
504
-
505
-
506
-    else:
507
-        if len(sys.argv)>1:
508
-            data= sys.argv[1]
509
-        else:
510
-            data = "iplayer::home"
511
-        content = c.get_content(data)
512
-        for item in content:
513
-            print item
514
-        #cat = api.get_categories(country)
515
-        #chan = api.get_channels("lv")
516
-        #prog = api.get_programs(channel=6400)
517
-        #prog = api.get_programs(category=55)
518
-        #seas = api.get_seasons(program=6453)
519
-        #str = api.get_streams(660243)
520
-        #res = api.get_videos(802)
521
-        #formats = api.getAllFormats()
522
-        #det = api.detailed("1516")
523
-        #vid = api.getVideos("13170")
524
-        pass

+ 0
- 261
resources/lib/sources0/jsinterp.py View File

@@ -1,261 +0,0 @@
1
-# This code comes from youtube-dl: https://github.com/rg3/youtube-dl/blob/master/youtube_dl/jsinterp.py
2
-
3
-from __future__ import unicode_literals
4
-
5
-import json
6
-import operator
7
-import re
8
-
9
-
10
-_OPERATORS = [
11
-    ('|', operator.or_),
12
-    ('^', operator.xor),
13
-    ('&', operator.and_),
14
-    ('>>', operator.rshift),
15
-    ('<<', operator.lshift),
16
-    ('-', operator.sub),
17
-    ('+', operator.add),
18
-    ('%', operator.mod),
19
-    ('/', operator.truediv),
20
-    ('*', operator.mul),
21
-]
22
-_ASSIGN_OPERATORS = [(op + '=', opfunc) for op, opfunc in _OPERATORS]
23
-_ASSIGN_OPERATORS.append(('=', lambda cur, right: right))
24
-
25
-_NAME_RE = r'[a-zA-Z_$][a-zA-Z_$0-9]*'
26
-
27
-
28
-class JSInterpreter(object):
29
-    def __init__(self, code, objects=None):
30
-        if objects is None:
31
-            objects = {}
32
-        self.code = code
33
-        self._functions = {}
34
-        self._objects = objects
35
-
36
-    def interpret_statement(self, stmt, local_vars, allow_recursion=100):
37
-        if allow_recursion < 0:
38
-            print '[JSInterpreter] Recursion limit reached'
39
-            return None
40
-
41
-        should_abort = False
42
-        stmt = stmt.lstrip()
43
-        stmt_m = re.match(r'var\s', stmt)
44
-        if stmt_m:
45
-            expr = stmt[len(stmt_m.group(0)):]
46
-        else:
47
-            return_m = re.match(r'return(?:\s+|$)', stmt)
48
-            if return_m:
49
-                expr = stmt[len(return_m.group(0)):]
50
-                should_abort = True
51
-            else:
52
-                # Try interpreting it as an expression
53
-                expr = stmt
54
-
55
-        v = self.interpret_expression(expr, local_vars, allow_recursion)
56
-        return v, should_abort
57
-
58
-    def interpret_expression(self, expr, local_vars, allow_recursion):
59
-        expr = expr.strip()
60
-
61
-        if expr == '':  # Empty expression
62
-            return None
63
-
64
-        if expr.startswith('('):
65
-            parens_count = 0
66
-            for m in re.finditer(r'[()]', expr):
67
-                if m.group(0) == '(':
68
-                    parens_count += 1
69
-                else:
70
-                    parens_count -= 1
71
-                    if parens_count == 0:
72
-                        sub_expr = expr[1:m.start()]
73
-                        sub_result = self.interpret_expression(
74
-                            sub_expr, local_vars, allow_recursion)
75
-                        remaining_expr = expr[m.end():].strip()
76
-                        if not remaining_expr:
77
-                            return sub_result
78
-                        else:
79
-                            expr = json.dumps(sub_result) + remaining_expr
80
-                        break
81
-            else:
82
-                print '[JSInterpreter] Premature end of parens in %r' % expr
83
-                return None
84
-
85
-        for op, opfunc in _ASSIGN_OPERATORS:
86
-            m = re.match(r'''(?x)
87
-                (?P<out>%s)(?:\[(?P<index>[^\]]+?)\])?
88
-                \s*%s
89
-                (?P<expr>.*)$''' % (_NAME_RE, re.escape(op)), expr)
90
-            if not m:
91
-                continue
92
-            right_val = self.interpret_expression(
93
-                m.group('expr'), local_vars, allow_recursion - 1)
94
-
95
-            if m.groupdict().get('index'):
96
-                lvar = local_vars[m.group('out')]
97
-                idx = self.interpret_expression(
98
-                    m.group('index'), local_vars, allow_recursion)
99
-                assert isinstance(idx, int)
100
-                cur = lvar[idx]
101
-                val = opfunc(cur, right_val)
102
-                lvar[idx] = val
103
-                return val
104
-            else:
105
-                cur = local_vars.get(m.group('out'))
106
-                val = opfunc(cur, right_val)
107
-                local_vars[m.group('out')] = val
108
-                return val
109
-
110
-        if expr.isdigit():
111
-            return int(expr)
112
-
113
-        var_m = re.match(
114
-            r'(?!if|return|true|false)(?P<name>%s)$' % _NAME_RE,
115
-            expr)
116
-        if var_m:
117
-            return local_vars[var_m.group('name')]
118
-
119
-        try:
120
-            return json.loads(expr)
121
-        except ValueError:
122
-            pass
123
-
124
-        m = re.match(
125
-            r'(?P<var>%s)\.(?P<member>[^(]+)(?:\(+(?P<args>[^()]*)\))?$' % _NAME_RE,
126
-            expr)
127
-        if m:
128
-            variable = m.group('var')
129
-            member = m.group('member')
130
-            arg_str = m.group('args')
131
-
132
-            if variable in local_vars:
133
-                obj = local_vars[variable]
134
-            else:
135
-                if variable not in self._objects:
136
-                    self._objects[variable] = self.extract_object(variable)
137
-                obj = self._objects[variable]
138
-
139
-            if arg_str is None:
140
-                # Member access
141
-                if member == 'length':
142
-                    return len(obj)
143
-                return obj[member]
144
-
145
-            assert expr.endswith(')')
146
-            # Function call
147
-            if arg_str == '':
148
-                argvals = tuple()
149
-            else:
150
-                argvals = tuple([
151
-                    self.interpret_expression(v, local_vars, allow_recursion)
152
-                    for v in arg_str.split(',')])
153
-
154
-            if member == 'split':
155
-                assert argvals == ('',)
156
-                return list(obj)
157
-            if member == 'join':
158
-                assert len(argvals) == 1
159
-                return argvals[0].join(obj)
160
-            if member == 'reverse':
161
-                assert len(argvals) == 0
162
-                obj.reverse()
163
-                return obj
164
-            if member == 'slice':
165
-                assert len(argvals) == 1
166
-                return obj[argvals[0]:]
167
-            if member == 'splice':
168
-                assert isinstance(obj, list)
169
-                index, howMany = argvals
170
-                res = []
171
-                for i in range(index, min(index + howMany, len(obj))):
172
-                    res.append(obj.pop(index))
173
-                return res
174
-
175
-            return obj[member](argvals)
176
-
177
-        m = re.match(
178
-            r'(?P<in>%s)\[(?P<idx>.+)\]$' % _NAME_RE, expr)
179
-        if m:
180
-            val = local_vars[m.group('in')]
181
-            idx = self.interpret_expression(
182
-                m.group('idx'), local_vars, allow_recursion - 1)
183
-            return val[idx]
184
-
185
-        for op, opfunc in _OPERATORS:
186
-            m = re.match(r'(?P<x>.+?)%s(?P<y>.+)' % re.escape(op), expr)
187
-            if not m:
188
-                continue
189
-            x, abort = self.interpret_statement(
190
-                m.group('x'), local_vars, allow_recursion - 1)
191
-            if abort:
192
-                print '[JSInterpreter] Premature left-side return of %s in %r' % (op, expr)
193
-                return None
194
-            y, abort = self.interpret_statement(
195
-                m.group('y'), local_vars, allow_recursion - 1)
196
-            if abort:
197
-                print '[JSInterpreter] Premature right-side return of %s in %r' % (op, expr)
198
-                return None
199
-            return opfunc(x, y)
200
-
201
-        m = re.match(
202
-            r'^(?P<func>%s)\((?P<args>[a-zA-Z0-9_$,]+)\)$' % _NAME_RE, expr)
203
-        if m:
204
-            fname = m.group('func')
205
-            argvals = tuple([
206
-                int(v) if v.isdigit() else local_vars[v]
207
-                for v in m.group('args').split(',')])
208
-            if fname not in self._functions:
209
-                self._functions[fname] = self.extract_function(fname)
210
-            return self._functions[fname](argvals)
211
-
212
-        print '[JSInterpreter] Unsupported JS expression %r' % expr
213
-        return None
214
-
215
-    def extract_object(self, objname):
216
-        obj = {}
217
-        obj_m = re.search(
218
-            (r'(?:var\s+)?%s\s*=\s*\{' % re.escape(objname)) +
219
-            r'\s*(?P<fields>([a-zA-Z$0-9]+\s*:\s*function\(.*?\)\s*\{.*?\}(?:,\s*)?)*)' +
220
-            r'\}\s*;',
221
-            self.code)
222
-        fields = obj_m.group('fields')
223
-        # Currently, it only supports function definitions
224
-        fields_m = re.finditer(
225
-            r'(?P<key>[a-zA-Z$0-9]+)\s*:\s*function'
226
-            r'\((?P<args>[a-z,]+)\){(?P<code>[^}]+)}',
227
-            fields)
228
-        for f in fields_m:
229
-            argnames = f.group('args').split(',')
230
-            obj[f.group('key')] = self.build_function(argnames, f.group('code'))
231
-
232
-        return obj
233
-
234
-    def extract_function(self, funcname):
235
-        func_m = re.search(
236
-            r'''(?x)
237
-                (?:function\s+%s|[{;,]%s\s*=\s*function|var\s+%s\s*=\s*function)\s*
238
-                \((?P<args>[^)]*)\)\s*
239
-                \{(?P<code>[^}]+)\}''' % (
240
-                re.escape(funcname), re.escape(funcname), re.escape(funcname)),
241
-            self.code)
242
-        if func_m is None:
243
-            print '[JSInterpreter] Could not find JS function %r' % funcname
244
-            return None
245
-        argnames = func_m.group('args').split(',')
246
-
247
-        return self.build_function(argnames, func_m.group('code'))
248
-
249
-    def call_function(self, funcname, *args):
250
-        f = self.extract_function(funcname)
251
-        return f(args)
252
-
253
-    def build_function(self, argnames, code):
254
-        def resf(args):
255
-            local_vars = dict(zip(argnames, args))
256
-            for stmt in code.split(';'):
257
-                res, abort = self.interpret_statement(stmt, local_vars)
258
-                if abort:
259
-                    break
260
-            return res
261
-        return resf

+ 0
- 4
resources/lib/sources0/ltc.cfg View File

@@ -1,4 +0,0 @@
1
-[ltc]
2
-user = lietotajs
3
-password = parole
4
-

+ 0
- 1018
resources/lib/sources0/ltc.py
File diff suppressed because it is too large
View File


+ 0
- 230
resources/lib/sources0/movieplace.py View File

@@ -1,230 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-import urllib2, urllib
13
-import datetime, re, sys,os
14
-import ConfigParser
15
-from collections import OrderedDict
16
-from SourceBase import SourceBase
17
-import resolver
18
-try:
19
-    import util
20
-except:
21
-    sys.path.insert(0,'..')
22
-    import util
23
-
24
-
25
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
26
-import HTMLParser
27
-h = HTMLParser.HTMLParser()
28
-
29
-class Source(SourceBase):
30
-
31
-    def __init__(self, country=""):
32
-        self.name = "movieplace"
33
-        self.title = "MoviePlace.lv"
34
-        self.img = "http://movieplace.lv/images/logo.png"
35
-        self.desc = "Movieplace.lv - filmas latviesu valodā"
36
-        self.headers = headers2dict("""
37
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
38
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
39
-Accept-Language: en-US,en;q=0.5
40
-""")
41
-        self.headers2 = headers2dict("""
42
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
43
-X-Requested-With: XMLHttpRequest
44
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
45
-""")
46
-        self.url = "http://movieplace.lv/"
47
-
48
-
49
-    ######### Entry point ########
50
-    def get_content(self, data):
51
-        print "[movieplace] get_content:", data
52
-        source, data, path, plist, clist, params, qs = self.parse_data(data)
53
-        content = []
54
-        content.append(("..return", "back","","Return back"))
55
-
56
-        if clist=="home":
57
-            content.extend([
58
-                ("Meklēt", "movieplace::search/?q={0}","","Meklēt"),
59
-                ("Jaunākās filmas", "movieplace::load/?page1","","Visu žanru jaunākās filmas"),
60
-                ("Jaunākie seriāli", "movieplace::dir/?page1","","Visu žanru jaunākās filmas"),
61
-                #("Top50 filmas", "movieplace::index/top_50_filmas/0-4","","Top 50 filmas"),
62
-            ])
63
-            r = self.call("load/")
64
-            #i = r.find('<div class="cat-title">Meklēt pēc žanriem</div>')
65
-            #if i<=0:
66
-            #    return content
67
-            i = 0
68
-            for item in re.findall('<a href="/([^"]+)" class="catName">([^>]+)</a>', r[i:]):
69
-                title = item[1]
70
-                data2 = item[0]+"-1"
71
-                img = self.img
72
-                desc = title
73
-                content.append((title,self.name+"::"+data2,img,desc))
74
-            return content
75
-
76
-        elif clist=="search":
77
-            # TODO
78
-            r=self.call(data)
79
-            result = re.findall('<a href="([^"]+)"> (.+?) </a></div>.+?> (.+?)</div>', r, re.DOTALL)
80
-            for item in result:
81
-                title = item[1].replace("<b>","").replace("</b>","")
82
-                data2 = item[0].replace("http://movieplace.lv/","")
83
-                img = self.img
84
-                desc = item[2].replace("<b>","").replace("</b>","")
85
-                content.append((title,self.name+"::"+data2,img,desc))
86
-            if '<span>&raquo;</span>' in r:
87
-                m = re.search("p=(\d+)",data)
88
-                if m:
89
-                    page = int(m.group(1))+1
90
-                    data2 = re.sub(r"p=\d+", r"p=%s"%page, data)
91
-                    content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
92
-            return content
93
-
94
-        # Filmu saraksti ##
95
-        elif clist in ["load","dir"] and len(plist)<=3:
96
-            if clist == "jaunakas":
97
-                r = self.call("")
98
-            else:
99
-                r = self.call(data)
100
-            #r = r.decode("cp1251").encode("utf8")
101
-            if clist == "load":
102
-                result = re.findall(r' <a href="/([^"]+)" alt="([^"]+)"><img src="/([^"]+)" title="([^"]+)">.+?<div class="years">([^<]+)</div>\s+<div class="country">([^<]+)</div>', r, re.DOTALL)
103
-            else:
104
-                result = re.findall(r' <a href="/([^"]+)" alt="([^"]+)"><img src="/([^"]+)" title="[^"]+">.+?<span>([^<]+)</span>\s*<div class="country">([^<]+)</div>', r, re.IGNORECASE | re.DOTALL)
105
-            for item in result:
106
-                title = item[1]+" [%s]"%item[4] if clist=="load" else item[1]+" / %s [%s]"%(item[3],item[4])
107
-                img = "http://movieplace.lv/"+item[2]
108
-                data2 = item[0]
109
-                desc = "%s\n%s"%(title,item[5]) if clist=="load" else title
110
-                content.append((title,self.name+"::"+data2,img,desc))
111
-            m = re.search('<[ab] class="swchItemA*1"( href="/([^"]+)" onclick="[^"]+")*><span>([^<]+)</span></[ab]> </span>', r, re.DOTALL)
112
-            if m:
113
-                if m.group(1):
114
-                    page = int(re.search("\d+$",data).group())
115
-                    page = page+1
116
-                    data2 = re.sub("\d$","%s"%page,data)
117
-                    content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
118
-            return content
119
-
120
-        ### Seriāls ###
121
-        elif clist=="dir" and len(plist)==4:
122
-            r = self.call(path)
123
-            title0 = re.search('<h2 class="title" itemprop="name">(.+?)</h2>', r, re.DOTALL).group(1)
124
-            m = re.search(r'<span>VALODA:</span> <b><em itemprop="alternativeHeadline"><a href="[^"]*" class="entAllCats">([^<]+)</a></em></b></div>\s+?<div><span>SEZONA:</span> <b>([^<]+)</b></div>', r, re.IGNORECASE | re.DOTALL)
125
-            if m:
126
-                title0 = "%s / Season %s [%s]"%(title0,m.group(2),m.group(1))
127
-            desc0 = title0
128
-            img0 = "http://movieplace.lv" + re.search('<img src="(.+?)".+?itemprop="image">', r, re.DOTALL).group(1)
129
-            #TODO
130
-            result = re.findall(r'<summary>([^<]+)</summary><iframe src="https://openload\.co/embed/[^/]+/"', r, re.DOTALL)
131
-            i = 1
132
-            for item in result:
133
-                title = title0+" - " + item
134
-                data2 = data+"?e=%s"%i
135
-                img = img0
136
-                desc = desc0
137
-                content.append((title,self.name+"::"+data2,img,desc))
138
-                i += 1
139
-            return content
140
-
141
-        ### kaut kas neparedzets ###
142
-        else:
143
-            return content
144
-
145
-    def is_video(self,data):
146
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
147
-        if clist=="dir" and len(plist) == 4 and "e"in qs: # sērija
148
-            return True
149
-        elif clist=="load" and len(plist) == 4:
150
-            return True
151
-        else:
152
-            return False
153
-
154
-    def call(self, data,params=None,headers=None,lang=""):
155
-        if not headers: headers = self.headers
156
-        url = self.url+data
157
-        result = self._http_request(url,params,headers=headers)
158
-        return result
159
-
160
-    def get_streams(self,data):
161
-        print "[movieplace] get_streams:", data
162
-        if not self.is_video(data):
163
-            return []
164
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
165
-        r = self.call(path)
166
-        if clist=="load":
167
-            m = re.search('<h2 class="title" itemprop="name">([^<]+)</h2>', r, re.DOTALL)
168
-            title = re.search('<itemprop="name">(.+?)</itemprop="name">', r, re.DOTALL).group(1)
169
-            m = re.search(r'<div role="tabpanel" class="tab-pane fade in active" id="heading-tab4">\s*(.+?)\s*</div>', r, re.DOTALL)
170
-            desc = m.group(1) if m else title
171
-            m = re.search('<meta property="og:image" content="([^"]+)" />', r, re.DOTALL)
172
-            img = m.group(1) if m else ""
173
-            rr = []
174
-            for m in re.finditer("(RU|ENG|LAT|LAT SUB)<BR( /)*>.*?>?<BR( /)*>.*?<iframe", r, re.IGNORECASE | re.DOTALL):
175
-                if len(rr)>0:
176
-                    rr[-1]["end"] = m.start()
177
-                rr.append({"lang":m.group(1),"start":m.start(),"end":len(r)})
178
-            streams = []
179
-            for m in re.finditer(r'src="(https*://(goo\.gl|songs2dl|kodik|cdn\.kapnob|hqq|openload|sv1.servkino|vidwatch|online\.kinozz).+?)"', r, re.IGNORECASE | re.DOTALL):
180
-                url = m.group(1)
181
-                lang = "?"
182
-                for rrr in rr:
183
-                    if m.start()>rrr["start"] and m.start()<rrr["end"]:
184
-                        lang = rrr["lang"]
185
-                        break
186
-                for s in resolver.resolve(url):
187
-                    s["name"] = title
188
-                    s["desc"] = desc
189
-                    s["img"] = img
190
-                    s["type"] = self.stream_type(s["url"])
191
-                    s["lang"] = lang
192
-                    streams.append(s)
193
-            return streams
194
-
195
-
196
-        elif clist=="dir" and "e" in qs: # serialā sērija
197
-            #TODO
198
-            result = re.findall(r'<summary>([^<]+)</summary><iframe src="([^"]+)"', r, re.DOTALL)
199
-            i = int(qs["s"])-1
200
-            url0 = result[i][1]
201
-            title = title + " - " + result[i][0]
202
-        else:
203
-            #iframe src="https://openload.co/embed/wlw6Vl9zwL0/"
204
-            result = re.findall(r'<iframe src="([^"]+)"', r, re.DOTALL)
205
-            if not result:
206
-                return []
207
-            url0 = result[0]
208
-        return streams
209
-
210
-if __name__ == "__main__":
211
-    country= "lv"
212
-    c = Source(country)
213
-    if len(sys.argv)>1:
214
-        data= sys.argv[1]
215
-    else:
216
-        data = "home"
217
-    content = c.get_content(data)
218
-    for item in content:
219
-        print item
220
-    #cat = api.get_categories(country)
221
-    #chan = api.get_channels("lv")
222
-    #prog = api.get_programs(channel=6400)
223
-    #prog = api.get_programs(category=55)
224
-    #seas = api.get_seasons(program=6453)
225
-    #str = api.get_streams(660243)
226
-    #res = api.get_videos(802)
227
-    #formats = api.getAllFormats()
228
-    #det = api.detailed("1516")
229
-    #vid = api.getVideos("13170")
230
-    pass

+ 0
- 279
resources/lib/sources0/mtgplay.py View File

@@ -1,279 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-
9
-
10
-try:
11
-    import json
12
-except:
13
-    import simplejson as json
14
-#!/usr/bin/env python
15
-# coding=utf8
16
-import urllib2, urllib
17
-import datetime, re, sys
18
-from SourceBase import SourceBase
19
-
20
-API_URL = 'http://playapi.mtgx.tv/v3/'
21
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
22
-headers0 = headers2dict("""
23
-User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
24
-""")
25
-
26
-REGIONS = [
27
-    ("Latvia",None,"lv",""),
28
-    ("Estonia",None,"ee",""),
29
-    ("Lituania",None,"lt",""),
30
-    ("Sweden",None,"se",""),
31
-    ("Denmark",None,"dk",""),
32
-    ("Norway",None,"no",""),
33
-    ("Bulgaria",None,"bg","")
34
-]
35
-
36
-
37
-class Source(SourceBase):
38
-    
39
-    def __init__(self,country="lv"):
40
-        self.name = "mtgplay"
41
-        self.title = "Skaties.lv (TV3)"
42
-        self.img = "http://skaties.lv/touch-icon-192x192.png"
43
-        self.desc = "MTG skaties.lv satura skatīšanās (LNT,TV3, TV6 u.c.)"
44
-        
45
-        self.country=country
46
-        self.pic_size = "327x250" #"1000x765"
47
-        
48
-    def get_content(self, data):
49
-        print "[mtgplay] get_content:", data
50
-        if "::" in data:
51
-            data = data.split("::")[1]        
52
-        if "/" in data:
53
-            citem,cid = data.split("/")
54
-            clist = ""
55
-        else:
56
-            clist = data.split("?")[0]
57
-            qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",data)))
58
-            citem,cid = ("","")
59
-            self.country = qs["country"] if "country" in qs else "lv"
60
-        
61
-        content=[]
62
-        content.append(("..return", "back","","Return back"))
63
-        
64
-        if clist=="home":
65
-            content.extend([
66
-                #("Search", "mtgplay::meklet?country=%s&term={0}"%self.country,"","Search videos"), ### TODO                
67
-                ("TV Live", "mtgplay::videos?country=%s&order=title&type=live"%self.country,"","TV live streams(not always available)"),
68
-                ("Last videos", "mtgplay::videos?country=%s&order=-airdate"%self.country,"","Last aired videos"),
69
-                ("Categories", "mtgplay::categories?country=%s&order=name"%self.country,"","Categories"),
70
-                ("Channels", "mtgplay::channels?country=%s&order=id"%self.country,"","TV channels"),
71
-                ("Programs by name", "mtgplay::formats?country=%s&order=-title"%self.country,"","Programs by name"),             
72
-                ("Programs by popularity", "mtgplay::formats?country=%s&order=-popularity"%self.country,"","Programs by popularity")             
73
-            ])
74
-            return content
75
-        
76
-        r = self.call(data)
77
-        if not r:
78
-            content.append(("Error", "","","Error reading '%s'"%data))
79
-            return content
80
-        
81
-        if clist:
82
-            if r["_links"].has_key("prev"):
83
-                data2 = r["_links"]["prev"]["href"].replace(API_URL,"")
84
-                content.append(("Previous page", self.name+"::"+data2.encode("utf8"),"", "Goto previous page"))
85
-                
86
-            if "_embedded" in r:
87
-                for item in r["_embedded"][clist]:
88
-                    if "title" in item:
89
-                        title = item["title"]
90
-                    elif "name" in item:
91
-                        title = item["name"]
92
-                    #data2 = self.name+"::"+"%s/%s"%(clist,item["id"]) 
93
-                    img = item["_links"]["image"]["href"].replace("{size}",self.pic_size) if "image" in item["_links"] else ""
94
-                    desc = item["summary"] if "summary" in item and item["summary"] else ""
95
-                    
96
-                    ### Video ###
97
-                    if clist=="videos":
98
-                        data2 = "videos/%s"%item["id"]                            
99
-                        summary = item["summary"] if item["summary"] else ""
100
-                        air_at = item["broadcasts"][0]["air_at"] if "broadcasts" in item and len(item["broadcasts"])>0 and "air_at" in item["broadcasts"][0] else ""
101
-                        if not air_at:
102
-                            air_at = item["publish_at"] if "publish_at" in item else ""
103
-                        air_at = air_at[0:16].replace("T"," ") if air_at else ""
104
-                        try: playable_to = item["broadcasts"][0]["playable_to"]
105
-                        except: playable_to =""
106
-                        playable_to = "(till "+playable_to[0:10].replace("T"," ")+")" if playable_to else ""
107
-                        duration = item["duration"] if "duration" in item else ""
108
-                        duration = str(datetime.timedelta(seconds=int(duration))) if duration else ""
109
-                        try:
110
-                            views = item["views"]["total"] if "views" in item and "total" in item["views"] else ""
111
-                            views = views+" views"
112
-                        except: views = ""
113
-                        desc = "Aired: %s %s\nDuration: %s %s\n\n%s"%(air_at, playable_to,duration,views,summary)
114
-                        
115
-                    ### Categories ###     
116
-                    elif clist == "categories":
117
-                        #data2 = item["_links"]["formats"]["href"].replace(API_URL,"")
118
-                        data2 = "formats?category=%s"%item["id"]
119
-                        if "country" in qs: data2 += "&country="+qs["country"]
120
-                        if "category" in qs: data2 += "&category="+qs["category"]
121
-                        if "channel" in qs: data2 += "&channel="+qs["channel"]
122
-                        data2 += "&order=title"
123
-                        
124
-                    ### Channels ###     
125
-                    elif clist == "channels":
126
-                        #data2 = item["_links"]["categories"]["href"].replace(API_URL,"")
127
-                        data2 = "categories?channel=%s"%item["id"]
128
-                        if "country" in qs: data2 += "&country="+qs["country"]
129
-                        if "category" in qs: data2 += "&category="+qs["category"]
130
-                        if "channel" in qs: data2 += "&channel="+qs["channel"]
131
-                        data2 += "&order=name"
132
-                        
133
-                    ### Formats (programs) ###     
134
-                    elif clist == "formats":
135
-                        #data2 = item["_links"]["videos"]["href"].replace(API_URL,"")
136
-                        data2 = "seasons?format=%s"%item["id"]
137
-                        #if "country" in qs: data2 += "&country="+qs["country"]
138
-                        #if "category" in qs: data2 += "&category="+qs["category"]
139
-                        #if "channel" in qs: data2 += "&channel="+qs["channel"]
140
-                        data2 += "&order=title"
141
-                        air_at = item["latest_video"]["publish_at"] if "publish_at" in item["latest_video"] else ""
142
-                        air_at = air_at[0:16].replace("T"," ") if air_at else ""
143
-                        if air_at:
144
-                            desc = "Last video: %s\n"%air_at + desc                        
145
-                        
146
-                    ### Seasons ###     
147
-                    elif clist == "seasons":
148
-                        #data2 = item["_links"]["videos"]["href"].replace(API_URL,"")
149
-                        data2 = "videos?season=%s"%item["id"]
150
-                        #if "country" in qs: data2 += "&country="+qs["country"]
151
-                        #if "category" in qs: data2 += "&category="+qs["category"]
152
-                        #if "channel" in qs: data2 += "&channel="+qs["channel"]
153
-                        data2 += "&order=title"
154
-                        
155
-                        summary = item["summary"] if "summary" in item and item["summary"] else ""
156
-                        try:
157
-                            latest_video = item["latest_video"]["publish_at"]
158
-                            latest_video = latest_video[0:16].replace("T"," ")
159
-                        except: latest_video = ""
160
-                        desc = ("%s\nLatest video: %s"%(summary,latest_video))
161
-                                      
162
-                    content.append((title.encode("utf8"),self.name+"::"+data2.encode("utf8"),img.encode("utf8"),desc.encode("utf8")))
163
-                    
164
-            if r["_links"].has_key("next"):
165
-                data2 = r["_links"]["next"]["href"].replace(API_URL,"").encode("utf8")
166
-                content.append(("Next page", self.name+"::"+data2.encode("utf8"),"","Goto next page"))
167
-                
168
-        elif citem:
169
-            item = r
170
-            if "title" in item:
171
-                title = item["title"]
172
-            elif "name" in item:
173
-                title = r["name"]
174
-            #data2 = self.name+"::"+"%s/%s"%(clist,item["id"]) 
175
-            img = item["_links"]["image"]["href"].replace("{size}",self.pic_size) if "image" in item["_links"] else ""
176
-            desc = item["summary"] if "summary" in item and item["summary"] else ""
177
-            
178
-            dd = "videos/stream/%s"%cid
179
-            r2 = self.call(dd)
180
-            if "streams" in r2 and "hls" in r2["streams"]:
181
-                data2 = r2["streams"]["hls"]
182
-                content = (title.encode("utf8"),data2.encode("utf8"),img.encode("utf8"),desc.encode("utf8"))
183
-            elif "msg" in r2:
184
-                content = (r2["msg"].encode("utf8"),"","","")
185
-            else: 
186
-                content = ("Error getting stream","","","")            
187
-            
188
-        else:
189
-            pass
190
-        return content
191
-    
192
-    def is_video(self,data):
193
-        if "::" in data:
194
-            data = data.split("::")[1]
195
-        cmd = data.split("/")
196
-        if cmd[0]=="videos":
197
-            return True
198
-        else:
199
-            return False
200
-    
201
-    def get_stream(self,id):   
202
-        dd = "videos/stream/%s"%id
203
-        r2 = self.call(dd)
204
-        if "streams" in r2 and "hls" in r2["streams"]:
205
-            data2 = r2["streams"]["hls"]
206
-        else:
207
-            data2 = ""
208
-        return data2.encode("utf8")
209
-        
210
-    def call_all(self, endpoint, params = None):
211
-        url = API_URL % (endpoint)
212
-        if params:
213
-            url += '?' + params
214
-        print "[TVPlay Api] url: ",url
215
-        result = []
216
-        while True:
217
-            content = self._http_request(url)
218
-            if content:
219
-                try:
220
-                    content = json.loads(content)
221
-                except Exception, ex:
222
-                    return {" Error " : "in call_api: %s" % ex}
223
-            else: break
224
-            if content.has_key("_embedded") and content["_embedded"].has_key(endpoint):
225
-                result.extend(content["_embedded"][endpoint])
226
-                pass
227
-            else: break
228
-            if content.has_key("_links") and content["_links"].has_key("next"):
229
-                url = content["_links"]["next"]["href"]
230
-            else: break
231
-        return result
232
-    
233
-    def call(self, data,headers=headers0):
234
-        url = API_URL + data
235
-        #print "[TVPlay Api] url: ",url
236
-        result = []
237
-        content = self._http_request(url)
238
-        if content:
239
-            try:
240
-                result = json.loads(content)
241
-            except Exception, ex:
242
-                return None
243
-        return result
244
-
245
-    def _http_request0(self, url,headers=headers0):
246
-        try:
247
-            r = urllib2.Request(url, headers=headers)
248
-            u = urllib2.urlopen(r)
249
-            content = u.read()
250
-            u.close()
251
-            return content
252
-        except Exception as ex:
253
-            if "read" in ex:
254
-                content = ex.read()
255
-            else:
256
-                content = None
257
-            return content
258
-
259
-if __name__ == "__main__":
260
-    country= "lv"
261
-    c = Source(country)
262
-    if len(sys.argv)>1:
263
-        data= sys.argv[1]
264
-    else:
265
-        data = "home"
266
-    content = c.get_content(data)
267
-    for item in content:
268
-        print item
269
-    #cat = api.get_categories(country)
270
-    #chan = api.get_channels("lv")
271
-    #prog = api.get_programs(channel=6400)
272
-    #prog = api.get_programs(category=55)
273
-    #seas = api.get_seasons(program=6453)
274
-    #str = api.get_streams(660243)
275
-    #res = api.get_videos(802)
276
-    #formats = api.getAllFormats()
277
-    #det = api.detailed("1516")
278
-    #vid = api.getVideos("13170")
279
-    pass

+ 0
- 212
resources/lib/sources0/play24.py View File

@@ -1,212 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys
15
-from SourceBase import SourceBase
16
-
17
-API_URL = 'http://replay.lsm.lv/'
18
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
19
-headers0 = headers2dict("""
20
-User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
21
-""")
22
-import HTMLParser
23
-h = HTMLParser.HTMLParser()
24
-    
25
-class Source(SourceBase):
26
-    
27
-    def __init__(self,country="lv"):
28
-        self.name = "play24"
29
-        self.title = "Play24.lv"
30
-        self.img = "http://play24.lv/images/play24-logo-black.png"
31
-        self.desc = "play24.lv (Riga24TV) satura skatīšanās"
32
-        
33
-        self.country=country
34
-        
35
-    def get_content(self, data):
36
-        print "[play24] get_content:", data
37
-        if "::" in data:
38
-            data = data.split("::")[1] 
39
-        path = data.split("?")[0]
40
-        clist = path.split("/")[0]
41
-        params = data[data.find("?"):] if "?" in data else ""
42
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
43
-        lang = qs["lang"] if "lang" in qs else self.country
44
-    
45
-        content=[]
46
-        content.append(("..return", "back","","Return back"))
47
-        
48
-        if clist=="home":
49
-            content.extend([
50
-                ("Live stream", "play24::tiesraide","","TV live streams"),
51
-                ("Last videos", "play24::jaunakie","","Last videos"),
52
-                ("Categories", "play24::kategorijas","","Categories"),
53
-                ("Programs", "play24::raidijumi","","Programs"),             
54
-             ])
55
-            return content
56
-  
57
-        ### Jaunākie video ###
58
-        elif clist=="jaunakie":
59
-            url = "http://play24.lv/"
60
-            r = self._http_request(url)
61
-            for item in re.findall(' <div class="top-article__image">.*?<a class="top-article__image-link" href="([^"]+)">.*?<img.+?src="([^"]+)".+?alt="([^"]+)" />.+?</picture>', r, re.DOTALL):
62
-                title = item[2]
63
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
64
-                img = item[1]
65
-                data2 = item[0].replace("http://play24.lv/","")
66
-                desc = title
67
-                content.append((title,self.name+"::"+data2,img,desc))
68
-            return content
69
-                
70
-        ### Kategorijas ###
71
-        elif clist=="kategorijas":
72
-            url = "http://play24.lv/"
73
-            r = self._http_request(url)
74
-            r2 = r[r.find('<div class="footer-navigation">'):]
75
-            for item in re.findall('<a href="http://play24.lv/(kategorija/[^"]+)" class="navigation__link">([^<]+)</a>', r2, re.DOTALL):
76
-                title = item[1]
77
-                data2 = item[0]
78
-                img = ""
79
-                desc = title
80
-                content.append((title,self.name+"::"+data2,img,desc))
81
-            return content
82
-       
83
-        elif clist=="kategorija":
84
-            url = "http://play24.lv/"+data
85
-            r = self._http_request(url)
86
-            for article in re.findall(r"<article\b[^>]*>(.+?)</article>", r, re.DOTALL):
87
-                m = re.search('<a class="masonry-item__link" href="http://play24\.lv/([^"]+)">', article, re.DOTALL)
88
-                data2 = m.group(1) if m else ""
89
-                m = re.search('<img src="([^"]+)" alt="([^"]+)" />', article, re.DOTALL)
90
-                if m:
91
-                    img = m.group(1)
92
-                    title = m.group(2)
93
-                    title =  h.unescape(title.decode("utf8")).encode("utf8")
94
-                else:
95
-                    img = ""
96
-                    title = ""
97
-                m = re.search(r'<span class="masonry-item__tags">\s+<a href="([^"]+)">([^<]+)</a>.*?</span>', article, re.DOTALL)
98
-                progr = m.group(2) if m else ""
99
-                m = re.search('<span class="masonry-item__date">([^<]+)</span>', article, re.DOTALL)
100
-                date = m.group(1).strip() if m else ""
101
-                         
102
-                if date:
103
-                    title = title + " (%s %s)"%(date,progr)
104
-                desc = title + "\n%s - %s"%(progr,date)
105
-                content.append((title,self.name+"::"+data2,img,desc))
106
-            m = re.search(r'<li><a href="http://play24\.lv/([^"]+)" rel="next">&raquo;</a></li>', r, re.DOTALL)
107
-            if m:
108
-                data2 = m.group(1)
109
-                content.append(("Next page",self.name+"::"+data2,"","Next page"))                                            
110
-            return content
111
-        
112
-        ### Raidijumi (programmas)
113
-        elif clist=="raidijumi":
114
-            url = "http://play24.lv/"
115
-            r = self._http_request(url)
116
-            for item in re.findall(r'<li class="tag-box__item">.*?<a href="http://play24\.lv/(birka/[^"]+)">([^<]+)</a>.*?</li>', r, re.DOTALL):
117
-                title = item[1]
118
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
119
-                data2 = item[0]
120
-                img = ""
121
-                desc = title
122
-                content.append((title,self.name+"::"+data2,img,desc))
123
-            return content
124
-
125
-        ### Programmas (video saraksts)
126
-        elif clist=="birka":
127
-            url = "http://play24.lv/"+data
128
-            r = self._http_request(url)
129
-            for item in re.findall(r'<article\b[^>]*>.+?<a class="masonry-item__link" href="http://play24.lv/([^"]+)">.*?<img src="([^"]+)" alt="([^"]+)" />.*?<span class="masonry-item__tags">.+?<a href="([^"]+)">([^<]+)</a>.*?<span class="masonry-item__date">([^<]+)</span>.*?</article>', r, re.DOTALL):
130
-                title = item[2]
131
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
132
-                title = title + " (%s)"%item[5].strip()
133
-                img = item[1]
134
-                data2 = item[0]
135
-                desc = title + "\n%s - %s"%(item[4],item[5].strip())
136
-                content.append((title,self.name+"::"+data2,img,desc))
137
-            m = re.search(r'<li><a href="http://play24\.lv/([^"]+)" rel="next">&raquo;</a></li>', r, re.DOTALL)
138
-            if m:
139
-                data2 = m.group(1)
140
-                content.append(("Next page",self.name+"::"+data2,"","Next page"))                                            
141
-            return content
142
-
143
-        elif clist == "video" or clist == "tiesraide":
144
-            if clist == "video":  
145
-                url = "http://play24.lv/"+data
146
-                r = self._http_request(url)
147
-                # var ov_video_id = '59422';
148
-                m = re.search(r"var ov_video_id = '(\d+)';", r, re.DOTALL)
149
-                if m:
150
-                    id = m.group(1)
151
-                else:
152
-                    return ("No stream found %s"%data,"","","No stream found")
153
-                m = re.search('<meta name="description" content="([^"]+)" />', r, re.DOTALL)
154
-                desc = m.group(1) if m else ""
155
-                desc = h.unescape(desc.decode("utf8")).encode("utf8")
156
-                
157
-                url = "http://player.tvnet.lv/v/%s"%id
158
-            else:
159
-                url = "http://player.tvnet.lv/l/11"
160
-                desc = ""
161
-            r = self._http_request(url)
162
-            m = re.search('<h1 class="static title">.+?<a href="[^"]+">([^<]+)</a>', r, re.DOTALL)
163
-            title = m.group(1) if m else ""   
164
-            s = {}
165
-            for item in re.findall('source src="([^"]+)" data-stream="([^"]+)" data-quality="([^"]+)"', r, re.DOTALL):
166
-                s[item[1]] = (item[0],item[2])
167
-            data2 = ""
168
-            for t in ("hls","http","rtmp"):
169
-                if t in s:
170
-                    data2 = s[t][0]
171
-                    break
172
-            return (title,data2,"",desc)
173
-               
174
-    
175
-    def is_video(self,data):
176
-        if "::" in data:
177
-            data = data.split("::")[1]
178
-        cmd = data.split("/")
179
-        if cmd[0] in ("video","tiesraide"):
180
-            return True
181
-        else:
182
-            return False
183
-    
184
-    def call(self, data,headers=headers0,lang=""):
185
-        if not lang: lang = self.country
186
-        url = API_URL%lang + data
187
-        #print "[TVPlay Api] url: ",url
188
-        result = []
189
-        content = self._http_request(url)
190
-        return content
191
-
192
-if __name__ == "__main__":
193
-    country= "lv"
194
-    c = Source(country)
195
-    if len(sys.argv)>1:
196
-        data= sys.argv[1]
197
-    else:
198
-        data = "home"
199
-    content = c.get_content(data)
200
-    for item in content:
201
-        print item
202
-    #cat = api.get_categories(country)
203
-    #chan = api.get_channels("lv")
204
-    #prog = api.get_programs(channel=6400)
205
-    #prog = api.get_programs(category=55)
206
-    #seas = api.get_seasons(program=6453)
207
-    #str = api.get_streams(660243)
208
-    #res = api.get_videos(802)
209
-    #formats = api.getAllFormats()
210
-    #det = api.detailed("1516")
211
-    #vid = api.getVideos("13170")
212
-    pass

+ 0
- 305
resources/lib/sources0/replay.py View File

@@ -1,305 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys
15
-from SourceBase import SourceBase
16
-import util
17
-
18
-API_URL = 'http://replay.lsm.lv/%s/'
19
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
20
-headers0 = headers2dict("""
21
-User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
22
-""")
23
-import HTMLParser
24
-h = HTMLParser.HTMLParser()
25
-from YouTubeVideoUrl import YouTubeVideoUrl
26
-
27
-class Source(SourceBase):
28
-
29
-    def __init__(self,country="lv"):
30
-        self.name = "replay"
31
-        self.title = "Replay.lv (LTV)"
32
-        self.img = "http://replay.lsm.lv/apple-touch-icon.png"
33
-        self.desc = "LSM replay.lv satura skatīšanās"
34
-
35
-        self.country=country
36
-        self.pic_size = "327x250" #"1000x765"
37
-
38
-    def get_content(self, data):
39
-        print "[replay] get_content:", data
40
-        if "::" in data:
41
-            data = data.split("::")[1]
42
-        path = data.split("?")[0]
43
-        clist = path.split("/")[0]
44
-        params = data[data.find("?"):] if "?" in data else ""
45
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
46
-        lang = qs["lang"] if "lang" in qs else self.country
47
-
48
-        content=[]
49
-        content.append(("..return", "back","","Return back"))
50
-
51
-        if clist=="home":
52
-            content.extend([
53
-                ("Live streams", "replay::tiesraide","","TV live streams"),
54
-                ("Search LV", "replay::search/?term={0}&lang=lv","","Search content LV"),
55
-                ("Last videos LV", "replay::visi/jaunakie/?source=ltv&lang=lv","","Last aired videos LV"),
56
-                ("Last videos by categories LV", "replay::kategorijas/?lang=lv","","Last videos by categories LV"),
57
-                ("All programs LV", "replay::raidijumi/?type=video","","All programs by name LV"),
58
-                ("Programs by categories LV", "replay::categories?lang=lv","","All programs by categories LV"),
59
-                #("Channels", "replay::channels?language=%s"%self.country,"","TV channels"),
60
-                ("Videos by popularity LV", "replay::visi/popularie/?source=ltv&lang=lv","","Programs by popularity"),
61
-
62
-                ("Search RU", "replay::search/?term={0}&lang=ru","","Search content RU"),
63
-                ("Last videos RU", "replay::vse/novie/?source=ltv&lang=ru","","Last aired videos RU"),
64
-                ("Last videos by categories RU", "replay::kategorijas/?lang=ru","","Last videos by categories RU"),
65
-                ("All programs RU", "replay::peredachi/?lang=ru&type=video","","All programs by name"),
66
-                ("Programs by categories RU", "replay::categories?lang=ru","","Programs by categories RU")
67
-            ])
68
-            return content
69
-
70
-        ### programmu kategorijas ###
71
-        elif clist=="categories":
72
-            url = "http://replay.lsm.lv/lv/raidijumi/?lang=lv&type=video" if lang =="lv" else "http://replay.lsm.lv/ru/peredachi/?lang=ru&type=video"
73
-            r = self._http_request(url)
74
-            for item in re.findall(r'<a .+href="(\?lang=\w+&type=video&theme=\d+)">([^<]+)</a>\t', r):
75
-                title = item[1]
76
-                data2 = url.split("?")[0]+item[0]
77
-                data2 = data2.replace(API_URL%lang,"")
78
-                img = ""
79
-                desc = title
80
-                content.append((title,self.name+"::"+data2,img,desc))
81
-            return content
82
-
83
-        ### jaunāko raidijumu kategorijas ###
84
-        elif clist=="kategorijas":
85
-            url = "http://replay.lsm.lv/lv/" if lang =="lv" else "http://replay.lsm.lv/ru/"
86
-            r = self._http_request(url)
87
-            for item in re.findall(r'<a href="/(lv|ru)/kategorija/(\w+)/">.+?<i class="[^"]+"></i>.+?<span>([^<]+)</span>', r, re.DOTALL):
88
-                title = item[2]
89
-                data2 = "kategorija/%s/?lang=%s"%(item[1],item[0])
90
-                img = ""
91
-                desc = title
92
-                content.append((title,self.name+"::"+data2,img,desc))
93
-            return content
94
-
95
-        ### Tiešraides kanānālu saraksts
96
-        elif path=="tiesraide":
97
-            url = "http://replay.lsm.lv/styles/main.css"
98
-            r= self._http_request(url)
99
-            for item in re.findall(r'channel-logo--(\w+)\{background-image:url\("([^"]+\.png)"', r):
100
-                ch = item[0]
101
-                title = ch.upper()
102
-                data2 = "tiesraide/%s/"%ch
103
-                img = "http://replay.lsm.lv"+item[1]
104
-                veids = "video "if "tv" in ch else "audio"
105
-                desc = title+" tiesraide (%s)"%veids
106
-                content.append((title,self.name+"::"+data2,img,desc))
107
-            return content
108
-
109
-        ### Kanāla tiesraide
110
-        elif clist == "tiesraide" and "/" in data:
111
-            ch = data.split('/')[1]
112
-            veids = "video" if "tv" in ch else "audio"
113
-            #url = "http://replay.lsm.lv/lv/tiesraide/ltv7/"
114
-            url = "http://replay.lsm.lv/lv/tiesraide/%s/"%ch
115
-            r= self._http_request(url)
116
-
117
-            m = re.search('%s/">.+?<h5>([^<]+)+</h5>.*?<time>([^<]+)</time>'%ch, r, re.DOTALL)
118
-            tagad = m.group(1).strip() if m else ""
119
-            laiks = m.group(2).strip() if m else ""
120
-            laiks = h.unescape(laiks).encode("utf8")
121
-            m = re.search("<h1>([^<]+)</h1>", r)
122
-            title = m.group(1).strip() if m else path.split("/")[1].upper()
123
-            title = "%s - %s (%s)"%(title,tagad,laiks)
124
-
125
-            if veids == "video":
126
-                m = re.search('<div class="video"><iframe.+src="([^"]+)"', r)
127
-                if not m:
128
-                    content=("No stream found %s"%data,"","","No stream found")
129
-                    return content
130
-                url = m.group(1)
131
-                headers = headers2dict("""
132
-            User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
133
-            Referer: http://replay.lsm.lv/lv/ieraksts/ltv/70398/tiesa-runa.-lielbritanija-gatavojas-referendumam-par-tu/
134
-                    """)
135
-                r = self._http_request(url,headers=headers)
136
-
137
-                m = re.search('<div class="video-player"><iframe.+src="([^"]+)"', r)
138
-                if not m:
139
-                    content=("No stream found %s"%data,"","","No stream found")
140
-                    return content
141
-                url = m.group(1)
142
-
143
-                r = self._http_request(url,headers=headers)
144
-                m = re.search('"([^"]+m3u8[^"]+)"', r)
145
-                if not m:
146
-                    content=("No stream found %s"%data,"","","No stream found")
147
-                    return content
148
-                data2 = m.group(1).replace("\\","")
149
-
150
-            else: # audio
151
-                lrn = ch.replace("lr","")
152
-                url = "http://www.latvijasradio.lsm.lv/lv/tiesraide/?channel=%s"%lrn
153
-                r = self._http_request(url)
154
-                m = re.search('"file":"([^"]+?m3u8.*?)"', r)
155
-                if not m:
156
-                    content=("No stream found %s"%data,"","","No stream found")
157
-                    return content
158
-                data2 = m.group(1).replace("\\","")
159
-
160
-            img = ""
161
-            desc = ""
162
-            content =(title,data2,img,desc)
163
-            return content
164
-
165
-        #m = re.search(r'(\?page=\d+)" class=" paging__prev', r, re.IGNORECASE)
166
-        #if m:
167
-        #    data = re.sub("\?page=\d+", "", data)
168
-        #    data2 = data+m.group(1)
169
-        #    content.append(("Previous page",self.name+"::"+data2,"","Previous page"))
170
-
171
-        r = self.call(data, lang=lang)
172
-        if not r:
173
-            return content
174
-
175
-        if clist == "search":
176
-            #for r2 in re.findall('<article itemtype="http://schema.org/Article" itemscope class="thumbnail thumbnail--default ">(.+?)</article>', r2, re.DOTALL):
177
-            for item in re.findall('itemprop="image" data-image="([^"]+)".+?<figcaption><h5 itemprop="name"><a itemprop="url" href="([^<]+)">([^<]+)</a></h5></figcaption>', r):
178
-                title = item[2]
179
-                data2 = item[1].replace("/%s/"%lang,"")+"?lang=%s"%lang
180
-                img = "http://replay.lsm.lv" + item[0]
181
-                desc  = title
182
-                content.append((title,self.name+"::"+data2,img,desc))
183
-
184
-            #for item in re.findall('itemprop="image" data-image="([^"]+)".+?<figcaption><h4 itemprop="about"><a href="([^"]+)">([^<]+)</a></h4>.*?<h5 itemprop="name"><a itemprop="url" href="([^"]+)">([^<]+)</a></h5>.+?datetime="([^"]+)" class="thumbnail__date ">([^<]+)</time>', r2):
185
-            for item in re.findall('itemprop="image" data-image="([^"]+)".+? class="icon-(ltv|lr).+?<figcaption><h4 itemprop="about"><a href="([^"]+)">([^<]+)</a></h4>.*?<h5 itemprop="name"><a itemprop="url" href="([^"]+)">([^<]+)</a></h5>.+?datetime="([^"]+)" class="thumbnail__date ">([^<]+)</time>', r):
186
-                if item[1]=="lr":continue
187
-                title = "%s - %s (%s)"%(item[3],item[5],item[7])
188
-                data2 = item[4].replace("/%s/"%lang,"")+"?lang=%s"%lang
189
-                img = item[0].replace("https:","http:")
190
-                desc = title
191
-                content.append((title,self.name+"::"+data2,img,desc))
192
-
193
-        ### Raidijumi (programmas) ###
194
-        elif clist in ( "raidijumi","peredachi"):
195
-            for item in re.findall('<li itemprop="name"><a href="([^"]+)" itemprop="url">([^<]+)', r):
196
-            #for item in re.findall('<li itemprop="name"><a href="([^"]+)" itemprop="url">([^<]+)</a></li>', r):
197
-                title = item[1]
198
-                data2 = item[0].replace("/%s/"%lang,"")+"?lang=%s"%lang
199
-                img = ""
200
-                desc  = ""
201
-                content.append((title,self.name+"::"+data2,img,desc))
202
-
203
-        ### Raidijuma ieraksti speciālie###
204
-        elif clist in ( "visi","vse",):
205
-            for item in re.findall('(?i)<figure><a href="([^"]+)" itemprop="image" data-image="([^"]+)".+class="thumbnail__duration">([^<]+)</time></figure><figcaption><h4 itemprop="about"><a href="[^"]+">([^<]+)</a></h4>.+>([^<]+).*</h5>.+>([^<]+)</time></figcaption>', r):
206
-                title = item[3]
207
-                data2 = item[0].replace("/%s/"%lang,"")+"?lang=%s"%lang
208
-                img = item[1].replace("https:","http:")
209
-                desc  = "%s - %s\n%s"%(item[5],item[2],item[4])
210
-                content.append((title,self.name+"::"+data2,img,desc))
211
-
212
-        ### Raidijuma ieraksti (videos)
213
-        elif clist in ("raidijums","peredacha","kategorija"):
214
-            for item in re.findall('<article .+ href="([^"]+)".+image="([^"]+)".+class="thumbnail__duration">([^<]+).+">([^<]+).+class="thumbnail__date ">([^"]+)</time></figcaption></article>', r):
215
-                title = item[3]
216
-                data2 = item[0].replace("/%s/"%lang,"")+"?lang=%s"%lang
217
-                img = item[1].replace("https:","http:")
218
-                desc = "%s - %s"%(item[4],item[2])
219
-                content.append((title,self.name+"::"+data2,img,desc))
220
-
221
-        ### Ieraksts (video) ###
222
-        elif clist in ("ieraksts","statja"):
223
-            m = re.search('src="([^"]+)"></iframe>', r)
224
-            if m:
225
-                url2 = m.group(1)
226
-                headers = headers2dict("""
227
-User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
228
-Referer: http://replay.lsm.lv/lv/ieraksts/ltv/70398/tiesa-runa.-lielbritanija-gatavojas-referendumam-par-tu/
229
-            """)
230
-                r2 = self._http_request(url2,headers=headers)
231
-                m = re.search('"file":"([^"]+)', r2)
232
-                if m:
233
-                    data2 = m.group(1).replace("\\","")
234
-                    m = re.search('"idstring":"([^"]+)', r2)
235
-                    title = m.group(1) if m else ""
236
-                    title = title.decode("unicode-escape").encode("utf8")
237
-                    title = title.replace("\n","")
238
-                    img = ""
239
-                    desc = ""
240
-                    if "youtube" in data2:
241
-                        video_id = re.search(r"/watch\?v=([^&]+)",data2).group(1)
242
-                        data2 = YouTubeVideoUrl().extract(video_id)
243
-                        if not data2:
244
-                            content=("No stream found %s"%data,"","","No stream found")
245
-                            return content
246
-                    content =(title,data2,img,desc)
247
-                    return content
248
-            content=("No stream found %s"%data,"","","No stream found")
249
-            return content
250
-
251
-        m = re.search(r'href="\?([^"]+)" class=" paging__next', r)
252
-        if m:
253
-            page = int(re.search("page=(\d+)",m.group(1)).group(1))
254
-            if "page="in data:
255
-                data2 = re.sub("page=\d+","page=%i"%page,data)
256
-            else:
257
-                if "?" in data:
258
-                    data2 =data+"&page=%i"%page
259
-                else:
260
-                    data2 =data+"?page=%i"%page
261
-            content.append(("Next page",self.name+"::"+data2,"","Next page"))
262
-
263
-        return content
264
-
265
-    def is_video(self,data):
266
-        if "::" in data:
267
-            data = data.split("::")[1]
268
-        cmd = data.split("/")
269
-        if cmd[0] in ("ieraksts","statja"):
270
-            return True
271
-        elif cmd[0]=="tiesraide" and len(cmd)>1:
272
-            return True
273
-        else:
274
-            return False
275
-
276
-    def call(self, data,headers=headers0,lang=""):
277
-        if not lang: lang = self.country
278
-        url = API_URL%lang + data
279
-        #print "[TVPlay Api] url: ",url
280
-        result = []
281
-        content = self._http_request(url,headers=headers0)
282
-        return content
283
-
284
-
285
-if __name__ == "__main__":
286
-    country= "lv"
287
-    c = Source(country)
288
-    if len(sys.argv)>1:
289
-        data= sys.argv[1]
290
-    else:
291
-        data = "home"
292
-    content = c.get_content(data)
293
-    for item in content:
294
-        print item
295
-    #cat = api.get_categories(country)
296
-    #chan = api.get_channels("lv")
297
-    #prog = api.get_programs(channel=6400)
298
-    #prog = api.get_programs(category=55)
299
-    #seas = api.get_seasons(program=6453)
300
-    #str = api.get_streams(660243)
301
-    #res = api.get_videos(802)
302
-    #formats = api.getAllFormats()
303
-    #det = api.detailed("1516")
304
-    #vid = api.getVideos("13170")
305
-    pass

+ 0
- 230
resources/lib/sources0/serialguru.py View File

@@ -1,230 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys,os
15
-import ConfigParser
16
-from SourceBase import SourceBase
17
-
18
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
19
-import HTMLParser
20
-h = HTMLParser.HTMLParser()
21
-
22
-class Source(SourceBase):
23
-
24
-    def __init__(self,country=""):
25
-        self.name = "serialguru"
26
-        self.title = "SerialGURU.ru"
27
-        self.img = "http://serialguru.ru/images/xlogo_new.png.pagespeed.ic.0sre2_2OJN.png"
28
-        self.desc = "Serialguru.ru portāla satura skatīšanās"
29
-        self.country=country
30
-        self.headers = headers2dict("""
31
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36
32
-Referer: http://serialguru.ru/
33
-""")
34
-        self.headers2 = headers2dict("""
35
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36
36
-X-Requested-With: XMLHttpRequest
37
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
38
-Referer: http://serialguru.ru/
39
-""")
40
-        self.url = "http://serialguru.ru/"
41
-        #self.login()
42
-
43
-    def login(self,user="",password=""):
44
-        return True
45
-
46
-    def get_content(self, data):
47
-        print "[tvdom] get_content:", data
48
-        if "::" in data:
49
-            data = data.split("::")[1]
50
-        path = data.split("?")[0]
51
-        clist = path.split("/")[0]
52
-        params = data[data.find("?"):] if "?" in data else ""
53
-        qs = dict(map(lambda x:x.split("="),re.findall("[%\w]+=\w+",params)))
54
-        lang = qs["lang"] if "lang" in qs else self.country
55
-
56
-        content=[]
57
-        content.append(("..return", "back","","Return back"))
58
-
59
-        if clist=="home":
60
-            content.extend([
61
-                ("Search", "serialguru::search/{0}","","Search content"),
62
-                ("Last", "serialguru::last","","Last series"),
63
-                ("Series", "serialguru::serials","","TV Series"),
64
-                ("Shows", "serialguru::tv","","TV Shows"),
65
-                ("Animations", "serialguru::mult","","Animation series"),
66
-
67
-                #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
68
-            ])
69
-            return content
70
-
71
-        elif data == "last":
72
-            r = self.call("")
73
-            for item in re.findall(r'<li><a href="(http://serialguru\.ru/[^"]+)"><i>([^<]+)</i>  <i>([^<]+)</i> <b>([^<]+)</b></a></li>', r, re.DOTALL):
74
-                title = item[1] + " - " + item[2]+"/"+item[3]
75
-                img = ""
76
-                data2 = item[0].replace(self.url, "")
77
-                desc = title
78
-                content.append((title, self.name+"::"+data2, img, desc))
79
-            return content
80
-
81
-        elif data=="serials":
82
-            content.extend([
83
-                ("All", "serialguru::serials?o=0&t=S","","All series"),
84
-                ("Russian", "serialguru::serials?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=S","","Russian countries series"),
85
-                ("English", "serialguru::serials?c%5B%5D=27&c%5B%5D=26&c%5B%5D=43&c%5B%5D=30&c%5B%5D=34&c%5B%5D=25&o=0&t=S","","English countries series"),
86
-                ("Europe", "serialguru::serials?c%5B%5D=29&c%5B%5D=66&c%5B%5D=44&c%5B%5D=28&c%5B%5D=51&c%5B%5D=65&c%5B%5D=62&c%5B%5D=40&c%5B%5D=45&c%5B%5D=68&c%5B%5D=59&c%5B%5D=39&c%5B%5D=35&c%5B%5D=47&o=0&t=S","","European countries series"),
87
-                ("Other", "serialguru::serials?c%5B%5D=36&c%5B%5D=32&c%5B%5D=67&c%5B%5D=63&c%5B%5D=60&c%5B%5D=64&c%5B%5D=38&c%5B%5D=52&c%5B%5D=41&c%5B%5D=58&c%5B%5D=57&c%5B%5D=37&c%5B%5D=50&c%5B%5D=46&o=0&t=S","","Other countries series"),
88
-                #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
89
-            ])
90
-            return content
91
-
92
-        elif data=="tv":
93
-            content.extend([
94
-                ("All", "serialguru::tv?o=0&t=S","","All series"),
95
-                ("Russian", "serialguru::tv?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=P","","Russian countries TV shows"),
96
-                ("English", "serialguru::tv?c%5B%5D=27&c%5B%5D=26&c%5B%5D=43&c%5B%5D=30&c%5B%5D=34&c%5B%5D=25&o=0&t=P","","English countries TV shows"),
97
-                ("Europe", "serialguru::tv?c%5B%5D=29&c%5B%5D=66&c%5B%5D=44&c%5B%5D=28&c%5B%5D=51&c%5B%5D=65&c%5B%5D=62&c%5B%5D=40&c%5B%5D=45&c%5B%5D=68&c%5B%5D=59&c%5B%5D=39&c%5B%5D=35&c%5B%5D=47&o=0&t=P","","European countries TV shows series"),
98
-                ("Other", "serialguru::tv?c%5B%5D=36&c%5B%5D=32&c%5B%5D=67&c%5B%5D=63&c%5B%5D=60&c%5B%5D=64&c%5B%5D=38&c%5B%5D=52&c%5B%5D=41&c%5B%5D=58&c%5B%5D=57&c%5B%5D=37&c%5B%5D=50&c%5B%5D=46&o=0&t=P","","Other countries TV shows"),
99
-                #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
100
-            ])
101
-            return content
102
-
103
-        elif data=="mult":
104
-            content.extend([
105
-                ("All", "serialguru::mult?o=0&t=S","","All series"),
106
-                ("Russian", "serialguru::mult?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=M","","Russian countries animantions"),
107
-                ("English", "serialguru::mult?c%5B%5D=27&c%5B%5D=26&c%5B%5D=43&c%5B%5D=30&c%5B%5D=34&c%5B%5D=25&o=0&t=M","","English countries animantions"),
108
-                ("Europe", "serialguru::mult?c%5B%5D=29&c%5B%5D=66&c%5B%5D=44&c%5B%5D=28&c%5B%5D=51&c%5B%5D=65&c%5B%5D=62&c%5B%5D=40&c%5B%5D=45&c%5B%5D=68&c%5B%5D=59&c%5B%5D=39&c%5B%5D=35&c%5B%5D=47&o=0&t=M","","European countries animantions"),
109
-                ("Other", "serialguru::mult?c%5B%5D=36&c%5B%5D=32&c%5B%5D=67&c%5B%5D=63&c%5B%5D=60&c%5B%5D=64&c%5B%5D=38&c%5B%5D=52&c%5B%5D=41&c%5B%5D=58&c%5B%5D=57&c%5B%5D=37&c%5B%5D=50&c%5B%5D=46&o=0&t=M","","Other countries animantions"),
110
-                #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
111
-            ])
112
-            return content
113
-
114
-        elif clist=="search":
115
-            if data.split("/")>1:
116
-                term = data.split("/")[1]
117
-            else:
118
-                return content
119
-            r = self.call("main/autocomplete?term=%s"%(term))
120
-            if r=="null":
121
-                return content
122
-            js = json.loads(r)
123
-            for item in js:
124
-                title = item["name"].encode("utf8")
125
-                data2 = item["url"].encode("utf8")
126
-                img = "http://serialguru.ru/uploads/cover/"+item["image_s"].replace("_s","")+".jpg"
127
-                rating = item["rating"].encode("utf8") if item["rating"] else ""
128
-                desc = title +"\nRating:%s (%s+/%s-)"%(rating,item["plus_cnt"].encode("utf8"),item["minus_cnt"].encode("utf8"))
129
-                content.append((title,self.name+"::"+data2,img,desc))
130
-            return content
131
-
132
-        elif path=="serials" or path=="tv" or path=="mult":
133
-            if path=="serials" and not "cat%5B%5D" in data:
134
-                #content.append(("All", "serialguru::"+data+"&cat%5B%5D=","","All series"))
135
-                categories = self.get_categories(path)
136
-                for c in categories:
137
-                    content.append((c[1], "serialguru::"+data+"&cat%5B%5D="+c[0],"",c[1]))
138
-                return content
139
-            else:
140
-                r = self.call("main/load", params[1:], headers=self.headers2)
141
-                for item in re.findall('<li><a href="([^"]+)"><div>.*?<img src="([^"]+)" alt="([^"]+)"[^<]*?><p>([^<]+)<i><span class="r">([^<]+)</span> <span class="plus">([^<]+)</span> <span class="minus">([^<]+)</span></i></p></div>([^<]+)</a></li>', r, re.DOTALL):
142
-                    title = "%s (%s)"%(item[2],item[3])
143
-                    img = item[1].replace("_s.jpg","_l.jpg")
144
-                    data2 = item[0].replace(self.url,"")
145
-                    desc = title +"\nRating:%s (%s+/%s-)"%(item[4],item[5],item[6])
146
-                    content.append((title,self.name+"::"+data2,img,desc))
147
-                page=int(re.search("o=(\d+)",data).group(1))
148
-                data2 = re.sub("o=(\d+)","o=%s"%(page+15),data)
149
-                content.append(("Next page",self.name+"::"+data2,"","Go to next page"))
150
-                return content
151
-
152
-
153
-        ### Pārraide
154
-        else:
155
-            r = self.call(clist)
156
-            title0=re.search('<h2>(.+?)</h2>',r,re.DOTALL).group(1)
157
-            m=re.search('<div class="description">(.+?)</div>',r,re.DOTALL)
158
-            desc0=m.group(1) if m else ""
159
-            desc0=desc0.replace("<p>","").replace("</p>","\n").replace('<a href="#">ПОКАЗАТЬ ПОЛНОСТЬЮ</a>',"")
160
-            desc0=title0+"\n"+desc0.strip()
161
-            img0=""
162
-            m = re.search("http://serialguru.ru/main/playlist/\d+",r)
163
-            if m:
164
-                url = m.group()
165
-            else:
166
-                raise Exception ("No stream found")
167
-            r = self._http_request(url)
168
-            js = json.loads(r,"utf8")
169
-            if not "/" in data: # sezonas
170
-                for i,item in enumerate(js["playlist"]):
171
-                    title = title0 + " - " + item["comment"].encode("utf8")
172
-                    img = img0
173
-                    data2 = "%s/%s"%(data,i)
174
-                    desc = desc0
175
-                    content.append((title,self.name+"::"+data2,img,desc))
176
-            else:
177
-                snum = int(data.split("/")[1])
178
-                title1 = js["playlist"][snum]["comment"].encode('utf8')
179
-                for i,item in enumerate(js["playlist"][snum]["playlist"]):
180
-                    title = title0 + " - " + title1+"/"+item["comment"].encode("utf8")
181
-                    img = img0
182
-                    data2 = item["file"].encode("utf8")
183
-                    desc = desc0
184
-                    content.append((title,data2,img,desc))
185
-            return content
186
-
187
-
188
-    def is_video(self,data):
189
-        if "::" in data:
190
-            data = data.split("::")[1]
191
-        if "live/view" in data:
192
-            return True
193
-        else:
194
-            return False
195
-
196
-    def get_categories(self,data):
197
-        r = self.call(data)
198
-        r2 = re.search('<td class="category">(.+?)</td>', r, re.DOTALL).group(1)
199
-        items = re.findall(r'<a href="#" data-id="(\d+)">([^<]+)</a>', r2, re.DOTALL)
200
-        return items
201
-
202
-
203
-    def call(self, data,params = None, headers=None):
204
-        if not headers: headers = self.headers
205
-        #if not lang: lang = self.country
206
-        url = self.url + data
207
-        content = self._http_request(url,params, headers)
208
-        return content
209
-
210
-if __name__ == "__main__":
211
-    country= "lv"
212
-    c = Source(country)
213
-    if len(sys.argv)>1:
214
-        data= sys.argv[1]
215
-    else:
216
-        data = "home"
217
-    content = c.get_content(data)
218
-    for item in content:
219
-        print item
220
-    #cat = api.get_categories(country)
221
-    #chan = api.get_channels("lv")
222
-    #prog = api.get_programs(channel=6400)
223
-    #prog = api.get_programs(category=55)
224
-    #seas = api.get_seasons(program=6453)
225
-    #str = api.get_streams(660243)
226
-    #res = api.get_videos(802)
227
-    #formats = api.getAllFormats()
228
-    #det = api.detailed("1516")
229
-    #vid = api.getVideos("13170")
230
-    pass

+ 0
- 108
resources/lib/sources0/streams.cfg View File

@@ -1,108 +0,0 @@
1
-[home]
2
-My TV|config::my_tv|default|Mani TV kanāli (tiešraide)
3
-My TV archive|config::my_archive|default|Mani TV arhīvu video
4
-My Video|config::my_video||Mani video
5
-My Kids|config::my_kids||Mani bērnu video
6
-My Radio|config::my_radio||Mani radio kanāli
7
-Replay.lv (LTV)|replay::home|http://replay.lsm.lv/apple-touch-icon.png|Latvijas TV tiešraides un arhīvs
8
-Skaties.lv (TV3)|mtgplay::home|http://skaties.lv/touch-icon-192x192.png|MTG kanālu (LNT,TV3, TV6 u.c.) arhīvs
9
-Shortcut (lattelecom.tv)|ltc::home|https://kursors.lv/wp-content/uploads/2016/07/Shortcut-logo.png|lattelecom TV, arhīves un video
10
-Play24.lv (Riga24TV)|play24::home|http://play24.lv/images/play24-logo-black.png|play24.lv (Riga24TV)tiešraide un arhīvs
11
-viaplay.lv|viaplay::home|https://yt3.ggpht.com/-noVdjbNR-V8/AAAAAAAAAAI/AAAAAAAAAAA/yZ9XNP5urLY/s900-c-k-no-mo-rj-c0xffffff/photo.jpg|Viaplay.lv - filmas latviešu, krievu u.c. valodās
12
-TVDom.tv|tvdom::home|https://tvdom.tv/front/assets/images/logo.png|PBK tiešraides un arhīvs
13
-BBC iPlayer|iplayer::home|http://www.userlogos.org/files/logos/inductiveload/BBC_iPlayer_logo.png|BBC live streams and arhive
14
-Euronews|euronews::home|http://pbs.twimg.com/profile_images/732665354242150400/tZsCnjuh_400x400.jpg|Euronews live streams and archive
15
-cinemalive.tv|cinemalive::home|https://cinemalive.tv/assets/img/filmas-online-latviski.jpg|cinemalive.tv - flmas  latvišu valodā
16
-MoviePlace.lv|movieplace::home||Movieplace.lv - filmas latviesu valodā
17
-Filmix.net|filmix::home|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Filmix.net - filmas krievu valodā
18
-SerialGURU.ru|serialguru::home|http://serialguru.ru/images/xlogo_new.png.pagespeed.ic.0sre2_2OJN.png|Serialguru.ru - filmas krievu valodā
19
-USTVNow|ustvnow::home|http://watch.ustvnow.com/assets/ustvnow/img/ustvnow_og_image.png|USTVNow kanālu tiešraide
20
-FilmOn|filmon::home|http://behindthegloves.com/wp-content/uploads/2016/01/FilmOn-logo1.jpg|FilmOn - tiešraides un video (dažādās valodās)
21
-MTGPlay|config::mtg|https://www.mtg.com/wp-content/uploads/2015/11/MTG-Logo-Medium-Red-PNG.png|Other countries MTG media portals content
22
-
23
-
24
-[my_tv]
25
-..return|back|default|Atgriezties atpakaļ
26
-LTV1|replay::tiesraide/ltv1/|http://replay.lsm.lv/resources/logo/large_ltv1.png|LTV1 tiesraide (video )
27
-LTV7|replay::tiesraide/ltv7/|http://replay.lsm.lv/resources/logo/large_ltv7.png|LTV7 tiesraide (video )
28
-TV3|http://wpc.11eb4.teliasoneracdn.net/8011EB4/origin1/tvplay/mtgstream2_high.stream/playlist.m3u8|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/TV3_logo.png|TV3
29
-TV3 (ltc)|ltc::content/live-streams/103?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/TV3_logo.png|TV3
30
-LNT (ltc)|ltc::content/live-streams/104?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/LNT_logo.png|LNT
31
-TV6|ltc::content/live-streams/106?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/TV6_logo.png|TV6
32
-Kanāls 2|ltc::content/live-streams/608?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/Kanals2_logo.png|Kanāls 2
33
-3+|ltc::content/live-streams/107?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/3_logo.png|3+
34
-360TV|ltc::content/live-streams/1051?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/360TV_new.png|360TV
35
-STV Pirmā!|ltc::content/live-streams/1069?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/STV.png|STV Pirmā!
36
-TVRiga24|play24::tiesraide||TV live streams
37
-Re:TV|ltc::content/live-streams/924?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/RE_TV.png|Re:TV
38
-RU live|tvdom::tiesraides||RU live streams from TVDom
39
-BBC live (iPlayer)|iplayer::live||BBC live streams from iPlayer
40
-UK live (FilmOn) TV|filmon::group?id=5|https://static.filmon.com/assets/groups/5/big_logo.png|UK live streams from FilmOn
41
-US live (FilmOn)|ustvnow::tvlive||US live streams from FilmOn
42
-Canadian live (FilmOn)|filmon::group?id=44|https://static.filmon.com/assets/groups/44/big_logo.png|Canada live streams from FilmOn
43
-Sport stream|rtmp://184.172.124.216/live/test111||
44
-
45
-[my_archive]
46
-..return|back||Atgriezties atpakaļ
47
-LTV arhīvs LV|replay::visi/jaunakie/?source=ltv&lang=lv|http://replay.lsm.lv/apple-touch-icon.png|LTV1, LTV2 pārraižu arhīvs LV
48
-LTV arhīvs RU|replay::vse/novie/?source=ltv&lang=ru|http://replay.lsm.lv/apple-touch-icon.png|LTV1, LTV2 pārraižu arhīvs RU
49
-skaties.lv arhīvs|mtgplay::videos?country=lv&order=-airdate|http://skaties.lv/touch-icon-192x192.png|MTG (LNT, TV3, TV6 u.c.) pārraižu arhīvs
50
-Lattelecom.tv arhīvs - categories|ltc::archive/categories|http://www.lattelecom.tv/images/default-social-icon_free.png|Lattelecom.tv pārraižu arhīvs
51
-TVRiga24 arhīvs|play24::kategorija/raidijumi|http://play24.lv/images/play24-logo-black.png|TVRiga24.tv pārraižu arhīvs
52
-TVDom arhīvs - categories|tvdom::arhivs|https://tvdom.tv/front/assets/images/logo.png|TVDom(PBK, NTV, REN u.c.) pārraižu arhīvs RU
53
-BBC (iPlayer) arhīvs|iplayer::categories||BBC programmes by categories
54
-Category - News|euronews::content/getVertical?lang=en&byPage=40&page=1&vId=1|http://pbs.twimg.com/profile_images/732665354242150400/tZsCnjuh_400x400.jpg|Category - News
55
-Latest programs|euronews::content/getLatestPrograms?lang=en&byPage=40&page=1|http://pbs.twimg.com/profile_images/732665354242150400/tZsCnjuh_400x400.jpg|Latest programs
56
-
57
-[my_video]
58
-..return|back||Atgriezties atpakaļ
59
-Все фильмы|filmix::films|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Все фильмы
60
-Все сериалы|filmix::serialy|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Все сериалы
61
-
62
-[my_kids]
63
-..return|back|default|Atgriezties atpakaļ
64
-Bērnu TV|config::my_kids_tv||Bērnu TV kanāli
65
-Bērnu video|config::my_kids_video||Saglabātie bērnu video
66
-LTV bērnu TV arhīvs|replay::raidijumi/?lang=lv&type=video&theme=5||LTV bērnu TV arhīvs
67
-Skaties.lv bērnu TV arhīvs|mtgplay::formats?category=51&country=lv&order=title|http://mtgonline.lv/tv3play/categories/berni-new.jpg|Skaties.lv bērnu TV arhīvs
68
-Shortcut.lv video bērniem - latviski|ltc::videonoma?page=0&genre=3&sorts=title&cnt=40&clear=true&filter={"valoda":["lv"]}|https://www.lattelecom.tv/images/redesign/videonoma_dropdown_berniem.png|Shortuc.lv (Lattelecom) bērnu video latviski
69
-CBeebies video|iplayer::categories/cbeebies|http://www.userlogos.org/files/logos/inductiveload/BBC_iPlayer_logo.png|CBeebies videos from iPlayer
70
-CBBC video|iplayer::categories/cbbc|http://www.userlogos.org/files/logos/inductiveload/BBC_iPlayer_logo.png|CBBC videos from iPlayer
71
-TVDom bērnu video|tvdom::arhivs/bernu||TVDom bērnu video RU
72
-Filmix bērnu filmas|filmix::detskij|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Filmix bērnu filmas
73
-Filmix bērnu seriāli|filmix::detskij/s7|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Filmix bērnu seriāli
74
-SerialGURU multenes|serialguru::mult||SerialGURU multenes
75
-
76
-[my_kids_tv]
77
-..return|back|default|Atgriezties atpakaļ
78
-Kidzone|ltc::content/live-streams/951?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/kidzone2_new.png|Kidzone
79
-Nickelodeon|ltc::content/live-streams/302?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/Nickelodeon.png|Nickelodeon
80
-Jim Jam|ltc::content/live-streams/303?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/Jim_Jam.png|Jim Jam
81
-Nick Jr|ltc::content/live-streams/1095?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/NickJR.png|Nick Jr
82
-CBeebies (iPlayer)|iplayer::live/cbeebies|http://www.lyngsat-logo.com/hires/bb/bbc_cbeebies_uk.png|CBeebies
83
-CBBC (iPlayer)|iplayer::live/cbbc|http://www.lyngsat-logo.com/hires/bb/bbc_cbbc.png|CBBC
84
-CBeebies (FilmOn)|filmon::channel?id=3191|http://static.filmon.com/assets/channels/3191/big_logo.png|CBeebies is dedicated to preschoolers. Packed full of their favourite characters, CBeebies offers 13 hours of programmes every day which encourage your child to play along and learn. It's also completely advert free and with a dedicated website and interactive service, at CBeebies it's "Playtime All the Time!"
85
-CBBC (FilmOn)|filmon::channel?id=29|http://static.filmon.com/assets/channels/29/big_logo.png|CBBC is a BBC Television channel aimed at 6 to 12 year olds.
86
-Om Nom (FilmOn)|filmon::channel?id=3824|http://static.filmon.com/assets/channels/3824/big_logo.png|The series chronicles Om Nom's adventures with a young boy named Evan, beginning  with the little monster's mysterious appearance on the boy's doorstep in Episode 1. The animation series goes on to reveal Om Nom's mischievous, yet endearing personality as he and Evan bond over day-to-day activities such as playing games, exploring house-hold items and celebrating holidays.
87
-
88
-[my_kids_video]
89
-..return|back|default|Atgriezties atpakaļ
90
-
91
-[my_radio]
92
-..return|back|default|Atgriezties atpakaļ
93
-LR1|replay::tiesraide/lr1/|http://replay.lsm.lv/resources/logo/lr1_logo.png|LR1 tiesraide (audio)
94
-LR2|replay::tiesraide/lr2/|http://replay.lsm.lv/resources/logo/lr2_logo.png|LR2 tiesraide (audio)
95
-LR3|replay::tiesraide/lr3/|http://replay.lsm.lv/resources/logo/lr3_logo.png|LR3 tiesraide (audio)
96
-LR4|replay::tiesraide/lr4/|http://replay.lsm.lv/resources/logo/lr4_logo.png|LR4 tiesraide (audio)
97
-LR5|replay::tiesraide/lr5/|http://replay.lsm.lv/resources/logo/lr5_logo.png|LR5 tiesraide (audio)
98
-LR6|replay::tiesraide/lr6/|http://replay.lsm.lv/resources/logo/lr6_logo.png|LR6 tiesraide (audio)
99
-
100
-[mtg]
101
-..return|back|default|Atgriezties atpakaļ
102
-Estonia (tv3play.ee)|mtgplay::home?country=ee||MTG Estonia media portal content
103
-Lithuania (play.tv3.lt/)|mtgplay::home?country=lt||MTG Lithuania media portal content
104
-Sweden (tvXplay.se)|mtgplay::home?country=se||MTG Sweden media portal content
105
-Denmark (tv3play.dk)|mtgplay::home?country=dk||MTG Denmark media portal content
106
-Norway (tv3play.no)|mtgplay::home?country=no||MTG Norway media portal content
107
-Bulgaria (play.novatv.bg/)|mtgplay::home?country=bg||MTG Bulgaria media portal content
108
-

+ 0
- 828
resources/lib/sources0/swfinterp.py View File

@@ -1,828 +0,0 @@
1
-# This code comes from youtube-dl: https://github.com/rg3/youtube-dl/blob/master/youtube_dl/swfinterp.py
2
-
3
-from __future__ import unicode_literals
4
-
5
-import collections
6
-import io
7
-import struct
8
-import zlib
9
-
10
-
11
-def _extract_tags(file_contents):
12
-    if file_contents[1:3] != b'WS':
13
-        print '[SWFInterpreter] Not an SWF file; header is %r' % file_contents[:3]
14
-    if file_contents[:1] == b'C':
15
-        content = zlib.decompress(file_contents[8:])
16
-    else:
17
-        raise NotImplementedError(
18
-            'Unsupported compression format %r' %
19
-            file_contents[:1])
20
-
21
-    # Determine number of bits in framesize rectangle
22
-    framesize_nbits = struct.unpack('!B', content[:1])[0] >> 3
23
-    framesize_len = (5 + 4 * framesize_nbits + 7) // 8
24
-
25
-    pos = framesize_len + 2 + 2
26
-    while pos < len(content):
27
-        header16 = struct.unpack('<H', content[pos:pos + 2])[0]
28
-        pos += 2
29
-        tag_code = header16 >> 6
30
-        tag_len = header16 & 0x3f
31
-        if tag_len == 0x3f:
32
-            tag_len = struct.unpack('<I', content[pos:pos + 4])[0]
33
-            pos += 4
34
-        assert pos + tag_len <= len(content), \
35
-            ('Tag %d ends at %d+%d - that\'s longer than the file (%d)'
36
-                % (tag_code, pos, tag_len, len(content)))
37
-        yield (tag_code, content[pos:pos + tag_len])
38
-        pos += tag_len
39
-
40
-
41
-class _AVMClass_Object(object):
42
-    def __init__(self, avm_class):
43
-        self.avm_class = avm_class
44
-
45
-    def __repr__(self):
46
-        return '%s#%x' % (self.avm_class.name, id(self))
47
-
48
-
49
-class _ScopeDict(dict):
50
-    def __init__(self, avm_class):
51
-        super(_ScopeDict, self).__init__()
52
-        self.avm_class = avm_class
53
-
54
-    def __repr__(self):
55
-        return '%s__Scope(%s)' % (
56
-            self.avm_class.name,
57
-            super(_ScopeDict, self).__repr__())
58
-
59
-
60
-class _AVMClass(object):
61
-    def __init__(self, name_idx, name, static_properties=None):
62
-        self.name_idx = name_idx
63
-        self.name = name
64
-        self.method_names = {}
65
-        self.method_idxs = {}
66
-        self.methods = {}
67
-        self.method_pyfunctions = {}
68
-        self.static_properties = static_properties if static_properties else {}
69
-
70
-        self.variables = _ScopeDict(self)
71
-        self.constants = {}
72
-
73
-    def make_object(self):
74
-        return _AVMClass_Object(self)
75
-
76
-    def __repr__(self):
77
-        return '_AVMClass(%s)' % (self.name)
78
-
79
-    def register_methods(self, methods):
80
-        self.method_names.update(methods.items())
81
-        self.method_idxs.update(dict(
82
-            (idx, name)
83
-            for name, idx in methods.items()))
84
-
85
-
86
-class _Multiname(object):
87
-    def __init__(self, kind):
88
-        self.kind = kind
89
-
90
-    def __repr__(self):
91
-        return '[MULTINAME kind: 0x%x]' % self.kind
92
-
93
-
94
-def _read_int(reader):
95
-    res = 0
96
-    shift = 0
97
-    for _ in range(5):
98
-        buf = reader.read(1)
99
-        assert len(buf) == 1
100
-        b = struct.unpack('<B', buf)[0]
101
-        res = res | ((b & 0x7f) << shift)
102
-        if b & 0x80 == 0:
103
-            break
104
-        shift += 7
105
-    return res
106
-
107
-
108
-def _u30(reader):
109
-    res = _read_int(reader)
110
-    assert res & 0xf0000000 == 0
111
-    return res
112
-_u32 = _read_int
113
-
114
-
115
-def _s32(reader):
116
-    v = _read_int(reader)
117
-    if v & 0x80000000 != 0:
118
-        v = - ((v ^ 0xffffffff) + 1)
119
-    return v
120
-
121
-
122
-def _s24(reader):
123
-    bs = reader.read(3)
124
-    assert len(bs) == 3
125
-    last_byte = b'\xff' if (ord(bs[2:3]) >= 0x80) else b'\x00'
126
-    return struct.unpack('<i', bs + last_byte)[0]
127
-
128
-
129
-def _read_string(reader):
130
-    slen = _u30(reader)
131
-    resb = reader.read(slen)
132
-    assert len(resb) == slen
133
-    return resb.decode('utf-8')
134
-
135
-
136
-def _read_bytes(count, reader):
137
-    assert count >= 0
138
-    resb = reader.read(count)
139
-    assert len(resb) == count
140
-    return resb
141
-
142
-
143
-def _read_byte(reader):
144
-    resb = _read_bytes(1, reader=reader)
145
-    res = struct.unpack('<B', resb)[0]
146
-    return res
147
-
148
-
149
-StringClass = _AVMClass('(no name idx)', 'String')
150
-ByteArrayClass = _AVMClass('(no name idx)', 'ByteArray')
151
-TimerClass = _AVMClass('(no name idx)', 'Timer')
152
-TimerEventClass = _AVMClass('(no name idx)', 'TimerEvent', {'TIMER': 'timer'})
153
-_builtin_classes = {
154
-    StringClass.name: StringClass,
155
-    ByteArrayClass.name: ByteArrayClass,
156
-    TimerClass.name: TimerClass,
157
-    TimerEventClass.name: TimerEventClass,
158
-}
159
-
160
-
161
-class _Undefined(object):
162
-    def __bool__(self):
163
-        return False
164
-    __nonzero__ = __bool__
165
-
166
-    def __hash__(self):
167
-        return 0
168
-
169
-    def __str__(self):
170
-        return 'undefined'
171
-    __repr__ = __str__
172
-
173
-undefined = _Undefined()
174
-
175
-
176
-class SWFInterpreter(object):
177
-    def __init__(self, file_contents):
178
-        self._patched_functions = {
179
-            (TimerClass, 'addEventListener'): lambda params: undefined,
180
-        }
181
-        code_tag = next(tag
182
-                        for tag_code, tag in _extract_tags(file_contents)
183
-                        if tag_code == 82)
184
-        p = code_tag.index(b'\0', 4) + 1
185
-        code_reader = io.BytesIO(code_tag[p:])
186
-
187
-        # Parse ABC (AVM2 ByteCode)
188
-
189
-        # Define a couple convenience methods
190
-        u30 = lambda *args: _u30(*args, reader=code_reader)
191
-        s32 = lambda *args: _s32(*args, reader=code_reader)
192
-        u32 = lambda *args: _u32(*args, reader=code_reader)
193
-        read_bytes = lambda *args: _read_bytes(*args, reader=code_reader)
194
-        read_byte = lambda *args: _read_byte(*args, reader=code_reader)
195
-
196
-        # minor_version + major_version
197
-        read_bytes(2 + 2)
198
-
199
-        # Constant pool
200
-        int_count = u30()
201
-        self.constant_ints = [0]
202
-        for _c in range(1, int_count):
203
-            self.constant_ints.append(s32())
204
-        self.constant_uints = [0]
205
-        uint_count = u30()
206
-        for _c in range(1, uint_count):
207
-            self.constant_uints.append(u32())
208
-        double_count = u30()
209
-        read_bytes(max(0, (double_count - 1)) * 8)
210
-        string_count = u30()
211
-        self.constant_strings = ['']
212
-        for _c in range(1, string_count):
213
-            s = _read_string(code_reader)
214
-            self.constant_strings.append(s)
215
-        namespace_count = u30()
216
-        for _c in range(1, namespace_count):
217
-            read_bytes(1)  # kind
218
-            u30()  # name
219
-        ns_set_count = u30()
220
-        for _c in range(1, ns_set_count):
221
-            count = u30()
222
-            for _c2 in range(count):
223
-                u30()
224
-        multiname_count = u30()
225
-        MULTINAME_SIZES = {
226
-            0x07: 2,  # QName
227
-            0x0d: 2,  # QNameA
228
-            0x0f: 1,  # RTQName
229
-            0x10: 1,  # RTQNameA
230
-            0x11: 0,  # RTQNameL
231
-            0x12: 0,  # RTQNameLA
232
-            0x09: 2,  # Multiname
233
-            0x0e: 2,  # MultinameA
234
-            0x1b: 1,  # MultinameL
235
-            0x1c: 1,  # MultinameLA
236
-        }
237
-        self.multinames = ['']
238
-        for _c in range(1, multiname_count):
239
-            kind = u30()
240
-            assert kind in MULTINAME_SIZES, 'Invalid multiname kind %r' % kind
241
-            if kind == 0x07:
242
-                u30()  # namespace_idx
243
-                name_idx = u30()
244
-                self.multinames.append(self.constant_strings[name_idx])
245
-            elif kind == 0x09:
246
-                name_idx = u30()
247
-                u30()
248
-                self.multinames.append(self.constant_strings[name_idx])
249
-            else:
250
-                self.multinames.append(_Multiname(kind))
251
-                for _c2 in range(MULTINAME_SIZES[kind]):
252
-                    u30()
253
-
254
-        # Methods
255
-        method_count = u30()
256
-        MethodInfo = collections.namedtuple(
257
-            'MethodInfo',
258
-            ['NEED_ARGUMENTS', 'NEED_REST'])
259
-        method_infos = []
260
-        for method_id in range(method_count):
261
-            param_count = u30()
262
-            u30()  # return type
263
-            for _ in range(param_count):
264
-                u30()  # param type
265
-            u30()  # name index (always 0 for youtube)
266
-            flags = read_byte()
267
-            if flags & 0x08 != 0:
268
-                # Options present
269
-                option_count = u30()
270
-                for c in range(option_count):
271
-                    u30()  # val
272
-                    read_bytes(1)  # kind
273
-            if flags & 0x80 != 0:
274
-                # Param names present
275
-                for _ in range(param_count):
276
-                    u30()  # param name
277
-            mi = MethodInfo(flags & 0x01 != 0, flags & 0x04 != 0)
278
-            method_infos.append(mi)
279
-
280
-        # Metadata
281
-        metadata_count = u30()
282
-        for _c in range(metadata_count):
283
-            u30()  # name
284
-            item_count = u30()
285
-            for _c2 in range(item_count):
286
-                u30()  # key
287
-                u30()  # value
288
-
289
-        def parse_traits_info():
290
-            trait_name_idx = u30()
291
-            kind_full = read_byte()
292
-            kind = kind_full & 0x0f
293
-            attrs = kind_full >> 4
294
-            methods = {}
295
-            constants = None
296
-            if kind == 0x00:  # Slot
297
-                u30()  # Slot id
298
-                u30()  # type_name_idx
299
-                vindex = u30()
300
-                if vindex != 0:
301
-                    read_byte()  # vkind
302
-            elif kind == 0x06:  # Const
303
-                u30()  # Slot id
304
-                u30()  # type_name_idx
305
-                vindex = u30()
306
-                vkind = 'any'
307
-                if vindex != 0:
308
-                    vkind = read_byte()
309
-                if vkind == 0x03:  # Constant_Int
310
-                    value = self.constant_ints[vindex]
311
-                elif vkind == 0x04:  # Constant_UInt
312
-                    value = self.constant_uints[vindex]
313
-                else:
314
-                    return {}, None  # Ignore silently for now
315
-                constants = {self.multinames[trait_name_idx]: value}
316
-            elif kind in (0x01, 0x02, 0x03):  # Method / Getter / Setter
317
-                u30()  # disp_id
318
-                method_idx = u30()
319
-                methods[self.multinames[trait_name_idx]] = method_idx
320
-            elif kind == 0x04:  # Class
321
-                u30()  # slot_id
322
-                u30()  # classi
323
-            elif kind == 0x05:  # Function
324
-                u30()  # slot_id
325
-                function_idx = u30()
326
-                methods[function_idx] = self.multinames[trait_name_idx]
327
-            else:
328
-                print '[SWFInterpreter] Unsupported trait kind %d' % kind
329
-                return None
330
-
331
-            if attrs & 0x4 != 0:  # Metadata present
332
-                metadata_count = u30()
333
-                for _c3 in range(metadata_count):
334
-                    u30()  # metadata index
335
-
336
-            return methods, constants
337
-
338
-        # Classes
339
-        class_count = u30()
340
-        classes = []
341
-        for class_id in range(class_count):
342
-            name_idx = u30()
343
-
344
-            cname = self.multinames[name_idx]
345
-            avm_class = _AVMClass(name_idx, cname)
346
-            classes.append(avm_class)
347
-
348
-            u30()  # super_name idx
349
-            flags = read_byte()
350
-            if flags & 0x08 != 0:  # Protected namespace is present
351
-                u30()  # protected_ns_idx
352
-            intrf_count = u30()
353
-            for _c2 in range(intrf_count):
354
-                u30()
355
-            u30()  # iinit
356
-            trait_count = u30()
357
-            for _c2 in range(trait_count):
358
-                trait_methods, trait_constants = parse_traits_info()
359
-                avm_class.register_methods(trait_methods)
360
-                if trait_constants:
361
-                    avm_class.constants.update(trait_constants)
362
-
363
-        assert len(classes) == class_count
364
-        self._classes_by_name = dict((c.name, c) for c in classes)
365
-
366
-        for avm_class in classes:
367
-            avm_class.cinit_idx = u30()
368
-            trait_count = u30()
369
-            for _c2 in range(trait_count):
370
-                trait_methods, trait_constants = parse_traits_info()
371
-                avm_class.register_methods(trait_methods)
372
-                if trait_constants:
373
-                    avm_class.constants.update(trait_constants)
374
-
375
-        # Scripts
376
-        script_count = u30()
377
-        for _c in range(script_count):
378
-            u30()  # init
379
-            trait_count = u30()
380
-            for _c2 in range(trait_count):
381
-                parse_traits_info()
382
-
383
-        # Method bodies
384
-        method_body_count = u30()
385
-        Method = collections.namedtuple('Method', ['code', 'local_count'])
386
-        self._all_methods = []
387
-        for _c in range(method_body_count):
388
-            method_idx = u30()
389
-            u30()  # max_stack
390
-            local_count = u30()
391
-            u30()  # init_scope_depth
392
-            u30()  # max_scope_depth
393
-            code_length = u30()
394
-            code = read_bytes(code_length)
395
-            m = Method(code, local_count)
396
-            self._all_methods.append(m)
397
-            for avm_class in classes:
398
-                if method_idx in avm_class.method_idxs:
399
-                    avm_class.methods[avm_class.method_idxs[method_idx]] = m
400
-            exception_count = u30()
401
-            for _c2 in range(exception_count):
402
-                u30()  # from
403
-                u30()  # to
404
-                u30()  # target
405
-                u30()  # exc_type
406
-                u30()  # var_name
407
-            trait_count = u30()
408
-            for _c2 in range(trait_count):
409
-                parse_traits_info()
410
-
411
-        assert p + code_reader.tell() == len(code_tag)
412
-
413
-    def patch_function(self, avm_class, func_name, f):
414
-        self._patched_functions[(avm_class, func_name)] = f
415
-
416
-    def extract_class(self, class_name, call_cinit=True):
417
-        try:
418
-            res = self._classes_by_name[class_name]
419
-        except KeyError:
420
-            print '[SWFInterpreter] Class %r not found' % class_name
421
-            return None
422
-
423
-        if call_cinit and hasattr(res, 'cinit_idx'):
424
-            res.register_methods({'$cinit': res.cinit_idx})
425
-            res.methods['$cinit'] = self._all_methods[res.cinit_idx]
426
-            cinit = self.extract_function(res, '$cinit')
427
-            cinit([])
428
-
429
-        return res
430
-
431
-    def extract_function(self, avm_class, func_name):
432
-        p = self._patched_functions.get((avm_class, func_name))
433
-        if p:
434
-            return p
435
-        if func_name in avm_class.method_pyfunctions:
436
-            return avm_class.method_pyfunctions[func_name]
437
-        if func_name in self._classes_by_name:
438
-            return self._classes_by_name[func_name].make_object()
439
-        if func_name not in avm_class.methods:
440
-            print '[SWFInterpreter] Cannot find function %s.%s' % (
441
-                avm_class.name, func_name)
442
-            return None
443
-        m = avm_class.methods[func_name]
444
-
445
-        def resfunc(args):
446
-            # Helper functions
447
-            coder = io.BytesIO(m.code)
448
-            s24 = lambda: _s24(coder)
449
-            u30 = lambda: _u30(coder)
450
-
451
-            registers = [avm_class.variables] + list(args) + [None] * m.local_count
452
-            stack = []
453
-            scopes = collections.deque([
454
-                self._classes_by_name, avm_class.constants, avm_class.variables])
455
-            while True:
456
-                opcode = _read_byte(coder)
457
-                if opcode == 9:  # label
458
-                    pass  # Spec says: "Do nothing."
459
-                elif opcode == 16:  # jump
460
-                    offset = s24()
461
-                    coder.seek(coder.tell() + offset)
462
-                elif opcode == 17:  # iftrue
463
-                    offset = s24()
464
-                    value = stack.pop()
465
-                    if value:
466
-                        coder.seek(coder.tell() + offset)
467
-                elif opcode == 18:  # iffalse
468
-                    offset = s24()
469
-                    value = stack.pop()
470
-                    if not value:
471
-                        coder.seek(coder.tell() + offset)
472
-                elif opcode == 19:  # ifeq
473
-                    offset = s24()
474
-                    value2 = stack.pop()
475
-                    value1 = stack.pop()
476
-                    if value2 == value1:
477
-                        coder.seek(coder.tell() + offset)
478
-                elif opcode == 20:  # ifne
479
-                    offset = s24()
480
-                    value2 = stack.pop()
481
-                    value1 = stack.pop()
482
-                    if value2 != value1:
483
-                        coder.seek(coder.tell() + offset)
484
-                elif opcode == 21:  # iflt
485
-                    offset = s24()
486
-                    value2 = stack.pop()
487
-                    value1 = stack.pop()
488
-                    if value1 < value2:
489
-                        coder.seek(coder.tell() + offset)
490
-                elif opcode == 32:  # pushnull
491
-                    stack.append(None)
492
-                elif opcode == 33:  # pushundefined
493
-                    stack.append(undefined)
494
-                elif opcode == 36:  # pushbyte
495
-                    v = _read_byte(coder)
496
-                    stack.append(v)
497
-                elif opcode == 37:  # pushshort
498
-                    v = u30()
499
-                    stack.append(v)
500
-                elif opcode == 38:  # pushtrue
501
-                    stack.append(True)
502
-                elif opcode == 39:  # pushfalse
503
-                    stack.append(False)
504
-                elif opcode == 40:  # pushnan
505
-                    stack.append(float('NaN'))
506
-                elif opcode == 42:  # dup
507
-                    value = stack[-1]
508
-                    stack.append(value)
509
-                elif opcode == 44:  # pushstring
510
-                    idx = u30()
511
-                    stack.append(self.constant_strings[idx])
512
-                elif opcode == 48:  # pushscope
513
-                    new_scope = stack.pop()
514
-                    scopes.append(new_scope)
515
-                elif opcode == 66:  # construct
516
-                    arg_count = u30()
517
-                    args = list(reversed(
518
-                        [stack.pop() for _ in range(arg_count)]))
519
-                    obj = stack.pop()
520
-                    res = obj.avm_class.make_object()
521
-                    stack.append(res)
522
-                elif opcode == 70:  # callproperty
523
-                    index = u30()
524
-                    mname = self.multinames[index]
525
-                    arg_count = u30()
526
-                    args = list(reversed(
527
-                        [stack.pop() for _ in range(arg_count)]))
528
-                    obj = stack.pop()
529
-
530
-                    if obj == StringClass:
531
-                        if mname == 'String':
532
-                            assert len(args) == 1
533
-                            assert isinstance(args[0], (
534
-                                int, unicode, _Undefined))
535
-                            if args[0] == undefined:
536
-                                res = 'undefined'
537
-                            else:
538
-                                res = unicode(args[0])
539
-                            stack.append(res)
540
-                            continue
541
-                        else:
542
-                            raise NotImplementedError(
543
-                                'Function String.%s is not yet implemented'
544
-                                % mname)
545
-                    elif isinstance(obj, _AVMClass_Object):
546
-                        func = self.extract_function(obj.avm_class, mname)
547
-                        res = func(args)
548
-                        stack.append(res)
549
-                        continue
550
-                    elif isinstance(obj, _AVMClass):
551
-                        func = self.extract_function(obj, mname)
552
-                        res = func(args)
553
-                        stack.append(res)
554
-                        continue
555
-                    elif isinstance(obj, _ScopeDict):
556
-                        if mname in obj.avm_class.method_names:
557
-                            func = self.extract_function(obj.avm_class, mname)
558
-                            res = func(args)
559
-                        else:
560
-                            res = obj[mname]
561
-                        stack.append(res)
562
-                        continue
563
-                    elif isinstance(obj, unicode):
564
-                        if mname == 'split':
565
-                            assert len(args) == 1
566
-                            assert isinstance(args[0], unicode)
567
-                            if args[0] == '':
568
-                                res = list(obj)
569
-                            else:
570
-                                res = obj.split(args[0])
571
-                            stack.append(res)
572
-                            continue
573
-                        elif mname == 'charCodeAt':
574
-                            assert len(args) <= 1
575
-                            idx = 0 if len(args) == 0 else args[0]
576
-                            assert isinstance(idx, int)
577
-                            res = ord(obj[idx])
578
-                            stack.append(res)
579
-                            continue
580
-                    elif isinstance(obj, list):
581
-                        if mname == 'slice':
582
-                            assert len(args) == 1
583
-                            assert isinstance(args[0], int)
584
-                            res = obj[args[0]:]
585
-                            stack.append(res)
586
-                            continue
587
-                        elif mname == 'join':
588
-                            assert len(args) == 1
589
-                            assert isinstance(args[0], unicode)
590
-                            res = args[0].join(obj)
591
-                            stack.append(res)
592
-                            continue
593
-                    raise NotImplementedError(
594
-                        'Unsupported property %r on %r'
595
-                        % (mname, obj))
596
-                elif opcode == 71:  # returnvoid
597
-                    res = undefined
598
-                    return res
599
-                elif opcode == 72:  # returnvalue
600
-                    res = stack.pop()
601
-                    return res
602
-                elif opcode == 73:  # constructsuper
603
-                    # Not yet implemented, just hope it works without it
604
-                    arg_count = u30()
605
-                    args = list(reversed(
606
-                        [stack.pop() for _ in range(arg_count)]))
607
-                    obj = stack.pop()
608
-                elif opcode == 74:  # constructproperty
609
-                    index = u30()
610
-                    arg_count = u30()
611
-                    args = list(reversed(
612
-                        [stack.pop() for _ in range(arg_count)]))
613
-                    obj = stack.pop()
614
-
615
-                    mname = self.multinames[index]
616
-                    assert isinstance(obj, _AVMClass)
617
-
618
-                    # We do not actually call the constructor for now;
619
-                    # we just pretend it does nothing
620
-                    stack.append(obj.make_object())
621
-                elif opcode == 79:  # callpropvoid
622
-                    index = u30()
623
-                    mname = self.multinames[index]
624
-                    arg_count = u30()
625
-                    args = list(reversed(
626
-                        [stack.pop() for _ in range(arg_count)]))
627
-                    obj = stack.pop()
628
-                    if isinstance(obj, _AVMClass_Object):
629
-                        func = self.extract_function(obj.avm_class, mname)
630
-                        res = func(args)
631
-                        assert res is undefined
632
-                        continue
633
-                    if isinstance(obj, _ScopeDict):
634
-                        assert mname in obj.avm_class.method_names
635
-                        func = self.extract_function(obj.avm_class, mname)
636
-                        res = func(args)
637
-                        assert res is undefined
638
-                        continue
639
-                    if mname == 'reverse':
640
-                        assert isinstance(obj, list)
641
-                        obj.reverse()
642
-                    else:
643
-                        raise NotImplementedError(
644
-                            'Unsupported (void) property %r on %r'
645
-                            % (mname, obj))
646
-                elif opcode == 86:  # newarray
647
-                    arg_count = u30()
648
-                    arr = []
649
-                    for i in range(arg_count):
650
-                        arr.append(stack.pop())
651
-                    arr = arr[::-1]
652
-                    stack.append(arr)
653
-                elif opcode == 93:  # findpropstrict
654
-                    index = u30()
655
-                    mname = self.multinames[index]
656
-                    for s in reversed(scopes):
657
-                        if mname in s:
658
-                            res = s
659
-                            break
660
-                    else:
661
-                        res = scopes[0]
662
-                    if mname not in res and mname in _builtin_classes:
663
-                        stack.append(_builtin_classes[mname])
664
-                    else:
665
-                        stack.append(res[mname])
666
-                elif opcode == 94:  # findproperty
667
-                    index = u30()
668
-                    mname = self.multinames[index]
669
-                    for s in reversed(scopes):
670
-                        if mname in s:
671
-                            res = s
672
-                            break
673
-                    else:
674
-                        res = avm_class.variables
675
-                    stack.append(res)
676
-                elif opcode == 96:  # getlex
677
-                    index = u30()
678
-                    mname = self.multinames[index]
679
-                    for s in reversed(scopes):
680
-                        if mname in s:
681
-                            scope = s
682
-                            break
683
-                    else:
684
-                        scope = avm_class.variables
685
-
686
-                    if mname in scope:
687
-                        res = scope[mname]
688
-                    elif mname in _builtin_classes:
689
-                        res = _builtin_classes[mname]
690
-                    else:
691
-                        # Assume unitialized
692
-                        # TODO warn here
693
-                        res = undefined
694
-                    stack.append(res)
695
-                elif opcode == 97:  # setproperty
696
-                    index = u30()
697
-                    value = stack.pop()
698
-                    idx = self.multinames[index]
699
-                    if isinstance(idx, _Multiname):
700
-                        idx = stack.pop()
701
-                    obj = stack.pop()
702
-                    obj[idx] = value
703
-                elif opcode == 98:  # getlocal
704
-                    index = u30()
705
-                    stack.append(registers[index])
706
-                elif opcode == 99:  # setlocal
707
-                    index = u30()
708
-                    value = stack.pop()
709
-                    registers[index] = value
710
-                elif opcode == 102:  # getproperty
711
-                    index = u30()
712
-                    pname = self.multinames[index]
713
-                    if pname == 'length':
714
-                        obj = stack.pop()
715
-                        assert isinstance(obj, (unicode, list))
716
-                        stack.append(len(obj))
717
-                    elif isinstance(pname, unicode):  # Member access
718
-                        obj = stack.pop()
719
-                        if isinstance(obj, _AVMClass):
720
-                            res = obj.static_properties[pname]
721
-                            stack.append(res)
722
-                            continue
723
-
724
-                        assert isinstance(obj, (dict, _ScopeDict)),\
725
-                            'Accessing member %r on %r' % (pname, obj)
726
-                        res = obj.get(pname, undefined)
727
-                        stack.append(res)
728
-                    else:  # Assume attribute access
729
-                        idx = stack.pop()
730
-                        assert isinstance(idx, int)
731
-                        obj = stack.pop()
732
-                        assert isinstance(obj, list)
733
-                        stack.append(obj[idx])
734
-                elif opcode == 104:  # initproperty
735
-                    index = u30()
736
-                    value = stack.pop()
737
-                    idx = self.multinames[index]
738
-                    if isinstance(idx, _Multiname):
739
-                        idx = stack.pop()
740
-                    obj = stack.pop()
741
-                    obj[idx] = value
742
-                elif opcode == 115:  # convert_
743
-                    value = stack.pop()
744
-                    intvalue = int(value)
745
-                    stack.append(intvalue)
746
-                elif opcode == 128:  # coerce
747
-                    u30()
748
-                elif opcode == 130:  # coerce_a
749
-                    value = stack.pop()
750
-                    # um, yes, it's any value
751
-                    stack.append(value)
752
-                elif opcode == 133:  # coerce_s
753
-                    assert isinstance(stack[-1], (type(None), unicode))
754
-                elif opcode == 147:  # decrement
755
-                    value = stack.pop()
756
-                    assert isinstance(value, int)
757
-                    stack.append(value - 1)
758
-                elif opcode == 149:  # typeof
759
-                    value = stack.pop()
760
-                    return {
761
-                        _Undefined: 'undefined',
762
-                        unicode: 'String',
763
-                        int: 'Number',
764
-                        float: 'Number',
765
-                    }[type(value)]
766
-                elif opcode == 160:  # add
767
-                    value2 = stack.pop()
768
-                    value1 = stack.pop()
769
-                    res = value1 + value2
770
-                    stack.append(res)
771
-                elif opcode == 161:  # subtract
772
-                    value2 = stack.pop()
773
-                    value1 = stack.pop()
774
-                    res = value1 - value2
775
-                    stack.append(res)
776
-                elif opcode == 162:  # multiply
777
-                    value2 = stack.pop()
778
-                    value1 = stack.pop()
779
-                    res = value1 * value2
780
-                    stack.append(res)
781
-                elif opcode == 164:  # modulo
782
-                    value2 = stack.pop()
783
-                    value1 = stack.pop()
784
-                    res = value1 % value2
785
-                    stack.append(res)
786
-                elif opcode == 168:  # bitand
787
-                    value2 = stack.pop()
788
-                    value1 = stack.pop()
789
-                    assert isinstance(value1, int)
790
-                    assert isinstance(value2, int)
791
-                    res = value1 & value2
792
-                    stack.append(res)
793
-                elif opcode == 171:  # equals
794
-                    value2 = stack.pop()
795
-                    value1 = stack.pop()
796
-                    result = value1 == value2
797
-                    stack.append(result)
798
-                elif opcode == 175:  # greaterequals
799
-                    value2 = stack.pop()
800
-                    value1 = stack.pop()
801
-                    result = value1 >= value2
802
-                    stack.append(result)
803
-                elif opcode == 192:  # increment_i
804
-                    value = stack.pop()
805
-                    assert isinstance(value, int)
806
-                    stack.append(value + 1)
807
-                elif opcode == 208:  # getlocal_0
808
-                    stack.append(registers[0])
809
-                elif opcode == 209:  # getlocal_1
810
-                    stack.append(registers[1])
811
-                elif opcode == 210:  # getlocal_2
812
-                    stack.append(registers[2])
813
-                elif opcode == 211:  # getlocal_3
814
-                    stack.append(registers[3])
815
-                elif opcode == 212:  # setlocal_0
816
-                    registers[0] = stack.pop()
817
-                elif opcode == 213:  # setlocal_1
818
-                    registers[1] = stack.pop()
819
-                elif opcode == 214:  # setlocal_2
820
-                    registers[2] = stack.pop()
821
-                elif opcode == 215:  # setlocal_3
822
-                    registers[3] = stack.pop()
823
-                else:
824
-                    raise NotImplementedError(
825
-                        'Unsupported opcode %d' % opcode)
826
-
827
-        avm_class.method_pyfunctions[func_name] = resfunc
828
-        return resfunc

+ 0
- 4
resources/lib/sources0/tvdom.cfg View File

@@ -1,4 +0,0 @@
1
-[tvdom]
2
-user = lietotajs
3
-password = parole
4
-

+ 0
- 277
resources/lib/sources0/tvdom.py View File

@@ -1,277 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys,os
15
-from collections import OrderedDict
16
-from SourceBase import SourceBase
17
-
18
-API_URL = 'http://replay.lsm.lv/'
19
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
20
-headers0 = headers2dict("""
21
-User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
22
-""")
23
-import HTMLParser
24
-h = HTMLParser.HTMLParser()
25
-
26
-class Source(SourceBase):
27
-
28
-    def __init__(self,country="lv"):
29
-        self.name = "tvdom"
30
-        self.title = "TVDom.tv"
31
-        self.img = "https://tvdom.tv/front/assets/images/logo.png"
32
-        self.desc = "TVDom.tv portāla satura skatīšanās"
33
-        self.headers = headers0
34
-
35
-        self.country=country
36
-        self.session = None
37
-        self.token = None
38
-
39
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
40
-        self.config_file = os.path.join(cur_directory,self.name+".cfg")
41
-        self.options = OrderedDict([("user","lietotajs"),("password","parole")])
42
-        self.options_read()
43
-
44
-    def login(self,user="",password=""):
45
-        self.options_read()        
46
-        if not user: user=self.options["user"]
47
-        if not password: password = self.options["password"]
48
-        headers = headers2dict("""
49
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0
50
-Accept: */*
51
-Accept-Language: en-US,en;q=0.5
52
-Accept-Encoding: gzip, deflate, br
53
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
54
-X-Requested-With: XMLHttpRequest
55
-Referer: https://tvdom.tv/
56
-        """)
57
-        url = "https://tvdom.tv/infinity/on_register_user"
58
-        params = "email=%s&password=%s&remember=false&auth_type=login"%(user,password)
59
-        import requests
60
-        r = requests.post(url, data=params, headers=headers)	
61
-        js = json.loads(r.content)
62
-        if 'success' in r.content:
63
-            self.token = js["access_token"] 
64
-            if 'PHPSESSID' in r.cookies:
65
-                self.session = r.cookies["PHPSESSID"]
66
-            return True
67
-        else:
68
-            raise Exception(js["error"])
69
-
70
-
71
-    def get_content(self, data):
72
-        print "[tvdom] get_content:", data
73
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
74
-        lang = qs["lang"] if "lang" in qs else self.country
75
-        content=[]
76
-        content.append(("..return", "back","","Return back"))
77
-
78
-        if clist=="home":
79
-            content.extend([
80
-                ("Live stream", "tvdom::tiesraides","","TV live streams"),
81
-                ("Archive - categories", "tvdom::arhivs","","Video archive by categories"),
82
-                ("Search", "tvdom::search/?srch-term={0}","","Search archive"),
83
-
84
-                #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
85
-            ])
86
-            return content
87
-
88
-        ### Tiesraides kanalu saraksts ###
89
-        elif data=="tiesraides":
90
-            ch_name = {"49":"Дом Кино","50":"Карусель","51":"Время","52":"Музыка Первого","53":"Телекафе"}
91
-            url = "https://tvdom.tv/"
92
-            r = self._http_request(url)
93
-            #channels1 = re.findall(r'data-xprs_status="\d" data-href="/tiesraides/([^/]+)/[^"]+">.+?src="([^"]+)" alt="([^"]+)">', r, re.DOTALL)
94
-            channels2 = re.findall(r'<a class="channel-name">([^<]*)</a>\s+<div class="redirect-to-url" data-href="/tiesraides/([^/]+)/[^"]+">.+?<img style="width:100%;" src="([^"]+)".+?<h3>([^<]+)</h3>.+?<p class="unix">([^<]+)</p>', r, re.DOTALL)
95
-            channels = {}
96
-            for item in channels2:
97
-                title = item[0]
98
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
99
-                img = "https://tvdom.tv"+item[2]
100
-                data2 = "tiesraides/%s/"%item[1]
101
-                desc = "%s\n%s\n%s"%(title,item[3],item[4])		    
102
-                channels[item[1]]={"title":title,"img":img,"desc":desc}
103
-                #content.append((title,self.name+"::"+data2,img,desc))
104
-
105
-            for r2 in re.findall(r'<div class="thumbnail-menu pull-left updater"(.+?)</div>\s+</div>', r, re.DOTALL):
106
-                ch = re.search('data-href="/tiesraides/([^/]+)/[^"]+"', r2, re.DOTALL).group(1)
107
-                data2 = "tiesraides/"+ch
108
-                m = re.search('src="(.+?)" alt="(.+?)">', r2, re.DOTALL)
109
-                title = m.group(2)
110
-                img = m.group(1)
111
-                desc = title
112
-                if ch in channels:
113
-                    img = channels[ch]["img"]
114
-                    desc = channels[ch]["desc"]
115
-                else:
116
-                    m = re.search('<img src="([^"]+)" alt="aaaaaa([^"]+)"><h3>.+<p class="unix">([^<]+)</p>', r2, re.DOTALL)
117
-                    if m:
118
-                        desc  = "%s\n%s\n%s"%(title,m.group(1),m.group(3))
119
-                        img = m.group(2)
120
-                content.append((title,self.name+"::"+data2,img,desc))
121
-            return content
122
-
123
-        elif clist == "tiesraides":
124
-            if not self.session:
125
-                self.login()
126
-            url = "https://tvdom.tv/" + data
127
-            headers = self.headers
128
-            headers["Cookie"] = "PHPSESSID=%s; neverending_story=1;"%self.session
129
-            r = self._http_request(url,headers=headers)
130
-            m = re.search("var streamConnectionUrl = '([^']+)'", r, re.DOTALL)
131
-            if m:
132
-                data2 = m.group(1)
133
-            else:
134
-                return ("No stream found %s"%data,"","","No stream found")
135
-            m = re.search('title: "([^"]+)"', r, re.DOTALL)
136
-            title = m.group(1) if m else data2
137
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
138
-            desc = m.group(1) if m else title
139
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
140
-            desc = m.group(1) if m else title 
141
-            m = re.search('var promo_image *= "([^"]+)', r, re.DOTALL)
142
-            img = m.group(1) if m else ""            
143
-            return (title,data2,img,desc)
144
-
145
-        ### Search ###
146
-        elif clist=="search":
147
-            url = "https://tvdom.tv/" + data
148
-            r = self._http_request(url)
149
-            for item in re.findall(r'<li data-xprs-search="\d+" data-href="([^"]+)".*?<img class="img-responsive" src="([^"]+)".*?<h3>([^<]+)</h3>.*?<h5>([^<]+)</h5>', r, re.DOTALL):
150
-                title = item[2] + " "+ item[3]
151
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
152
-                img = "https://tvdom.tv" + item[1]
153
-                data2 = item[0][1:]
154
-                desc = title
155
-                content.append((title,self.name+"::"+data2,img,desc))
156
-            return content
157
-
158
-        ### Arhīva kategorijas ###
159
-        elif data=="arhivs":
160
-            url = "https://tvdom.tv/"+data
161
-            r = self._http_request(url)
162
-            for item in re.findall('pointer" href="/([^"]+)">([^<]+)</a>', r, re.DOTALL):
163
-                title = item[1]
164
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
165
-                img = ""
166
-                data2 = item[0]
167
-                desc = title
168
-                content.append((title,self.name+"::"+data2,img,desc))
169
-            return content
170
-
171
-        ### Arhīva kategorijas programmas ###
172
-        elif clist=="arhivs":
173
-            url = "https://tvdom.tv/"+data
174
-            r = self._http_request(url)
175
-            for item in re.findall(r"""<li><div class="thumbnail pull-left" onclick="location\.href='([^']+)'" data-toggle="popover" title="([^"]+)" data-content="([^"]*)".+?<img class="img-responsive archive-image" src="([^"]+)""", r, re.DOTALL):
176
-            #for item in re.findall(r"""<li><div class="thumbnail pull-left" onclick="location\.href='([^']+)'" data-toggle="popover" title="([^"]+)" data-content="([^"]+)".+?<img class="img-responsive archive-image" src="([^"]+)""", r, re.DOTALL):
177
-                title = item[1].replace("&lt;br&gt;"," - ")
178
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
179
-                img = "https://tvdom.tv"+item[3]
180
-                data2 = item[0][1:]
181
-                desc = item[2]
182
-                content.append((title,self.name+"::"+data2,img,desc))
183
-            return content
184
-
185
-        ### Arhīva programmas video saraksts ###
186
-        elif clist=="play_arhivs" and len(data.split("/"))==3 and not re.search("_\d+",plist[2]):
187
-            url = "https://tvdom.tv/"+data
188
-            r = self._http_request(url)
189
-            vid=re.search(r"id:(\d+), type: type", r, re.DOTALL).group(1)
190
-            data2 = data+"_"+vid
191
-            m = re.search('program_title        = "([^"]+)"', r, re.DOTALL)
192
-            title = m.group(1) if m else data2
193
-            m = re.search('<a class="episode">Pārraides laiks ēterā: <span>([^<]+)</span></a>', r, re.DOTALL)
194
-            datums = m.group(1) if m else ""
195
-            title = title + " " + datums
196
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
197
-            desc = m.group(1) if m else title
198
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
199
-            desc = m.group(1) if m else title 
200
-            m = re.search('var share_image *= "([^"]+)', r, re.DOTALL)
201
-            img = m.group(1) if m else ""            
202
-            content.append((title,self.name+"::"+data2,img,desc)) 
203
-            i = r.find('<span class="slider-top-title"')
204
-            if i>0: r = r[:i]
205
-            for item in re.findall('<div class="col-md-9 redirect-to-url same-event" data-href="/([^"]+)">.+?image" src="([^"]+)".+?<h3 class="same-title">([^<]+)</h3>.*?<h5 class="same-online">([^<]+)</h5>', r, re.DOTALL):
206
-                title = item[2] + " " + item[3]
207
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
208
-                img = "https://tvdom.tv"+item[1]
209
-                data2 = item[0]
210
-                desc = title # TODO
211
-                content.append((title,self.name+"::"+data2,img,desc))
212
-            return content
213
-
214
-        ### Arhīva video
215
-        elif clist=="play_arhivs" and len(data.split("/"))==3 and re.search("_\d+",plist[2]):
216
-            url = "https://tvdom.tv/" + data
217
-            headers = self.headers
218
-            headers["Cookie"] = "PHPSESSID=%s; neverending_story=1;"%self.session
219
-            r = self._http_request(url,headers=headers)
220
-            m = re.search('var streamConnectionUrl  = "([^"]+)"', r, re.DOTALL)
221
-            if m:
222
-                data2 = m.group(1)
223
-            else:
224
-                return ("No stream found %s"%data,"","","No stream found")
225
-            m = re.search('program_title        = "([^"]+)"', r, re.DOTALL)
226
-            title = m.group(1) if m else data2
227
-            m = re.search('<a class="episode">Pārraides laiks ēterā: <span>([^<]+)</span></a>', r, re.DOTALL)
228
-            datums = m.group(1) if m else ""
229
-            title = title + " " + datums
230
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
231
-            desc = m.group(1) if m else title
232
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
233
-            desc = m.group(1) if m else title 
234
-            m = re.search('var share_image *= "([^"]+)', r, re.DOTALL)
235
-            img = m.group(1) if m else ""            
236
-            return (title,data2,img,desc)
237
-
238
-
239
-    def is_video(self,data):
240
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
241
-        cmd = data.split("/")
242
-        if cmd[0] in ("tiesraides") and len(cmd)>1:
243
-            return True
244
-        elif cmd[0]=="play_arhivs" and len(cmd)==3 and re.search("_\d+",plist[2]):
245
-            return True
246
-        else:
247
-            return False
248
-
249
-    def call(self, data,headers=headers0,lang=""):
250
-        if not lang: lang = self.country
251
-        url = API_URL%lang + data
252
-        #print "[TVPlay Api] url: ",url
253
-        result = []
254
-        content = self._http_request(url)
255
-        return content
256
-
257
-if __name__ == "__main__":
258
-    country= "lv"
259
-    c = Source(country)
260
-    if len(sys.argv)>1:
261
-        data= sys.argv[1]
262
-    else:
263
-        data = "home"
264
-    content = c.get_content(data)
265
-    for item in content:
266
-        print item
267
-    #cat = api.get_categories(country)
268
-    #chan = api.get_channels("lv")
269
-    #prog = api.get_programs(channel=6400)
270
-    #prog = api.get_programs(category=55)
271
-    #seas = api.get_seasons(program=6453)
272
-    #str = api.get_streams(660243)
273
-    #res = api.get_videos(802)
274
-    #formats = api.getAllFormats()
275
-    #det = api.detailed("1516")
276
-    #vid = api.getVideos("13170")
277
-    pass

+ 0
- 4
resources/lib/sources0/ustvnow.cfg View File

@@ -1,4 +0,0 @@
1
-[ustvnow]
2
-user = lietotajs
3
-password = parole
4
-

+ 0
- 176
resources/lib/sources0/ustvnow.py View File

@@ -1,176 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import urllib2, urllib
14
-import datetime, re, sys,os
15
-from collections import OrderedDict
16
-from SourceBase import SourceBase
17
-
18
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
19
-headers0 = headers2dict("""
20
-Host: m-api.ustvnow.com
21
-User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46
22
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
23
-DNT: 1
24
-Connection: keep-alive
25
-""")
26
-import HTMLParser
27
-h = HTMLParser.HTMLParser()
28
-
29
-class Source(SourceBase):
30
-
31
-    def __init__(self,country="lv"):
32
-        self.name = "ustvnow"
33
-        self.title = "USTVNow"
34
-        self.img = "http://watch.ustvnow.com/assets/ustvnow/img/ustvnow_og_image.png"
35
-        self.desc = "USTVNow kanālu tiešraide"
36
-        self.headers = headers0
37
-
38
-        self.country=country
39
-        self.token = ""
40
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
41
-        self.config_file = os.path.join(cur_directory,self.name+".cfg")
42
-        self.options = OrderedDict([("user","lietotajs"),("password","parole")])
43
-        self.options_read()
44
-
45
-    def login(self,user="",password=""):
46
-        if not user: user=self.options["user"]
47
-        if not password: password = self.options["password"]
48
-        self.options_read()        
49
-        headers = headers2dict("""
50
-        Host: m-api.ustvnow.com
51
-        Accept-Language: en-US,en;q=0.5
52
-        User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
53
-        Accept: text/html,application/xhtml+xml,application/xml
54
-        Connection: keep-alive
55
-        """)
56
-
57
-        url = "http://m-api.ustvnow.com/iphone/1/live/login?username=%s&password=%s&device=gtv&redir=0"%(user,password)
58
-        #url = "http://m-api.ustvnow.com/gtv/1/live/login?username=%s&password=%s&device=gtv&redir=0"%(user,password)
59
-        r = self._http_request(url,headers=headers)
60
-        if 'success' in r:
61
-            self.token = re.search('"token":"([^"]+)',r).group(1)
62
-            return True
63
-        else:
64
-            return False
65
-
66
-    def get_content(self, data):
67
-        print "[tvdom] get_content:", data
68
-        if "::" in data:
69
-            data = data.split("::")[1] 
70
-        path = data.split("?")[0]
71
-        clist = path.split("/")[0]
72
-        params = data[data.find("?"):] if "?" in data else ""
73
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
74
-        lang = qs["lang"] if "lang" in qs else self.country
75
-
76
-        content=[]
77
-        content.append(("..return", "back","","Return back"))
78
-
79
-        if clist=="home":
80
-            content.extend([
81
-                ("TV live streams", "ustvnow::tvlive","","TV live streams"),
82
-                ("Movies", "ustvnow::movies","","Movies (not implemented yet"),
83
-                ("Recordings", "ustvnow::recordings","","Recordings (not implemented yet"),
84
-            ])
85
-            return content
86
-
87
-        if clist=="movies":
88
-            return content
89
-
90
-        if clist=="recordings":
91
-            return content
92
-
93
-        ### Tiesraides kanalu saraksts ###
94
-        elif data=="tvlive":
95
-            if not self.token:
96
-                if not self.login():
97
-                    raise Exception("Can not login\nPlease check USTVNow username/password in\n/usr/lib/enigma2/python/Plugins/Extensions/sources/ustvnow.cfg file")
98
-            data = "live/channelguide?token=%s"%self.token
99
-            self.r = self.call(data)
100
-            if not self.r:
101
-                return content
102
-            for item in self.r["results"]:
103
-                if item["order"] == 1:    
104
-                    title = item["stream_code"]
105
-                    title =  h.unescape(title.decode("utf8")).encode("utf8")
106
-                    img = "http://m-api.ustvnow.com/"+item["prg_img"] #item["img"]
107
-                    data2 = "live/view?scode=%s&token=%s"%(item["scode"],self.token)
108
-                    desc = "%s\n%s (+%s')\n%s"%(item["title"],item["event_time"],int(item["actualremainingtime"])/60,item["description"])
109
-                    content.append((title,self.name+"::"+data2,img,desc))
110
-            return content
111
-
112
-        ### Tiesraides kanāls ###
113
-        elif path == "live/view":
114
-            url = "http://m-api.ustvnow.com/stream/1/%s"%data
115
-            r = self._http_request(url)
116
-            if not r:
117
-                return ("No stream found %s"%data,"","","No stream found")
118
-            r = json.loads(r)
119
-            if self.r:
120
-                ch = qs["scode"]
121
-                for item in self.r["results"]:
122
-                    if item["order"] == 1 and item["scode"] == ch:
123
-                        title = item["stream_code"]
124
-                        title = "%s - %s (%s)"%(item["stream_code"],item["title"],item["event_time"])
125
-                        img = "http://m-api.ustvnow.com/"+item["prg_img"]
126
-                        data2 = "live/view?scode=%s&token=%s"%(item["scode"],self.token)
127
-                        desc = "%s\n%s (+%s')\n%s"%(item["title"],item["event_time"],int(item["actualremainingtime"])/60,item["description"])
128
-            else:
129
-                title = data
130
-            data2 = r["stream"]
131
-            desc = title
132
-            img = ""          
133
-            return (title,data2,img,desc)               
134
-
135
-    def is_video(self,data):
136
-        if "::" in data:
137
-            data = data.split("::")[1]
138
-        if "live/view" in data:
139
-            return True
140
-        else:
141
-            return False
142
-
143
-    def call(self, data,headers=headers0,lang=""):
144
-        if not lang: lang = self.country
145
-        url = "http://m-api.ustvnow.com/gtv/1/"+data
146
-        content = self._http_request(url)
147
-        result = None
148
-        if content:
149
-            try:
150
-                result = json.loads(content)
151
-            except Exception, ex:
152
-                return None
153
-        return result
154
-
155
-
156
-if __name__ == "__main__":
157
-    country= "lv"
158
-    c = Source(country)
159
-    if len(sys.argv)>1:
160
-        data= sys.argv[1]
161
-    else:
162
-        data = "home"
163
-    content = c.get_content(data)
164
-    for item in content:
165
-        print item
166
-    #cat = api.get_categories(country)
167
-    #chan = api.get_channels("lv")
168
-    #prog = api.get_programs(channel=6400)
169
-    #prog = api.get_programs(category=55)
170
-    #seas = api.get_seasons(program=6453)
171
-    #str = api.get_streams(660243)
172
-    #res = api.get_videos(802)
173
-    #formats = api.getAllFormats()
174
-    #det = api.detailed("1516")
175
-    #vid = api.getVideos("13170")
176
-    pass

+ 0
- 5
resources/lib/sources0/viaplay.cfg View File

@@ -1,5 +0,0 @@
1
-[viaplay]
2
-user = change_user
3
-password = change_password
4
-device = 
5
-

+ 0
- 478
resources/lib/sources0/viaplay.py View File

@@ -1,478 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
5
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
6
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
7
-#
8
-try:
9
-    import json
10
-except:
11
-    import simplejson as json
12
-
13
-import requests, urlparse, urllib
14
-import datetime, time,re, sys,os
15
-from collections import OrderedDict
16
-from SourceBase import SourceBase
17
-try:
18
-    import util
19
-except:
20
-    parent = os.path.dirname(os.path.abspath(__file__))
21
-    parent = os.sep.join(parent.split(os.sep)[:-1])
22
-    sys.path.insert(0,parent)
23
-    import util
24
-
25
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
26
-
27
-class Source(SourceBase):
28
-
29
-    def __init__(self,language="en"):
30
-        self.name = "viaplay"
31
-        self.title = "viaplay.lv"
32
-        self.img = "https://yt3.ggpht.com/-noVdjbNR-V8/AAAAAAAAAAI/AAAAAAAAAAA/yZ9XNP5urLY/s900-c-k-no-mo-rj-c0xffffff/photo.jpg"
33
-        self.desc = "Viaplay.lv saturs"
34
-        self.url = "https://viaplay.lv/"
35
-        self.headers = headers2dict("""
36
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
37
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
38
-Connection: keep-alive
39
-Upgrade-Insecure-Requests: 1
40
-        """)
41
-        #self.language=language
42
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
43
-        self.config_file = os.path.join(cur_directory,self.name+".cfg")
44
-        self.options = OrderedDict([("user","change_user"),("password","change_password"),("device","")])
45
-        self.options_read()
46
-        self.device = self.options["device"]
47
-        self.r = None # requests
48
-        self.play_session = None
49
-        self.s = None
50
-
51
-    def login(self,user="",password=""):
52
-        self.options_read()
53
-        if not user: user=self.options["user"]
54
-        if not password: password = self.options["password"]
55
-        self.s = requests.Session()
56
-
57
-        ### Dabu sesijas ID ===
58
-        headers = headers2dict("""
59
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
60
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
61
-Accept-Language: en-US,en;q=0.5
62
-Accept-Encoding: gzip, deflate, br
63
-Referer: https://viaplay.lv/
64
-Cookie: ott_cookies_confirmed=1;
65
-DNT: 1
66
-Connection: keep-alive
67
-Upgrade-Insecure-Requests: 1
68
-""")
69
-        r = requests.get(self.url,headers=headers)
70
-        if not "PLAY_SESSION" in r.cookies:
71
-            return False
72
-        self.play_session = r.cookies["PLAY_SESSION"]
73
-        self.csrfToken = re.search("csrfToken=(.+)",self.play_session).group(1)
74
-
75
-        ### Ielogojamies ###
76
-        headers = headers2dict("""
77
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
78
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
79
-Accept-Language: en-US,en;q=0.5
80
-Accept-Encoding: gzip, deflate, br
81
-Referer: https://viaplay.lv/
82
-Cookie: ott_cookies_confirmed=1; PLAY_SESSION=e618c42b377a65021298ff63309d5a907988ed1b-PSESSIONID=b010ea1b-fc5e-4a18-aa15-ebbe8b57b3f0&csrfToken=b4eb35263d9be16ef9f7b2f5d10a8ee99dfe75a8-1478051634814-63682b20f1e7e5579de6d056
83
-DNT: 1
84
-Connection: keep-alive
85
-Upgrade-Insecure-Requests: 1
86
-Content-Type: application/x-www-form-urlencoded
87
-""")
88
-        url = "https://viaplay.lv/tdi/login/nav/formular?csrfToken=%s"%self.csrfToken
89
-        params = "nav_redirectUri=https%3A%2F%2Fviaplay.lv%2F&nav_email={}&nav_password={}".format(urllib.quote(user),urllib.quote(password))
90
-        headers["Cookie"] = "ott_cookies_confirmed=1; PLAY_SESSION=%s;"%self.play_session
91
-        if self.device:
92
-            headers["Cookie"] += "ott_dids=%s"%self.device
93
-        #cookie = dict(PLAY_SESSION=self.play_session,_hjIncludedInSample=1, mobileAppPromo="shown")
94
-        r = requests.post(url,params,headers=headers,allow_redirects=False)
95
-        if not "Set-Cookie" in r.headers:
96
-            self.play_session = None
97
-            return False
98
-        self.ott = r.cookies["ott_web_sac"]
99
-
100
-        ### Dabu iekārtas ID ###
101
-        if not self.device:
102
-            headers = headers2dict("""
103
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
104
-Accept: application/xml, text/xml, */*; q=0.01
105
-Accept-Language: en-US,en;q=0.5
106
-Accept-Encoding: gzip, deflate, br
107
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
108
-X-Requested-With: XMLHttpRequest
109
-Referer: https://viaplay.lv/movies/me-and-earl-and-the-dying-girl
110
-DNT: 1
111
-Connection: keep-alive    """)
112
-            url = "https://viaplay.lv/tdi/account/device/create?_infuse=1&csrfToken=%s"%self.csrfToken
113
-            params = "successRedirectUri=https%3A%2F%2Fviaplay.lv%2Fmovies%2F&slotId=&title=Enigma2"
114
-            headers["Cookie"] = "PLAY_SESSION=%s; ott_cookies_confirmed=1; ott_web_sac=%s;"%(self.play_session,self.ott)
115
-            #cookie = dict(PLAY_SESSION=self.play_session,_hjIncludedInSample=1, mobileAppPromo="shown")
116
-            r = requests.post(url,params,headers=headers,allow_redirects=False)
117
-            if not ("Set-Cookie" in r.headers and "ott_dids" in r.headers["Set-Cookie"]):
118
-                self.play_session = None
119
-                return False
120
-            self.device =  r.cookies["ott_dids"]
121
-            self.options["device"] = self.device
122
-            self.options_write(self.options)
123
-        return True
124
-
125
-    def logout(self):
126
-        return True
127
-
128
-    def is_logedin(self):
129
-        if self.play_session:
130
-            return True
131
-        else:
132
-            return False
133
-
134
-    def get_video_info(self,vid):
135
-        import demjson
136
-        ### Dabu strimus ###
137
-        headers = headers2dict("""
138
-Host: viaplay.lv
139
-User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46
140
-Accept: application/xml, text/xml, */*; q=0.01
141
-Accept-Language: en-US,en;q=0.5
142
-Accept-Encoding: gzip, deflate, br
143
-X-Requested-With: XMLHttpRequest
144
-DNT: 1
145
-Connection: keep-alive
146
-Referer: https://viaplay.lv/
147
-""")
148
-        url = "https://viaplay.lv/prehravac/init?_infuse=1&productId=%s"%vid #t110623
149
-        headers["Cookie"] = "ott_cookies_confirmed=1; ott_dids=%s; PLAY_SESSION=%s"%(self.device,self.play_session)
150
-        r = requests.get(url,headers=headers,allow_redirects=False)
151
-        statuss = re.search("<status>(.+?)</status>", r.content).group(1)
152
-        if statuss.lower() <> "ok":
153
-            raise Exception(statuss)
154
-        #print r.content
155
-        m = re.search(r"<!\[CDATA\[\s+var TDIPlayerOptions = (.+?);[\n\t\s]+\]\]>\s+</script>", r.content, re.DOTALL)
156
-        if not m:
157
-            raise "Can not find stream info"
158
-        txt = m.group(1)
159
-        txt = re.sub("// .+$", "", txt, flags=re.MULTILINE)
160
-        #print txt
161
-        #for m in re.finditer("// .+$", txt, re.MULTILINE):
162
-        #    txt = txt[:m.start()] + txt[m.end():]
163
-        #print txt
164
-        js = demjson.decode(txt)
165
-        return js
166
-        #return txt
167
-
168
-
169
-    def get_content(self, data):
170
-        print "[%s] get_content:"%self.name, data
171
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
172
-        content=[]
173
-        content.append(("..return", "back","","Return back"))
174
-
175
-        if clist=="home":
176
-            content.extend([
177
-                ("Search", "viaplay::search-results-all?query={0}",self.img,"Meklēt"),
178
-                ("Filmas", "viaplay::movies",self.img,"Filmas"),
179
-                ("Seriāli", "viaplay::series",self.img,"Seriāli"),
180
-                ("Bērniem", "viaplay::kids",self.img,"Bērniem"),
181
-                ("Dokumentalās filmas", "viaplay::documentary",self.img,"Dokumentalās filmas"),
182
-                ("Sports", "viaplay::live",self.img,"Sports"),
183
-             ])
184
-            return content
185
-
186
-        ### Meklēt ###
187
-        elif clist=="search-results-all":
188
-            url = "https://viaplay.lv/"+data
189
-            r = self._http_request(url)
190
-            result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<h3 class="is-size-h6">([^<]+)</h3>.*?<p>([^<]+).+?</p>.+?<p class="promo-notice">([^<]+)</p>.+?<p class="info">([^<]+)</p>', r, re.DOTALL)
191
-            for item in result:
192
-                vid = item[0]
193
-                data2 = item[1].replace("https://viaplay.lv/","")
194
-                img = item[2]
195
-                ep = item[3]
196
-                title= item[4]
197
-                seas = item[5].replace("\n","").replace("\t","")
198
-                desc = item[6]
199
-                desc2 = item[7]
200
-                if ep==title:
201
-                    title = "%s (%s)"%(title,seas)
202
-                else:
203
-                    title = "%s - %s%s"%(title,seas,ep)
204
-                desc = "%s\n%s\n%s"%(title,desc2,desc)
205
-                content.append((title,self.name+"::"+data2,img,desc))
206
-            return content
207
-
208
-        ### Sadalas ##
209
-        elif data in ["movies","series","kids","documentary"]:
210
-            r = self._http_request(self.url+data)
211
-            # https://viaplay.lv/tdi/movies/next?sections[]=MOVIES&genres[]=a3591&sort[]=latest&offset=0
212
-            # https://viaplay.lv/tdi/series/next?sections[]=SERIES&sort[]=latest&offset=0
213
-            # https://viaplay.lv/tdi/kids/next?sections[]=KIDS&cat[]=SERIES&cat[]=MOVIE&sort[]=latest&offset=18
214
-            # https://viaplay.lv/kids?sections[]=KIDS&cat[]=SERIES&sort[]=latest
215
-            sections =  {"movies":"MOVIES","series":"SERIES","kids":"KIDS","documentary":"DOCUMENTS"}
216
-            nosaukums = {"movies":"Flmas","series":"Seriāli","kids":"Bērnu","documentary":"Dokumentalās"}
217
-            #availability = {"new":"jaunākās","last":"pēdējā iespēja"}
218
-            sort = OrderedDict([("latest","jaunākais"),("title","pēc nosaukuma"),("popular","pēc popularitātes"),("year","pēc gada")])
219
-            for s in sort:
220
-                if data in ("movies","series"):
221
-                    title = "%s - %s"%(nosaukums[data],sort[s])
222
-                    data2 = "%s/next?sections[]=%s&sort[]=%s"%(data,sections[data],s)
223
-                    content.append((title,self.name+"::"+data2,self.img,title))
224
-                else:
225
-                    title = "%s filmas - %s"%(nosaukums[data],sort[s])
226
-                    data2 = "%s/next?sections[]=%s&cat[]=MOVIE&sort[]=%s"%(data,sections[data],s)
227
-                    content.append((title,self.name+"::"+data2,self.img,title))
228
-                    title = "%s seriāli - %s"%(nosaukums[data],sort[s])
229
-                    data2 = "%s/next?sections[]=%s&cat[]=SERIES&sort[]=%s"%(data,sections[data],s)
230
-                    content.append((title,self.name+"::"+data2,self.img,title))
231
-
232
-            # Pievienojam žanru sarakstu
233
-            result = re.findall(r'name="genres\[\]" value="([^"]+)">.+?class="">([^<]+)</label>', r, re.DOTALL)
234
-            for item in result:
235
-                s = "latest"
236
-                genre = item[1].replace("&amp;","&")
237
-                title = "%s: %s"%(nosaukums[data],genre)
238
-                data2 = "%s/next?sections[]=%s&genres[]=%s&sort[]=%s"%(data,sections[data],item[0],s)
239
-                content.append((title,self.name+"::"+data2,self.img,title))
240
-
241
-            return content
242
-
243
-        ### Filmu/seriālu/sēriju saraksts ###
244
-        elif clist in ("movies","series","kids","documentary") and plist[1] == "next":
245
-            url = "https://viaplay.lv/tdi/"+data
246
-            r = self._http_request(url)
247
-            if clist == "series" and "season" in qs:
248
-                result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<h3 class="is-size-h6">([^<]+)</h3>.*?<p>([^<]+).+?</p>.+?<p class="promo-notice">([^<]+)</p>.+?<p class="info">([^<]+)</p>', r, re.DOTALL)
249
-                for item in result:
250
-                    vid = item[0]
251
-                    data2 = item[1].replace("https://viaplay.lv/","")
252
-                    img = item[2]
253
-                    ep = item[3]
254
-                    title= item[4]
255
-                    seas = item[5]
256
-                    desc = item[6]
257
-                    desc2 = item[7]
258
-                    title = "%s - %s%s"%(title,seas,ep)
259
-                    desc = "%s\n%s\n%s"%(title,desc2,desc)
260
-                    content.append((title,self.name+"::"+data2,img,desc))
261
-            else: # filmas
262
-                result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<p>([^<]+)</p>.+?<p class="promo-notice">([^<]+).+?<p class="is-strong detail">(.+?)</p>.+?<p class="info">([^<]+)</p>', r, re.DOTALL)
263
-                for item in result:
264
-                    vid = item[0]
265
-                    data2 = item[1].replace("https://viaplay.lv/","")
266
-                    img = item[2]
267
-                    title = item[3]
268
-                    year = item[4]
269
-                    year  = year.replace("\n","").replace("\t","")
270
-                    title = title +"(%s)"%year
271
-                    desc= item[5]
272
-                    genre = re.findall(">([^<]+)<", item[6], re.DOTALL)
273
-                    genre = ("".join(genre)).replace("&amp;","&")
274
-                    desc2 = item[7]
275
-                    desc = "%s\n%s\n%s"%(genre,desc2,desc)
276
-                    content.append((title,self.name+"::"+data2, img,desc))
277
-            m = re.search(r"data\('href', 'https://viaplay\.lv/tdi/([^']+)'\)", r, re.DOTALL)
278
-            if m:
279
-                data2 = m.group(1)
280
-                content.append(("Next page",self.name+"::"+data2,img,"Next page"))
281
-            return content
282
-
283
-        ### Seriāls ###
284
-        elif clist == "series" and len(plist)==2:
285
-            url = "https://viaplay.lv/"+data
286
-            r = self._http_request(url)
287
-            result = re.findall(r'<li>.*?<a class="tdi" href="https://viaplay\.lv/([^"]+)" data-related-ancestor="\.js-tdi-items-filter-and-items">([^<]+)</a>.*?</li>', r, re.DOTALL)
288
-            for item in result:
289
-                title = item[1]
290
-                data2 = item[0]
291
-                data2 = data2.replace("series/","series/next/")
292
-                data2 = data2+"&sort[]=ord"
293
-                #series/littlest-pet-shop?season=t6821
294
-                #series/next/peppa-pig?season=t8430
295
-                # &sort[]=ord
296
-                if "availability=" in data2: continue
297
-                content.append((title,self.name+"::"+data2,self.img,title)) #TODO bilde
298
-            return content
299
-
300
-    def is_video(self,data):
301
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
302
-        if clist in ("movies","documentary","kids") and len(plist)>1 and plist[1]<>"next":
303
-            return True
304
-        elif clist == "series"  and len(plist)>1 and plist[1] == "episode":
305
-            return True
306
-        else:
307
-            return False
308
-
309
-    def get_streams(self, data):
310
-        print "[viaplay] get_streams:", data
311
-        if not self.is_video(data):
312
-            return []
313
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
314
-        if not self.is_logedin():
315
-            self.login()
316
-        if not self.is_logedin():
317
-            raise Exception("Could not login to viaplay.lv, check username/password in options")
318
-
319
-        streams = []
320
-        url = "https://viaplay.lv/"+data
321
-        r = self._http_request(url)
322
-        if clist=="series":
323
-            m = re.search(r'<h1 class="is-bottom-sticked is-size-h2">(.+?)</h1>.*?<h2 class="is-size-h4">.*?<p class="is-size-h6 is-strong is-bottom-sticked">(.+?)<div class="toggler-content">\s+<p>(.+?)</p>', r, re.DOTALL)
324
-            if not m:
325
-                raise Exception("Problem getting video information")
326
-            title = m.group(1).replace("\n"," ").replace("\t","").strip()
327
-            title = re.sub("<[^>]+>","",title).strip()
328
-            desc2 = m.group(2).replace("\n"," ").replace("\t","").strip()
329
-            desc2 = re.sub("<[^>]+>","",desc2).strip()
330
-            desc = m.group(3)
331
-            desc = "%s\n%s"%(desc2,desc)
332
-            vid = re.search('data-productid="(\w+)"',r).group(1)
333
-        else:
334
-            m = re.search(r'<h1 class="is-strong is-bottom-sticked is-size-h2" jnp-id="(\w+)">([^<]+)</h1>.*?<h2 class="is-strong is-size-h4">([^<]+)</h2>.*?<p class="is-size-h6 is-strong is-bottom-sticked">(.+?)<div class="toggler-content">\s+<p>(.+?)</p>', r, re.DOTALL)
335
-            if not m:
336
-                raise Exception("Problem getting video information")
337
-            title = m.group(2).strip()
338
-            title2 = m.group(3).strip()
339
-            title = "%s | %s"%(title,title2)
340
-            desc = m.group(5).strip()
341
-            desc2 = m.group(4).strip()
342
-            desc2 = re.sub("<[^>]+>","",desc2)
343
-            desc2 = desc2.replace("\n"," ").replace("\t","")
344
-            desc = "%s\n%s"%(desc2,desc)
345
-            vid = m.group(1)
346
-
347
-        js = self.get_video_info(vid)
348
-        #for m in re.finditer(r"lang: '(?P<lang>\w+)',\s+src: '(?P<url>[^']+)',\s+type: '(?P<mime>[^']+)',\s+drm: \[(?P<drm>.+?)\]\s*\}", r, re.DOTALL):
349
-        if not js:
350
-            return []
351
-        tracks = js["tracks"]
352
-        #if not tracks["HLS"]:
353
-        #    raise Exception("Encrypted DASH playing not yet implemented")
354
-
355
-        captions = []
356
-        llist = ["fr","en","ru","lv"]
357
-        for st in js["plugins"]["settings"]["subtitles"]:
358
-            sub = {}
359
-            sub["url"] = st["src"]
360
-            sub["lang"] = st["srclang"]
361
-            sub["name"] = st["label"]
362
-            sub["type"] = "vtt"
363
-            sub["order"] = llist.index(sub["lang"])*10 if sub["lang"] in llist else 0
364
-            captions.append(sub)
365
-        captions = sorted(captions,key=lambda item: item["order"],reverse=True)
366
-
367
-        for s in tracks["HLS"] if tracks["HLS"]  else tracks["DASH"] :
368
-            stype = "DASH" if "dash" in s["type"] else "HLS"
369
-            if "drm" in s: ###
370
-                # TODO, encrypted stream
371
-                continue
372
-            url = s["src"]
373
-            #urlp = util.streamproxy_encode(s["src"])
374
-            stream = util.item()
375
-            stream["url"]=url
376
-            stream["resolver"] = "viaplay"
377
-            stream["lang"]=s["lang"]
378
-            stream["quality"]="variant"
379
-            stream["bitrate"]= "1000000"
380
-            stream["name"]= title
381
-            stream["desc"]=desc
382
-            stream["type"]=stype
383
-            stream["subs"] = captions
384
-            print url
385
-            if stype=="DASH": streams.append(stream)
386
-
387
-            if stype == "HLS": # izvelkam individuālos strimus
388
-                r = requests.get(url)
389
-                result = re.findall("#EXT-X-STREAM-INF:BANDWIDTH=(\d+),RESOLUTION=(\d+x\d+)\n(\w+.m3u8)", r.content)
390
-                if not result:
391
-                    continue
392
-                for s2 in result:
393
-                    ### TODO vajag lietot cookie ar tokenu no playlista requesta
394
-                    if "set-cookie" in r.headers:
395
-                        headers = {"Cookie":r.headers["set-cookie"]}
396
-                    else:
397
-                        headers={}
398
-                    #url2 = re.sub(r"(http.*://.+/)\w+.m3u8", r"\1"+s2[2], url)
399
-                    url2 = "/".join(url.split("/")[:-1])+"/"+s2[2]
400
-                    #r2 = requests.get(url2,headers=headers)
401
-                    #if "set-cookie" in r2.headers:
402
-                        #headers = {"Cookie":r2.headers["set-cookie"]}
403
-                    #else:
404
-                        #headers={}
405
-                    url2p=util.streamproxy_encode(url2,headers)
406
-                    stream = util.item()
407
-                    stream["url"]=url2p
408
-                    stream["lang"]=s["lang"]
409
-                    stream["quality"]="%s"%(s2[1])
410
-                    stream["name"]= title
411
-                    stream["desc"]=desc
412
-                    stream["bitrate"]=s2[0]
413
-                    stream["type"]="DASH" if "dash" in s["type"] else "HLS"
414
-                    streams.append(stream)
415
-
416
-        ### TODO - sakārtot sarakstu, lai pirmais ir labakais video
417
-        qlist = ["","512","640","758","1024","variant"]
418
-        llist = ["lt","et","fr","en","ru","lv"]
419
-        for s in streams:
420
-            lv = llist.index(s["lang"])*10000000 if s["lang"] in llist else 0
421
-            #qv=qlist.index(s["quality"]) if s["quality"] in qlist else 0
422
-            qv = int(s["bitrate"]) if s["bitrate"] else 0
423
-            s["order"] = lv+qv
424
-            #print s["lang"],s["quality"],s["bitrate"],s["order"]
425
-
426
-        streams = sorted(streams,key=lambda item: item["order"],reverse=True)
427
-        return streams
428
-
429
-    def call(self, data,params = None, headers=None):
430
-        if not headers: headers = self.headers
431
-        #if not lang: lang = self.country
432
-        url = "https://viaplay.lv/tdi/" + data
433
-        content = self._http_request(url, params, headers)
434
-        return content
435
-
436
-if __name__ == "__main__":
437
-    if len(sys.argv)>1:
438
-        data= sys.argv[1]
439
-    else:
440
-        data = "kids/child-and-karlson"
441
-    c = Source()
442
-    print "login: %s"%c.login()
443
-    if "/" in data:
444
-        streams = c.get_streams(data)
445
-        util.play_video(streams)
446
-    else:
447
-        vinfo = c.get_video_info(data)
448
-        if "HLS" in vinfo["tracks"] and vinfo["tracks"]["HLS"]:
449
-            url = vinfo["tracks"]["HLS"][0]["src"]
450
-            urlp = util.streamproxy_encode(url)
451
-            util.player(urlp)
452
-        else:
453
-            print "No HLS stream"
454
-    sys.exit()
455
-
456
-    r = requests.get("https://viaplay.lv/movies?sections[]=MOVIES")
457
-    result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<p class="promo-notice">([^<]+)<', r.content, re.DOTALL)
458
-    for item in result:
459
-        vid = item[0]
460
-        url = item[1]
461
-        img = item[2]
462
-        title = item[3]
463
-        desc= item[4]
464
-        print "\n%s (%s):"%(title,vid)
465
-        vinfo = c.get_video_info(vid)
466
-        if "HLS" in vinfo["tracks"]:
467
-            for s in vinfo["tracks"]["HLS"]:
468
-                print "HLS %s: \n%s"%(s["lang"],s["src"])
469
-
470
-        if "DASH" in vinfo["tracks"]:
471
-            for s in vinfo["tracks"]["DASH"]:
472
-                print "DASH %s: \n%s"%(s["lang"],s["src"])
473
-        #except Exception,ex:
474
-            #print ex.message
475
-    #content = c.get_content(data)
476
-    #for item in content:
477
-    #    print item
478
-    pass

+ 0
- 687
resources/lib/util.py View File

@@ -1,687 +0,0 @@
1
-# -*- coding: UTF-8 -*-
2
-# /*
3
-# *      Copyright (C) 2011 Libor Zoubek,ivars777
4
-# *
5
-# *
6
-# *  This Program is free software; you can redistribute it and/or modify
7
-# *  it under the terms of the GNU General Public License as published by
8
-# *  the Free Software Foundation; either version 2, or (at your option)
9
-# *  any later version.
10
-# *
11
-# *  This Program is distributed in the hope that it will be useful,
12
-# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
-# *  GNU General Public License for more details.
15
-# *
16
-# *  You should have received a copy of the GNU General Public License
17
-# *  along with this program; see the file COPYING.  If not, write to
18
-# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
-# *  http://www.gnu.org/copyleft/gpl.html
20
-# *
21
-# */
22
-import os, sys, re
23
-import urllib, urllib2
24
-import datetime
25
-import traceback
26
-import cookielib
27
-import requests
28
-try:
29
-    from requests.packages.urllib3.exceptions import InsecureRequestWarning
30
-    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
31
-except:
32
-    pass
33
-from htmlentitydefs import name2codepoint as n2cp
34
-import HTMLParser
35
-import StringIO
36
-
37
-#import threading
38
-#import Queue
39
-import pickle
40
-import string
41
-import simplejson as json
42
-#from demjson import demjson
43
-#import demjson
44
-import json
45
-#from bs4 import BeautifulSoup
46
-
47
-UA = 'Mozilla/6.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.5) Gecko/2008092417 Firefox/3.0.3'
48
-LOG = 2
49
-
50
-_cookie_jar = None
51
-CACHE_COOKIES = 'cookies'
52
-
53
-def system():
54
-    if "kodi" in sys.executable.lower():
55
-        return "kodi"
56
-    elif sys.platform == "win32":
57
-        return "windows"
58
-    elif sys.platform == "linux2":
59
-        return "enigma2"
60
-    else:
61
-        return "unknown"
62
-
63
-def nfo2xml(nfo_dict):
64
-    nfo_type,nfo = next(nfo_dict.iteritems())
65
-    s= "<%s>\n"%nfo_type.encode("utf8")
66
-    for k,v in nfo.iteritems():
67
-        if isinstance(v,list):
68
-            for v2 in v:
69
-                if isinstance(v2,unicode): v2 = v2.encode("utf8")
70
-                s += "    <%s>%s</%s>\n"%(k.encode("utf8"), v2, k.encode("utf8"))
71
-        else:
72
-            if isinstance(v,unicode): v = v.encode("utf8")
73
-            s += "    <%s>%s</%s>\n"%(k.encode("utf8"), v, k.encode("utf8"))
74
-    s += "</%s>\n"%nfo_type.encode("utf8")
75
-    return s
76
-
77
-def nfo2desc(nfo):
78
-
79
-    if not "title" in nfo:
80
-        nfo_type, nfo = next(nfo.iteritems())
81
-    desc = nfo2title(nfo)
82
-    dd = lambda t: "\n" + nfo[t] if t in nfo and nfo[t] else ""
83
-    dd2 = lambda t: "\n" + ",".join(nfo[t]) if t in nfo and nfo[t] else ""
84
-
85
-    def ddd(t,title=""):
86
-        if title:
87
-            title = title + ": "
88
-        if t in nfo and nfo[t]:
89
-            if isinstance(nfo[t],list):
90
-                return "\n" + title + ",".join(nfo[t])
91
-            else:
92
-                return "\n" + title + nfo[t]
93
-        else:
94
-            return ""
95
-
96
-    desc += ddd("tagline")
97
-    if "plot" in nfo and "tagline" in nfo and nfo["tagline"] <> nfo["plot"]:
98
-        desc += ddd("plot")
99
-    elif "plot" in nfo and not "tagline" in nfo:
100
-        desc += ddd("plot")
101
-    desc += ddd("genre","Genre")
102
-    desc += ddd("runtime","Length")
103
-    desc += ddd("director","Director")
104
-    desc += ddd("actor","Actors")
105
-    desc += ddd("language","Languages")
106
-    desc += ddd("quality","Quality")
107
-    return desc.encode("utf8") if isinstance(desc,unicode) else desc
108
-
109
-def nfo2title(nfo):
110
-    if not "title" in nfo:
111
-        nfo_type, nfo = next(nfo.iteritems())
112
-    title = nfo["title"]
113
-    if "originaltitle" in nfo and nfo["originaltitle"] and nfo["originaltitle"]<>nfo["title"]:
114
-        title +=" ~ "+nfo["originaltitle"]
115
-    if "year" in nfo and nfo["year"]:
116
-        title += " (%s)"%nfo["year"]
117
-    return title.encode("utf8") if isinstance(title,unicode) else title
118
-
119
-def play_video(streams):
120
-    if len(streams)>1:
121
-        for i,s in enumerate(streams):
122
-
123
-            print "%s: [%s,%s,%s] %s"%(i,s["quality"],s["lang"],s["type"],s["name"])
124
-        a = raw_input("Select stram to play: ")
125
-        try:
126
-            n = int(a)
127
-        except:
128
-            n = 0
129
-        if n>=len(streams):
130
-            stream = streams[-1]
131
-        else:
132
-            stream = streams[n]
133
-    else:
134
-        stream = streams[0]
135
-
136
-    stream = stream_change(stream)
137
-    title = stream["name"] if not "nfo" in stream else nfo2title(stream["nfo"])
138
-    desc = stream["desc"] if not "nfo" in stream else nfo2desc(stream["nfo"])
139
-    img = stream["img"]
140
-    url = stream["url"]
141
-    suburl = ""
142
-    print url
143
-    if "subs" in stream and stream["subs"]:
144
-        suburl = stream["subs"][0]["url"]
145
-        print "\n**Download subtitles %s - %s"%(title,suburl)
146
-        subs = urllib2.urlopen(suburl).read()
147
-        if subs:
148
-            fname0 = re.sub("[/\n\r\t,]","_",title)
149
-            subext = ".srt"
150
-            subfile = os.path.join("",fname0+subext)
151
-            if ".xml" in suburl:
152
-                subs = ttaf2srt(subs)
153
-            with open(subfile,"w") as f:
154
-                f.write(subs)
155
-        else:
156
-            print "\n Error downloading subtitle %s"%suburl
157
-    print "\n**Play stream %s\n%s" % (title, url.encode("utf8"))
158
-    return player(url,title,suburl,stream["headers"])
159
-
160
-def player(url, title = "", suburl= "",headers={}):
161
-    from subprocess import call
162
-    cmd1 = [r"c:\Program Files\VideoLAN\VLC\vlc.exe",url,
163
-           "--meta-title",title.decode("utf8").encode(sys.getfilesystemencoding()),
164
-           "--http-user-agent","Enigma2"
165
-    ]
166
-    # gst-launch-1.0 -v souphttpsrc ssl-strict=false proxy=127.0.0.1:8888 extra-headers="Origin:adadadasd"  location="http://bitdash-a.akamaihd.net/content/sintel/sintel.mpd" ! decodebin! autovideosink
167
-    cmd2 = [
168
-        r"C:\gstreamer\1.0\x86_64\bin\gst-launch-1.0","-v",
169
-        "playbin", 'uri="%s"'%url,
170
-        #"souphttpsrc", "ssl-strict=false",
171
-        #"proxy=127.0.0.1:8888",
172
-        #'location="%s"'%url,
173
-        #'!decodebin!autovideosink'
174
-    ]
175
-    cmd3 = ["ffplay.exe",url]
176
-    cmd = cmd1 if url.startswith("https") else cmd2
177
-    ret = call(cmd3)
178
-    #if ret:
179
-        #a = raw_input("*** Error, continue")
180
-    return
181
-
182
-def check_version(package,url="http://feed.blue.lv/Packages"):
183
-    "Return current package version from OPKG feed"
184
-    url = "http://feed.blue.lv/Packages"
185
-    r = requests.get(url)
186
-    if not r.ok:
187
-        return ""
188
-    m = re.search("Package: %s\nVersion: (.+?)\n"%package, r.content)
189
-    if not m:
190
-        return ""
191
-    return m.group(1)
192
-
193
-SPLIT_CHAR = "~"
194
-SPLIT_CODE = urllib.quote(SPLIT_CHAR)
195
-EQ_CODE = urllib.quote("=")
196
-COL_CODE = urllib.quote(":")
197
-SPACE_CODE = urllib.quote(" ")
198
-PROXY_URL = "http://localhost:88/"
199
-
200
-
201
-def make_fname(title):
202
-    "Make file name from title"
203
-    title = title.strip()
204
-    fname0 = re.sub("[/\n\r\t,:]"," ",title)
205
-    fname0 = re.sub("['""]","",fname0)
206
-    return fname0
207
-
208
-def stream_change(stream):
209
-    #return stream # TODO
210
-    if "resolver" in stream and stream["resolver"] in ("viaplay","hqq","filmas") or \
211
-        "surl" in stream and re.search("https*://(hqq|goo.\gl)",stream["surl"]):
212
-        stream["url"] = streamproxy_encode(stream["url"],stream["headers"])
213
-        stream["headers"] = {}
214
-        return stream
215
-    else:
216
-        return stream
217
-
218
-def streamproxy_encode(url,headers=[]):
219
-    if not "?" in url:
220
-        url = url+"?"
221
-    url2 = url.replace(SPLIT_CHAR,SPLIT_CODE).replace(":",COL_CODE).replace(" ",SPACE_CODE)
222
-    url2 = PROXY_URL + url2
223
-    if headers:
224
-        headers2 = []
225
-        for h in headers:
226
-            headers2.append("%s=%s"%(h,headers[h].replace("=",EQ_CODE).replace(SPLIT_CHAR,SPLIT_CODE).replace(" ",SPACE_CODE)))
227
-        headers2 = SPLIT_CHAR.join(headers2)
228
-        url2 = url2+SPLIT_CHAR+headers2
229
-    return url2
230
-
231
-def streamproxy_decode(urlp):
232
-    import urlparse
233
-    path = urlp.replace(re.search("http://[^/]+",urlp).group(0),"")
234
-    p = path.split(SPLIT_CHAR)
235
-    url = urllib.unquote(p[0][1:])
236
-    #headers = {"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46"}
237
-    headers={}
238
-    if len(p)>1:
239
-        for h in p[1:]:
240
-            #h = urllib.unquote()
241
-            headers[h.split("=")[0]]=urllib.unquote(h.split("=")[1])
242
-    return url,headers
243
-
244
-class Captions(object):
245
-    def __init__(self,uri):
246
-        self.uri = uri
247
-        self.subs = []
248
-        self.styles = {}
249
-        if uri.startswith("http"):
250
-            r = requests.get(uri)
251
-        if r.status_code == 200:
252
-            self.loads(r.content)
253
-
254
-    def loads(self,s):
255
-        if "WEBVTT" in s[:s.find("\n")]: # vtt captions
256
-            self.load_vtt(s)
257
-        elif "<?xml" in s[:s.find("\n")]:
258
-            self.load_ttaf(s)
259
-        else:
260
-            self.load_vtt(s) # TODO
261
-
262
-
263
-    def load_ttaf(self,s):
264
-        for r2 in re.findall("<style .+?/>", s):
265
-            st = {}
266
-            for a in re.findall(r'(\w+)="([^ "]+)"', r2):
267
-                st[a[0]] = a[1]
268
-                if a[0] == "id":
269
-                    sid = a[1]
270
-            self.styles[sid] = st
271
-        for r2 in re.findall("<p .+?</p>", s):
272
-            sub = {}
273
-            sub["begin"] = str2sec(re.search('begin="([^"]+)"', r2).group(1)) if re.search('begin="([^"]+)"', r2) else -1
274
-            sub["end"] = str2sec(re.search('end="([^"]+)"', r2).group(1)) if re.search('end="([^"]+)"', r2) else -1
275
-            sub["style"] = re.search('style="([^"]+)"', r2).group(1) if re.search('style="([^"]+)"', r2) else None
276
-            sub["text"] = re.search("<p[^>]+>(.+)</p>", r2).group(1).replace("\n","")
277
-            sub["text"] = re.sub("<br\s*?/>","\n",sub["text"])
278
-            sub["text"] = re.sub("<.+?>"," ",sub["text"])
279
-            self.subs.append(sub)
280
-        pass
281
-
282
-    def load_vtt(self,s):
283
-        f = StringIO.StringIO(s)
284
-        while True:
285
-            line = f.readline()
286
-            if not line:
287
-                break
288
-            m = re.search(r"([\d\.\,:]+)\s*-->\s*([\d\.\,\:]+)",line)
289
-            if m:
290
-                sub = {}
291
-                sub["begin"] = str2sec(m.group(1))
292
-                sub["end"] = str2sec(m.group(2))
293
-                sub["style"] = None
294
-                sub["text"] = []
295
-                line = f.readline()
296
-                while line.strip():
297
-                    txt = line.strip()
298
-                    if isinstance(txt,unicode):
299
-                        txt = txt.encode("utf8")
300
-                    sub["text"].append(txt)
301
-                    line = f.readline()
302
-                sub["text"] = "\n".join(sub["text"])
303
-                self.subs.append(sub)
304
-            else:
305
-                continue
306
-        pass
307
-
308
-    def get_srt(self):
309
-        out = ""
310
-        i = 0
311
-        for sub in self.subs:
312
-            i +=1
313
-            begin = sub["begin"]
314
-            begin = "%s,%03i"%(str(datetime.timedelta(seconds=begin/1000)),begin%1000)
315
-            end = sub["end"]
316
-            end = "%s,%03i"%(str(datetime.timedelta(seconds=end/1000)),end%1000)
317
-            txt2 = sub["text"]
318
-            out += "%s\n%s --> %s\n%s\n\n\n"%(i,begin,end,txt2)
319
-        return out
320
-
321
-def str2sec(r):
322
-    # Convert str time to miliseconds
323
-    r= r.replace(",",".")
324
-    m = re.search(r"(\d+\:)*(\d+)\:(\d+\.\d+)", r)
325
-    if m:
326
-        sec = int(m.group(1)[:-1])*60*60*1000 if m.group(1) else 0
327
-        sec += int(m.group(2))*60*1000 + int(float(m.group(3))*1000)
328
-        return sec
329
-    else:
330
-        return -1
331
-
332
-
333
-#c = Captions("http://195.13.216.2/mobile-vod/mp4:lb_barbecue_fr_lq.mp4/lb_barbecue_lv.vtt")
334
-#c = Captions("http://www.bbc.co.uk/iplayer/subtitles/ng/modav/bUnknown-0edd6227-0f38-411c-8d46-fa033c4c61c1_b05ql1s3_1479853893356.xml")
335
-#url = "http://195.13.216.2/mobile-vod/mp4:ac_now_you_see_me_2_en_lq.mp4/ac_now_you_see_me_2_lv.vtt"
336
-#c = Captions(url)
337
-
338
-#pass
339
-
340
-
341
-def ttaf2srt(s):
342
-    out = u""
343
-    i = 0
344
-    for p,txt in re.findall("<p ([^>]+)>(.+?)</p>", s, re.DOTALL):
345
-        i +=1
346
-        begin = re.search('begin="(.+?)"',p).group(1)
347
-        begin = begin.replace(".",",")
348
-        end = re.search('end="(.+?)"',p).group(1)
349
-        end = end.replace(".",",")
350
-        txt2 = re.sub("<br */>","\n",txt)
351
-        out += "%s\n%s --> %s\n%s\n\n"%(i,begin,end,txt2)
352
-    return out
353
-
354
-
355
-def item():
356
-    """Default item content"""
357
-    stream0 = {
358
-        'name': '', #
359
-        'url': '',
360
-        'quality': '?',
361
-        'surl': '',
362
-        'subs': [],
363
-        'headers': {},
364
-        "desc":"",
365
-        "img":"",
366
-        "lang":"",
367
-        "type":"",
368
-        "resolver":"",
369
-        "order":0,
370
-        "live":False
371
-        }
372
-    return stream0
373
-
374
-class _StringCookieJar(cookielib.LWPCookieJar):
375
-
376
-    def __init__(self, string=None, filename=None, delayload=False, policy=None):
377
-        cookielib.LWPCookieJar.__init__(self, filename, delayload, policy)
378
-        if string and len(string) > 0:
379
-            self._cookies = pickle.loads(str(string))
380
-
381
-    def dump(self):
382
-        return pickle.dumps(self._cookies)
383
-
384
-
385
-def init_urllib(cache=None):
386
-    """
387
-    Initializes urllib cookie handler
388
-    """
389
-    global _cookie_jar
390
-    data = None
391
-    if cache is not None:
392
-        data = cache.get(CACHE_COOKIES)
393
-    _cookie_jar = _StringCookieJar(data)
394
-    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(_cookie_jar))
395
-    urllib2.install_opener(opener)
396
-
397
-
398
-def cache_cookies(cache):
399
-    """
400
-    Saves cookies to cache
401
-    """
402
-    global _cookie_jar
403
-    if _cookie_jar:
404
-        cache.set(CACHE_COOKIES, _cookie_jar.dump())
405
-
406
-
407
-def request0(url, headers={}):
408
-    debug('request: %s' % url)
409
-    req = urllib2.Request(url, headers=headers)
410
-    req.add_header('User-Agent', UA)
411
-    try:
412
-        response = urllib2.urlopen(req)
413
-        data = response.read()
414
-        response.close()
415
-    except urllib2.HTTPError, error:
416
-        data = error.read()
417
-
418
-    debug('len(data) %s' % len(data))
419
-    return data
420
-
421
-def request(url, headers={}):
422
-    debug('request: %s' % url)
423
-    #req = urllib2.Request(url, headers=headers)
424
-    #req.add_header('User-Agent', UA)
425
-    if 'User-Agent' not in headers:
426
-        headers['User-Agent']= UA
427
-    try:
428
-        r = requests.get(url, headers=headers)
429
-        data = r.content
430
-    except:
431
-        data = r.content
432
-
433
-    debug('len(data) %s' % len(data))
434
-    return data
435
-
436
-def post(url, data, headers={}):
437
-    postdata = urllib.urlencode(data)
438
-    #req = urllib2.Request(url, postdata, headers)
439
-    #req.add_header('User-Agent', UA)
440
-    import requests
441
-    if 'User-Agent' not in headers:
442
-        headers['User-Agent']= UA
443
-    try:
444
-        r = requests.post(url, data=postdata,headers=headers)
445
-        data = r.content
446
-    except urllib2.HTTPError, error:
447
-        data = r.content
448
-    return data
449
-
450
-def post0(url, data, headers={}):
451
-    postdata = urllib.urlencode(data)
452
-    req = urllib2.Request(url, postdata, headers)
453
-    req.add_header('User-Agent', UA)
454
-    try:
455
-        response = urllib2.urlopen(req)
456
-        data = response.read()
457
-        response.close()
458
-    except urllib2.HTTPError, error:
459
-        data = error.read()
460
-    return data
461
-
462
-
463
-def post_json(url, data, headers={}):
464
-    postdata = json.dumps(data)
465
-    headers['Content-Type'] = 'application/json'
466
-    req = urllib2.Request(url, postdata, headers)
467
-    req.add_header('User-Agent', UA)
468
-    response = urllib2.urlopen(req)
469
-    data = response.read()
470
-    response.close()
471
-    return data
472
-
473
-
474
-#def run_parallel_in_threads(target, args_list):
475
-    #result = Queue.Queue()
476
-    ## wrapper to collect return value in a Queue
477
-
478
-    #def task_wrapper(*args):
479
-        #result.put(target(*args))
480
-
481
-    #threads = [threading.Thread(target=task_wrapper, args=args) for args in args_list]
482
-    #for t in threads:
483
-        #t.start()
484
-    #for t in threads:
485
-        #t.join()
486
-    #return result
487
-
488
-
489
-def substr(data, start, end):
490
-    i1 = data.find(start)
491
-    i2 = data.find(end, i1)
492
-    return data[i1:i2]
493
-
494
-
495
-def save_to_file(url, file):
496
-    try:
497
-        return save_data_to_file(request(url), file)
498
-    except:
499
-        traceback.print_exc()
500
-
501
-
502
-def save_data_to_file(data, file):
503
-    try:
504
-        f = open(file, 'wb')
505
-        f.write(data)
506
-        f.close()
507
-        info('File %s saved' % file)
508
-        return True
509
-    except:
510
-        traceback.print_exc()
511
-
512
-
513
-def read_file(file):
514
-    if not os.path.exists(file):
515
-        return ''
516
-    f = open(file, 'r')
517
-    data = f.read()
518
-    f.close()
519
-    return data
520
-
521
-
522
-def _substitute_entity(match):
523
-    ent = match.group(3)
524
-    if match.group(1) == '#':
525
-        # decoding by number
526
-        if match.group(2) == '':
527
-            # number is in decimal
528
-            return unichr(int(ent))
529
-        elif match.group(2) == 'x':
530
-            # number is in hex
531
-            return unichr(int('0x' + ent, 16))
532
-    else:
533
-        # they were using a name
534
-        cp = n2cp.get(ent)
535
-        if cp:
536
-            return unichr(cp)
537
-        else:
538
-            return match.group()
539
-
540
-
541
-def decode_html(data):
542
-    if not type(data) == str:
543
-        return data
544
-    try:
545
-        if not type(data) == unicode:
546
-            data = unicode(data, 'utf-8', errors='ignore')
547
-        entity_re = re.compile(r'&(#?)(x?)(\w+);')
548
-        return entity_re.subn(_substitute_entity, data)[0]
549
-    except:
550
-        traceback.print_exc()
551
-        print[data]
552
-        return data
553
-
554
-def unescape(s0):
555
-    #s2 = re.sub("&#\w+;",HTMLParser.HTMLParser().unescape("\1"),s)
556
-    s0 = s0.replace("&amp;","&")
557
-    for s in re.findall("&#\w+;",s0):
558
-        s2 = HTMLParser.HTMLParser().unescape(s)
559
-        if isinstance(s0,str):
560
-            s2 = s2.encode("utf8")
561
-        s0 = s0.replace(s,s2)
562
-        pass
563
-    return s0
564
-
565
-def debug(text):
566
-    if LOG > 1:
567
-        print('[DEBUG] ' + str([text]))
568
-
569
-def info(text):
570
-    if LOG > 0:
571
-        print('[INFO] ' + str([text]))
572
-
573
-def error(text):
574
-    print('[ERROR] ' + str([text]))
575
-
576
-_diacritic_replace = {u'\u00f3': 'o',
577
-                      u'\u0213': '-',
578
-                      u'\u00e1': 'a',
579
-                      u'\u010d': 'c',
580
-                      u'\u010c': 'C',
581
-                      u'\u010f': 'd',
582
-                      u'\u010e': 'D',
583
-                      u'\u00e9': 'e',
584
-                      u'\u011b': 'e',
585
-                      u'\u00ed': 'i',
586
-                      u'\u0148': 'n',
587
-                      u'\u0159': 'r',
588
-                      u'\u0161': 's',
589
-                      u'\u0165': 't',
590
-                      u'\u016f': 'u',
591
-                      u'\u00fd': 'y',
592
-                      u'\u017e': 'z',
593
-                      u'\xed': 'i',
594
-                      u'\xe9': 'e',
595
-                      u'\xe1': 'a',
596
-                      }
597
-
598
-
599
-def replace_diacritic(string):
600
-    ret = []
601
-    for char in string:
602
-        if char in _diacritic_replace:
603
-            ret.append(_diacritic_replace[char])
604
-        else:
605
-            ret.append(char)
606
-    return ''.join(ret)
607
-
608
-
609
-def params(url=None):
610
-    if not url:
611
-        url = sys.argv[2]
612
-    param = {}
613
-    paramstring = url
614
-    if len(paramstring) >= 2:
615
-        params = url
616
-        cleanedparams = params.replace('?', '')
617
-        if (params[len(params) - 1] == '/'):
618
-            params = params[0:len(params) - 2]
619
-        pairsofparams = cleanedparams.split('&')
620
-        param = {}
621
-        for i in range(len(pairsofparams)):
622
-            splitparams = {}
623
-            splitparams = pairsofparams[i].split('=')
624
-            if (len(splitparams)) == 2:
625
-                param[splitparams[0]] = splitparams[1]
626
-    for p in param.keys():
627
-        param[p] = param[p].decode('hex')
628
-    return param
629
-
630
-
631
-def int_to_base(number, base):
632
-    digs = string.digits + string.letters
633
-    if number < 0:
634
-        sign = -1
635
-    elif number == 0:
636
-        return digs[0]
637
-    else:
638
-        sign = 1
639
-    number *= sign
640
-    digits = []
641
-    while number:
642
-        digits.append(digs[number % base])
643
-        number /= base
644
-    if sign < 0:
645
-        digits.append('-')
646
-    digits.reverse()
647
-    return ''.join(digits)
648
-
649
-
650
-def extract_jwplayer_setup(data):
651
-    """
652
-    Extracts jwplayer setup configuration and returns it as a dictionary.
653
-
654
-    :param data: A string to extract the setup from
655
-    :return: A dictionary containing the setup configuration
656
-    """
657
-    data = re.search(r'<script.+?}\(\'(.+)\',\d+,\d+,\'([\w\|]+)\'.*</script>', data, re.I | re.S)
658
-    if data:
659
-        replacements = data.group(2).split('|')
660
-        data = data.group(1)
661
-        for i in reversed(range(len(replacements))):
662
-            if len(replacements[i]) > 0:
663
-                data = re.sub(r'\b%s\b' % int_to_base(i, 36), replacements[i], data)
664
-        data = re.search(r'\.setup\(([^\)]+?)\);', data)
665
-        if data:
666
-            return json.loads(data.group(1).decode('string_escape'))
667
-        #return demjson.decode(data.group(1).decode('string_escape')) ### III
668
-    return None
669
-
670
-
671
-#def parse_html(url):
672
-#    return BeautifulSoup(request(url), 'html5lib', from_encoding='utf-8')
673
-
674
-if __name__ == "__main__":
675
-    s = 'B\xc4\x93thovena D\xc4\x81rgumu Taka (2014)/Beethoven&#x27;s Treasure [LV]'
676
-    #s = s.decode("utf8")
677
-    #s=unescape(s)
678
-    #url = "http://localhost:88/https://walterebert.com/playground/video/hls/ts/480x270.m3u8?token=xxxx~User-Agent=Enigma2~Cookie=xxxxx"
679
-    url = "http://hyt4d6.vkcache.com/secip/0/UMQ3q2gNjTlOPnEVm3iTiA/ODAuMjMyLjI0MC42/1479610800/hls-vod-s3/flv/api/files/videos/2015/09/11/144197748923a22.mp4.m3u8http://hyt4d6.vkcache.com/secip/0/Y-ZA1qRm8toplc0dN_L6_w/ODAuMjMyLjI0MC42/1479654000/hls-vod-s3/flv/api/files/videos/2015/09/11/144197748923a22.mp4.m3u8"
680
-    headers = {"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46"}
681
-    urlp = streamproxy_encode(url,headers)
682
-    print urlp
683
-    player(urlp)
684
-
685
-    pass
686
-
687
-

BIN
resources/picons/art-default.jpg View File


+ 0
- 0
resources/picons/back.png View File


Some files were not shown because too many files changed in this diff