· 5 years ago · Mar 17, 2020, 02:10 PM
1# -*- coding: utf-8 -*-
2
3'''
4 Genesis Add-on
5 Copyright (C) 2015 lambda
6
7 -Mofidied by The Crew
8 -Copyright (C) 2019 lambda
9
10
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23'''
24
25import base64
26import hashlib
27import os
28import random
29import re
30import requests
31import shutil
32import string
33import sys
34import urllib
35import urllib2
36import json
37import resolveurl
38import ssl
39import zipfile
40import urlparse
41import datetime
42import xbmc
43import xbmcgui
44from resources.lib.modules import cache, metacache, client, control, regex, trailer, workers, youtube, views, trakt, common, notify
45
46try:
47 from sqlite3 import dbapi2 as database
48except:
49 from pysqlite2 import dbapi2 as database
50
51traktCredentials = trakt.getTraktCredentialsInfo()
52traktIndicators = trakt.getTraktIndicatorsInfo()
53TXTHeader = '[B]>>[COLOR lime]Disclaimer[/COLOR]<<[/B]'
54addon_id = 'plugin.video.thecrew'
55ADDON_FOLDER = xbmc.translatePath(
56 os.path.join('special://home/addons/' + addon_id))
57TERMS = xbmc.translatePath(os.path.join(
58 ADDON_FOLDER, 'resources/disclaimer.txt'))
59DATA_FOLDER = xbmc.translatePath(os.path.join(
60 'special://home/userdata/addon_data/' + addon_id))
61I_AGREE = xbmc.translatePath(os.path.join(DATA_FOLDER, 'agreed.txt'))
62fanart = xbmc.translatePath(os.path.join(
63 'special://home/addons/' + addon_id, 'fanart.gif'))
64icon = xbmc.translatePath(os.path.join(
65 'special://home/addons/' + addon_id, 'icon.gif'))
66dialog = xbmcgui.Dialog()
67User_Agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
68
69
70class indexer:
71 if not os.path.exists(DATA_FOLDER):
72 os.makedirs(DATA_FOLDER)
73 if not os.path.exists(I_AGREE):
74 notify.AgreeFirst()
75 open(I_AGREE, 'w')
76 else:
77 pass
78
79 def __init__(self):
80 self.list = []
81 self.hash = []
82
83 def root_porn(self):
84 try:
85 regex.clear()
86 url = 'https://bitbucket.org/threw/pinkhat/raw/master/pinkhat/xxx.xml'
87 self.list = self.the_crew_list(url)
88 for i in self.list:
89 i.update({'content': 'addons'})
90 self.addDirectory(self.list)
91 return self.list
92 except:
93 pass
94
95 def root_titan(self):
96 try:
97 regex.clear()
98 url = 'http://magnetic.website/Mad%20Titan/main.xml'
99 self.list = self.the_crew_list(url)
100 for i in self.list:
101 i.update({'content': 'addons'})
102 self.addDirectory(self.list)
103 return self.list
104 except:
105 pass
106
107 def root_greyhat(self):
108 try:
109 regex.clear()
110 url = 'https://bitbucket.org/team-crew/xmls/raw/master/kids/greyhat_main.xml'
111 self.list = self.the_crew_list(url)
112 for i in self.list:
113 i.update({'content': 'addons'})
114 self.addDirectory(self.list)
115 return self.list
116 except:
117 pass
118
119 def root_yellowhat(self):
120 try:
121 regex.clear()
122 url = 'https://pastebin.com/raw/d5cb3Wxw'
123 self.list = self.the_crew_list(url)
124 for i in self.list:
125 i.update({'content': 'addons'})
126 self.addDirectory(self.list)
127 return self.list
128 except:
129 pass
130
131 def root_redhat(self):
132 try:
133 regex.clear()
134 url = 'https://bitbucket.org/team-crew/xmls/raw/master/standup/main.xml'
135 self.list = self.the_crew_list(url)
136 for i in self.list:
137 i.update({'content': 'addons'})
138 self.addDirectory(self.list)
139 return self.list
140 except:
141 pass
142
143 def root_blackhat(self):
144 try:
145 regex.clear()
146 url = 'https://bitbucket.org/team-crew/xmls/raw/master/fitness/main.xml'
147 self.list = self.the_crew_list(url)
148 for i in self.list:
149 i.update({'content': 'addons'})
150 self.addDirectory(self.list)
151 return self.list
152 except:
153 pass
154
155 def root_food(self):
156 try:
157 regex.clear()
158 url = 'https://bitbucket.org/team-crew/xmls/raw/master/food/food_main.xml'
159 self.list = self.the_crew_list(url)
160 for i in self.list:
161 i.update({'content': 'addons'})
162 self.addDirectory(self.list)
163 return self.list
164 except:
165 pass
166
167 def root_greenhat(self):
168 try:
169 regex.clear()
170 url = 'https://bitbucket.org/threw/greenhat/raw/master/greenhat/green.xml'
171 self.list = self.the_crew_list(url)
172 for i in self.list:
173 i.update({'content': 'addons'})
174 self.addDirectory(self.list)
175 return self.list
176 except:
177 pass
178
179 def root_absolution(self):
180 try:
181 regex.clear()
182 url = 'https://bitbucket.org/team-crew/xmls/raw/master/absolution/absolution_main.xml'
183 self.list = self.the_crew_list(url)
184 for i in self.list:
185 i.update({'content': 'addons'})
186 self.addDirectory(self.list)
187 return self.list
188 except:
189 pass
190
191 def root_eyecandy(self):
192 try:
193 regex.clear()
194 url = 'http://www.revelationmedia.tk/eyecandynew/main.xml'
195 self.list = self.the_crew_list(url)
196 for i in self.list:
197 i.update({'content': 'addons'})
198 self.addDirectory(self.list)
199 return self.list
200 except:
201 pass
202
203 def root_retribution(self):
204 try:
205 regex.clear()
206 url = 'http://www.revelationmedia.tk/retributionnew/main.xml'
207 self.list = self.the_crew_list(url)
208 for i in self.list:
209 i.update({'content': 'addons'})
210 self.addDirectory(self.list)
211 return self.list
212 except:
213 pass
214
215 def root_iptv(self):
216 try:
217 regex.clear()
218 url = 'https://pastebin.com/raw/ZzGTySZE'
219 self.list = self.the_crew_list(url)
220 for i in self.list:
221 i.update({'content': 'addons'})
222 self.addDirectory(self.list)
223 return self.list
224 except:
225 pass
226
227 def root_247movies(self):
228 try:
229 regex.clear()
230 url = 'https://bitbucket.org/team-crew/text_files/raw/master/247movies.xml'
231 self.list = self.the_crew_list(url)
232 for i in self.list:
233 i.update({'content': 'addons'})
234 self.addDirectory(self.list)
235 return self.list
236 except:
237 pass
238
239 def root_247tvshows(self):
240 try:
241 regex.clear()
242 url = 'https://bitbucket.org/team-crew/text_files/raw/master/247shows.xml'
243 self.list = self.the_crew_list(url)
244 for i in self.list:
245 i.update({'content': 'addons'})
246 self.addDirectory(self.list)
247 return self.list
248 except:
249 pass
250
251 def root_ncaa(self):
252 try:
253 regex.clear()
254 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/ncaa/ncaa.xml'
255 self.list = self.the_crew_list(url)
256 for i in self.list:
257 i.update({'content': 'addons'})
258 self.addDirectory(self.list)
259 return self.list
260 except:
261 pass
262
263 def root_ncaab(self):
264 try:
265 regex.clear()
266 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/ncaa/ncaab.xml'
267 self.list = self.the_crew_list(url)
268 for i in self.list:
269 i.update({'content': 'addons'})
270 self.addDirectory(self.list)
271 return self.list
272 except:
273 pass
274
275 def root_lfl(self):
276 try:
277 regex.clear()
278 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/lfl/lfl.xml'
279 self.list = self.the_crew_list(url)
280 for i in self.list:
281 i.update({'content': 'addons'})
282 self.addDirectory(self.list)
283 return self.list
284 except:
285 pass
286
287 def root_mlb(self):
288 try:
289 regex.clear()
290 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/mlb/mlb.xml'
291 self.list = self.the_crew_list(url)
292 for i in self.list:
293 i.update({'content': 'addons'})
294 self.addDirectory(self.list)
295 return self.list
296 except:
297 pass
298
299 def root_nfl(self):
300 try:
301 regex.clear()
302 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/nfl/nfl.xml'
303 self.list = self.the_crew_list(url)
304 for i in self.list:
305 i.update({'content': 'addons'})
306 self.addDirectory(self.list)
307 return self.list
308 except:
309 pass
310
311 def root_nhl(self):
312 try:
313 regex.clear()
314 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/nhl/nhl.xml'
315 self.list = self.the_crew_list(url)
316 for i in self.list:
317 i.update({'content': 'addons'})
318 self.addDirectory(self.list)
319 return self.list
320 except:
321 pass
322
323 def root_nba(self):
324 try:
325 regex.clear()
326 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/nba/nba.xml'
327 self.list = self.the_crew_list(url)
328 for i in self.list:
329 i.update({'content': 'addons'})
330 self.addDirectory(self.list)
331 return self.list
332 except:
333 pass
334
335 def root_ufc(self):
336 try:
337 regex.clear()
338 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/ufc_mma/ufc.xml'
339 self.list = self.the_crew_list(url)
340 for i in self.list:
341 i.update({'content': 'addons'})
342 self.addDirectory(self.list)
343 return self.list
344 except:
345 pass
346
347 def root_motogp(self):
348 try:
349 regex.clear()
350 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/motor/motogp.xml'
351 self.list = self.the_crew_list(url)
352 for i in self.list:
353 i.update({'content': 'addons'})
354 self.addDirectory(self.list)
355 return self.list
356 except:
357 pass
358
359 def root_boxing(self):
360 try:
361 regex.clear()
362 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/boxing/boxing.xml'
363 self.list = self.the_crew_list(url)
364 for i in self.list:
365 i.update({'content': 'addons'})
366 self.addDirectory(self.list)
367 return self.list
368 except:
369 pass
370
371 def root_fifa(self):
372 try:
373 regex.clear()
374 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/fifa/fifa.xml'
375 self.list = self.the_crew_list(url)
376 for i in self.list:
377 i.update({'content': 'addons'})
378 self.addDirectory(self.list)
379 return self.list
380 except:
381 pass
382
383 def root_wwe(self):
384 try:
385 regex.clear()
386 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/wwe/wwe.xml'
387 self.list = self.the_crew_list(url)
388 for i in self.list:
389 i.update({'content': 'addons'})
390 self.addDirectory(self.list)
391 return self.list
392 except:
393 pass
394
395 def root_sports_channels(self):
396 try:
397 regex.clear()
398 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/channels/channels.xml'
399 self.list = self.the_crew_list(url)
400 for i in self.list:
401 i.update({'content': 'addons'})
402 self.addDirectory(self.list)
403 return self.list
404 except:
405 pass
406
407 def root_sreplays(self):
408 try:
409 regex.clear()
410 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/replays/replays.xml'
411 self.list = self.the_crew_list(url)
412 for i in self.list:
413 i.update({'content': 'addons'})
414 self.addDirectory(self.list)
415 return self.list
416 except:
417 pass
418
419 def root_iptv_lodge(self):
420 try:
421 regex.clear()
422 url = 'https://pastebin.com/raw/2D80tRy5'
423 self.list = self.the_crew_list(url)
424 for i in self.list:
425 i.update({'content': 'addons'})
426 self.addDirectory(self.list)
427 return self.list
428 except:
429 pass
430
431 def root_stratus(self):
432 try:
433 regex.clear()
434 url = 'https://pastebin.com/raw/4cQ9mj8X'
435 self.list = self.the_crew_list(url)
436 for i in self.list:
437 i.update({'content': 'addons'})
438 self.addDirectory(self.list)
439 return self.list
440 except:
441 pass
442
443 def root_spanish(self):
444 try:
445 regex.clear()
446 url = 'https://pastebin.com/raw/ZzGTySZE'
447 self.list = self.the_crew_list(url)
448 for i in self.list:
449 i.update({'content': 'addons'})
450 self.addDirectory(self.list)
451 return self.list
452 except:
453 pass
454
455 def root_faith(self):
456 try:
457 regex.clear()
458 url = 'https://pastebin.com/raw/ikshwe1W'
459 self.list = self.the_crew_list(url)
460 for i in self.list:
461 i.update({'content': 'addons'})
462 self.addDirectory(self.list)
463 return self.list
464 except:
465 pass
466
467 def root_cctv(self):
468 try:
469 regex.clear()
470 url = 'https://pastebin.com/raw/pQJ9pFjH'
471 self.list = self.the_crew_list(url)
472 for i in self.list:
473 i.update({'content': 'addons'})
474 self.addDirectory(self.list)
475 return self.list
476 except:
477 pass
478
479 def root_misc_sports(self):
480 try:
481 regex.clear()
482 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/misc/misc_sports.xml'
483 self.list = self.the_crew_list(url)
484 for i in self.list:
485 i.update({'content': 'addons'})
486 self.addDirectory(self.list)
487 return self.list
488 except:
489 pass
490
491 def root_tennis(self):
492 try:
493 regex.clear()
494 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/tennis/tennis.xml'
495 self.list = self.the_crew_list(url)
496 for i in self.list:
497 i.update({'content': 'addons'})
498 self.addDirectory(self.list)
499 return self.list
500 except:
501 pass
502
503 def root_f1(self):
504 try:
505 regex.clear()
506 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/motor/f1.xml'
507 self.list = self.the_crew_list(url)
508 for i in self.list:
509 i.update({'content': 'addons'})
510 self.addDirectory(self.list)
511 return self.list
512 except:
513 pass
514
515 def root_pga(self):
516 try:
517 regex.clear()
518 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/pga/pga.xml'
519 self.list = self.the_crew_list(url)
520 for i in self.list:
521 i.update({'content': 'addons'})
522 self.addDirectory(self.list)
523 return self.list
524 except:
525 pass
526
527 def root_kiddo(self):
528 try:
529 regex.clear()
530 url = 'http://cellardoortv.com/kiddo/master/main.xml'
531 self.list = self.the_crew_list(url)
532 for i in self.list:
533 i.update({'content': 'addons'})
534 self.addDirectory(self.list)
535 return self.list
536 except:
537 pass
538
539 def root_purplehat(self):
540 try:
541 regex.clear()
542 url = 'https://bitbucket.org/team-crew/purplehat/raw/master/CCcinema.xml'
543 self.list = self.the_crew_list(url)
544 for i in self.list:
545 i.update({'content': 'addons'})
546 self.addDirectory(self.list)
547 return self.list
548 except:
549 pass
550
551 def root_personal(self):
552 try:
553 regex.clear()
554 url = control.setting('personal.list')
555 self.list = self.the_crew_list(url)
556 for i in self.list:
557 i.update({'content': 'addons'})
558 self.addDirectory(self.list)
559 return self.list
560 except:
561 pass
562
563 def root_git(self):
564 try:
565 regex.clear()
566 url = 'https://bitbucket.org/team-crew/xmls/raw/master/iptv/main.xml'
567 self.list = self.the_crew_list(url)
568 for i in self.list:
569 i.update({'content': 'addons'})
570 self.addDirectory(self.list)
571 return self.list
572 except:
573 pass
574
575 def root_nascar(self):
576 try:
577 regex.clear()
578 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/nascar/nascar.xml'
579 self.list = self.the_crew_list(url)
580 for i in self.list:
581 i.update({'content': 'addons'})
582 self.addDirectory(self.list)
583 return self.list
584 except:
585 pass
586
587 def root_xfl(self):#
588 try:
589 regex.clear()
590 url = 'IaaHR0cHM6Ly9iaXRidWNrZXQub3JnL3RlYW0tY3Jldy94bWxzL3Jhdy9tYXN0ZXIvc3BvcnRzL3hmbC94ZmwueG1s'[2:].decode('base64')
591 self.list = self.the_crew_list(url)
592 for i in self.list: i.update({'content': 'addons'})
593 self.addDirectory(self.list)
594 return self.list
595 except:
596 pass
597
598 def root_cricket(self):
599 try:
600 regex.clear()
601 url = 'https://bitbucket.org/team-crew/xmls/raw/master/sports/cricket/cricket.xml'
602 self.list = self.the_crew_list(url)
603 for i in self.list:
604 i.update({'content': 'addons'})
605 self.addDirectory(self.list)
606 return self.list
607 except:
608 pass
609
610 def get(self, url):
611 try:
612 self.list = self.the_crew_list(url)
613 self.worker()
614 self.addDirectory(self.list)
615 return self.list
616 except:
617 pass
618
619 def getq(self, url):
620 try:
621 self.list = self.the_crew_list(url)
622 self.worker()
623 self.addDirectory(self.list, queue=True)
624 return self.list
625 except:
626 pass
627
628 def getx(self, url, worker=False):
629 try:
630 r, x = re.findall('(.+?)\|regex=(.+?)$', url)[0]
631 x = regex.fetch(x)
632 r += urllib.unquote_plus(x)
633 url = regex.resolve(r)
634 self.list = self.the_crew_list('', result=url)
635 self.addDirectory(self.list)
636 return self.list
637 except:
638 pass
639
640 def developer(self):
641 try:
642 url = os.path.join(control.dataPath, 'testings.xml')
643 f = control.openFile(url)
644 result = f.read()
645 f.close()
646 self.list = self.the_crew_list('', result=result)
647 for i in self.list:
648 i.update({'content': 'videos'})
649 self.addDirectory(self.list)
650 return self.list
651 except:
652 pass
653
654 def youtube(self, url, action):
655 try:
656 key = trailer.trailer().key_link.split('=', 1)[-1]
657
658 if 'PlaylistTuner' in action:
659 self.list = cache.get(
660 youtube.youtube(key=key).playlist, 1, url)
661 elif 'Playlist' in action:
662 self.list = cache.get(youtube.youtube(
663 key=key).playlist, 1, url, True)
664 elif 'ChannelTuner' in action:
665 self.list = cache.get(youtube.youtube(key=key).videos, 1, url)
666 elif 'Channel' in action:
667 self.list = cache.get(youtube.youtube(
668 key=key).videos, 1, url, True)
669
670 if 'Tuner' in action:
671 for i in self.list:
672 i.update(
673 {'name': i['title'], 'poster': i['image'], 'action': 'plugin', 'folder': False})
674 if 'Tuner2' in action:
675 self.list = sorted(
676 self.list, key=lambda x: random.random())
677 self.addDirectory(self.list, queue=True)
678 else:
679 for i in self.list:
680 i.update({'name': i['title'], 'poster': i['image'],
681 'nextaction': action, 'action': 'plugin', 'folder': False})
682 self.addDirectory(self.list)
683
684 return self.list
685 except:
686 pass
687
688 def tvtuner(self, url):
689 try:
690 preset = re.findall('<preset>(.+?)</preset>', url)[0]
691
692 today = ((datetime.datetime.utcnow() -
693 datetime.timedelta(hours=5))).strftime('%Y-%m-%d')
694 today = int(re.sub('[^0-9]', '', str(today)))
695
696 url, imdb, tvdb, tvshowtitle, year, thumbnail, fanart = re.findall('<url>(.+?)</url>', url)[0], re.findall('<imdb>(.+?)</imdb>', url)[0], re.findall('<tvdb>(.+?)</tvdb>', url)[0], re.findall(
697 '<tvshowtitle>(.+?)</tvshowtitle>', url)[0], re.findall('<year>(.+?)</year>', url)[0], re.findall('<thumbnail>(.+?)</thumbnail>', url)[0], re.findall('<fanart>(.+?)</fanart>', url)[0]
698
699 tvm = client.request(
700 'http://api.tvmaze.com/lookup/shows?thetvdb=%s' % tvdb)
701 if tvm == None:
702 tvm = client.request(
703 'http://api.tvmaze.com/lookup/shows?imdb=%s' % imdb)
704 tvm = 'http://api.tvmaze.com/shows/%s/episodes' % str(
705 json.loads(tvm).get('id'))
706 items = json.loads(client.request(tvm))
707 items = [(str(i.get('season')), str(i.get('number')), i.get(
708 'name').strip(), i.get('airdate')) for i in items]
709
710 if preset == 'tvtuner':
711 choice = random.choice(items)
712 items = items[items.index(choice):] + \
713 items[:items.index(choice)]
714 items = items[:100]
715
716 result = ''
717
718 for i in items:
719 try:
720 if int(re.sub('[^0-9]', '', str(i[3]))) > today:
721 raise Exception()
722 result += '<item><title> %01dx%02d . %s</title><meta><content>episode</content><imdb>%s</imdb><tvdb>%s</tvdb><tvshowtitle>%s</tvshowtitle><year>%s</year><title>%s</title><premiered>%s</premiered><season>%01d</season><episode>%01d</episode></meta><link><sublink>search</sublink><sublink>searchsd</sublink></link><thumbnail>%s</thumbnail><fanart>%s</fanart></item>' % (
723 int(i[0]), int(i[1]), i[2], imdb, tvdb, tvshowtitle, year, i[2], i[3], int(i[0]), int(i[1]), thumbnail, fanart)
724 except:
725 pass
726
727 result = re.sub(r'[^\x00-\x7F]+', ' ', result)
728
729 if preset == 'tvtuner':
730 result = result.replace('<sublink>searchsd</sublink>', '')
731
732 self.list = self.the_crew_list('', result=result)
733
734 if preset == 'tvtuner':
735 self.addDirectory(self.list, queue=True)
736 else:
737 self.worker()
738 self.addDirectory(self.list)
739 except:
740 pass
741
742 def search(self, url):
743 try:
744 mark = False
745 if (url == None or url == ''):
746 self.list = [{'name': 30702, 'action': 'addSearch'}]
747 self.list += [{'name': 30703, 'action': 'delSearch'}]
748 else:
749 if '|SECTION|' in url:
750 mark = url.split('|SECTION|')[0]
751 self.list = [
752 {'name': 30702, 'url': url, 'action': 'addSearch'}]
753 self.list += [{'name': 30703, 'action': 'delSearch'}]
754
755 try:
756 def search(): return
757 query = cache.get(search, 600000000, table='rel_srch')
758
759 for url in query:
760
761 if mark != False:
762 if mark in url:
763 name = url.split('|SPLITER|')[0]
764 try:
765 self.list += [{'name': '%s...' % name,
766 'url': url, 'action': 'addSearch'}]
767 except:
768 pass
769 else:
770 if not '|SPLITER|' in url:
771 try:
772 self.list += [{'name': '%s...' % url,
773 'url': url, 'action': 'addSearch'}]
774 except:
775 pass
776 except:
777 pass
778
779 self.addDirectory(self.list)
780 return self.list
781 except:
782 pass
783
784 def delSearch(self):
785 try:
786 cache.clear('rel_srch')
787 control.refresh()
788 except:
789 pass
790
791 def addSearch(self, url):
792
793 try:
794 skip = 0
795 if '|SPLITER|' in url:
796 keep = url
797 url, matcher = url.split('|SPLITER|')
798 skip = 1
799 section = 1
800 elif '|SECTION|' in url:
801 matcher = url.replace('|SECTION|', '')
802 section = 1
803 else:
804 section = 0
805 except:
806 section = 0
807
808 link = 'http://google.com'
809
810 if skip == 0:
811 if section == 1:
812 keyboard = control.keyboard(
813 '', control.lang(30702).encode('utf-8'))
814 keyboard.doModal()
815 if not (keyboard.isConfirmed()):
816 return
817 url = keyboard.getText()
818 keep = url + '|SPLITER|' + matcher
819 else:
820 if (url == None or url == ''):
821 keyboard = control.keyboard(
822 '', control.lang(30702).encode('utf-8'))
823 keyboard.doModal()
824 if not (keyboard.isConfirmed()):
825 return
826 url = keyboard.getText()
827
828 if (url == None or url == ''):
829 return
830
831 if section == 1:
832 input = keep
833 else:
834 input = url
835
836 def search(): return [input]
837 query = cache.get(search, 600000000, table='rel_srch')
838
839 def search(): return [x for y, x in enumerate(
840 (query + [input])) if x not in (query + [input])[:y]]
841 cache.get(search, 0, table='rel_srch')
842
843 links = client.request(link)
844 links = re.findall('<link>(.+?)</link>', links)
845 if section == 0:
846 links = [i for i in links if str(i).startswith('http')]
847 else:
848 links = [i for i in links if str(i).startswith(
849 'http') and matcher.lower() in str(i).lower()]
850
851 self.list = []
852 threads = []
853 for link in links:
854 threads.append(workers.Thread(self.the_crew_list, link))
855 [i.start() for i in threads]
856 [i.join() for i in threads]
857
858 self.list = [i for i in self.list if url.lower() in i['name'].lower()]
859
860 for i in self.list:
861 try:
862 name = ''
863 if not i['vip'] in ['The Crew']:
864 name += '[B]%s[/B] | ' % i['vip'].upper()
865 name += i['name']
866 i.update({'name': name})
867 except:
868 pass
869
870 for i in self.list:
871 i.update({'content': 'videos'})
872 self.addDirectory(self.list)
873
874 def the_crew_list(self, url, result=None):
875
876 try:
877 if result == None:
878 result = cache.get(client.request, 0, url)
879
880 if result.strip().startswith('#EXTM3U') and '#EXTINF' in result:
881 result = re.compile(
882 '#EXTINF:.+?\,(.+?)\n(.+?)\n', re.MULTILINE | re.DOTALL).findall(result)
883 result = ['<item><title>%s</title><link>%s</link></item>' %
884 (i[0], i[1]) for i in result]
885 result = ''.join(result)
886
887 try:
888 r = base64.b64decode(result)
889 except:
890 r = ''
891 if '</link>' in r:
892 result = r
893
894 result = str(result)
895
896 info = result.split('<item>')[0].split('<dir>')[0]
897
898 try:
899 vip = re.findall('<poster>(.+?)</poster>', info)[0]
900 except:
901 vip = '0'
902
903 try:
904 image = re.findall('<thumbnail>(.+?)</thumbnail>', info)[0]
905 except:
906 image = '0'
907
908 try:
909 fanart = re.findall('<fanart>(.+?)</fanart>', info)[0]
910 except:
911 fanart = '0'
912
913 items = re.compile(
914 '((?:<item>.+?</item>|<dir>.+?</dir>|<plugin>.+?</plugin>|<info>.+?</info>|<name>[^<]+</name><link>[^<]+</link><thumbnail>[^<]+</thumbnail><mode>[^<]+</mode>|<name>[^<]+</name><link>[^<]+</link><thumbnail>[^<]+</thumbnail><date>[^<]+</date>))', re.MULTILINE | re.DOTALL).findall(result)
915 except:
916 return
917
918 for item in items:
919 try:
920 regdata = re.compile('(<regex>.+?</regex>)',
921 re.MULTILINE | re.DOTALL).findall(item)
922 regdata = ''.join(regdata)
923 reglist = re.compile(
924 '(<listrepeat>.+?</listrepeat>)', re.MULTILINE | re.DOTALL).findall(regdata)
925 regdata = urllib.quote_plus(regdata)
926
927 reghash = hashlib.md5()
928 for i in regdata:
929 reghash.update(str(i))
930 reghash = str(reghash.hexdigest())
931
932 item = item.replace('\r', '').replace(
933 '\n', '').replace('\t', '').replace(' ', '')
934 item = re.sub('<regex>.+?</regex>', '', item)
935 item = re.sub(
936 '<sublink></sublink>|<sublink\s+name=(?:\'|\").*?(?:\'|\")></sublink>', '', item)
937 item = re.sub('<link></link>', '', item)
938
939 name = re.sub('<meta>.+?</meta>', '', item)
940 try:
941 name = re.findall('<title>(.+?)</title>', name)[0]
942 except:
943 name = re.findall('<name>(.+?)</name>', name)[0]
944
945 try:
946 date = re.findall('<date>(.+?)</date>', item)[0]
947 except:
948 date = ''
949 if re.search(r'\d+', date):
950 name += ' [COLOR red] Updated %s[/COLOR]' % date
951
952 try:
953 image2 = re.findall(
954 '<thumbnail>(.+?)</thumbnail>', item)[0]
955 except:
956 image2 = image
957
958 try:
959 fanart2 = re.findall('<fanart>(.+?)</fanart>', item)[0]
960 except:
961 fanart2 = fanart
962
963 try:
964 meta = re.findall('<meta>(.+?)</meta>', item)[0]
965 except:
966 meta = '0'
967
968 try:
969 url = re.findall('<link>(.+?)</link>', item)[0]
970 except:
971 url = '0'
972 url = url.replace(
973 '>search<', '><preset>search</preset>%s<' % meta)
974 url = '<preset>search</preset>%s' % meta if url == 'search' else url
975 url = url.replace(
976 '>searchsd<', '><preset>searchsd</preset>%s<' % meta)
977 url = '<preset>searchsd</preset>%s' % meta if url == 'searchsd' else url
978 url = re.sub(
979 '<sublink></sublink>|<sublink\s+name=(?:\'|\").*?(?:\'|\")></sublink>', '', url)
980
981 if item.startswith('<item>'):
982 action = 'play'
983 elif item.startswith('<plugin>'):
984 action = 'plugin'
985 elif item.startswith('<info>') or url == '0':
986 action = '0'
987 else:
988 action = 'directory'
989 if action == 'play' and reglist:
990 action = 'xdirectory'
991
992 if not regdata == '':
993 self.hash.append({'regex': reghash, 'response': regdata})
994 url += '|regex=%s' % reghash
995
996 if action in ['directory', 'xdirectory', 'plugin']:
997 folder = True
998 else:
999 folder = False
1000
1001 try:
1002 content = re.findall('<content>(.+?)</content>', meta)[0]
1003 except:
1004 content = '0'
1005 if content == '0':
1006 try:
1007 content = re.findall(
1008 '<content>(.+?)</content>', item)[0]
1009 except:
1010 content = '0'
1011 if not content == '0':
1012 content += 's'
1013
1014 if 'tvshow' in content and not url.strip().endswith('.xml'):
1015 url = '<preset>tvindexer</preset><url>%s</url><thumbnail>%s</thumbnail><fanart>%s</fanart>%s' % (
1016 url, image2, fanart2, meta)
1017 action = 'tvtuner'
1018
1019 if 'tvtuner' in content and not url.strip().endswith('.xml'):
1020 url = '<preset>tvtuner</preset><url>%s</url><thumbnail>%s</thumbnail><fanart>%s</fanart>%s' % (
1021 url, image2, fanart2, meta)
1022 action = 'tvtuner'
1023
1024 try:
1025 imdb = re.findall('<imdb>(.+?)</imdb>', meta)[0]
1026 except:
1027 imdb = '0'
1028
1029 try:
1030 tvdb = re.findall('<tvdb>(.+?)</tvdb>', meta)[0]
1031 except:
1032 tvdb = '0'
1033
1034 try:
1035 tvshowtitle = re.findall(
1036 '<tvshowtitle>(.+?)</tvshowtitle>', meta)[0]
1037 except:
1038 tvshowtitle = '0'
1039
1040 try:
1041 title = re.findall('<title>(.+?)</title>', meta)[0]
1042 except:
1043 title = '0'
1044
1045 if title == '0' and not tvshowtitle == '0':
1046 title = tvshowtitle
1047
1048 try:
1049 year = re.findall('<year>(.+?)</year>', meta)[0]
1050 except:
1051 year = '0'
1052
1053 try:
1054 premiered = re.findall(
1055 '<premiered>(.+?)</premiered>', meta)[0]
1056 except:
1057 premiered = '0'
1058
1059 try:
1060 season = re.findall('<season>(.+?)</season>', meta)[0]
1061 except:
1062 season = '0'
1063
1064 try:
1065 episode = re.findall('<episode>(.+?)</episode>', meta)[0]
1066 except:
1067 episode = '0'
1068
1069 self.list.append({'name': name, 'vip': vip, 'url': url, 'action': action, 'folder': folder, 'poster': image2, 'banner': '0', 'fanart': fanart2, 'content': content, 'imdb': imdb,
1070 'tvdb': tvdb, 'tmdb': '0', 'title': title, 'originaltitle': title, 'tvshowtitle': tvshowtitle, 'year': year, 'premiered': premiered, 'season': season, 'episode': episode})
1071 except:
1072 pass
1073
1074 regex.insert(self.hash)
1075
1076 return self.list
1077
1078 def worker(self):
1079
1080 self.imdb_info_link = 'http://www.omdbapi.com/?i=%s&plot=full&r=json'
1081 self.tvmaze_info_link = 'http://api.tvmaze.com/lookup/shows?thetvdb=%s'
1082 self.lang = 'en'
1083
1084 self.meta = []
1085 total = len(self.list)
1086 if total == 0:
1087 return
1088
1089 for i in range(0, total):
1090 self.list[i].update({'metacache': False})
1091 self.list = metacache.fetch(self.list, self.lang)
1092
1093 multi = [i['imdb'] for i in self.list]
1094 multi = [x for y, x in enumerate(multi) if x not in multi[:y]]
1095 if len(multi) == 1:
1096 self.movie_info(0)
1097 self.tv_info(0)
1098 if self.meta:
1099 metacache.insert(self.meta)
1100
1101 for i in range(0, total):
1102 self.list[i].update({'metacache': False})
1103 self.list = metacache.fetch(self.list, self.lang)
1104
1105 for r in range(0, total, 50):
1106 threads = []
1107 for i in range(r, r+50):
1108 if i <= total:
1109 threads.append(workers.Thread(self.movie_info, i))
1110 if i <= total:
1111 threads.append(workers.Thread(self.tv_info, i))
1112 [i.start() for i in threads]
1113 [i.join() for i in threads]
1114
1115 if self.meta:
1116 metacache.insert(self.meta)
1117
1118 def movie_info(self, i):
1119 try:
1120 if self.list[i]['metacache'] == True:
1121 raise Exception()
1122
1123 if not self.list[i]['content'] == 'movies':
1124 raise Exception()
1125
1126 imdb = self.list[i]['imdb']
1127 if imdb == '0':
1128 raise Exception()
1129
1130 item = trakt.getMovieSummary(imdb)
1131
1132 if 'Error' in item and 'incorrect imdb' in item['Error'].lower():
1133 return self.meta.append({'imdb': imdb, 'tmdb': '0', 'tvdb': '0', 'lang': self.lang, 'item': {'code': '0'}})
1134
1135 title = item.get('title')
1136 title = client.replaceHTMLCodes(title)
1137
1138 originaltitle = title
1139
1140 year = item.get('year', 0)
1141 year = re.sub('[^0-9]', '', str(year))
1142
1143 imdb = item.get('ids', {}).get('imdb', '0')
1144 imdb = 'tt' + re.sub('[^0-9]', '', str(imdb))
1145
1146 tmdb = str(item.get('ids', {}).get('tmdb', 0))
1147
1148 premiered = item.get('released', '0')
1149 try:
1150 premiered = re.compile(
1151 '(\d{4}-\d{2}-\d{2})').findall(premiered)[0]
1152 except:
1153 premiered = '0'
1154
1155 genre = item.get('genres', [])
1156 genre = [x.title() for x in genre]
1157 genre = ' / '.join(genre).strip()
1158 if not genre:
1159 genre = '0'
1160
1161 duration = str(item.get('Runtime', 0))
1162
1163 rating = item.get('rating', '0')
1164 if not rating or rating == '0.0':
1165 rating = '0'
1166
1167 votes = item.get('votes', '0')
1168 try:
1169 votes = str(format(int(votes), ',d'))
1170 except:
1171 pass
1172
1173 mpaa = item.get('certification', '0')
1174 if not mpaa:
1175 mpaa = '0'
1176
1177 tagline = item.get('tagline', '0')
1178
1179 plot = item.get('overview', '0')
1180
1181 people = trakt.getPeople(imdb, 'movies')
1182
1183 director = writer = ''
1184 if 'crew' in people and 'directing' in people['crew']:
1185 director = ', '.join([director['person']['name'] for director in people['crew']
1186 ['directing'] if director['job'].lower() == 'director'])
1187 if 'crew' in people and 'writing' in people['crew']:
1188 writer = ', '.join([writer['person']['name'] for writer in people['crew']
1189 ['writing'] if writer['job'].lower() in ['writer', 'screenplay', 'author']])
1190
1191 cast = []
1192 for person in people.get('cast', []):
1193 cast.append(
1194 {'name': person['person']['name'], 'role': person['character']})
1195 cast = [(person['name'], person['role']) for person in cast]
1196
1197 self.meta.append({'imdb': imdb, 'tmdb': '0', 'tvdb': '0', 'lang': self.lang, 'item': {'title': title, 'year': year, 'code': imdb, 'imdb': imdb, 'premiered': premiered,
1198 'genre': genre, 'duration': duration, 'rating': rating, 'votes': votes, 'mpaa': mpaa, 'director': director, 'writer': writer, 'cast': cast, 'plot': plot}})
1199 except:
1200 pass
1201
1202 def tv_info(self, i):
1203 try:
1204 if self.list[i]['metacache'] == True:
1205 raise Exception()
1206
1207 if not self.list[i]['content'] in ['tvshows', 'seasons', 'episodes']:
1208 raise Exception()
1209
1210 tvdb = self.list[i]['tvdb']
1211 if tvdb == '0':
1212 raise Exception()
1213
1214 url = self.tvmaze_info_link % tvdb
1215
1216 item = client.request(url, output='extended',
1217 error=True, timeout='10')
1218
1219 if item[1] == '404':
1220 return self.meta.append({'imdb': '0', 'tmdb': '0', 'tvdb': tvdb, 'lang': self.lang, 'item': {'code': '0'}})
1221
1222 item = json.loads(item[0])
1223
1224 tvshowtitle = item['name']
1225 tvshowtitle = tvshowtitle.encode('utf-8')
1226 if not tvshowtitle == '0':
1227 self.list[i].update({'tvshowtitle': tvshowtitle})
1228
1229 year = item['premiered']
1230 year = re.findall('(\d{4})', year)[0]
1231 year = year.encode('utf-8')
1232 if not year == '0':
1233 self.list[i].update({'year': year})
1234
1235 try:
1236 imdb = item['externals']['imdb']
1237 except:
1238 imdb = '0'
1239 if imdb == '' or imdb == None:
1240 imdb = '0'
1241 imdb = imdb.encode('utf-8')
1242 if self.list[i]['imdb'] == '0' and not imdb == '0':
1243 self.list[i].update({'imdb': imdb})
1244
1245 try:
1246 studio = item['network']['name']
1247 except:
1248 studio = '0'
1249 if studio == '' or studio == None:
1250 studio = '0'
1251 studio = studio.encode('utf-8')
1252 if not studio == '0':
1253 self.list[i].update({'studio': studio})
1254
1255 genre = item['genres']
1256 if genre == '' or genre == None or genre == []:
1257 genre = '0'
1258 genre = ' / '.join(genre)
1259 genre = genre.encode('utf-8')
1260 if not genre == '0':
1261 self.list[i].update({'genre': genre})
1262
1263 try:
1264 duration = str(item['runtime'])
1265 except:
1266 duration = '0'
1267 if duration == '' or duration == None:
1268 duration = '0'
1269 try:
1270 duration = str(int(duration) * 60)
1271 except:
1272 pass
1273 duration = duration.encode('utf-8')
1274 if not duration == '0':
1275 self.list[i].update({'duration': duration})
1276
1277 rating = str(item['rating']['average'])
1278 if rating == '' or rating == None:
1279 rating = '0'
1280 rating = rating.encode('utf-8')
1281 if not rating == '0':
1282 self.list[i].update({'rating': rating})
1283
1284 plot = item['summary']
1285 if plot == '' or plot == None:
1286 plot = '0'
1287 plot = re.sub('\n|<.+?>|</.+?>|.+?#\d*:', '', plot)
1288 plot = plot.encode('utf-8')
1289 if not plot == '0':
1290 self.list[i].update({'plot': plot})
1291
1292 self.meta.append({'imdb': imdb, 'tmdb': '0', 'tvdb': tvdb, 'lang': self.lang, 'item': {'tvshowtitle': tvshowtitle, 'year': year,
1293 'code': imdb, 'imdb': imdb, 'tvdb': tvdb, 'studio': studio, 'genre': genre, 'duration': duration, 'rating': rating, 'plot': plot}})
1294 except:
1295 pass
1296
1297 def addDirectory(self, items, queue=False):
1298 if items == None or len(items) == 0:
1299 return
1300
1301 sysaddon = sys.argv[0]
1302 addonPoster = addonBanner = control.addonInfo('icon')
1303 addonFanart = control.addonInfo('fanart')
1304
1305 playlist = control.playlist
1306 if not queue == False:
1307 playlist.clear()
1308
1309 try:
1310 devmode = True if 'testings.xml' in control.listDir(control.dataPath)[
1311 1] else False
1312 except:
1313 devmode = False
1314
1315 mode = [i['content'] for i in items if 'content' in i]
1316 if 'movies' in mode:
1317 mode = 'movies'
1318 elif 'tvshows' in mode:
1319 mode = 'tvshows'
1320 elif 'seasons' in mode:
1321 mode = 'seasons'
1322 elif 'episodes' in mode:
1323 mode = 'episodes'
1324 elif 'videos' in mode:
1325 mode = 'videos'
1326 else:
1327 mode = 'addons'
1328
1329 for i in items:
1330 try:
1331
1332 try:
1333 name = control.lang(int(i['name'])).encode('utf-8')
1334 except:
1335 name = i['name']
1336
1337 if name == '':
1338 name = i['name']
1339
1340 url = '%s?action=%s' % (sysaddon, i['action'])
1341 try:
1342 url += '&url=%s' % urllib.quote_plus(i['url'])
1343 except:
1344 pass
1345 try:
1346 url += '&content=%s' % urllib.quote_plus(i['content'])
1347 except:
1348 pass
1349
1350 if i['action'] == 'plugin' and 'url' in i:
1351 url = i['url']
1352
1353 try:
1354 devurl = dict(urlparse.parse_qsl(
1355 urlparse.urlparse(url).query))['action']
1356 except:
1357 devurl = None
1358 if devurl == 'developer' and not devmode == True:
1359 raise Exception()
1360
1361 poster = i['poster'] if 'poster' in i else '0'
1362 banner = i['banner'] if 'banner' in i else '0'
1363 fanart = i['fanart'] if 'fanart' in i else '0'
1364 if poster == '0':
1365 poster = addonPoster
1366 if banner == '0' and poster == '0':
1367 banner = addonBanner
1368 elif banner == '0':
1369 banner = poster
1370
1371 content = i['content'] if 'content' in i else '0'
1372
1373 folder = i['folder'] if 'folder' in i else True
1374
1375 meta = dict((k, v) for k, v in i.iteritems() if not v == '0')
1376
1377 cm = []
1378
1379 if content in ['movies', 'tvshows']:
1380 meta.update({'trailer': '%s?action=trailer&name=%s' % (
1381 sysaddon, urllib.quote_plus(name))})
1382 cm.append((control.lang(30707).encode(
1383 'utf-8'), 'RunPlugin(%s?action=trailer&name=%s)' % (sysaddon, urllib.quote_plus(name))))
1384
1385 if content in ['movies', 'tvshows', 'seasons', 'episodes']:
1386 cm.append((control.lang(30708).encode(
1387 'utf-8'), 'XBMC.Action(Info)'))
1388
1389 if (folder == False and not '|regex=' in str(i.get('url'))) or (folder == True and content in ['tvshows', 'seasons']):
1390 cm.append((control.lang(30723).encode('utf-8'),
1391 'RunPlugin(%s?action=queueItem)' % sysaddon))
1392
1393 if content == 'movies':
1394 try:
1395 dfile = '%s (%s)' % (i['title'], i['year'])
1396 except:
1397 dfile = name
1398 try:
1399 cm.append((control.lang(30722).encode('utf-8'), 'RunPlugin(%s?action=addDownload&name=%s&url=%s&image=%s)' %
1400 (sysaddon, urllib.quote_plus(dfile), urllib.quote_plus(i['url']), urllib.quote_plus(poster))))
1401 except:
1402 pass
1403 elif content == 'episodes':
1404 try:
1405 dfile = '%s S%02dE%02d' % (
1406 i['tvshowtitle'], int(i['season']), int(i['episode']))
1407 except:
1408 dfile = name
1409 try:
1410 cm.append((control.lang(30722).encode('utf-8'), 'RunPlugin(%s?action=addDownload&name=%s&url=%s&image=%s)' %
1411 (sysaddon, urllib.quote_plus(dfile), urllib.quote_plus(i['url']), urllib.quote_plus(poster))))
1412 except:
1413 pass
1414 elif content == 'songs':
1415 try:
1416 cm.append((control.lang(30722).encode('utf-8'), 'RunPlugin(%s?action=addDownload&name=%s&url=%s&image=%s)' %
1417 (sysaddon, urllib.quote_plus(name), urllib.quote_plus(i['url']), urllib.quote_plus(poster))))
1418 except:
1419 pass
1420
1421 if mode == 'movies':
1422 cm.append((control.lang(30711).encode(
1423 'utf-8'), 'RunPlugin(%s?action=addView&content=movies)' % sysaddon))
1424 elif mode == 'tvshows':
1425 cm.append((control.lang(30712).encode(
1426 'utf-8'), 'RunPlugin(%s?action=addView&content=tvshows)' % sysaddon))
1427 elif mode == 'seasons':
1428 cm.append((control.lang(30713).encode(
1429 'utf-8'), 'RunPlugin(%s?action=addView&content=seasons)' % sysaddon))
1430 elif mode == 'episodes':
1431 cm.append((control.lang(30714).encode(
1432 'utf-8'), 'RunPlugin(%s?action=addView&content=episodes)' % sysaddon))
1433
1434 if devmode == True:
1435 try:
1436 cm.append(('Open in browser', 'RunPlugin(%s?action=browser&url=%s)' % (
1437 sysaddon, urllib.quote_plus(i['url']))))
1438 except:
1439 pass
1440
1441 item = control.item(
1442 label=name, iconImage=poster, thumbnailImage=poster)
1443
1444 try:
1445 item.setArt({'poster': poster, 'tvshow.poster': poster, 'season.poster': poster,
1446 'banner': banner, 'tvshow.banner': banner, 'season.banner': banner})
1447 except:
1448 pass
1449
1450 if not fanart == '0':
1451 item.setProperty('Fanart_Image', fanart)
1452 elif not addonFanart == None:
1453 item.setProperty('Fanart_Image', addonFanart)
1454
1455 if queue == False:
1456 item.setInfo(type='Video', infoLabels=meta)
1457 item.addContextMenuItems(cm)
1458 control.addItem(handle=int(
1459 sys.argv[1]), url=url, listitem=item, isFolder=folder)
1460 else:
1461 item.setInfo(type='Video', infoLabels=meta)
1462 playlist.add(url=url, listitem=item)
1463 except:
1464 pass
1465
1466 if not queue == False:
1467 return control.player.play(playlist)
1468
1469 try:
1470 i = items[0]
1471 if i['next'] == '':
1472 raise Exception()
1473 url = '%s?action=%s&url=%s' % (
1474 sysaddon, i['nextaction'], urllib.quote_plus(i['next']))
1475 item = control.item(label=control.lang(30500).encode('utf-8'))
1476 item.setArt({'addonPoster': addonPoster, 'thumb': addonPoster, 'poster': addonPoster, 'tvshow.poster': addonPoster,
1477 'season.poster': addonPoster, 'banner': addonPoster, 'tvshow.banner': addonPoster, 'season.banner': addonPoster})
1478 item.setProperty('addonFanart_Image', addonFanart)
1479 control.addItem(handle=int(
1480 sys.argv[1]), url=url, listitem=item, isFolder=True)
1481 except:
1482 pass
1483
1484 if not mode == None:
1485 control.content(int(sys.argv[1]), mode)
1486 control.directory(int(sys.argv[1]), cacheToDisc=True)
1487 if mode in ['movies', 'tvshows', 'seasons', 'episodes']:
1488 views.setView(mode, {'skin.estuary': 55})
1489
1490
1491class resolver:
1492 def browser(self, url):
1493 try:
1494 url = self.get(url)
1495 if url == False:
1496 return
1497 control.execute(
1498 'RunPlugin(plugin://plugin.program.chrome.launcher/?url=%s&mode=showSite&stopPlayback=no)' % urllib.quote_plus(url))
1499 except:
1500 pass
1501
1502 def link(self, url):
1503 try:
1504 url = self.get(url)
1505 if url == False:
1506 return
1507
1508 control.execute('ActivateWindow(busydialog)')
1509 url = self.process(url)
1510 control.execute('Dialog.Close(busydialog)')
1511
1512 if url == None:
1513 return control.infoDialog(control.lang(30705).encode('utf-8'))
1514 return url
1515 except:
1516 pass
1517
1518 def get(self, url):
1519 try:
1520 items = re.compile(
1521 '<sublink(?:\s+name=|)(?:\'|\"|)(.*?)(?:\'|\"|)>(.+?)</sublink>').findall(url)
1522
1523 if len(items) == 0:
1524 return url
1525 if len(items) == 1:
1526 return items[0][1]
1527
1528 items = [('Link %s' % (int(items.index(i))+1) if i[0]
1529 == '' else i[0], i[1]) for i in items]
1530
1531 select = control.selectDialog(
1532 [i[0] for i in items], control.infoLabel('listitem.label'))
1533
1534 if select == -1:
1535 return False
1536 else:
1537 return items[select][1]
1538 except:
1539 pass
1540
1541 def f4m(self, url, name):
1542 try:
1543 if not any(i in url for i in ['.f4m', '.ts', '.m3u8']):
1544 raise Exception()
1545 ext = url.split('?')[0].split('&')[0].split(
1546 '|')[0].rsplit('.')[-1].replace('/', '').lower()
1547 if not ext:
1548 ext = url
1549 if not ext in ['f4m', 'ts', 'm3u8']:
1550 raise Exception()
1551
1552 params = urlparse.parse_qs(url)
1553
1554 try:
1555 proxy = params['proxy'][0]
1556 except:
1557 proxy = None
1558
1559 try:
1560 proxy_use_chunks = json.loads(params['proxy_for_chunks'][0])
1561 except:
1562 proxy_use_chunks = True
1563
1564 try:
1565 maxbitrate = int(params['maxbitrate'][0])
1566 except:
1567 maxbitrate = 0
1568
1569 try:
1570 simpleDownloader = json.loads(params['simpledownloader'][0])
1571 except:
1572 simpleDownloader = False
1573
1574 try:
1575 auth_string = params['auth'][0]
1576 except:
1577 auth_string = ''
1578
1579 try:
1580 streamtype = params['streamtype'][0]
1581 except:
1582 if ext == 'ts':
1583 streamtype = 'TSDOWNLOADER'
1584 elif ext == 'm3u8':
1585 streamtype = 'HLS'
1586 else:
1587 streamtype = 'HDS'
1588
1589 try:
1590 swf = params['swf'][0]
1591 except:
1592 swf = None
1593
1594 from F4mProxy import f4mProxyHelper
1595 return f4mProxyHelper().playF4mLink(url, name, proxy, proxy_use_chunks, maxbitrate, simpleDownloader, auth_string, streamtype, False, swf)
1596 except:
1597 pass
1598
1599 def process(self, url, direct=True):
1600 try:
1601 if not any(i in url for i in ['.jpg', '.png', '.gif']):
1602 raise Exception()
1603 ext = url.split('?')[0].split('&')[0].split(
1604 '|')[0].rsplit('.')[-1].replace('/', '').lower()
1605 if not ext in ['jpg', 'png', 'gif']:
1606 raise Exception()
1607 try:
1608 i = os.path.join(control.dataPath, 'img')
1609 control.deleteFile(i)
1610 f = control.openFile(i, 'w')
1611 f.write(client.request(url))
1612 f.close()
1613 control.execute('ShowPicture("%s")' % i)
1614 return False
1615 except:
1616 return
1617 except:
1618 pass
1619
1620 try:
1621 r, x = re.findall('(.+?)\|regex=(.+?)$', url)[0]
1622 x = regex.fetch(x)
1623 r += urllib.unquote_plus(x)
1624 if not '</regex>' in r:
1625 raise Exception()
1626 u = regex.resolve(r)
1627 if not u == None:
1628 url = u
1629 except:
1630 pass
1631
1632 try:
1633 if not url.startswith('rtmp'):
1634 raise Exception()
1635 if len(re.compile('\s*timeout=(\d*)').findall(url)) == 0:
1636 url += ' timeout=10'
1637 return url
1638 except:
1639 pass
1640
1641 try:
1642 if not any(i in url for i in ['.m3u8', '.f4m', '.ts']):
1643 raise Exception()
1644 ext = url.split('?')[0].split('&')[0].split(
1645 '|')[0].rsplit('.')[-1].replace('/', '').lower()
1646 if not ext in ['m3u8', 'f4m', 'ts']:
1647 raise Exception()
1648 return url
1649 except:
1650 pass
1651
1652 try:
1653 preset = re.findall('<preset>(.+?)</preset>', url)[0]
1654
1655 if not 'search' in preset:
1656 raise Exception()
1657
1658 title, year, imdb = re.findall('<title>(.+?)</title>', url)[0], re.findall(
1659 '<year>(.+?)</year>', url)[0], re.findall('<imdb>(.+?)</imdb>', url)[0]
1660
1661 try:
1662 tvdb, tvshowtitle, premiered, season, episode = re.findall('<tvdb>(.+?)</tvdb>', url)[0], re.findall('<tvshowtitle>(.+?)</tvshowtitle>', url)[0], re.findall(
1663 '<premiered>(.+?)</premiered>', url)[0], re.findall('<season>(.+?)</season>', url)[0], re.findall('<episode>(.+?)</episode>', url)[0]
1664 except:
1665 tvdb = tvshowtitle = premiered = season = episode = None
1666
1667 direct = False
1668
1669 quality = 'HD' if not preset == 'searchsd' else 'SD'
1670
1671 from resources.lib.modules import sources2
1672
1673 u = sources2.sources().getSources(title, year, imdb, tvdb, season,
1674 episode, tvshowtitle, premiered, quality)
1675
1676 if not u == None:
1677 return u
1678 except:
1679 pass
1680
1681 try:
1682 from resources.lib.modules import sources2
1683
1684 u = sources2.sources().getURISource(url)
1685
1686 if not u == False:
1687 direct = False
1688 if u == None or u == False:
1689 raise Exception()
1690
1691 return u
1692 except:
1693 pass
1694
1695 try:
1696 if not '.google.com' in url:
1697 raise Exception()
1698 from resources.lib.modules import directstream
1699 u = directstream.google(url)[0]['url']
1700 return u
1701 except:
1702 pass
1703
1704 try:
1705 if not 'filmon.com/' in url:
1706 raise Exception()
1707 from resources.lib.modules import filmon
1708 u = filmon.resolve(url)
1709 return u
1710 except:
1711 pass
1712
1713 try:
1714 import resolveurl
1715
1716 hmf = resolveurl.HostedMediaFile(url=url)
1717
1718 if hmf.valid_url() == False:
1719 raise Exception()
1720
1721 direct = False
1722 u = hmf.resolve()
1723
1724 if not u == False:
1725 return u
1726 except:
1727 pass
1728
1729 if direct == True:
1730 return url
1731
1732
1733class player(xbmc.Player):
1734 def __init__(self):
1735 xbmc.Player.__init__(self)
1736
1737 def play(self, url, content=None):
1738 try:
1739 base = url
1740
1741 url = resolver().get(url)
1742 if url == False:
1743 return
1744
1745 control.execute('ActivateWindow(busydialog)')
1746 url = resolver().process(url)
1747 control.execute('Dialog.Close(busydialog)')
1748
1749 if url == None:
1750 return control.infoDialog(control.lang(30705).encode('utf-8'))
1751 if url == False:
1752 return
1753
1754 meta = {}
1755 for i in ['title', 'originaltitle', 'tvshowtitle', 'year', 'season', 'episode', 'genre', 'rating', 'votes', 'director', 'writer', 'plot', 'tagline']:
1756 try:
1757 meta[i] = control.infoLabel('listitem.%s' % i)
1758 except:
1759 pass
1760 meta = dict((k, v) for k, v in meta.iteritems() if not v == '')
1761 if not 'title' in meta:
1762 meta['title'] = control.infoLabel('listitem.label')
1763 icon = control.infoLabel('listitem.icon')
1764
1765 self.name = meta['title']
1766 self.year = meta['year'] if 'year' in meta else '0'
1767
1768 self.getbookmark = True if (
1769 content == 'movies' or content == 'episodes') else False
1770
1771 self.offset = bookmarks().get(self.name, self.year)
1772
1773 f4m = resolver().f4m(url, self.name)
1774 if not f4m == None:
1775 return
1776
1777 item = control.item(path=url, iconImage=icon, thumbnailImage=icon)
1778 try:
1779 item.setArt({'icon': icon})
1780 except:
1781 pass
1782 item.setInfo(type='Video', infoLabels=meta)
1783 control.player.play(url, item)
1784 control.resolve(int(sys.argv[1]), True, item)
1785
1786 self.totalTime = 0
1787 self.currentTime = 0
1788
1789 for i in range(0, 240):
1790 if self.isPlayingVideo():
1791 break
1792 control.sleep(1000)
1793 while self.isPlayingVideo():
1794 try:
1795 self.totalTime = self.getTotalTime()
1796 self.currentTime = self.getTime()
1797 except:
1798 pass
1799 control.sleep(2000)
1800 control.sleep(5000)
1801 except:
1802 pass
1803
1804 def onPlayBackStarted(self):
1805 control.execute('Dialog.Close(all,true)')
1806 if self.getbookmark == True and not self.offset == '0':
1807 self.seekTime(float(self.offset))
1808
1809 def onPlayBackStopped(self):
1810 if self.getbookmark == True:
1811 bookmarks().reset(self.currentTime, self.totalTime, self.name, self.year)
1812
1813 def onPlayBackEnded(self):
1814 self.onPlayBackStopped()
1815
1816
1817class bookmarks:
1818 def get(self, name, year='0'):
1819 try:
1820 offset = '0'
1821
1822 #if not control.setting('bookmarks') == 'true': raise Exception()
1823
1824 idFile = hashlib.md5()
1825 for i in name:
1826 idFile.update(str(i))
1827 for i in year:
1828 idFile.update(str(i))
1829 idFile = str(idFile.hexdigest())
1830
1831 dbcon = database.connect(control.bookmarksFile)
1832 dbcur = dbcon.cursor()
1833 dbcur.execute(
1834 "SELECT * FROM bookmark WHERE idFile = '%s'" % idFile)
1835 match = dbcur.fetchone()
1836 self.offset = str(match[1])
1837 dbcon.commit()
1838
1839 if self.offset == '0':
1840 raise Exception()
1841
1842 minutes, seconds = divmod(float(self.offset), 60)
1843 hours, minutes = divmod(minutes, 60)
1844 label = '%02d:%02d:%02d' % (hours, minutes, seconds)
1845 label = (control.lang(32502) % label).encode('utf-8')
1846
1847 try:
1848 yes = control.dialog.contextmenu(
1849 [label, control.lang(32501).encode('utf-8'), ])
1850 except:
1851 yes = control.yesnoDialog(label, '', '', str(name), control.lang(
1852 32503).encode('utf-8'), control.lang(32501).encode('utf-8'))
1853
1854 if yes:
1855 self.offset = '0'
1856
1857 return self.offset
1858 except:
1859 return offset
1860
1861 def reset(self, currentTime, totalTime, name, year='0'):
1862 try:
1863 #if not control.setting('bookmarks') == 'true': raise Exception()
1864
1865 timeInSeconds = str(currentTime)
1866 ok = int(currentTime) > 180 and (currentTime / totalTime) <= .92
1867
1868 idFile = hashlib.md5()
1869 for i in name:
1870 idFile.update(str(i))
1871 for i in year:
1872 idFile.update(str(i))
1873 idFile = str(idFile.hexdigest())
1874
1875 control.makeFile(control.dataPath)
1876 dbcon = database.connect(control.bookmarksFile)
1877 dbcur = dbcon.cursor()
1878 dbcur.execute(
1879 "CREATE TABLE IF NOT EXISTS bookmark (""idFile TEXT, ""timeInSeconds TEXT, ""UNIQUE(idFile)"");")
1880 dbcur.execute("DELETE FROM bookmark WHERE idFile = '%s'" % idFile)
1881 if ok:
1882 dbcur.execute("INSERT INTO bookmark Values (?, ?)",
1883 (idFile, timeInSeconds))
1884 dbcon.commit()
1885 except:
1886 pass