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