/[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 3261 - (show annotations) (download) (as text)
Fri Feb 19 21:39:29 2021 UTC (3 years, 2 months ago) by torben
File MIME type: text/x-python
File size: 14790 byte(s)
v1.9.0 support kodi 19 / python3
breaks compability with older versions !


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

  ViewVC Help
Powered by ViewVC 1.1.20