/[projects]/misc/xbmc/plugin.video.todic/default.py
ViewVC logotype

Contents of /misc/xbmc/plugin.video.todic/default.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3265 - (show annotations) (download) (as text)
Sat Mar 20 18:35:52 2021 UTC (3 years, 1 month ago) by torben
File MIME type: text/x-python
File size: 15431 byte(s)
Add User Agent to requests
1
2 # This Python file uses the following encoding: utf-8
3
4 '''
5 Todic plugin for XBMC
6 Version 1.9.4
7 '''
8
9 import sys
10 import os
11
12
13 import xbmc
14 import xbmcaddon
15 import xbmcgui
16 import xbmcvfs
17 import xbmcplugin
18 import urllib
19 import urllib.request
20
21 import platform
22
23 # import pprint
24
25 from xml.dom.minidom import parseString
26 from time import time
27
28 __addon__ = xbmcaddon.Addon(id='plugin.video.todic')
29 __key__ = __addon__.getSetting('xbmckey').lower()
30 __entrypoint__ = __addon__.getSetting('entrypoint').lower()
31 __backend__ = "https://todic.dk/xbmc.php?xbmckey=" + __key__
32
33
34 if __entrypoint__ == "alternative":
35 __backend__ = "https://alt.todic.dk/xbmc.php?xbmckey=" + __key__
36
37 if __entrypoint__ == "testing":
38 __backend__ = "https://todic.dk/xbmc-beta.php?xbmckey=" + __key__
39
40 print( "[Todic] entrypoint: " + __entrypoint__ )
41 print( "[Todic] backend: " + __backend__ )
42 print( "[Todic] version: " + __addon__.getAddonInfo('version') )
43
44 fanartImage = os.path.join(__addon__.getAddonInfo('path'), 'movie_bg_blur.jpg')
45 datapath = xbmcvfs.translatePath(
46 'special://profile/addon_data/plugin.video.todic/')
47
48 ADDON_PATH = __addon__.getAddonInfo('path')
49 SkinMasterPath = os.path.join(ADDON_PATH, 'skins') + '/'
50 MySkinPath = (os.path.join(SkinMasterPath, '720p')) + '/'
51 MySkin = 'main.xml'
52
53
54 class TodicMovieDialog(xbmcgui.WindowXMLDialog):
55
56 def __new__(cls):
57 return super(TodicMovieDialog, cls).__new__(cls, "main.xml", ADDON_PATH)
58
59 def __init__(self):
60 super(TodicMovieDialog, self).__init__()
61 self.position = 0
62
63 def onClick(self, controlId):
64 print( "[Todic] MovieDialog OnClick: " + str(controlId) )
65
66 if (controlId == 50):
67 self.close()
68 play_real_video(self.url, self.name, 0)
69
70 if (controlId == 51):
71 self.close()
72 play_real_video(self.url, self.name, self.position)
73
74 if (controlId == 98):
75 self.close()
76
77 def onInit(self):
78
79 print( "[Todic] MovieDialog onInit" )
80 self.getControl(1).setLabel(self.name)
81 self.getControl(2).setLabel(self.moviegroups)
82 self.getControl(3).setLabel(self.description)
83 self.getControl(10).setLabel(self.playlength)
84 self.getControl(11).setLabel(self.codecdetails)
85
86 if (self.position > 0):
87 self.getControl(51).setVisible(True)
88 self.getControl(50).setPosition(100, 570)
89 self.getControl(51).setPosition(450, 570)
90 self.getControl(50).controlLeft( self.getControl(51) )
91 self.getControl(50).controlRight( self.getControl(51) )
92 else:
93 self.getControl(51).setVisible(False)
94
95 #orig_img_width = self.getControl(40).getWidth()
96 #self.starwidth = (float(self.imdbrating) / 10.0) * orig_img_width
97 #self.getControl(40).setWidth(int(self.starwidth))
98
99 def setDetailsDoc(self, detailsDoc):
100 print( "[Todic] MovieDialog setDetailsDoc:")
101 self.imdbrating = getText(detailsDoc.getElementsByTagName("imdbrating"))
102 self.moviegroups = getText(detailsDoc.getElementsByTagName("moviegroups"))
103 self.playlength = getText(detailsDoc.getElementsByTagName("playlength"))
104 self.codecdetails = getText(detailsDoc.getElementsByTagName("codecdetails"))
105 self.position = int( getText(detailsDoc.getElementsByTagName("position")) )
106
107 def setUrl(self, url):
108 self.url = url
109
110 def setName(self, name):
111 self.name = name
112
113 def setDescription(self, description):
114 self.description = description
115
116
117 class TodicPlayer(xbmc.Player):
118
119 def __init__(self, *args, **kwargs):
120 # xbmc.Player.__init__(selv,*args,**kwargs)
121 xbmc.Player.__init__(self)
122 self.stopped = False
123 self.started = False
124 self.playingPosition = 0.0
125 self.lastReport = 0
126 print( "[TodicPlayer] init")
127
128 def onPlayBackStarted(self):
129 self.started = True
130 print( "[TodicPlayer] : started")
131
132 #When user presses stop, we report back the the position registered in the last call to self.tick()
133 def onPlayBackStopped(self):
134 self.stopped = True
135 print( "[TodicPlayer] : stopped")
136 self.reportPlaytime("stopped")
137
138 def onPlayBackPaused(self):
139 print( "[TodicPlayer] : paused")
140 self.reportPlaytime("paused")
141
142 def onPlayBackResumed(self):
143 print( "[TodicPlayer] : resumed")
144 self.reportPlaytime("resumed")
145
146
147 def onPlayBackEnded(self):
148 self.stopped = True
149 print( "[TodicPlayer] : ended")
150 self.reportPlaytime("ended")
151
152 def tick(self):
153 #print( "[Todic] Tick: " + str( self.isPlaying() ) )
154 if ( self.isPlaying() ):
155 tmpTime = self.getTime()
156
157 #only report time if it has changed in the mean time
158 if tmpTime != self.playingPosition:
159 self.playingPosition = tmpTime
160 now = time()
161 #print( "[Todic] tick " + str(now) + " " + str(self.lastReport) + " : " +str(now - self.lastReport) )
162 if ( (now - self.lastReport) > 60.0):
163 self.lastReport = now
164 self.reportPlaytime("playing")
165
166 def reportPlaytime(self, subaction):
167 if (self.playingPosition > 60):
168 url = __backend__ + "&action=playbacktime&subaction=" + subaction + "&time=" + str( self.playingPosition )
169 print( "[Todic] reportPlaytime:" + url)
170 open_url_safe(url)
171
172
173
174 def getText2(nodelist):
175 rc = []
176 for node in nodelist:
177 if node.nodeType == node.TEXT_NODE:
178 rc.append(node.data)
179 else:
180 rc.append(getText(node.childNodes))
181 return ''.join(rc)
182
183
184 def getText(nodelist):
185 if nodelist.length == 0:
186 return ''
187 else:
188 if nodelist[0].childNodes.length == 0:
189 return ''
190 else:
191 return nodelist[0].childNodes[0].nodeValue
192
193
194
195 def SaveFile(path, data):
196 file = open(path, 'w')
197 file.write(data)
198 file.close()
199
200
201
202 def open_url(url):
203 kodi_ver = xbmc.getInfoLabel('System.BuildVersion')
204 reqobj = urllib.request.Request(
205 url,
206 data=None,
207 headers={
208 'User-Agent': 'TodicKodi:' + str(__addon__.getAddonInfo('version')) + " Kodi:" + str(kodi_ver) + " Platform:" + str(platform.system()) + " " + str(platform.release())
209 }
210 )
211
212 with urllib.request.urlopen(reqobj) as req:
213 #data = response.read()
214 #return data
215 charset=req.info().get_content_charset()
216 content=req.read().decode(charset)
217 return content
218
219
220 # wraps open url in a catch-all exception handler
221 # usefull for periodic back-reporting that should not interrupt the program flow
222 def open_url_safe(url):
223 try:
224 return open_url(url)
225 except:
226 print( "[Todic] Some error during open_url call to ", url)
227
228
229
230 def rootMenu():
231 kodi_ver = xbmc.getInfoLabel('System.BuildVersion')
232 plugin_ver = __addon__.getAddonInfo('version')
233 msgurl = __backend__ + "&action=messages&kodi=" + urllib.parse.quote(kodi_ver) + "&todicplugin=" + urllib.parse.quote(plugin_ver)
234
235 msg = open_url(msgurl)
236 msg = msg.strip()
237
238 if msg != "":
239 print("[Todic] rootMenu Dialog =" + str(msg))
240 dialog = xbmcgui.Dialog()
241 dialog.ok('XBMC Todic', msg)
242
243 buildList(__backend__, "", False) # call default list
244
245 # Adde xtra items to root menu
246 listitem = xbmcgui.ListItem(label="Søg Film ...")
247 listitem.setArt( { 'icon':'DefaultFolder.png', 'thumb':'DefaultFolder.png'} )
248 listitem.setProperty('Fanart_Image', fanartImage)
249
250 u = sys.argv[0] + "?mode=10&name="
251 xbmcplugin.addDirectoryItem(
252 handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
253
254 # add search series
255 listitem = xbmcgui.ListItem(label="Søg Serier ...")
256 listitem.setArt( { 'icon':'DefaultFolder.png', 'thumb':'DefaultFolder.png'} )
257 listitem.setProperty('Fanart_Image', fanartImage)
258
259 u = sys.argv[0] + "?mode=11&name="
260 xbmcplugin.addDirectoryItem(
261 handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
262
263 xbmcplugin.endOfDirectory(int(sys.argv[1]))
264
265
266 def buildList(url, title, endlist=True):
267 print( '[Todic::buildList]:' + str(url) )
268
269 link = open_url(url)
270 doc = parseString(link)
271 ty = doc.getElementsByTagName("meta")[0].getAttribute("type")
272 print( '[Todic]' + str(ty))
273
274 if ty == 'clipList':
275 mode = '50'
276 folder = False
277 else:
278 mode = '1'
279 folder = True
280
281 entries = doc.getElementsByTagName("entry")
282 l = len(entries)
283
284 for entry in entries:
285 name = getText(entry.getElementsByTagName("title"))
286 url = getText(entry.getElementsByTagName("url"))
287 thumb = getText(entry.getElementsByTagName("cover"))
288 playcount = getText(entry.getElementsByTagName("playcount"))
289
290
291 if playcount == '':
292 playcount = '0'
293 playcount = int(playcount)
294
295 # print "name:" + name
296 # print "url:" + url
297 # print "thumb:" + thumbi
298 listitem = xbmcgui.ListItem(label=name, label2='test')
299 listitem.setArt( {'icon': 'DefaultFolder.png'} )
300 listitem.setProperty('Fanart_Image', fanartImage)
301 listitem.addContextMenuItems([('Refresh', 'Container.Refresh')])
302 listitem.setArt( {'thumb': thumb} )
303
304 if mode == '50':
305 infoLabels = {}
306 infoLabels['title'] = name
307 infoLabels['playcount'] = playcount
308 # if playcount > 0:
309 # listitem.setArt( {'thumb': thumb} ) #not pretty - but at least we can show a different icon for unwatched/watched in kodi18
310 listitem.setInfo('video', infoLabels)
311
312 name = name.encode('UTF-8')
313
314 u = sys.argv[0] + "?mode=" + urllib.parse.quote(mode) + "&name=" + urllib.parse.quote(name) + "&url=" + urllib.parse.quote(url)
315 xbmcplugin.addDirectoryItem(
316 handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=folder, totalItems=l)
317
318 if (endlist == True):
319 xbmcplugin.endOfDirectory(int(sys.argv[1]))
320
321
322 def play_video(url, name):
323 description = ""
324 playPosition = 0
325 savedPosition = 0
326 try:
327 param1 = parse_parameter_string(url)
328 clipkey = param1["clipkey"]
329
330 print( "[Todic] ClipKey:" + clipkey)
331 detailurl = __backend__ + "&action=clipdetails&clipkey=" + clipkey
332 print( "[Todic] detailURL = " + detailurl)
333
334 xml = open_url(detailurl)
335
336 clipDetailsDoc = parseString(xml)
337 savedPosition = int( getText(clipDetailsDoc.getElementsByTagName("position")) )
338 description = getText(clipDetailsDoc.getElementsByTagName("description"))
339 except:
340 print( "[Todic] Unexpected error:", sys.exc_info()[0] )
341
342 if (description == None or description == ""):
343 if (savedPosition > 0):
344 dialog = xbmcgui.Dialog()
345 #yes / true -afspil fra position
346 answer = dialog.yesno(heading='Todic', message='Afspil fra sidste position', nolabel='Fra start', yeslabel='Fortsæt')
347 if (answer == True):
348 playPosition = savedPosition
349
350 play_real_video(url, name, playPosition)
351
352 else:
353 d = TodicMovieDialog()
354 d.setDetailsDoc(clipDetailsDoc)
355 d.setName(name)
356 d.setUrl(url)
357 d.setDescription(description)
358
359 d.doModal()
360
361
362 def play_real_video(url, name, position):
363 xml = open_url(url)
364 print( '[Todic] url: ' + str(url) )
365 print( '[Todic] xml: ' + str(xml) )
366 print( '[Todic] pos: ' + str(position) )
367
368 doc = parseString(xml)
369 url = getText(doc.getElementsByTagName("url"))
370
371 subtitleurl = getText(doc.getElementsByTagName("subtitles"))
372
373
374 print( '[Todic] subs: ' + str(subtitleurl) )
375
376 image = xbmc.getInfoImage('ListItem.Thumb')
377 listitem = xbmcgui.ListItem(label=name)
378 listitem.setArt( {'icon': 'DefaultVideo.png', 'thumb':image} )
379 listitem.setInfo(type="Video", infoLabels={"Title": name})
380
381 listitem.setProperty('StartOffset', str(position) )
382
383 if len(subtitleurl) > 0:
384 listitem.setSubtitles([subtitleurl])
385
386 player = TodicPlayer()
387 player.play(str(url), listitem)
388
389
390 #Holder python kørernde indtil at det bliver bedt om at stoppe
391 kodiMonitor = xbmc.Monitor()
392
393
394 while (not kodiMonitor.abortRequested()):
395 player.tick()
396 kodiMonitor.waitForAbort( 1 )
397
398
399
400 def search():
401 search = getUserInput("Todic Søgning")
402
403 if (search != None and search != ""):
404 url = __backend__ + "&action=search&search=" + \
405 urllib.parse.quote(search)
406
407 # print "[Todic] Search start: " + search
408 # print "[Todic] Search url: " + url
409
410 buildList(url, "søgning")
411
412
413 def searchSeries():
414 search = getUserInput("Todic Serie Søgning")
415
416 if (search != None and search != ""):
417 url = __backend__ + "&action=searchseries&search=" + \
418 urllib.parse.quote(search)
419
420 # print "[Todic] Search start: " + search
421 # print "[Todic] Search url: " + url
422
423 buildList(url, "serie søgning")
424
425
426 #=================================== Tool Box =======================================
427 # shows a more userfriendly notification
428 def showMessage(heading, message):
429 print( "[Todic::showMessage] " + str(message) )
430 print( message )
431 duration = 15 * 1000
432 xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' %
433 (heading, message, duration))
434
435
436 # raise a keyboard for user input
437 def getUserInput(title="Input", default="", hidden=False):
438 result = None
439
440 # Fix for when this functions is called with default=None
441 if not default:
442 default = ""
443
444 keyboard = xbmc.Keyboard(default, title)
445 keyboard.setHiddenInput(hidden)
446 keyboard.doModal()
447
448 if keyboard.isConfirmed():
449 result = keyboard.getText()
450
451 return result
452
453
454 def get_params():
455 return parse_parameter_string(sys.argv[2])
456
457
458 def parse_parameter_string(paramstring):
459 param = []
460 if len(paramstring) >= 2:
461 params = paramstring
462 cleanedparams = params.replace('?', '')
463 if (params[len(params) - 1] == '/'):
464 params = params[0:len(params) - 2]
465 pairsofparams = cleanedparams.split('&')
466 param = {}
467 for i in range(len(pairsofparams)):
468 splitparams = {}
469 splitparams = pairsofparams[i].split('=')
470 if (len(splitparams)) == 2:
471 param[splitparams[0]] = splitparams[1]
472 return param
473
474
475 params = get_params()
476 url = None
477 name = None
478 mode = None
479
480
481 #print params
482
483 try:
484 url = urllib.parse.unquote(params["url"])
485 except:
486 pass
487 try:
488 name = urllib.parse.unquote(params["name"])
489 except:
490 pass
491 try:
492 mode = int(params["mode"])
493 except:
494 pass
495
496 print( "[Todic] url=" + str(url))
497 print( "[Todic] name=" + str(name))
498 print( "[Todic] mode=" + str(mode))
499
500
501 try:
502 open_url("https://todic.dk")
503 except:
504 showMessage("Fejl", "Kunne ikke forbinde til todic.dk")
505 exit()
506
507
508 if url == 'refresh':
509 # xbmc.output("[tvserver] Container.Refresh") #20130418 xbmc.output virker
510 # ikke med XBMC12
511 xbmc.executebuiltin("Container.Refresh")
512
513
514 elif mode == None:
515 # build main menu
516 rootMenu()
517
518 elif mode == 1:
519 # build list of movie starting letters
520 buildList(url, name)
521
522 elif mode == 10:
523 search()
524
525 elif mode == 11:
526 searchSeries()
527
528
529 elif mode == 50:
530 play_video(url, name)

  ViewVC Help
Powered by ViewVC 1.1.20