Ivars 7 jaren geleden
bovenliggende
commit
dddb35390d
75 gewijzigde bestanden met toevoegingen van 0 en 16263 verwijderingen
  1. 0
    262
      ContentSources.py
  2. 0
    293
      Downloader.py
  3. 0
    6281
      demjson.py
  4. BIN
      offline.mp4
  5. BIN
      picons/art-default.jpg
  6. BIN
      picons/back.png
  7. BIN
      picons/cinemalive.png
  8. BIN
      picons/euronews.png
  9. BIN
      picons/filmas.png
  10. BIN
      picons/filmix.png
  11. BIN
      picons/filmon.png
  12. BIN
      picons/folder.png
  13. BIN
      picons/folder2.png
  14. BIN
      picons/folder_search.png
  15. BIN
      picons/icon-default.png
  16. BIN
      picons/iplayer.png
  17. BIN
      picons/lmt.jpg
  18. BIN
      picons/lmt.png
  19. BIN
      picons/movieplace.png
  20. BIN
      picons/my_archive.png
  21. BIN
      picons/my_kids.png
  22. BIN
      picons/my_radio.png
  23. BIN
      picons/my_tv.png
  24. BIN
      picons/my_video.png
  25. BIN
      picons/prefs.png
  26. BIN
      picons/replay.png
  27. BIN
      picons/riga24.png
  28. BIN
      picons/shortcut.png
  29. BIN
      picons/skaties.png
  30. BIN
      picons/tvdom.png
  31. BIN
      picons/tvplay.png
  32. BIN
      picons/ustvnow.png
  33. BIN
      picons/viaplay.jpg
  34. BIN
      picons/viaplay.png
  35. BIN
      picons/video.png
  36. BIN
      release/enigma2-plugin-extensions-playstream_0.7f.ipk
  37. BIN
      release/enigma2-plugin-extensions-playstream_0.7g.ipk
  38. 0
    138
      resolver.py
  39. 0
    31
      resolvers/__init__.py
  40. 0
    209
      resolvers/aadecode.py
  41. 0
    100
      resolvers/hdgo.py
  42. 0
    239
      resolvers/hqqresolver.py
  43. 0
    99
      resolvers/kapnob.py
  44. 0
    100
      resolvers/kodik.py
  45. 0
    114
      resolvers/openload3.py
  46. 0
    347
      resolvers/youtuberesolver.py
  47. 0
    169
      sources/SourceBase.py
  48. 0
    407
      sources/YouTubeVideoUrl.py
  49. 0
    0
      sources/__init__.py
  50. 0
    213
      sources/cinemalive.py
  51. 0
    115
      sources/config.py
  52. 0
    3
      sources/euronews.cfg
  53. 0
    305
      sources/euronews.py
  54. 0
    412
      sources/filmix.py
  55. 0
    276
      sources/filmon.py
  56. 0
    4
      sources/iplayer.cfg
  57. 0
    559
      sources/iplayer.py
  58. 0
    261
      sources/jsinterp.py
  59. 0
    219
      sources/lmt.py
  60. 0
    4
      sources/ltc.cfg
  61. 0
    1088
      sources/ltc.py
  62. 0
    235
      sources/movieplace.py
  63. 0
    283
      sources/mtgplay.py
  64. 0
    216
      sources/play24.py
  65. 0
    310
      sources/replay.py
  66. 0
    235
      sources/serialguru.py
  67. 0
    118
      sources/streams.cfg
  68. 0
    828
      sources/swfinterp.py
  69. 0
    6
      sources/tvdom.cfg
  70. 0
    345
      sources/tvdom.py
  71. 0
    4
      sources/ustvnow.cfg
  72. 0
    193
      sources/ustvnow.py
  73. 0
    5
      sources/viaplay.cfg
  74. 0
    496
      sources/viaplay.py
  75. 0
    741
      util.py

+ 0
- 262
ContentSources.py Bestand weergeven

@@ -1,262 +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
-show_hidden = False  # Ja True, tad vienalga radā hidden sources (noder izstradē)
16
-
17
-class ContentSources(object):
18
-    """Wrapper for content sources plugin"""
19
-
20
-    #----------------------------------------------------------------------
21
-    def __init__(self, plugin_path):
22
-        self.plugins = {}
23
-        self.error_content = [("..atpakaļ", "back", None, "Kļūda, atgriezties atpakaļ")]
24
-        sys.path.insert(0, plugin_path)
25
-        #for f in os.listdir(plugin_path):
26
-        #for f in next(os.walk(plugin_path))[2]:
27
-        print "ContentSources: Importing sources from "+plugin_path
28
-        files = glob.glob(os.path.join(plugin_path, "*.py"))
29
-        for f in files:
30
-            fname, ext = os.path.splitext(f)
31
-            fname = os.path.split(fname)[1]
32
-            if fname == "__init__": continue
33
-            if ext == '.py':
34
-                print "Importing %s"%fname
35
-                mod = __import__(fname)
36
-                reload(mod)
37
-                if "Source" in dir(mod):
38
-                    self.plugins[fname] = mod.Source()
39
-                    print fname+ " imported"
40
-                else:
41
-                    pass
42
-                    #print fname+ "skipped"
43
-        sys.path.pop(0)
44
-        if not "config" in self.plugins:
45
-            raise Exception("Problem importing content sources")
46
-        cfg = self.plugins["config"]
47
-        for pl in self.plugins.keys():
48
-            found = False
49
-            for lst in cfg.get_lists():
50
-                for item in cfg.lists[lst]:
51
-                    if item[1].split("::")[0]==pl:
52
-                        found = True
53
-                        break
54
-                    if found: break
55
-            if not found:
56
-                title = self.plugins[pl].title if "title" in dir(self.plugins[pl]) else pl
57
-                img = self.plugins[pl].img if "img" in dir(self.plugins[pl]) else ""
58
-                desc = self.plugins[pl].desc if "desc" in dir(self.plugins[pl]) else title
59
-                cfg.add_item("home",(title,"%s::home"%pl,img,desc))
60
-                cfg.write_streams()
61
-
62
-    def get_content(self,data):
63
-        source = data.split("::")[0]
64
-        if source in self.plugins:
65
-            content0 = self.plugins[source].get_content(data)
66
-            if content0:
67
-                content = []
68
-                if isinstance(content0,list):
69
-                    for i,item in enumerate(content0):
70
-                        source2 = item[1].split("::")[0]
71
-                        if not (source2 == "back" or item[1].startswith("http") or item[1].startswith("rtmp")):
72
-                            if source2 not in self.plugins or (not show_hidden and "hidden" in dir(self.plugins[source2]) and self.plugins[source2].hidden):
73
-                                continue
74
-                        item2=[]
75
-                        for el in item:
76
-                            if isinstance(el,unicode):
77
-                                el = el.encode("utf8")
78
-                            item2.append(el)
79
-                        content.append(tuple(item2))
80
-                else:
81
-                    item2=[]
82
-                    for el in content0:
83
-                        if isinstance(el,unicode):
84
-                            el = el.encode("utf8")
85
-                        item2.append(el)
86
-                    content=tuple(item2)
87
-                return content
88
-            else:
89
-                return self.error_content
90
-        else:
91
-            return self.error_content
92
-
93
-    def get_streams(self,data):
94
-        if stream_type(data):
95
-            if "::" in data:
96
-                data = data.split("::")[1]
97
-            content = self.get_content(data)
98
-            stream = util.item()
99
-            stream["name"] = data
100
-            stream["url"] = data
101
-            stream["type"] = stream_type(data)
102
-            #stream["img"] = ""
103
-            #stream["desc"] = ""
104
-            return[stream]
105
-
106
-        if not self.is_video(data):
107
-            return []
108
-        source = data.split("::")[0]
109
-        if source in self.plugins:
110
-            streams = self.plugins[source].get_streams(data)
111
-            for s in streams:
112
-                for k in s:
113
-                    if isinstance(s[k],unicode):
114
-                        s[k] = s[k].encode("utf8")
115
-                if not "resolver" in s:
116
-                    s["resolver"] = source
117
-                if not "surl" in s or not s["surl"]:
118
-                    s["surl"] = data
119
-                if not "nfo" in s:
120
-                    s["nfo"]={"movie":{"title":s["name"],"thumb":s["img"],"plot":s["desc"]}}
121
-            return streams
122
-        else:
123
-            return []
124
-
125
-    def get_info(self,data):
126
-        nfo = {}
127
-        if self.is_video(data):
128
-            source = data.split("::")[0]
129
-            if source in self.plugins:
130
-                if "get_info" in dir(self.plugins[source]):
131
-                    streams = self.get_streams(data)
132
-                    nfo = streams[0]["nfo"] if streams and "nfo" in streams[0] else {}
133
-                else:
134
-                    nfo = self.plugins[source].get_info(data)
135
-        else:
136
-            pass    # TODO create nfo for listing
137
-        return nfo
138
-
139
-
140
-    def stream_type(self,data):
141
-        return stream_type(data)
142
-
143
-    def is_video(self,data):
144
-        if self.stream_type(data):
145
-            return True
146
-        source = data.split("::")[0]
147
-        if source in self.plugins:
148
-            return self.plugins[source].is_video(data)
149
-        else:
150
-            return False
151
-
152
-    def options_read(self,source):
153
-        if source in self.plugins:
154
-            options = self.plugins[source].options_read()
155
-            if options:
156
-                return options
157
-            else:
158
-                return None
159
-        else:
160
-            return None
161
-
162
-    def options_write(self,source,options):
163
-        if source in self.plugins:
164
-            return self.plugins[source].options_write(options)
165
-        else:
166
-            return None
167
-
168
-if __name__ == "__main__":
169
-
170
-    show_hidden = False
171
-    sources = ContentSources("sources")
172
-    if len(sys.argv)>1:
173
-        data= sys.argv[1]
174
-    else:
175
-        data = "config::home"
176
-
177
-    #options = sources.options_read("ltc")
178
-    #print options
179
-    history = []
180
-    cur = ("Home",data,None,None)
181
-    content = sources.get_content(cur[1])
182
-
183
-    exit_loop = False
184
-    while True:
185
-        print
186
-        for i,item in enumerate(content):
187
-            s = "%i: %s - %s %s"%(i,item[0],item[1],item[2])
188
-            print s #.encode(sys.stdout.encoding,"replace")
189
-
190
-        while True:
191
-            a = raw_input("Enter number, (-) for download, q for exit: ")
192
-            if a in ("q","Q","x","X"):
193
-                exit_loop = True
194
-                print "Exiting"
195
-                break
196
-            try:
197
-                n = int(a)
198
-                break
199
-            except:
200
-                print "Not number!"
201
-        if exit_loop: break
202
-        download = False
203
-        if n<0:
204
-            n = abs(n)
205
-            download = True
206
-        cur2 = content[n]
207
-        data0 = cur2[1].split("::")[1] if "::" in cur2[1] else cur2[1]
208
-        if not data0:
209
-            pass
210
-        elif cur2[1] == "back":
211
-            cur = history.pop()
212
-        elif sources.is_video(cur2[1]):
213
-            if sources.stream_type(cur2[1]):
214
-                stream = util.item()
215
-                stream["url"] = cur2[1]
216
-                stream["name"] = cur2[0]
217
-                streams = [stream]
218
-            else:
219
-                try:
220
-                    if not download:
221
-                        streams = sources.get_streams(cur2[1])
222
-                    else:
223
-                        stream = util.item()
224
-                        stream["url"] = cur2[1]
225
-                        stream["name"] = cur2[0]
226
-                        stream["url"] = util.streamproxy_encode2(stream["url"])
227
-                        print stream["url"]
228
-                        streams = [stream]
229
-                except Exception as e:
230
-                    print unicode(e)
231
-                    traceback.print_exc()
232
-                    streams = []
233
-            if streams:
234
-                if not download:
235
-                    util.play_video(streams)
236
-                else:
237
-                    #urlp = util.streamproxy_encode2(streams[0]["url"])
238
-                    #print urlp
239
-                    #util.player(urlp)
240
-                    #Downloader.download_video(streams)
241
-                    pass
242
-            else:
243
-                print "**No stream to play - %s "%(
244
-                    cur2[1])
245
-                raw_input("Press any key")
246
-            #import os
247
-            #os.system('"c:\Program Files (x86)\VideoLAN\VLC\vlc.exe" "%s"'%cur2[1])
248
-
249
-        else:
250
-            if "{0}" in cur2[1]:
251
-                a = raw_input("Enter value:")
252
-                cur2 = (cur2[0],cur2[1].format(a),cur2[2],cur2[3])
253
-            history.append(cur)
254
-            cur = cur2
255
-        try:
256
-            content = sources.get_content(cur[1])
257
-        except Exception as e:
258
-            print unicode(e)
259
-            traceback.print_exc()
260
-            raw_input("Continue?")
261
-
262
-

+ 0
- 293
Downloader.py Bestand weergeven

@@ -1,293 +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
-        self.ts_file = open(self.outputfile, "wb")
118
-        self.download_fragment()
119
-
120
-    def download_fragment(self):
121
-        if self.ts_num>=len(self.ts_list):
122
-            pass
123
-            #print "Call later"
124
-            reactor.callLater(10,self.update_manifest)
125
-            reactor.callLater(10, self.download_fragment)
126
-        else:
127
-            print "Start fragment download"
128
-            url = self.ts_list[self.ts_num][1]
129
-            if not "://" in url:
130
-                url = self.base_url+url
131
-            self.d = client.getPage(url,headers = self.headers)
132
-            self.d.addCallbacks(self.download_ok,self.download_err)
133
-
134
-
135
-    def download_ok(self,content):
136
-        content_length = len(content)
137
-        self.currentbytes += content_length
138
-        self.currenttime += float(self.ts_list[self.ts_num][0])
139
-        self.totalbytes = self.currentbytes * self.totaltime / self.currenttime
140
-        self.ts_num += 1
141
-        #print "Fragment %s downloaded (%s)"%(self.ts_num,len(content))
142
-        self.ts_file.write(content)
143
-        self.progress_callback(self.currentbytes, self.totalbytes)
144
-        if self.type == "vod":
145
-            if self.ts_num >= len(self.ts_list) or (self.limit and self.currenttime>self.limit):
146
-                self.ts_file.close()
147
-                self.download_finished()
148
-            else:
149
-                self.download_fragment()
150
-        else:
151
-            if self.limit and self.currenttime>self.limit: # TODO
152
-                self.ts_file.close()
153
-                self.download_finished()
154
-            else:
155
-                self.download_fragment()
156
-
157
-    def update_manifest(self):
158
-        self.d2 = client.getPage(self.url, headers=self.headers)
159
-        self.d2.addCallbacks(self.update_manifest_ok, self.update_manifest_err)
160
-
161
-    def update_manifest_ok(self,content):
162
-        print "Update manifest"
163
-        ts_list = re.findall(r"#EXTINF:([\d\.]+),\n(.+?)$", content, re.IGNORECASE | re.MULTILINE)
164
-        last_ts = self.ts_list[-1]
165
-        found = False
166
-        for ts in ts_list:
167
-            if ts == last_ts:
168
-                found = True
169
-            elif found:
170
-                print "Append %s"%ts[1]
171
-                self.ts_list.append(ts)
172
-        #reactor.callLater(5,self.download_fragment)
173
-
174
-    def update_manifest_err(self,content):
175
-        return
176
-
177
-    def download_err(self,content):
178
-        self.deferred.errback("Error while downloading %s"%self.ts_list[self.ts_num][1])
179
-
180
-    def download_finished(self):
181
-        self.totalbytes = self.currentbytes
182
-        self.deferred.callback("Done")
183
-
184
-    def start(self):
185
-        reactor.callLater(1,self.start_download)
186
-        return self.deferred
187
-
188
-    def stop(self):
189
-        self.deferred.errback() # TODO
190
-
191
-    def addProgress(self, progress_callback):
192
-        print "[addProgress]"
193
-        self.progress_callback = progress_callback
194
-
195
-#####################################################################################################
196
-def get_header(url,headers=None):
197
-    headers = {"user-agent":USER_AGENT}
198
-    r = requests.head(url,headers=headers)
199
-    return r.headers
200
-
201
-def get_ext(mtype):
202
-    stype = "http"
203
-    if mtype in ("vnd.apple.mpegURL","application/x-mpegURL",'application/x-mpegurl',"application/vnd.apple.mpegurl"):
204
-        return ".ts","hls"
205
-    elif mtype in ("application/dash+xml"):
206
-        return ".ts","dash" # TODO dash stream type  could be different !
207
-    elif mtype in ("video/mp4"):
208
-        return ".mp4","http"
209
-    elif mtype in ("video/MP2T","video/mp2t"):
210
-        return ".ts","http"
211
-    elif mtype in ("video/x-flv"):
212
-        return ".flv","http"
213
-    elif mtype in ("video/quicktime"):
214
-        return ".mov","http"
215
-    elif mtype in ("video/x-msvideo"):
216
-        return ".avi","http"
217
-    elif mtype in ("video/x-ms-wmv"):
218
-        return ".wmv","http"
219
-    elif mtype in ("video/x-matroska"):
220
-        return ".mkv","http"
221
-    else:
222
-        return ".mp4","http"
223
-
224
-
225
-
226
-##############################################
227
-def print_progress(currentbytes, totalbytes):
228
-    progress = float(currentbytes)/float(totalbytes)*100
229
-    print "%s (%i/%i)"%(progress,currentbytes,totalbytes)
230
-
231
-def download_ok(*args):
232
-    print "Download OK"
233
-    reactor.stop()
234
-
235
-def download_err(e):
236
-    print "Download Error %s"%e.getBriefTraceback()
237
-    pass
238
-def stop():
239
-    reactor.stop()
240
-###############################################
241
-
242
-def download_video(stream):
243
-    stream = stream[0]
244
-    url = stream["url"]
245
-    headers = stream["headers"]
246
-    output = stream["name"].replace("\\"," ").replace(":"," ").replace("|"," ")
247
-    try:
248
-        h = get_header(url,headers={"user-agent":"Enigma2"})
249
-        mtype = h.get("content-type")
250
-        ext,stream_type = get_ext(mtype)
251
-    except:
252
-        ext,stream_type = (".ts","hls")
253
-    #output = urlparse.urlparse(url)[2].split('/')[-1] + ext
254
-    output = output+ext
255
-    output = os.path.join("downloads", output)
256
-    if stream_type == "hls":
257
-        d = DownloadWithProgressFragmented(url,output,headers={"user-agent":"Enigma2"})
258
-    else:
259
-        d = DownloadWithProgress(url,output,headers={"user-agent":"Enigma2"})
260
-    d.addProgress(print_progress)
261
-    d.start().addCallback(download_ok).addErrback(download_err)
262
-    reactor.run()
263
-
264
-
265
-if __name__ == "__main__":
266
-    if len(sys.argv)>2:
267
-        url= sys.argv[1]
268
-        output = sys.argv[1]
269
-    else:
270
-        url = "http://walterebert.com/playground/video/hls/ts/480x270.m3u8"
271
-        url = "https://r3---sn-bavc5ajvh-gpme.googlevideo.com/videoplayback?key=yt6&mime=video%2Fmp4&sparams=clen%2Cdur%2Cei%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cupn%2Cexpire&expire=1490986184&lmt=1490940183963773&dur=1302.639&itag=18&ratebypass=yes&mm=31&requiressl=yes&ipbits=0&upn=azFGj8gY02w&ip=85.254.87.15&pl=23&ei=aFDeWLzqDcn-dLC_gdAM&signature=083F353AC09CD98A70AD7D9438DD3C91C781166B.715456B9C35F040BDC4728CA76A0D1779B684A90&source=youtube&mv=m&mt=1490964451&ms=au&mn=sn-bavc5ajvh-gpme&gir=yes&clen=73596250&id=o-AGH9y-hWn1MtW1VzCyI_8XYYEWODsTDBZbfagQH3BrfQ&initcwndbps=4493750"
272
-        #url = "http://techslides.com/demos/sample-videos/small.mp4"
273
-        #url = "http://wx17.poiuytrew.pw/s/c507282042b1bf25e0b72c34a68426f3/hd_30/Jackie.2016.D.iTunes.BDRip.1080p_720.mp4"
274
-        #url = "http://player.tvnet.lv/live/amlst:11/chunklist_w361981294_b528000.m3u8"
275
-        #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"
276
-        #url = "https://58174450afee9.streamlock.net/vod/mp4:_definst_/f/e/8e49fc32.mp4/playlist.m3u8?safwerwfasendtime=1490877870&safwerwfasstarttime=1490859339&safwerwfashash=hS2FfVZysQVazBQ6RJn1IhUevBkKxIF09Ly3BjfT43U="
277
-    try:
278
-        h = get_header(url,headers={"user-agent":"Enigma2"})
279
-        mtype = h.get("content-type")
280
-        ext,stream_type = get_ext(mtype)
281
-    except:
282
-        ext,stream_type = (".ts","hls")
283
-    output = urlparse.urlparse(url)[2].split('/')[-1] + ext
284
-    output = os.path.join("downloads", output)
285
-    if stream_type == "hls":
286
-        d = DownloadWithProgressFragmented(url,output,headers={"user-agent":"Enigma2"})
287
-    else:
288
-        d = DownloadWithProgress(url,output,headers={"user-agent":"Enigma2"})
289
-    d.addProgress(print_progress)
290
-    d.start().addCallback(download_ok).addErrback(download_err)
291
-    reactor.run()
292
-
293
-

+ 0
- 6281
demjson.py
Diff onderdrukt omdat het te groot bestand
Bestand weergeven


BIN
offline.mp4 Bestand weergeven


BIN
picons/art-default.jpg Bestand weergeven


BIN
picons/back.png Bestand weergeven


BIN
picons/cinemalive.png Bestand weergeven


BIN
picons/euronews.png Bestand weergeven


BIN
picons/filmas.png Bestand weergeven


BIN
picons/filmix.png Bestand weergeven


BIN
picons/filmon.png Bestand weergeven


BIN
picons/folder.png Bestand weergeven


BIN
picons/folder2.png Bestand weergeven


BIN
picons/folder_search.png Bestand weergeven


BIN
picons/icon-default.png Bestand weergeven


BIN
picons/iplayer.png Bestand weergeven


BIN
picons/lmt.jpg Bestand weergeven


BIN
picons/lmt.png Bestand weergeven


BIN
picons/movieplace.png Bestand weergeven


BIN
picons/my_archive.png Bestand weergeven


BIN
picons/my_kids.png Bestand weergeven


BIN
picons/my_radio.png Bestand weergeven


BIN
picons/my_tv.png Bestand weergeven


BIN
picons/my_video.png Bestand weergeven


BIN
picons/prefs.png Bestand weergeven


BIN
picons/replay.png Bestand weergeven


BIN
picons/riga24.png Bestand weergeven


BIN
picons/shortcut.png Bestand weergeven


BIN
picons/skaties.png Bestand weergeven


BIN
picons/tvdom.png Bestand weergeven


BIN
picons/tvplay.png Bestand weergeven


BIN
picons/ustvnow.png Bestand weergeven


BIN
picons/viaplay.jpg Bestand weergeven


BIN
picons/viaplay.png Bestand weergeven


BIN
picons/video.png Bestand weergeven


BIN
release/enigma2-plugin-extensions-playstream_0.7f.ipk Bestand weergeven


BIN
release/enigma2-plugin-extensions-playstream_0.7g.ipk Bestand weergeven


+ 0
- 138
resolver.py Bestand weergeven

@@ -1,138 +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
-    url = "https://www.youtube.com/embed/RUyQ_JJ6A84?rel=0&fs=1&wmode=transparent"
127
-    streams = resolve(url)
128
-    if not streams:
129
-        print "No streams found"
130
-        sys.exit()
131
-
132
-    for s in streams:
133
-        print s
134
-
135
-    print streams[0]["url"]
136
-    util.play_video(streams)
137
-    ##call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",streams[0]["url"]])
138
-    pass

+ 0
- 31
resolvers/__init__.py Bestand weergeven

@@ -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
resolvers/aadecode.py Bestand weergeven

@@ -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
resolvers/hdgo.py Bestand weergeven

@@ -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
resolvers/hqqresolver.py Bestand weergeven

@@ -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
resolvers/kapnob.py Bestand weergeven

@@ -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
resolvers/kodik.py Bestand weergeven

@@ -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
resolvers/openload3.py Bestand weergeven

@@ -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
resolvers/youtuberesolver.py Bestand weergeven

@@ -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
- 169
sources/SourceBase.py Bestand weergeven

@@ -1,169 +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, json
12
-import ssl
13
-if "_create_unverified_context" in dir(ssl):
14
-    ssl._create_default_https_context = ssl._create_unverified_context
15
-
16
-
17
-try:
18
-    from requests.packages.urllib3.exceptions import InsecureRequestWarning
19
-    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
20
-except:
21
-    pass
22
-from collections import OrderedDict
23
-import ConfigParser
24
-try:
25
-    import util
26
-except:
27
-    parent = os.path.dirname(os.path.abspath(__file__))
28
-    parent = os.sep.join(parent.split(os.sep)[:-1])
29
-    sys.path.insert(0,parent)
30
-    import util
31
-
32
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
33
-
34
-class SourceBase(object):
35
-    """Stream source base class"""
36
-
37
-    def __init__(self,country="lv"):
38
-        self.name = "name"
39
-        self.title = "Title"
40
-        self.img = ""
41
-        self.desc = ""
42
-        self.options = OrderedDict()
43
-        self.config_file = ""
44
-        self.url = "http://www.bbb.com/"
45
-        self.headers = headers2dict("""
46
-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
47
-""")
48
-
49
-    def login(self,user="",password=""):
50
-        return False
51
-
52
-    def logout(self):
53
-        return True
54
-
55
-    def get_content(self,data):
56
-        ### To be overriden in child class
57
-        return [("..atpakaļ","back",None,"Kļūda, atgriezties atpakaļ")]
58
-
59
-    def is_video(self,data):
60
-        ### To be overriden in child class
61
-        return False
62
-
63
-    def get_streams(self,data):
64
-        ### Normally to be overrided in child class
65
-
66
-        if not self.is_video(data):
67
-            return []
68
-        content = self.get_content(data)
69
-        stream = util.item()
70
-        stream["name"] = content[0].encode("utf8") if isinstance(content[0],unicode) else content[0]
71
-        stream["url"] = content[1].encode("utf8") if isinstance(content[1],unicode) else content[1]
72
-        stream["img"] = content[2].encode("utf8") if isinstance(content[2],unicode) else content[2]
73
-        stream["desc"] = content[3].encode("utf8") if isinstance(content[3],unicode) else content[3]
74
-        stream["type"] = stream_type(content[1]).encode("utf8")
75
-        return[stream]
76
-
77
-    def get_epg(self,data):
78
-        ### Normally to be overrided in child class
79
-        return [self.get_info(data)]
80
-
81
-    def options_read(self):
82
-        if not ("options" in dir(self) and self.options): # process options only if self.options defined, self.config_file should be defined too
83
-            return None
84
-        config = ConfigParser.ConfigParser()
85
-        if os.path.exists(self.config_file):
86
-            options0 = self.options
87
-            config.read(self.config_file)
88
-            self.options = OrderedDict(config.items(self.name))
89
-            for k in options0:
90
-                if not k in self.options:
91
-                    self.options[k] = options0[k]
92
-                    self.options_write(self.options)
93
-        else:
94
-            self.options_write(self.options)
95
-        return self.options
96
-
97
-    def options_write(self,options):
98
-        config = ConfigParser.ConfigParser()
99
-        config.add_section(self.name)
100
-        for k in options.keys():
101
-            config.set(self.name, k,options[k])
102
-        with open(self.config_file,"w") as f:
103
-            config.write(f)
104
-        self.options = OrderedDict(config.items(self.name))
105
-
106
-    def call(self, data,params=None,headers=None,lang=""):
107
-        if not headers: headers = self.headers
108
-        url = self.url+data
109
-        result = self._http_request(url,params,headers=headers)
110
-        return result
111
-
112
-    def call_json(self, data,params=None,headers=None,lang=""):
113
-        result = self.call(data,params,headers)
114
-        if result:
115
-            result = json.loads(result)
116
-            return result
117
-        else:
118
-            raise "No data returned"
119
-
120
-    def _http_request(self, url,params = None, headers=None):
121
-        if not headers:
122
-            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")
123
-        try:
124
-            if params:
125
-                r = requests.post(url, data=params, headers=headers,verify=False)
126
-            else:
127
-                r = requests.get(url, headers=headers,verify=False)
128
-            return r.content
129
-        except Exception as ex:
130
-            if "read" in ex:
131
-                content = ex.read()
132
-            else:
133
-                content = None
134
-            return content
135
-
136
-    @staticmethod
137
-    def stream_type(data):
138
-        return stream_type(data)
139
-
140
-    @staticmethod
141
-    def parse_data(data):
142
-        if "::" in data:
143
-            source = data.split("::")[0]
144
-            data = data.split("::")[1]
145
-        else:
146
-            source = ""
147
-        path = data.split("?")[0]
148
-        plist = path.split("/")
149
-        clist = plist[0]
150
-        params = data[data.find("?"):] if "?" in data else ""
151
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=[\w\-]+",params)))
152
-        return source,data,path,plist,clist,params,qs
153
-
154
-def stream_type(data):
155
-    data = data.lower()
156
-    m = re.search(r"^(\w+)://", data)
157
-    prefix = m.group(1) if m else ""
158
-    if prefix in ("http","https"):
159
-        if ".m3u8" in data:
160
-            return "hls"
161
-        elif ".mpd" in data:
162
-            return "dash"
163
-        else:
164
-            return "http"
165
-    else:
166
-        return prefix
167
-
168
-if __name__ == "__main__":
169
-    pass

+ 0
- 407
sources/YouTubeVideoUrl.py Bestand weergeven

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

+ 0
- 0
sources/__init__.py Bestand weergeven


+ 0
- 213
sources/cinemalive.py Bestand weergeven

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

+ 0
- 115
sources/config.py Bestand weergeven

@@ -1,115 +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",cfg_path=None):
16
-        self.name = "config"
17
-        self.country=country
18
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
19
-        if not cfg_path: cfg_path = cur_directory
20
-        self.streams_file = os.path.join(cfg_path,"streams.cfg")
21
-        self.lists = collections.OrderedDict()
22
-        self.titles = {}
23
-        self.read_streams()
24
-
25
-    def get_content(self, data):
26
-        print "[config] get_content",data
27
-        self.read_streams()
28
-        if "::" in data:
29
-            data = data.split("::")[1]
30
-        if not data in self.lists:
31
-            return []
32
-        return self.lists[data]
33
-
34
-    def is_video(self,data):
35
-        return False
36
-
37
-    def read_streams(self):
38
-        for line in open(self.streams_file,"r"):
39
-            r = re.search("^\[(\w+)\]", line)
40
-            if r:
41
-                name = r.group(1)
42
-                self.lists[name] = []
43
-            else:
44
-                if line[0] in ("#"): continue
45
-                items = line.strip().split("|")
46
-                if not items[0]: continue
47
-                if len(items)==1:
48
-                    self.titles[name] = items[0]
49
-                else:
50
-                    if len(items) == 4:
51
-                        items[3] = items[3].replace("\\n","\n")
52
-                    self.lists[name].append(items)
53
-
54
-    def write_streams(self):
55
-        f = open(self.streams_file,"w")
56
-        for l in self.lists.keys():
57
-            f.write("[%s]\n"%l)
58
-            t = self.get_title(l)
59
-            if t<>l:
60
-                f.write("%s\n"%t)
61
-            for item in self.lists[l]:
62
-                f.write("%s|%s|%s|%s\n"%(item[0].replace("\n",""),item[1],item[2],item[3].replace("\n","\\n")))
63
-            f.write("\n")
64
-        f.close()
65
-
66
-    def get_lists(self):
67
-        return self.lists.keys()
68
-
69
-    def get_list_items(self,name):
70
-        return self.lists[name]
71
-
72
-    def get_title(self,name):
73
-        if name in self.titles:
74
-            return self.titles[name]
75
-        else:
76
-            return name
77
-
78
-    def add_list(self,name):
79
-        if not name in self.lists.keys():
80
-            self.lists[name] = []
81
-
82
-    def del_list(self,name):
83
-        if name in self.lists.keys():
84
-            del self.lists[name]
85
-
86
-    def add_item(self,name,item,pos=None):
87
-        if name in self.lists.keys():
88
-            if pos==None:
89
-                self.lists[name].append(item)
90
-            else:
91
-                self.lists[name].insert(pos,item)
92
-
93
-    def del_item(self,name,pos):
94
-        self.lists[name].pop(pos)
95
-
96
-    def replace_item(self,name,item,pos):
97
-        self.lists[name][pos]=item
98
-
99
-
100
-if __name__ == "__main__":
101
-    c = Source()
102
-    content = c.get_content("home")
103
-    for item in content: print item
104
-    #c.del_item("home",0)
105
-    #c.del_list("favorites")
106
-
107
-    #c.add_item("home",("My Streams","config::favorites","","Mani saglabātie TV kanāli un video"),0)
108
-    c.replace_item("home",("My Streams","config::my_streams","default","Mani saglabātie TV kanāli un video"),0)
109
-    #c.add_list("favorites")
110
-    #c.add_item("favorites",("..return","back","","Atgriezties atpakaļ"))
111
-    #c.add_item("favorites",("LTV1","http://streamltv.cloudy.services/ltv/LTV02.smil/playlist.m3u8","picons/latvia1.png", "Latvijas televīzijas 1.kanāls"))
112
-
113
-    c.write_streams()
114
-    for item in content: print item
115
-

+ 0
- 3
sources/euronews.cfg Bestand weergeven

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

+ 0
- 305
sources/euronews.py Bestand weergeven

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

+ 0
- 412
sources/filmix.py Bestand weergeven

@@ -1,412 +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
-import ssl
21
-if "_create_unverified_context" in dir(ssl):
22
-    ssl._create_default_https_context = ssl._create_unverified_context
23
-
24
-try:
25
-    import util
26
-except:
27
-    sys.path.insert(0,'..')
28
-    import util
29
-
30
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
31
-
32
-class Source(SourceBase):
33
-
34
-    def __init__(self,country="",cfg_path=None):
35
-        self.name = "filmix"
36
-        self.title = "filmix.me"
37
-        self.img = "http://cs5324.vk.me/g33668783/a_903fcc63.jpg"
38
-        self.desc = "filmix.me satura skatīšanās"
39
-        self.country=country
40
-        self.headers = headers2dict("""
41
-Host: filmix.me
42
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
43
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
44
-Accept-Language: en-US,en;q=0.5
45
-""")
46
-        self.headers2 = headers2dict("""
47
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
48
-X-Requested-With: XMLHttpRequest
49
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
50
-""")
51
-        self.url = "https://filmix.me/"
52
-        #self.login()
53
-
54
-    def login(self,user="",password=""):
55
-        return True
56
-
57
-    def get_content(self, data):
58
-        print "[filmix] get_content:", data
59
-        source, data, path, plist, clist, params, qs = self.parse_data(data)
60
-        content=[]
61
-        content.append(("..return", "back","","Return back"))
62
-
63
-        if clist=="home":
64
-            content.extend([
65
-                ("Search", "filmix::search/{0}","","Search"),
66
-                ("Movies", "filmix::movies","","Movies"),
67
-                ("Series", "filmix::series","","TV Series"),
68
-                ("Cartoons", "filmix::cartoons","","Cartoons"),
69
-            ])
70
-            return content
71
-
72
-        #elif clist=="search":
73
-            # TODO
74
-            #return content
75
-
76
-        elif data in ("movies","series","cartoons"):
77
-            r = self.call("")
78
-            r = r.decode("cp1251").encode("utf8")
79
-            if data == "movies":
80
-                sname = "Фильмы"
81
-            elif data=="series":
82
-                sname = "Сериалы"
83
-            else:
84
-                sname = "Мультфильмы"
85
-            # <span class="menu-title">Фильмы</span>
86
-            m = re.search('<span class="menu-title">%s</span>(.+?)<li>\s+?<span'%sname, r, re.DOTALL|re.UNICODE)
87
-            if not m: return content
88
-            r2 = m.group(1)
89
-            result = re.findall(r'<a .*?href="https://filmix\.me/([^"]+)".*?>([^<]+)</', r2, re.DOTALL)
90
-            for item in result:
91
-                if "catalog" in item[0]: continue
92
-                title = item[1]
93
-                data2 = item[0]
94
-                img = self.img
95
-                desc = title
96
-                content.append((title,self.name+"::"+data2,img,desc))
97
-            return content
98
-
99
-        ## Seriāls
100
-        elif clist=="play":
101
-            r = self.call(path)
102
-            r = r.decode("cp1251").encode("utf8")
103
-            title = title0 = util.unescape(re.search("titlePlayer = '([^']+)'", r, re.DOTALL).group(1))
104
-            m = re.search('<meta itemprop="thumbnailUrl" content="([^"]+)',r,re.DOTALL)
105
-            img = m.group(1) if m else self.img
106
-            m = re.search('<meta itemprop="duration" content="([^"]+)" />', r, re.DOTALL)
107
-            duration = "(%s)"%m.group(1) if m else ""
108
-            m = re.search('<p itemprop="description"[^>]+>([^<]+)<', r, re.DOTALL)
109
-            desc = desc0 =  util.unescape(m.group(1).strip()) if m else ""
110
-            vid = plist[-1]
111
-            m = re.search(r"meta_key = \['(\w+)', '(\w+)', '(\w+)'\]", r, re.IGNORECASE)
112
-            key = m.group(3) if m else ""
113
-            js = self.get_movie_info(vid,key)
114
-            translations = js["message"]["translations"]["html5"]
115
-            for pl  in translations:
116
-                if translations[pl].startswith("http"):
117
-                    continue
118
-                pl_link = translations[pl]
119
-                lang = pl.encode("utf8")
120
-                break
121
-            else:
122
-                raise Exception("No episodes list found!")
123
-            #pl_link = js["message"]["translations"]["flash"].values()[0]
124
-            #  TODO process several players, currently taking the first
125
-            #TODO - kļuda, vairs nesradā
126
-            if not pl_link.startswith("http"):
127
-                pl_link = self.decode_direct_media_url(pl_link)
128
-            js = self._http_request(pl_link)
129
-            js = self.decode_direct_media_url(js)
130
-            js = json.loads(js)
131
-            if "s" in qs:
132
-                s = int(qs["s"])
133
-                for i,ep in enumerate(js["playlist"][s-1]["playlist"]):
134
-                    title = title0+" - "+js["playlist"][s-1]["playlist"][i]["comment"].encode("utf8")
135
-                    serie = js["playlist"][s-1]["playlist"][i]["comment"].encode("utf8")
136
-                    data2 = data+"&e=%s"%(i+1)
137
-                    desc = serie +"\n"+desc0
138
-                    content.append((title,self.name+"::"+data2,img,desc))
139
-            else:
140
-                for i,ep in enumerate(js["playlist"]):
141
-                    title = title0 +" - "+js["playlist"][i]["comment"].encode("utf8")
142
-                    serie = js["playlist"][i]["comment"].encode("utf8")
143
-                    if "file" in ep and ep["file"]:
144
-                        data2 = data+"?e=%s"%(i+1)
145
-                    else:
146
-                        data2 = data+"?s=%s"%(i+1)
147
-                    desc = serie +"\n"+desc0
148
-                    content.append((title,self.name+"::"+data2,img,desc))
149
-            return content
150
-            #r = self._http_request(url)
151
-
152
-
153
-        ### saraksts ###
154
-        else:
155
-            r = self.call(data)
156
-            r = r.decode("cp1251").encode("utf8")
157
-            for r2 in re.findall('<article class="shortstory line".+?</article>', r, re.DOTALL):
158
-                #m2 = re.search(r'<a class="watch icon-play" itemprop="url" href="([^"]+)"', r2, re.DOTALL)
159
-                #<a class="watch icon-play" itemprop="url" href="https://filmix.me/dramy/110957-stolik-19-2017.html"
160
-                #m = re.search(r'<a href="https://filmix\.me/play/(\d+)" class="watch icon-play">', r2, re.DOTALL)
161
-                m = re.search(r'<a class="watch icon-play" itemprop="url" href="https://filmix.me/\w+/(\d+)-', r2, re.DOTALL)
162
-                if not m: continue
163
-                vid = m.group(1)
164
-                data2 = "play/%s"%vid
165
-                #title = re.search('itemprop="name">([^<]+)</div>', r2, re.DOTALL).group(1)
166
-                title = re.search('itemprop="name" content="([^"]+)"', r2, re.DOTALL).group(1)
167
-                m = re.search('itemprop="alternativeHeadline" content="([^"]+)"', r2, re.DOTALL)
168
-                if m:
169
-                    title = title + "/"+m.group(1)
170
-                m = re.search('<img src="([^"]+.jpg)"', r2, re.DOTALL)
171
-                img = m.group(1) if m else self.img
172
-                m = re.search(r'<a itemprop="copyrightYear".+?>(\d+)<', r2, re.DOTALL)
173
-                if m:
174
-                    year = m.group(1) if m else ""
175
-                    title = "%s (%s)"%(title,year)
176
-                title = util.unescape(title)
177
-                genre = re.findall('<a itemprop="genre"[^>]+?">([^<]+)</a>', r2, re.DOTALL)
178
-                genre = ",".join(genre)
179
-                m = re.search('<p itemprop="description">([^<]+)</p>', r2, re.DOTALL)
180
-                desc0 = util.unescape(m.group(1)) if m else ""
181
-                m = re.search('<div class="quality">([^<]+)</div>', r2, re.DOTALL)
182
-                quality = m.group(1) if m else ""
183
-                actors = re.findall('itemprop="actor">([^<]+)<', r2, re.DOTALL)
184
-                actors = ",".join(actors)
185
-                desc="%s\n%s\n%s\n%s\n%s"%(title,genre,desc0,actors,quality)
186
-                content.append((title,self.name+"::"+data2,img,desc))
187
-            if '<div class="navigation">' in r:
188
-                m = re.search(r'href="https://filmix\.me/([^"]+)" class="next icon-arowRight btn-tooltip"', r, re.DOTALL)
189
-                if m:
190
-                    data2 = m.group(1)
191
-                else:
192
-                    m = re.search("/page/(\d)+",data)
193
-                    if m:
194
-                        page = int(m.group(1))+1
195
-                        data2 = re.sub("/page/(\d)+", "/page/%s"%page, data)
196
-                    else:
197
-                        data2 = data + "/page/2"
198
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
199
-
200
-            return content
201
-
202
-    def is_video(self,data):
203
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
204
-        if clist == "play" and "e=" in data:
205
-            return True
206
-        elif clist=="play" and not params:
207
-            r = self.call(path)
208
-            #r = r.decode("cp1251").encode("utf8")
209
-            #m = re.search('itemprop="contentUrl" content="(.+?)"', r, re.IGNORECASE | re.DOTALL)
210
-            #if not m:
211
-            if u"Фильм <a href=" in r.decode("cp1251"):
212
-                return True
213
-            else:
214
-                return False
215
-
216
-        else:
217
-            return False
218
-
219
-    def get_streams(self, data):
220
-        print "[filmix] get_streams:", data
221
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
222
-
223
-        r = self.call(path)
224
-        if not r:
225
-            return []
226
-        streams = []
227
-        r = r.decode("cp1251").encode("utf8")
228
-        title = title0 = util.unescape(re.search("titlePlayer = '([^']+)'", r, re.DOTALL).group(1))
229
-        m = re.search('<meta itemprop="thumbnailUrl" content="([^"]+)',r,re.DOTALL)
230
-        img = m.group(1) if m else self.img
231
-        m = re.search('<meta itemprop="duration" content="([^"]+)" />', r, re.DOTALL)
232
-        duration = "(%s)"%m.group(1) if m else ""
233
-        m = re.search('<p itemprop="description"[^>]+>([^<]+)<', r, re.DOTALL)
234
-        desc = desc0 =  util.unescape(m.group(1).strip()) if m else ""
235
-        m = re.search('itemprop="contentUrl" content="(.+?)"', r, re.IGNORECASE | re.DOTALL)
236
-        if not m:
237
-            raise Exception("Can not find video link")
238
-            #return []
239
-        video_link = m.group(1)
240
-        series = False if u"Фильм <a href=" in r.decode("utf8") else True
241
-        vid = plist[1]
242
-        m = re.search(r"meta_key = \['(\w+)', '(\w+)', '(\w+)'\]", r, re.IGNORECASE)
243
-        key = m.group(3) if m else ""
244
-        js = self.get_movie_info(vid,key)
245
-        translations = js["message"]["translations"]["html5"]
246
-        for pl in translations:
247
-            if translations[pl].startswith("http"):
248
-                continue
249
-            pl_link = translations[pl]
250
-            lang = pl.encode("utf8")
251
-            break
252
-        else:
253
-            raise Exception("No episodes list found!")
254
-        if not pl_link.startswith("http"):
255
-            pl_link = self.decode_direct_media_url(pl_link)
256
-
257
-        if not series : # Filma
258
-            url0 = pl_link
259
-            streams2 = self.get_streams2(url0)
260
-            for st in streams2:
261
-                stream = util.item()
262
-                stream["url"]=st[1]
263
-                stream["lang"]=lang
264
-                stream["quality"]=st[0]
265
-                stream["name"]= title
266
-                stream["desc"]=desc
267
-                streams.append(stream)
268
-            return streams
269
-
270
-        else: # Seriāls
271
-            #pl_link = video_link
272
-            js = self._http_request(pl_link)
273
-            js = self.decode_direct_media_url(js)
274
-            js = json.loads(js)
275
-            if "e" in qs:
276
-                if "s" in qs:
277
-                    s = int(qs["s"])
278
-                else:
279
-                    s = None
280
-                e = int(qs["e"])
281
-                if s: # sezona + epizode
282
-                    serie = js["playlist"][s-1]["playlist"][e-1]["comment"].encode("utf8")
283
-                    title = title0+" - "+ serie
284
-                    url0 = js["playlist"][s-1]["playlist"][e-1]["file"].encode("utf8")
285
-                else: # tikai epizode, nav sezonas
286
-                    title = title0 +" - "+js["playlist"][e-1]["comment"].encode("utf8")
287
-                    serie = js["playlist"][e-1]["comment"].encode("utf8")
288
-                    url0 = js["playlist"][e-1]["file"].encode("utf8")
289
-                streams2 = self.get_streams2(url0)
290
-                for st in streams2:
291
-                    stream = util.item()
292
-                    stream["url"]=st[1]
293
-                    stream["lang"]=lang
294
-                    stream["quality"]=st[0]
295
-                    stream["name"]= title
296
-                    stream["desc"]=desc
297
-                    streams.append(stream)
298
-                return streams
299
-
300
-    def call(self, data,params=None,headers=None,lang=""):
301
-        if not headers: headers = self.headers
302
-        url = self.url+data
303
-        result = self._http_request(url,params,headers=headers)
304
-        return result
305
-
306
-    def get_movie_info(self,vid,key=""):
307
-        headers = headers2dict("""
308
-    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
309
-    Accept: application/json, text/javascript, */*; q=0.01
310
-    Accept-Language: en-US,en;q=0.5
311
-    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
312
-    X-Requested-With: XMLHttpRequest
313
-    Referer: https://filmix.me/play/%s
314
-    Cookie: ad_win12=1;
315
-    """%vid )
316
-        post_data = {"post_id":vid,"key=":key}
317
-        r = util.post("https://filmix.me/api/movies/player_data", data=post_data, headers = headers)
318
-        if not r:
319
-            raise Exception("Can not get movie info")
320
-            #return []
321
-        js = json.loads(r)
322
-        return js
323
-
324
-    def decode_base64(self, encoded_url):
325
-        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", "=")
326
-        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")
327
-        i = 0
328
-        for a in codec_a:
329
-            b = codec_b[i]
330
-            i += 1
331
-            encoded_url = encoded_url.replace(a, '___')
332
-            encoded_url = encoded_url.replace(b, a)
333
-            encoded_url = encoded_url.replace('___', b)
334
-        return base64.b64decode(encoded_url)
335
-
336
-    def decode_unicode(self, encoded_url):
337
-        from itertools import izip_longest
338
-        def grouper(n, iterable, fillvalue=None):
339
-            "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
340
-            args = [iter(iterable)] * n
341
-            return izip_longest(fillvalue=fillvalue, *args)
342
-
343
-        _ = (encoded_url[1:] if encoded_url.find('#') != -1 else encoded_url)
344
-        tokens = map(lambda items: '\u0'+''.join(items), grouper(3, _))
345
-        return ''.join(tokens).decode('unicode_escape')
346
-
347
-    def decode_direct_media_url(self, encoded_url, checkhttp=False):
348
-        if(checkhttp == True and (encoded_url.find('http://') != -1 or encoded_url.find('https://') != -1)):
349
-            return False
350
-
351
-        try:
352
-            if encoded_url.find('#') != -1:
353
-                return self.decode_unicode(encoded_url)
354
-            else:
355
-                return self.decode_base64(encoded_url)
356
-        except:
357
-            return False
358
-
359
-
360
-
361
-    def decode_uppod_text(self, text):
362
-        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", "="]
363
-        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"]
364
-        text = text.replace("\n", "").strip()
365
-        for i in range(len(Client_codec_a)):
366
-            char1 = Client_codec_b[i]
367
-            char2 = Client_codec_a[i]
368
-            text = text.replace(char1, "___")
369
-            text = text.replace(char2, char1)
370
-            text = text.replace("___", char2)
371
-        result = base64.b64decode(text)
372
-        print result
373
-        return result
374
-
375
-    def get_streams2(self,url0):
376
-        m = re.search("\[([\d\w,]+)\]",url0)
377
-        if not m:
378
-            return [("?",url0)]
379
-        res = m.group(1)
380
-        streams=[]
381
-        for res in res.split(","):
382
-            if not res: continue
383
-            if res in ["1080p"]: continue #TODO fullhd only in PRO+ version
384
-            url=re.sub("\[[\d\w,]+\]",res,url0)
385
-            streams.append((res,url))
386
-        return streams
387
-
388
-
389
-if __name__ == "__main__":
390
-
391
-    c = Source()
392
-    #s = "ZnVuY3Rpb24gc2VuZE1lc3NhZ2U2MDc3ODkoZSl7dmFyIGg9bWdfd3M2MDc3ODkub25tZXNzYWdlOyBtZ193czYwNzc4OS5yZWFkeVN0YXRlPT1tZ193czYwNzc4OS5DTE9TRUQmJihtZ193czYwNzc4OT1uZXcgV2ViU29ja2V0KG1nX3dzNjA3Nzg5X2xvY2F0aW9uKSksbWdfd3M2MDc3ODkub25tZXNzYWdlPWgsd2FpdEZvclNvY2tldENvbm5lY3Rpb242MDc3ODkobWdfd3M2MDc3ODksZnVuY3Rpb24oKXttZ193czYwNzc4OS5zZW5kKGUpfSl9ZnVuY3Rpb24gd2FpdEZvclNvY2tldENvbm5lY3Rpb242MDc3ODkoZSx0KXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7cmV0dXJuIDE9PT1lLnJlYWR5U3RhdGU/dm9pZChudWxsIT10JiZ0KCkpOnZvaWQgd2FpdEZvclNvY2tldENvbm5lY3Rpb242MDc3ODkoZSx0KX0sNSl9OyB2YXIgbWdfd3M2MDc3ODlfbG9jYXRpb24gPSAid3NzOi8vd3NwLm1hcmtldGdpZC5jb20vd3MiOyBtZ193czYwNzc4OSA9IG5ldyBXZWJTb2NrZXQobWdfd3M2MDc3ODlfbG9jYXRpb24pLCBtZ193czYwNzc4OS5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAodCkge3Bvc3RNZXNzYWdlKHQuZGF0YSk7fSwgb25tZXNzYWdlID0gZnVuY3Rpb24oZSl7c2VuZE1lc3NhZ2U2MDc3ODkoZS5kYXRhKX0="
393
-
394
-    #txt = c.decode_uppod_text(s)
395
-    if len(sys.argv)>1:
396
-        data= sys.argv[1]
397
-    else:
398
-        data = "home"
399
-    content = c.get_content(data)
400
-    for item in content:
401
-        print item
402
-    #cat = api.get_categories(country)
403
-    #chan = api.get_channels("lv")
404
-    #prog = api.get_programs(channel=6400)
405
-    #prog = api.get_programs(category=55)
406
-    #seas = api.get_seasons(program=6453)
407
-    #str = api.get_streams(660243)
408
-    #res = api.get_videos(802)
409
-    #formats = api.getAllFormats()
410
-    #det = api.detailed("1516")
411
-    #vid = api.getVideos("13170")
412
-    pass

+ 0
- 276
sources/filmon.py Bestand weergeven

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

+ 0
- 4
sources/iplayer.cfg Bestand weergeven

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

+ 0
- 559
sources/iplayer.py Bestand weergeven

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

+ 0
- 261
sources/jsinterp.py Bestand weergeven

@@ -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
- 219
sources/lmt.py Bestand weergeven

@@ -1,219 +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
-import ssl
16
-if "_create_unverified_context" in dir(ssl):
17
-    ssl._create_default_https_context = ssl._create_unverified_context
18
-
19
-from SourceBase import SourceBase
20
-
21
-import resolver
22
-try:
23
-    import util
24
-except:
25
-    sys.path.insert(0,'..')
26
-    import util
27
-from YouTubeVideoUrl import YouTubeVideoUrl
28
-
29
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
30
-import HTMLParser
31
-h = HTMLParser.HTMLParser()
32
-
33
-class Source(SourceBase):
34
-
35
-    def __init__(self, country="",cfg_path=None):
36
-        self.name = "lmt"
37
-        self.title = "LMT straume"
38
-        self.img = "http://www.lob.lv/images/logo/lmt_straume_vert_rgb.png"
39
-        self.desc = "LMT straume - dažādi video latviesu valodā"
40
-        self.headers = headers2dict("""
41
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
42
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
43
-Accept-Language: en-US,en;q=0.5
44
-""")
45
-        self.headers2 = headers2dict("""
46
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
47
-X-Requested-With: XMLHttpRequest
48
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
49
-""")
50
-        self.url = "http://straume.lmt.lv/lv/"
51
-
52
-    ######### Entry point ########
53
-    def get_content(self, data):
54
-        print "[lmt] 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
-                ("Meklēt", "lmt::meklet?q={0}","","Meklēt"),
62
-                ("Straumes", "lmt::straumes","","Tiešraides un aktuāli video"),
63
-                #("TV", "lmt::tv","","TV tiešraides (tikai LMT tīklā)"),
64
-                ("Jaunākie", "lmt::video/jaunakie?videoPage=1", "", "Visu žanru jaunākie video"),
65
-                ("Sports", "lmt::video/sports?videoPage=1", "", "Sports"),
66
-                ("Kultūra un māksla", "lmt::video/kultura?videoPage=1", "", "Kultūra un māksla"),
67
-                ("Konferences", "lmt::video/konferences?videoPage=1", "", "Konferences"),
68
-                ("Raidījumi", "lmt::video/raidijumi?videoPage=1", "", "Raidījumi"),
69
-                ("Notikumi", "lmt::video/notikumi?videoPage=1", "", "Notikumi"),
70
-                ("Filmas un seriāli", "lmt::video/filmas?videoPage=1", "", "Filmas un seriāli"),
71
-                ("Dažādi video", "lmt::video/dazadi?videoPage=1", "", "Dažādi video"),
72
-                ("Viedtelevīzija", "lmt::video/viedtelevizija?videoPage=1", "", "Viedtelevīzija"),
73
-            ])
74
-            return content
75
-
76
-        elif clist in ("meklet","video", "straumes","video-saraksts"):
77
-            r=self.call(data)
78
-            result = re.findall('<a class="video-picture" (.+?)</li>', r, re.IGNORECASE | re.MULTILINE)
79
-            for r2 in result:
80
-                m = re.search('<a class="video-title" href="/lv/([^"]+)">([^<]+)<', r2)
81
-                title = m.group(2)
82
-                data2 = m.group(1)
83
-                m = re.search("([^ ]+) 2x", r2)
84
-                if m:
85
-                    img = m.group(1)
86
-                else:
87
-                    m = re.search('<img src="([^"]+)', r2)
88
-                    img = m.group(1) if m else ""
89
-                m = re.search('<span class="playlist-overlay">([^<]+)</span>', r2)
90
-                overlay = m.group(1) if m else ""
91
-                m = re.search('<span class="badge badge-[^>]+>([^<]+)(<[^>]+>([^<]+))*</span>', r2, re.IGNORECASE)
92
-                badge = ""
93
-                if m:
94
-                    badge = m.group(1)
95
-                    if m.group(3):
96
-                        badge = badge + m.group(3)
97
-                categories = re.findall('<span class="category-title">([^<]+)</span>', r2)
98
-                categories = "".join(categories)
99
-                if overlay:
100
-                    title = "%s [%s]"%(title,overlay)
101
-                if badge:
102
-                    title = "%s [%s]"%(title,badge)
103
-                desc = title
104
-                if categories:
105
-                    desc = desc + "\n"+ categories
106
-                content.append((title,self.name+"::"+data2,img,desc))
107
-            m = re.search("videoPage=(\d+)",data)
108
-            if m:
109
-                page = int(m.group(1))+1
110
-                data2 = re.sub(r"videoPage=\d+", r"videoPage=%s"%page, data)
111
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
112
-            #print content
113
-            return content
114
-
115
-
116
-        ### kaut kas neparedzets ###
117
-        else:
118
-            return content
119
-
120
-    def is_video(self,data):
121
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
122
-        if not clist in ("meklet","video", "straumes","video-saraksts","home"):
123
-            return True
124
-
125
-    def call(self, data,params=None,headers=None,lang=""):
126
-        if not headers: headers = self.headers
127
-        url = self.url+data
128
-        r = requests.get(url,headers = headers)
129
-        return r.content
130
-        #result = self._http_request(url,params,headers=headers)
131
-        return result
132
-
133
-    def get_streams(self,data):
134
-        print "[lmt] get_streams:", data
135
-        if not self.is_video(data):
136
-            return []
137
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
138
-        r = self.call(path)
139
-        title = re.search("<h1>(.+?)</h1", r, re.IGNORECASE).group(1)
140
-        m = re.search('<a class="category-title".+?[^>]+>([^<]+)<', r, re.IGNORECASE | re.DOTALL)
141
-        categories = m.group(1) if m else ""
142
-        m = re.search('<span class="category-title">([^<]+)</span>.+?</p>', r, re.IGNORECASE | re.DOTALL)
143
-        if m:
144
-            categories = categories + m.group(1)
145
-        if categories:
146
-            tite = "%s [%s]"%(title,categories)
147
-        img = re.search('<meta property="twitter:image" content="([^"]+)">', r, re.IGNORECASE | re.DOTALL).group(1)
148
-        desc = title + "\n" + re.search('<meta property="og:description" content="([^"]+)">', r, re.IGNORECASE | re.DOTALL).group(1)
149
-        m = re.search('file: "([^"]+)"', r, re.IGNORECASE)
150
-        if m:
151
-            data2 = m.group(1)
152
-            stream = util.item()
153
-            stream["name"] = title
154
-            stream["url"] = data2
155
-            stream["img"] = img
156
-            stream["desc"] = desc
157
-            stream["resolver"] = "lmt"
158
-            return [stream]
159
-        elif re.search('src="http*://www.youtube.com/embed/([\w-]+).*"',r):
160
-            m = re.search('src="http*://www.youtube.com/embed/([\w-]+).*"',r)
161
-            video_id = m.group(1)
162
-            #http://www.youtube.com/embed/RUyQ_JJ6A84?rel=0&fs=1&wmode=transparent
163
-            data2 = YouTubeVideoUrl().extract(video_id)
164
-            s = util.item()
165
-            s["name"] = title
166
-            s["url"] = data2
167
-            s["desc"] = desc
168
-            s["img"] = img
169
-            s["resolver"] = "lmt"
170
-            return [s]
171
-        elif 'src="http://cdn.tiesraides.lv/lmtstraume.lv/' in r:
172
-            m = re.search('src="(http://cdn\.tiesraides\.lv/[^"]+)"',r)
173
-            url = m.group(1)
174
-            # src="http://cdn.tiesraides.lv/lmtstraume.lv/live-record2-ip/40?c=614127284dcd58d8a84afcf498a3ac7a&v=1405"
175
-            r = self._http_request(url)
176
-            #http://edge-telia2.tiesraides.lv/live-record2/lmtstraume.lv.40_1/manifest.f4m
177
-            m = re.search("'(http://.+?\.m3u8)'",r)
178
-            data2 = m.group(1) if m else ""
179
-            s = util.item()
180
-            s["name"] = title
181
-            s["url"] = data2
182
-            s["desc"] = desc
183
-            s["img"] = img
184
-            s["resolver"] = "lmt"
185
-            return [s]
186
-        else:
187
-            raise Exception("No stream found")
188
-
189
-
190
-                # streams = resolver.resolve(url)
191
-            # for s in streams:
192
-            #     s["name"] = title
193
-            #     s["desc"] = desc
194
-            #     s["img"] = img
195
-            #     streams.append(s)
196
-            # return streams
197
-
198
-
199
-if __name__ == "__main__":
200
-    country= "lv"
201
-    c = Source(country)
202
-    if len(sys.argv)>1:
203
-        data= sys.argv[1]
204
-    else:
205
-        data = "home"
206
-    content = c.get_content(data)
207
-    for item in content:
208
-        print item
209
-    #cat = api.get_categories(country)
210
-    #chan = api.get_channels("lv")
211
-    #prog = api.get_programs(channel=6400)
212
-    #prog = api.get_programs(category=55)
213
-    #seas = api.get_seasons(program=6453)
214
-    #str = api.get_streams(660243)
215
-    #res = api.get_videos(802)
216
-    #formats = api.getAllFormats()
217
-    #det = api.detailed("1516")
218
-    #vid = api.getVideos("13170")
219
-    pass

+ 0
- 4
sources/ltc.cfg Bestand weergeven

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

+ 0
- 1088
sources/ltc.py
Diff onderdrukt omdat het te groot bestand
Bestand weergeven


+ 0
- 235
sources/movieplace.py Bestand weergeven

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

+ 0
- 283
sources/mtgplay.py Bestand weergeven

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

+ 0
- 216
sources/play24.py Bestand weergeven

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

+ 0
- 310
sources/replay.py Bestand weergeven

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

+ 0
- 235
sources/serialguru.py Bestand weergeven

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

+ 0
- 118
sources/streams.cfg Bestand weergeven

@@ -1,118 +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
-LMT straume|lmt::home|http://www.lob.lv/images/logo/lmt_straume_vert_rgb.png|LMT straume - dažādi video latviesu valodā
25
-
26
-[my_tv]
27
-My Tv
28
-..return|back|default|Atgriezties atpakaļ
29
-LTV1|replay::tiesraide/ltv1/|http://replay.lsm.lv/resources/logo/large_ltv1.png|LTV1 tiesraide (video )
30
-LTV7|replay::tiesraide/ltv7/|http://replay.lsm.lv/resources/logo/large_ltv7.png|LTV7 tiesraide (video )
31
-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
32
-TV3 (ltc)|ltc::content/live-streams/103?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/TV3_logo.png|TV3
33
-LNT (ltc)|ltc::content/live-streams/104?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/LNT_logo.png|LNT
34
-TV6|ltc::content/live-streams/106?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/TV6_logo.png|TV6
35
-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
36
-3+|ltc::content/live-streams/107?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/3_logo.png|3+
37
-360TV|ltc::content/live-streams/1051?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/360TV_new.png|360TV
38
-STV Pirmā!|ltc::content/live-streams/1069?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/STV.png|STV Pirmā!
39
-TVRiga24|play24::tiesraide||TV live streams
40
-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
41
-RU live|tvdom::tiesraides||RU live streams from TVDom
42
-BBC live (iPlayer)|iplayer::live||BBC live streams from iPlayer
43
-UK live (FilmOn) TV|filmon::group?id=5|https://static.filmon.com/assets/groups/5/big_logo.png|UK live streams from FilmOn
44
-US live (FilmOn)|ustvnow::tvlive||US live streams from FilmOn
45
-Canadian live (FilmOn)|filmon::group?id=44|https://static.filmon.com/assets/groups/44/big_logo.png|Canada live streams from FilmOn
46
-Sport stream|rtmp://184.172.124.216/live/test111||
47
-
48
-[my_archive]
49
-My Archive
50
-..return|back||Atgriezties atpakaļ
51
-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
52
-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
53
-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
54
-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
55
-TVRiga24 arhīvs|play24::kategorija/raidijumi|http://play24.lv/images/play24-logo-black.png|TVRiga24.tv pārraižu arhīvs
56
-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
57
-BBC (iPlayer) arhīvs|iplayer::categories||BBC programmes by categories
58
-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
59
-Latest programs|euronews::content/getLatestPrograms?lang=en&byPage=40&page=1|http://pbs.twimg.com/profile_images/732665354242150400/tZsCnjuh_400x400.jpg|Latest programs
60
-
61
-[my_video]
62
-My Video
63
-..return|back||Atgriezties atpakaļ
64
-Все фильмы|filmix::films|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Все фильмы
65
-Все сериалы|filmix::serialy|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Все сериалы
66
-
67
-[my_kids]
68
-My Kids
69
-..return|back|default|Atgriezties atpakaļ
70
-Bērnu TV|config::my_kids_tv||Bērnu TV kanāli
71
-Bērnu video|config::my_kids_video||Saglabātie bērnu video
72
-LTV bērnu TV arhīvs|replay::raidijumi/?lang=lv&type=video&theme=5||LTV bērnu TV arhīvs
73
-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
74
-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
75
-CBeebies video|iplayer::categories/cbeebies|http://www.userlogos.org/files/logos/inductiveload/BBC_iPlayer_logo.png|CBeebies videos from iPlayer
76
-CBBC video|iplayer::categories/cbbc|http://www.userlogos.org/files/logos/inductiveload/BBC_iPlayer_logo.png|CBBC videos from iPlayer
77
-TVDom bērnu video|tvdom::arhivs/bernu||TVDom bērnu video RU
78
-Filmix bērnu filmas|filmix::detskij|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Filmix bērnu filmas
79
-Filmix bērnu seriāli|filmix::detskij/s7|http://cs5324.vk.me/g33668783/a_903fcc63.jpg|Filmix bērnu seriāli
80
-SerialGURU multenes|serialguru::mult||SerialGURU multenes
81
-
82
-[my_kids_tv]
83
-My Kids TV
84
-..return|back|default|Atgriezties atpakaļ
85
-Kidzone|ltc::content/live-streams/951?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/kidzone2_new.png|Kidzone
86
-Nickelodeon|ltc::content/live-streams/302?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/Nickelodeon.png|Nickelodeon
87
-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
88
-Nick Jr|ltc::content/live-streams/1095?include=quality|https://manstv.lattelecom.tv/images/01_Bildes/02_Kanalu_raidijumu_default/NickJR.png|Nick Jr
89
-CBeebies (iPlayer)|iplayer::live/cbeebies|http://www.lyngsat-logo.com/hires/bb/bbc_cbeebies_uk.png|CBeebies
90
-CBBC (iPlayer)|iplayer::live/cbbc|http://www.lyngsat-logo.com/hires/bb/bbc_cbbc.png|CBBC
91
-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!"
92
-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.
93
-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.
94
-
95
-[my_kids_video]
96
-My Kids Video
97
-..return|back|default|Atgriezties atpakaļ
98
-
99
-[my_radio]
100
-My Radio
101
-..return|back|default|Atgriezties atpakaļ
102
-LR1|replay::tiesraide/lr1/|http://replay.lsm.lv/resources/logo/lr1_logo.png|LR1 tiesraide (audio)
103
-LR2|replay::tiesraide/lr2/|http://replay.lsm.lv/resources/logo/lr2_logo.png|LR2 tiesraide (audio)
104
-LR3|replay::tiesraide/lr3/|http://replay.lsm.lv/resources/logo/lr3_logo.png|LR3 tiesraide (audio)
105
-LR4|replay::tiesraide/lr4/|http://replay.lsm.lv/resources/logo/lr4_logo.png|LR4 tiesraide (audio)
106
-LR5|replay::tiesraide/lr5/|http://replay.lsm.lv/resources/logo/lr5_logo.png|LR5 tiesraide (audio)
107
-LR6|replay::tiesraide/lr6/|http://replay.lsm.lv/resources/logo/lr6_logo.png|LR6 tiesraide (audio)
108
-
109
-[mtg]
110
-MTG
111
-..return|back|default|Atgriezties atpakaļ
112
-Estonia (tv3play.ee)|mtgplay::home?country=ee||MTG Estonia media portal content
113
-Lithuania (play.tv3.lt/)|mtgplay::home?country=lt||MTG Lithuania media portal content
114
-Sweden (tvXplay.se)|mtgplay::home?country=se||MTG Sweden media portal content
115
-Denmark (tv3play.dk)|mtgplay::home?country=dk||MTG Denmark media portal content
116
-Norway (tv3play.no)|mtgplay::home?country=no||MTG Norway media portal content
117
-Bulgaria (play.novatv.bg/)|mtgplay::home?country=bg||MTG Bulgaria media portal content
118
-

+ 0
- 828
sources/swfinterp.py Bestand weergeven

@@ -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
- 6
sources/tvdom.cfg Bestand weergeven

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

+ 0
- 345
sources/tvdom.py Bestand weergeven

@@ -1,345 +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
-from collections import OrderedDict
15
-import ssl
16
-if "_create_unverified_context" in dir(ssl):
17
-    ssl._create_default_https_context = ssl._create_unverified_context
18
-
19
-from SourceBase import SourceBase
20
-import util
21
-
22
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
23
-headers0 = headers2dict("""
24
-User-Agent: Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04
25
-Accept: application/json, text/javascript, */*; q=0.01
26
-Accept-Language: en-US,en;q=0.5
27
-Accept-Encoding: gzip, deflate, br
28
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
29
-X-Requested-With: XMLHttpRequest""")
30
-import HTMLParser
31
-h = HTMLParser.HTMLParser()
32
-
33
-class Source(SourceBase):
34
-
35
-    def __init__(self,country="lv",cfg_path=None):
36
-        self.name = "tvdom"
37
-        self.title = "TVDom.tv"
38
-        self.img = "https://tvdom.tv/front/assets/images/logo.png"
39
-        self.desc = "TVDom.tv portāla satura skatīšanās"
40
-        self.headers = headers0
41
-        self.url = "https://tvdom.tv/"
42
-
43
-        self.country=country
44
-        self.session = None
45
-        self.token = None
46
-
47
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
48
-        if not cfg_path: cfg_path = cur_directory
49
-        self.config_file = os.path.join(cfg_path,self.name+".cfg")
50
-        self.options = OrderedDict([("user","lietotajs"),("password","parole"), ("region", "lv"), ("lang", "lv")])
51
-        self.options_read()
52
-
53
-    def login(self,user="",password=""):
54
-        self.options_read()
55
-        if not user: user=self.options["user"]
56
-        if not password: password = self.options["password"]
57
-        headers = headers2dict("""
58
-User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0
59
-Accept: */*
60
-Accept-Language: en-US,en;q=0.5
61
-Accept-Encoding: gzip, deflate, br
62
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
63
-X-Requested-With: XMLHttpRequest
64
-Referer: https://tvdom.tv/
65
-        """)
66
-        url = "https://tvdom.tv/infinity/on_register_user"
67
-        params = "email=%s&password=%s&remember=false&auth_type=login"%(user,password)
68
-        import requests
69
-        try:
70
-            from requests.packages.urllib3.exceptions import InsecureRequestWarning
71
-            requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
72
-        except:
73
-            pass
74
-        r = requests.post(url, data=params, headers=headers)
75
-        js = json.loads(r.content)
76
-        if 'success' in r.content:
77
-            self.token = js["access_token"]
78
-            if 'PHPSESSID' in r.cookies:
79
-                self.session = r.cookies["PHPSESSID"]
80
-            return True
81
-        else:
82
-            raise Exception(js["error"])
83
-
84
-
85
-    def get_content(self, data):
86
-        print "[tvdom] get_content:", data
87
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
88
-        lang = self.options["lang"]
89
-        region = self.options["region"]
90
-        content=[]
91
-        content.append(("..return", "back","","Return back"))
92
-
93
-        if clist=="home":
94
-            content.extend([
95
-                ("Live stream", "tvdom::tiesraides","","TV live streams"),
96
-                ("Archive - last", "tvdom::arhivs?filter=new&page=0&limit=30&region=%s&language=%s" % (region, lang),"","Video archive - last videos"),
97
-                ("Archive - popular", "tvdom::arhivs?filter=new&page=0&limit=30&region=%s&language=%s"% (region, lang),"","Video archive - popular video"),
98
-                ("Archive - categories", "tvdom::arhivs","","Video archive by categories"),
99
-                ("Search", "tvdom::search/?srch-term={0}","","Search archive"),
100
-
101
-                #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
102
-            ])
103
-            return content
104
-
105
-        ### Tiesraides kanalu saraksts ###
106
-        elif data=="tiesraides":
107
-            data1 = "infinity/on_front_filter_channels_list.json"
108
-            params = "hd=&language=%s&region=%s" % (self.options["lang"], self.options["region"])
109
-            r = self.call_json(data1, params)
110
-            for genre in  r["data"]:
111
-                for item in r["data"][genre]:
112
-                    ch = item["channel_name"]
113
-                    title = u"%s - %s" % (item["channel_name"], item["program_title"])
114
-                    img = "https://tvdom.tv"+item["channel_logo"]
115
-                    data2 = item["program_url"][1:]
116
-                    desc = u"%s\n%s-%s"%(title,item["time_start"],item["time_stop"])
117
-                    content.append((title,self.name+"::"+data2,img,desc))
118
-            return content
119
-
120
-#         elif clist == "tiesraides":
121
-#             if not self.session:
122
-#                 self.login()
123
-#             url = "https://tvdom.tv/" + data
124
-#             headers = self.headers
125
-#             headers["Cookie"] = "PHPSESSID=%s; neverending_story=1;"%self.session
126
-#             r = self._http_request(url,headers=headers)
127
-#             m = re.search("var streamConnectionUrl = '([^']+)'", r, re.DOTALL)
128
-#             if m:
129
-#                 data2 = m.group(1)
130
-#             else:
131
-#                 return ("No stream found %s"%data,"","","No stream found")
132
-#             m = re.search('title: "([^"]+)"', r, re.DOTALL)
133
-#             title = m.group(1) if m else data2
134
-#             m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
135
-#             desc = m.group(1) if m else title
136
-#             m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
137
-#             desc = m.group(1) if m else title
138
-#             m = re.search('var promo_image *= "([^"]+)', r, re.DOTALL)
139
-#             img = m.group(1) if m else ""
140
-#             return (title,data2,img,desc)
141
-
142
-        ### Search ###
143
-        elif clist=="search":
144
-            url = "https://tvdom.tv/" + data
145
-            r = self._http_request(url)
146
-            result = re.findall(r'<div class="film-block_img">\s*<img src="([^"]+).+?<a href="/([^"]+)">([^<]+)</a>\s*</div>\s*<ul class="film-block_descr_tag">\s*<li><a href="">([^<]+)</a>', r, re.DOTALL)
147
-            for item in result:
148
-                title = item[2] + " ("+ item[3] + ")"
149
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
150
-                img = "https://tvdom.tv" + item[0]
151
-                data2 = item[1]
152
-                desc = title
153
-                content.append((title,self.name+"::"+data2,img,desc))
154
-            return content
155
-
156
-        ### Arhīva kategorijas ###
157
-        elif data=="arhivs":
158
-            url = "https://tvdom.tv/"+data
159
-            headers = self.headers
160
-            headers["Cookie"] = "neverending_story=1; user_selected_language=%s"% (self.options["lang"])
161
-            r = self._http_request(url)
162
-            result = re.findall(r'data-text-mobile="(.+?)" data-id="(\d+)" data-filter-type="archive_genre">', r)
163
-            for item in result:
164
-                title = item[0]
165
-                img = ""
166
-                data2 = "arhivs?" + "genre1=%s&filter=new&region=%s&lang=%s&page=0&limit=30" % (item[1], region, lang)
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
-            data1 = "infinity/on_front_archive_get_events2.json"
174
-            r = self.call_json(data1, params[1:])
175
-
176
-            for item in r["data"]:
177
-                title = item["title"] + "- " + item["online_time"]
178
-                img = "https://tvdom.tv"+item["image"]
179
-                data2 = item["url"][1:]
180
-                desc = u"%s\nlast: %s\npopularity: %s\n%s" % (title, item["online_time"], item["popularity"], item["channel_code"])
181
-                content.append((title,self.name+"::"+data2,img,desc))
182
-            if len(r["data"]) == 30:
183
-                page = int(qs["page"]) + 1
184
-                data2 = re.sub("page=\d+", "page=%s" % page, data)
185
-                content.append(("Next page",self.name+"::"+data2,"","Go to next page"))
186
-            return content
187
-
188
-        ### Arhīva programmas video saraksts ###
189
-        elif clist=="play_arhivs" and len(data.split("/"))==3 and not re.search("_\d+",plist[2]):
190
-            url = "https://tvdom.tv/"+data
191
-            r = self._http_request(url)
192
-            vid=re.search('materialIdentifier : "(\d+)', r, re.DOTALL).group(1)
193
-            pname = re.split("[_\.\-]", plist[-1])[0]
194
-            data2 = data+"_"+vid
195
-            m = re.search(r'var program_title\s*= "(.+?)"', r)
196
-            title = title0 = m.group(1) if m else data2
197
-            m = re.search('<p class="content-info__descr-item">(.+?)</p>', r, re.DOTALL)
198
-            datums = m.group(1).strip() if m else ""
199
-            title = title + " " + datums
200
-            m = re.search('<p class="video-player__descr-text" style="height: 100px;">(.+?)<span', r, re.DOTALL)
201
-            desc = m.group(1).strip() if m else title
202
-            m = re.search('var share_image\s*= "([^"]+)', r, re.DOTALL)
203
-            img = m.group(1) if m else ""
204
-            content.append((title,self.name+"::"+data2,img,desc))
205
-            i2 = r.find("content  content--indent-pb")
206
-            r2 = r if i2 == -1 else r[:i2]
207
-            result = re.findall(r'<img src="([^"]+)" class="content-item__image" alt=""><a href="/([^"]+)" class="content-item__hide-info">.+?<h3 class="content-item__name">\s*<a href="#">\s*([^<]*)\s*<br>\s*([^<]*)\s*</a>\s*</h3>', r2, re.DOTALL)
208
-            for item in result:
209
-                if pname not in item[1]:
210
-                    continue
211
-                title = item[2] + " " + item[3].strip()
212
-                title =  h.unescape(title.decode("utf8")).encode("utf8")
213
-                img = "https://tvdom.tv"+item[0]
214
-                data2 = item[1]
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
-    def get_streams(self,data):
244
-        print "[tvdom] get_streams:", data
245
-        if not self.is_video(data):
246
-            return []
247
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
248
-        if not self.session:
249
-            self.login()
250
-        url = "https://tvdom.tv/" + data
251
-        headers = self.headers
252
-        headers["Cookie"] = "PHPSESSID=%s; neverending_story=1;"%self.session
253
-        r = self._http_request(url,headers=headers)
254
-
255
-        if clist == "play_arhivs":
256
-            m = re.search('program_title        = "([^"]+)"', r, re.DOTALL)
257
-            title = m.group(1) if m else data2
258
-            m = re.search('<a class="episode">Pārraides laiks ēterā: <span>([^<]+)</span></a>', r, re.DOTALL)
259
-            datums = m.group(1) if m else ""
260
-            title = title + " " + datums
261
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
262
-            desc = m.group(1) if m else title
263
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
264
-            desc = m.group(1) if m else title
265
-            m = re.search('var share_image *= "([^"]+)', r, re.DOTALL)
266
-            img = m.group(1) if m else ""
267
-
268
-            m = re.search(r"var streams\s*= ({[^;]+);", r, re.DOTALL)
269
-            if not m:
270
-                raise Exception("No stream found")
271
-            js = json.loads(m.group(1))
272
-            streams = []
273
-            for st in js:
274
-                if st == "qualities": continue
275
-                s = js[st]
276
-                data2 = s["url"]
277
-                stream = util.item()
278
-                stream["name"] = title
279
-                stream["url"] = data2
280
-                stream["img"] = img
281
-                stream["desc"] = desc
282
-                stream["resolver"] = "tvdom"
283
-                stream["quality"] = st
284
-                stream["order"] = int(st[:-1])
285
-                streams.append(stream)
286
-
287
-            streams = sorted(streams,key=lambda item: item["order"],reverse=True)
288
-            return streams
289
-
290
-        # Tiešraides video
291
-        else:
292
-            m = re.search("var streamConnectionUrl = '([^']+)'", r, re.DOTALL)
293
-            if m:
294
-                data2 = m.group(1)
295
-            else:
296
-                raise Exception("No stream found")
297
-            m = re.search('title: "([^"]+)"', r, re.DOTALL)
298
-            title = m.group(1) if m else data2
299
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
300
-            desc = m.group(1) if m else title
301
-            m = re.search('<div id="panel">([^<]+)<', r, re.DOTALL)
302
-            desc = m.group(1) if m else title
303
-            m = re.search('var promo_image *= "([^"]+)', r, re.DOTALL)
304
-            img = m.group(1) if m else ""
305
-            stream = util.item()
306
-            stream["name"] = title
307
-            stream["url"] = data2
308
-            stream["img"] = img
309
-            stream["desc"] = desc
310
-            stream["resolver"] = "tvdom"
311
-            return [stream]
312
-
313
-
314
-    def is_video(self,data):
315
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
316
-        cmd = data.split("/")
317
-        if cmd[0] in ("tiesraides") and len(cmd)>1:
318
-            return True
319
-        elif cmd[0]=="play_arhivs" and len(cmd)==3 and re.search("_\d+",plist[2]):
320
-            return True
321
-        else:
322
-            return False
323
-
324
-
325
-if __name__ == "__main__":
326
-    country= "lv"
327
-    c = Source(country)
328
-    if len(sys.argv)>1:
329
-        data= sys.argv[1]
330
-    else:
331
-        data = "home"
332
-    content = c.get_content(data)
333
-    for item in content:
334
-        print item
335
-    #cat = api.get_categories(country)
336
-    #chan = api.get_channels("lv")
337
-    #prog = api.get_programs(channel=6400)
338
-    #prog = api.get_programs(category=55)
339
-    #seas = api.get_seasons(program=6453)
340
-    #str = api.get_streams(660243)
341
-    #res = api.get_videos(802)
342
-    #formats = api.getAllFormats()
343
-    #det = api.detailed("1516")
344
-    #vid = api.getVideos("13170")
345
-    pass

+ 0
- 4
sources/ustvnow.cfg Bestand weergeven

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

+ 0
- 193
sources/ustvnow.py Bestand weergeven

@@ -1,193 +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 traceback
15
-from collections import OrderedDict
16
-import ssl
17
-if "_create_unverified_context" in dir(ssl):
18
-    ssl._create_default_https_context = ssl._create_unverified_context
19
-
20
-from SourceBase import SourceBase
21
-
22
-headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
23
-headers0 = headers2dict("""
24
-Host: m-api.ustvnow.com
25
-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
26
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
27
-DNT: 1
28
-Connection: keep-alive
29
-""")
30
-import HTMLParser
31
-h = HTMLParser.HTMLParser()
32
-
33
-class Source(SourceBase):
34
-
35
-    def __init__(self,country="lv",cfg_path=None):
36
-        self.hidden = True
37
-        self.name = "ustvnow"
38
-        self.title = "USTVNow"
39
-        self.img = "http://watch.ustvnow.com/assets/ustvnow/img/ustvnow_og_image.png"
40
-        self.desc = "USTVNow kanālu tiešraide"
41
-        self.headers = headers0
42
-
43
-        self.country=country
44
-        self.token = ""
45
-        cur_directory = os.path.dirname(os.path.abspath(__file__))
46
-        if not cfg_path: cfg_path = cur_directory
47
-        self.config_file = os.path.join(cfg_path,self.name+".cfg")
48
-        self.options = OrderedDict([("user","lietotajs"),("password","parole")])
49
-        self.options_read()
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
-        headers = headers2dict("""
56
-        Host: m-api.ustvnow.com
57
-        Accept-Language: en-US,en;q=0.5
58
-        User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
59
-        Accept: text/html,application/xhtml+xml,application/xml
60
-        Connection: keep-alive
61
-        """)
62
-
63
-        url = "http://m-api.ustvnow.com/iphone/1/live/login?username=%s&password=%s&device=gtv&redir=0"%(user,password)
64
-        #url = "http://m-api.ustvnow.com/gtv/1/live/login?username=%s&password=%s&device=gtv&redir=0"%(user,password)
65
-        r = self._http_request(url,headers=headers)
66
-        if 'success' in r:
67
-            self.token = re.search('"token":"([^"]+)',r).group(1)
68
-            return True
69
-        else:
70
-            return False
71
-
72
-    def get_content(self, data):
73
-        print "[ustvnow] get_content:", data
74
-        if "::" in data:
75
-            data = data.split("::")[1]
76
-        path = data.split("?")[0]
77
-        clist = path.split("/")[0]
78
-        params = data[data.find("?"):] if "?" in data else ""
79
-        qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
80
-        lang = qs["lang"] if "lang" in qs else self.country
81
-
82
-        content=[]
83
-        content.append(("..return", "back","","Return back"))
84
-
85
-        if clist=="home":
86
-            content.extend([
87
-                ("TV live streams", "ustvnow::tvlive","","TV live streams"),
88
-                ("Movies", "ustvnow::movies","","Movies (not implemented yet"),
89
-                ("Recordings", "ustvnow::recordings","","Recordings (not implemented yet"),
90
-            ])
91
-            return content
92
-
93
-        if clist=="movies":
94
-            return content
95
-
96
-        if clist=="recordings":
97
-            return content
98
-
99
-        ### Tiesraides kanalu saraksts ###
100
-        elif data=="tvlive":
101
-            if not self.token:
102
-                if not self.login():
103
-                    raise Exception("Can not login\nPlease check USTVNow username/password in\n/usr/lib/enigma2/python/Plugins/Extensions/sources/ustvnow.cfg file")
104
-            data = "live/channelguide?token=%s"%self.token
105
-            self.r = self.call(data)
106
-            if not self.r:
107
-                return content
108
-            for item in self.r["results"]:
109
-                if item["order"] == 1:
110
-                    title = item["stream_code"]
111
-                    title =  h.unescape(title.decode("utf8")).encode("utf8")
112
-                    img = "http://m-api.ustvnow.com/"+item["prg_img"] #item["img"]
113
-                    data2 = "live/view?scode=%s&token=%s"%(item["scode"],self.token)
114
-                    desc = "%s\n%s (+%s')\n%s"%(item["title"],item["event_time"],int(item["actualremainingtime"])/60,item["description"])
115
-                    content.append((title,self.name+"::"+data2,img,desc))
116
-            return content
117
-
118
-        ### Tiesraides kanāls ###
119
-        elif path == "live/view":
120
-            url = "http://m-api.ustvnow.com/stream/1/%s"%data
121
-            #url = "http://m.ustvnow.com/stream/1/live/view?scode=whphd&token=o7oxits4dcjd8hbxusf9d9cgcyad&br_n=Chrome&br_v=60&br_d=desktop"
122
-            url =  "http://m.ustvnow.com/stream/1/live/%s"%data
123
-            headers = headers2dict("""
124
-Accept: application/json, text/javascript, */*; q=0.01
125
-User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36
126
-Referer: http://watch.ustvnow.com/guide
127
-                """)
128
-            r = self._http_request(url, headers=headers )
129
-            if not r:
130
-                return ("No stream found %s"%data,"","","No stream found")
131
-            r = json.loads(r)
132
-            if not "r" in dir(self):
133
-                if not self.token:
134
-                    self.login()
135
-                self.r = self.call("live/channelguide?token=%s"%self.token)
136
-            if self.r:
137
-                ch = qs["scode"]
138
-                for item in self.r["results"]:
139
-                    if item["order"] == 1 and item["scode"] == ch:
140
-                        title = item["stream_code"]
141
-                        title = "%s - %s (%s)"%(item["stream_code"],item["title"],item["event_time"])
142
-                        img = "http://m-api.ustvnow.com/"+item["prg_img"]
143
-                        data2 = "live/view?scode=%s&token=%s"%(item["scode"],self.token)
144
-                        desc = "%s\n%s (+%s')\n%s"%(item["title"],item["event_time"],int(item["actualremainingtime"])/60,item["description"])
145
-            else:
146
-                title = data
147
-            data2 = r["stream"]
148
-            desc = title
149
-            img = "" # img TODO
150
-            return (title,data2,img,desc)
151
-
152
-    def is_video(self,data):
153
-        if "::" in data:
154
-            data = data.split("::")[1]
155
-        if "live/view" in data:
156
-            return True
157
-        else:
158
-            return False
159
-
160
-    def call(self, data,headers=headers0,lang=""):
161
-        if not lang: lang = self.country
162
-        url = "http://m-api.ustvnow.com/gtv/1/"+data
163
-        content = self._http_request(url)
164
-        result = None
165
-        if content:
166
-            try:
167
-                result = json.loads(content)
168
-            except Exception, ex:
169
-                return None
170
-        return result
171
-
172
-
173
-if __name__ == "__main__":
174
-    country= "lv"
175
-    c = Source(country)
176
-    if len(sys.argv)>1:
177
-        data= sys.argv[1]
178
-    else:
179
-        data = "home"
180
-    content = c.get_content(data)
181
-    for item in content:
182
-        print item
183
-    #cat = api.get_categories(country)
184
-    #chan = api.get_channels("lv")
185
-    #prog = api.get_programs(channel=6400)
186
-    #prog = api.get_programs(category=55)
187
-    #seas = api.get_seasons(program=6453)
188
-    #str = api.get_streams(660243)
189
-    #res = api.get_videos(802)
190
-    #formats = api.getAllFormats()
191
-    #det = api.detailed("1516")
192
-    #vid = api.getVideos("13170")
193
-    pass

+ 0
- 5
sources/viaplay.cfg Bestand weergeven

@@ -1,5 +0,0 @@
1
-[viaplay]
2
-user = ivars777@gmail.com
3
-password = kaskade7
4
-device = 14e06be92a07f9936749b560394669b7f32d3540-499b21d2-e6ec-4973-b57c-6db7cf43bdd0=c27f3554-13f4-40ca-a11a-6d97f832613a
5
-

+ 0
- 496
sources/viaplay.py Bestand weergeven

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

+ 0
- 741
util.py Bestand weergeven

@@ -1,741 +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 or not stream["nfo"] else nfo2title(stream["nfo"])
138
-    desc = stream["desc"] if not "nfo" in stream or not stream["nfo"] 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 = cmd3 if url.startswith("https") else cmd2
177
-    ret = call(cmd)
178
-    #if ret:
179
-        #a = raw_input("*** Error, continue")
180
-    return
181
-
182
-def stream_type(data):
183
-    data = data.lower()
184
-    m = re.search(r"^(\w+)://", data)
185
-    prefix = m.group(1) if m else ""
186
-    if prefix in ("http","https"):
187
-        if ".m3u8" in data:
188
-            return "hls"
189
-        elif ".mpd" in data:
190
-            return "dash"
191
-        else:
192
-            return "http"
193
-    else:
194
-        return prefix
195
-
196
-def check_version(package,url="http://feed.blue.lv/Packages"):
197
-    "Return current package version from OPKG feed"
198
-    url = "http://feed.blue.lv/Packages"
199
-    r = requests.get(url)
200
-    if not r.ok:
201
-        return ""
202
-    m = re.search("Package: %s\nVersion: (.+?)\n"%package, r.content)
203
-    if not m:
204
-        return ""
205
-    return m.group(1)
206
-
207
-SPLIT_CHAR = "~"
208
-SPLIT_CODE = urllib.quote(SPLIT_CHAR)
209
-EQ_CODE = urllib.quote("=")
210
-COL_CODE = urllib.quote(":")
211
-SPACE_CODE = urllib.quote(" ")
212
-
213
-def make_fname(title):
214
-    "Make file name from title"
215
-    title = title.strip()
216
-    fname0 = re.sub("[/\n\r\t,:]"," ",title)
217
-    fname0 = re.sub("['""]","",fname0)
218
-    return fname0
219
-
220
-def hls_base(url):
221
-    url2 = url.split("?")[0]
222
-    url2 = "/".join(url2.split("/")[0:-1])+ "/"
223
-    return url2
224
-
225
-def stream_change(stream):
226
-    #return stream # TODO
227
-    if "resolver" in stream and stream["resolver"] in ("viaplay","hqq","filmas") or \
228
-        "surl" in stream and re.search("https*://(hqq|goo\.gl)",stream["surl"]):
229
-        stream["url"] = streamproxy_encode(stream["url"],stream["headers"])
230
-        stream["headers"] = {}
231
-        return stream
232
-    else:
233
-        return stream
234
-
235
-def streamproxy_encode(url,headers=[],proxy_url=None):
236
-    PROXY_URL = "http://localhost:8880/"
237
-    if not "?" in url:
238
-        url = url+"?"
239
-    url2 = url.replace(SPLIT_CHAR,SPLIT_CODE).replace(":",COL_CODE).replace(" ",SPACE_CODE)
240
-    if not proxy_url:
241
-        proxy_url = PROXY_URL
242
-    url2 = proxy_url + url2
243
-    if headers:
244
-        headers2 = []
245
-        for h in headers:
246
-            headers2.append("%s=%s"%(h,headers[h].replace("=",EQ_CODE).replace(SPLIT_CHAR,SPLIT_CODE).replace(" ",SPACE_CODE)))
247
-        headers2 = SPLIT_CHAR.join(headers2)
248
-        url2 = url2+SPLIT_CHAR+headers2
249
-    #return url2.encode("utf8") if isinstance(url2,unicode) else url2
250
-    return url2
251
-
252
-def streamproxy_decode(urlp):
253
-    import urlparse
254
-    path = urlp.replace(re.search("http://[^/]+",urlp).group(0),"")
255
-    p = path.split(SPLIT_CHAR)
256
-    url = urllib.unquote(p[0][1:])
257
-    #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"}
258
-    headers={}
259
-    if len(p)>1:
260
-        for h in p[1:]:
261
-            #h = urllib.unquote()
262
-            headers[h.split("=")[0]]=urllib.unquote(h.split("=")[1])
263
-    return url,headers
264
-
265
-def streamproxy_encode2(url,headers=[],proxy_url=None):
266
-    PROXY_URL = "http://localhost:8880/"
267
-    #url2 = url.replace(SPLIT_CHAR,SPLIT_CODE).replace(":",COL_CODE).replace(" ",SPACE_CODE)
268
-    url2 = urllib.quote_plus(url)
269
-    if not proxy_url:
270
-        proxy_url = PROXY_URL
271
-    url2 = proxy_url + url2+"/?"
272
-    if headers:
273
-        headers2 = []
274
-        for h in headers:
275
-            headers2.append("%s=%s"%(h,headers[h].replace("=",EQ_CODE).replace(SPLIT_CHAR,SPLIT_CODE).replace(" ",SPACE_CODE)))
276
-        headers2 = SPLIT_CHAR.join(headers2)
277
-        url2 = url2+SPLIT_CHAR+headers2
278
-    return url2
279
-
280
-def streamproxy_decode2(urlp):
281
-    path = urlp.replace(re.search("http://[^/]+",urlp).group(0),"")
282
-    p = path.split(SPLIT_CHAR)
283
-    url = urllib.unquote_plus(p[0][1:-2])
284
-    #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"}
285
-    headers={}
286
-    if len(p)>1:
287
-        for h in p[1:]:
288
-            #h = urllib.unquote()
289
-            headers[h.split("=")[0]]=urllib.unquote(h.split("=")[1])
290
-    return url,headers
291
-
292
-class Captions(object):
293
-    def __init__(self,uri):
294
-        self.uri = uri
295
-        self.subs = []
296
-        self.styles = {}
297
-        if uri.startswith("http"):
298
-            r = requests.get(uri)
299
-        if r.status_code == 200:
300
-            self.loads(r.content)
301
-
302
-    def loads(self,s):
303
-        if "WEBVTT" in s[:s.find("\n")]: # vtt captions
304
-            self.load_vtt(s)
305
-        elif "<?xml" in s[:s.find("\n")]:
306
-            self.load_ttaf(s)
307
-        else:
308
-            self.load_vtt(s) # TODO
309
-
310
-
311
-    def load_ttaf(self,s):
312
-        for r2 in re.findall("<style .+?/>", s):
313
-            st = {}
314
-            for a in re.findall(r'(\w+)="([^ "]+)"', r2):
315
-                st[a[0]] = a[1]
316
-                if a[0] == "id":
317
-                    sid = a[1]
318
-            self.styles[sid] = st
319
-        for r2 in re.findall("<p .+?</p>", s):
320
-            sub = {}
321
-            sub["begin"] = str2sec(re.search('begin="([^"]+)"', r2).group(1)) if re.search('begin="([^"]+)"', r2) else -1
322
-            sub["end"] = str2sec(re.search('end="([^"]+)"', r2).group(1)) if re.search('end="([^"]+)"', r2) else -1
323
-            sub["style"] = re.search('style="([^"]+)"', r2).group(1) if re.search('style="([^"]+)"', r2) else None
324
-            sub["text"] = re.search("<p[^>]+>(.+)</p>", r2).group(1).replace("\n","")
325
-            sub["text"] = re.sub("<br\s*?/>","\n",sub["text"])
326
-            sub["text"] = re.sub("<.+?>"," ",sub["text"])
327
-            self.subs.append(sub)
328
-        pass
329
-
330
-    def load_vtt(self,s):
331
-        f = StringIO.StringIO(s)
332
-        while True:
333
-            line = f.readline()
334
-            if not line:
335
-                break
336
-            m = re.search(r"([\d\.\,:]+)\s*-->\s*([\d\.\,\:]+)",line)
337
-            if m:
338
-                sub = {}
339
-                sub["begin"] = str2sec(m.group(1))
340
-                sub["end"] = str2sec(m.group(2))
341
-                sub["style"] = None
342
-                sub["text"] = []
343
-                line = f.readline()
344
-                while line.strip():
345
-                    txt = line.strip()
346
-                    if isinstance(txt,unicode):
347
-                        txt = txt.encode("utf8")
348
-                    sub["text"].append(txt)
349
-                    line = f.readline()
350
-                sub["text"] = "\n".join(sub["text"])
351
-                self.subs.append(sub)
352
-            else:
353
-                continue
354
-        pass
355
-
356
-    def get_srt(self):
357
-        out = ""
358
-        i = 0
359
-        for sub in self.subs:
360
-            i +=1
361
-            begin = sub["begin"]
362
-            begin = "%s,%03i"%(str(datetime.timedelta(seconds=begin/1000)),begin%1000)
363
-            end = sub["end"]
364
-            end = "%s,%03i"%(str(datetime.timedelta(seconds=end/1000)),end%1000)
365
-            txt2 = sub["text"]
366
-            out += "%s\n%s --> %s\n%s\n\n\n"%(i,begin,end,txt2)
367
-        return out
368
-
369
-def str2sec(r):
370
-    # Convert str time to miliseconds
371
-    r= r.replace(",",".")
372
-    m = re.search(r"(\d+\:)*(\d+)\:(\d+\.\d+)", r)
373
-    if m:
374
-        sec = int(m.group(1)[:-1])*60*60*1000 if m.group(1) else 0
375
-        sec += int(m.group(2))*60*1000 + int(float(m.group(3))*1000)
376
-        return sec
377
-    else:
378
-        return -1
379
-
380
-
381
-#c = Captions("http://195.13.216.2/mobile-vod/mp4:lb_barbecue_fr_lq.mp4/lb_barbecue_lv.vtt")
382
-#c = Captions("http://www.bbc.co.uk/iplayer/subtitles/ng/modav/bUnknown-0edd6227-0f38-411c-8d46-fa033c4c61c1_b05ql1s3_1479853893356.xml")
383
-#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"
384
-#c = Captions(url)
385
-
386
-#pass
387
-
388
-
389
-def ttaf2srt(s):
390
-    out = u""
391
-    i = 0
392
-    for p,txt in re.findall("<p ([^>]+)>(.+?)</p>", s, re.DOTALL):
393
-        i +=1
394
-        begin = re.search('begin="(.+?)"',p).group(1)
395
-        begin = begin.replace(".",",")
396
-        end = re.search('end="(.+?)"',p).group(1)
397
-        end = end.replace(".",",")
398
-        txt2 = re.sub("<br */>","\n",txt)
399
-        out += "%s\n%s --> %s\n%s\n\n"%(i,begin,end,txt2)
400
-    return out
401
-
402
-
403
-def item():
404
-    """Default item content"""
405
-    stream0 = {
406
-        'name': '', #
407
-        'url': '',
408
-        'quality': '?',
409
-        'surl': '',
410
-        'subs': [],
411
-        'headers': {},
412
-        "desc":"",
413
-        "img":"",
414
-        "lang":"",
415
-        "type":"",
416
-        "resolver":"",
417
-        "order":0,
418
-        "live":False
419
-        }
420
-    return stream0
421
-
422
-class _StringCookieJar(cookielib.LWPCookieJar):
423
-
424
-    def __init__(self, string=None, filename=None, delayload=False, policy=None):
425
-        cookielib.LWPCookieJar.__init__(self, filename, delayload, policy)
426
-        if string and len(string) > 0:
427
-            self._cookies = pickle.loads(str(string))
428
-
429
-    def dump(self):
430
-        return pickle.dumps(self._cookies)
431
-
432
-
433
-def init_urllib(cache=None):
434
-    """
435
-    Initializes urllib cookie handler
436
-    """
437
-    global _cookie_jar
438
-    data = None
439
-    if cache is not None:
440
-        data = cache.get(CACHE_COOKIES)
441
-    _cookie_jar = _StringCookieJar(data)
442
-    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(_cookie_jar))
443
-    urllib2.install_opener(opener)
444
-
445
-
446
-def cache_cookies(cache):
447
-    """
448
-    Saves cookies to cache
449
-    """
450
-    global _cookie_jar
451
-    if _cookie_jar:
452
-        cache.set(CACHE_COOKIES, _cookie_jar.dump())
453
-
454
-
455
-def request0(url, headers={}):
456
-    debug('request: %s' % url)
457
-    req = urllib2.Request(url, headers=headers)
458
-    req.add_header('User-Agent', UA)
459
-    try:
460
-        response = urllib2.urlopen(req)
461
-        data = response.read()
462
-        response.close()
463
-    except urllib2.HTTPError, error:
464
-        data = error.read()
465
-
466
-    debug('len(data) %s' % len(data))
467
-    return data
468
-
469
-def request(url, headers={}):
470
-    debug('request: %s' % url)
471
-    #req = urllib2.Request(url, headers=headers)
472
-    #req.add_header('User-Agent', UA)
473
-    if 'User-Agent' not in headers:
474
-        headers['User-Agent']= UA
475
-    try:
476
-        r = requests.get(url, headers=headers)
477
-        data = r.content
478
-    except:
479
-        data = r.content
480
-
481
-    debug('len(data) %s' % len(data))
482
-    return data
483
-
484
-def post(url, data, headers={}):
485
-    postdata = urllib.urlencode(data)
486
-    #req = urllib2.Request(url, postdata, headers)
487
-    #req.add_header('User-Agent', UA)
488
-    import requests
489
-    if 'User-Agent' not in headers:
490
-        headers['User-Agent']= UA
491
-    try:
492
-        r = requests.post(url, data=postdata,headers=headers)
493
-        data = r.content
494
-    except urllib2.HTTPError, error:
495
-        data = r.content
496
-    return data
497
-
498
-def post0(url, data, headers={}):
499
-    postdata = urllib.urlencode(data)
500
-    req = urllib2.Request(url, postdata, headers)
501
-    req.add_header('User-Agent', UA)
502
-    try:
503
-        response = urllib2.urlopen(req)
504
-        data = response.read()
505
-        response.close()
506
-    except urllib2.HTTPError, error:
507
-        data = error.read()
508
-    return data
509
-
510
-
511
-def post_json(url, data, headers={}):
512
-    postdata = json.dumps(data)
513
-    headers['Content-Type'] = 'application/json'
514
-    req = urllib2.Request(url, postdata, headers)
515
-    req.add_header('User-Agent', UA)
516
-    response = urllib2.urlopen(req)
517
-    data = response.read()
518
-    response.close()
519
-    return data
520
-
521
-
522
-#def run_parallel_in_threads(target, args_list):
523
-    #result = Queue.Queue()
524
-    ## wrapper to collect return value in a Queue
525
-
526
-    #def task_wrapper(*args):
527
-        #result.put(target(*args))
528
-
529
-    #threads = [threading.Thread(target=task_wrapper, args=args) for args in args_list]
530
-    #for t in threads:
531
-        #t.start()
532
-    #for t in threads:
533
-        #t.join()
534
-    #return result
535
-
536
-
537
-def substr(data, start, end):
538
-    i1 = data.find(start)
539
-    i2 = data.find(end, i1)
540
-    return data[i1:i2]
541
-
542
-
543
-def save_to_file(url, file):
544
-    try:
545
-        return save_data_to_file(request(url), file)
546
-    except:
547
-        traceback.print_exc()
548
-
549
-
550
-def save_data_to_file(data, file):
551
-    try:
552
-        f = open(file, 'wb')
553
-        f.write(data)
554
-        f.close()
555
-        info('File %s saved' % file)
556
-        return True
557
-    except:
558
-        traceback.print_exc()
559
-
560
-
561
-def read_file(file):
562
-    if not os.path.exists(file):
563
-        return ''
564
-    f = open(file, 'r')
565
-    data = f.read()
566
-    f.close()
567
-    return data
568
-
569
-
570
-def _substitute_entity(match):
571
-    ent = match.group(3)
572
-    if match.group(1) == '#':
573
-        # decoding by number
574
-        if match.group(2) == '':
575
-            # number is in decimal
576
-            return unichr(int(ent))
577
-        elif match.group(2) == 'x':
578
-            # number is in hex
579
-            return unichr(int('0x' + ent, 16))
580
-    else:
581
-        # they were using a name
582
-        cp = n2cp.get(ent)
583
-        if cp:
584
-            return unichr(cp)
585
-        else:
586
-            return match.group()
587
-
588
-
589
-def decode_html(data):
590
-    if not type(data) == str:
591
-        return data
592
-    try:
593
-        if not type(data) == unicode:
594
-            data = unicode(data, 'utf-8', errors='ignore')
595
-        entity_re = re.compile(r'&(#?)(x?)(\w+);')
596
-        return entity_re.subn(_substitute_entity, data)[0]
597
-    except:
598
-        traceback.print_exc()
599
-        print[data]
600
-        return data
601
-
602
-def unescape(s0):
603
-    #s2 = re.sub("&#\w+;",HTMLParser.HTMLParser().unescape("\1"),s)
604
-    s0 = s0.replace("&amp;","&")
605
-    for s in re.findall("&#\w+;",s0):
606
-        s2 = HTMLParser.HTMLParser().unescape(s)
607
-        if isinstance(s0,str):
608
-            s2 = s2.encode("utf8")
609
-        s0 = s0.replace(s,s2)
610
-        pass
611
-    return s0
612
-
613
-def debug(text):
614
-    if LOG > 1:
615
-        print('[DEBUG] ' + str([text]))
616
-
617
-def info(text):
618
-    if LOG > 0:
619
-        print('[INFO] ' + str([text]))
620
-
621
-def error(text):
622
-    print('[ERROR] ' + str([text]))
623
-
624
-_diacritic_replace = {u'\u00f3': 'o',
625
-                      u'\u0213': '-',
626
-                      u'\u00e1': 'a',
627
-                      u'\u010d': 'c',
628
-                      u'\u010c': 'C',
629
-                      u'\u010f': 'd',
630
-                      u'\u010e': 'D',
631
-                      u'\u00e9': 'e',
632
-                      u'\u011b': 'e',
633
-                      u'\u00ed': 'i',
634
-                      u'\u0148': 'n',
635
-                      u'\u0159': 'r',
636
-                      u'\u0161': 's',
637
-                      u'\u0165': 't',
638
-                      u'\u016f': 'u',
639
-                      u'\u00fd': 'y',
640
-                      u'\u017e': 'z',
641
-                      u'\xed': 'i',
642
-                      u'\xe9': 'e',
643
-                      u'\xe1': 'a',
644
-                      }
645
-
646
-
647
-def replace_diacritic(string):
648
-    ret = []
649
-    for char in string:
650
-        if char in _diacritic_replace:
651
-            ret.append(_diacritic_replace[char])
652
-        else:
653
-            ret.append(char)
654
-    return ''.join(ret)
655
-
656
-
657
-def params(url=None):
658
-    if not url:
659
-        url = sys.argv[2]
660
-    param = {}
661
-    paramstring = url
662
-    if len(paramstring) >= 2:
663
-        params = url
664
-        cleanedparams = params.replace('?', '')
665
-        if (params[len(params) - 1] == '/'):
666
-            params = params[0:len(params) - 2]
667
-        pairsofparams = cleanedparams.split('&')
668
-        param = {}
669
-        for i in range(len(pairsofparams)):
670
-            splitparams = {}
671
-            splitparams = pairsofparams[i].split('=')
672
-            if (len(splitparams)) == 2:
673
-                param[splitparams[0]] = splitparams[1]
674
-    for p in param.keys():
675
-        param[p] = param[p].decode('hex')
676
-    return param
677
-
678
-
679
-def int_to_base(number, base):
680
-    digs = string.digits + string.letters
681
-    if number < 0:
682
-        sign = -1
683
-    elif number == 0:
684
-        return digs[0]
685
-    else:
686
-        sign = 1
687
-    number *= sign
688
-    digits = []
689
-    while number:
690
-        digits.append(digs[number % base])
691
-        number /= base
692
-    if sign < 0:
693
-        digits.append('-')
694
-    digits.reverse()
695
-    return ''.join(digits)
696
-
697
-
698
-def extract_jwplayer_setup(data):
699
-    """
700
-    Extracts jwplayer setup configuration and returns it as a dictionary.
701
-
702
-    :param data: A string to extract the setup from
703
-    :return: A dictionary containing the setup configuration
704
-    """
705
-    data = re.search(r'<script.+?}\(\'(.+)\',\d+,\d+,\'([\w\|]+)\'.*</script>', data, re.I | re.S)
706
-    if data:
707
-        replacements = data.group(2).split('|')
708
-        data = data.group(1)
709
-        for i in reversed(range(len(replacements))):
710
-            if len(replacements[i]) > 0:
711
-                data = re.sub(r'\b%s\b' % int_to_base(i, 36), replacements[i], data)
712
-        data = re.search(r'\.setup\(([^\)]+?)\);', data)
713
-        if data:
714
-            return json.loads(data.group(1).decode('string_escape'))
715
-        #return demjson.decode(data.group(1).decode('string_escape')) ### III
716
-    return None
717
-
718
-
719
-#def parse_html(url):
720
-#    return BeautifulSoup(request(url), 'html5lib', from_encoding='utf-8')
721
-
722
-if __name__ == "__main__":
723
-    s = 'B\xc4\x93thovena D\xc4\x81rgumu Taka (2014)/Beethoven&#x27;s Treasure [LV]'
724
-    #s = s.decode("utf8")
725
-    #s=unescape(s)
726
-    #url = "http://localhost:88/https://walterebert.com/playground/video/hls/ts/480x270.m3u8?token=xxxx~User-Agent=Enigma2~Cookie=xxxxx"
727
-    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"
728
-    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"}
729
-    url = "http://str1e.lattelecom.tv/mobile-vod/mp4:sf_fantastic_beasts_and_where_to_find_them_en_hd.mp4/playlist.m3u8?resource_id=fantastic_beasts_and_where_to_find_them&auth_token=6NAvMFDG+rYTAc4hb5JeL2bmsaRR7bAE23M6KDmhKYOGyXoo0gDpJUE9scYy+nQmfbgk03cWMe9MuXWSH1GqwolEk2jOQ/8Mrg7tOdbwrA8zM7nmkfCZPqQkwajZN4mfSJQVKHqXqJ8="
730
-    headers={}
731
-    print url
732
-    url = "replay::tiesraide/ltv1/"
733
-    url = "ltc::content/live-streams/103?include=quality"
734
-    urlp = streamproxy_encode2(url,headers)
735
-    print urlp
736
-    url2,headers2 = streamproxy_decode2(urlp)
737
-    print url2
738
-    player(urlp)
739
-    pass
740
-
741
-