def download(self, path, url): try: req = Request(url) req.add_header('User-Agent', randomagent()) opener = urlopen(req) data = opener.read() zip_file = zipfile.ZipFile(BytesIO(data)) opener.close() files = zip_file.namelist() srt = [i for i in files if i.endswith(('.srt', '.sub'))][0] subtitle = control.join(path, srt) zip_file.extractall(path) return subtitle except Exception as e: _, __, tb = sys.exc_info() print(traceback.print_tb(tb)) log_debug( 'Podnapisi.net subtitle download failed for the following reason: ' + str(e)) return
def dash_conditionals(stream): try: inputstream_adaptive = control.addon_details( 'inputstream.adaptive').get('enabled') except KeyError: inputstream_adaptive = False m3u8_dash = ('.hls' in stream or '.m3u8' in stream) and control.setting('m3u8_quality_picker') == '2' dash = ('.mpd' in stream or 'dash' in stream or '.ism' in stream or m3u8_dash) and inputstream_adaptive mimetype = None manifest_type = None if dash: if '.hls' in stream or '.m3u8' in stream: manifest_type = 'hls' mimetype = 'application/vnd.apple.mpegurl' elif '.ism' in stream: manifest_type = 'ism' else: manifest_type = 'mpd' log_debug('Activating adaptive parameters for this url: ' + stream) return dash, m3u8_dash, mimetype, manifest_type
def mgreekz_top10(self): self.list = cache.get(self._mgreekz_top10, 24) if self.list is None: log_debug('Mad Greekz top 10 section failed to load') return for item in self.list: item.update({'action': 'play', 'isFolder': 'False'}) for count, item in list(enumerate(self.list, start=1)): add_to_playlist = {'title': 30226, 'query': {'action': 'add_to_playlist'}} clear_playlist = {'title': 30227, 'query': {'action': 'clear_playlist'}} item.update( { 'cm': [add_to_playlist, clear_playlist], 'album': control.lang(30127), 'fanart': control.addonmedia( addonid=art_id, theme='networks', icon='mgz_fanart.jpg', media_subfolder=False ), 'tracknumber': count, 'code': count } ) control.sortmethods('tracknum', mask='%A') directory.add(self.list, content=self.content, infotype=self.infotype, argv=self.argv)
def play(url): stream = router(url) dash = ('.mpd' in stream or 'dash' in stream or '.ism' in stream or '.hls' in stream) if dash: if '.hls' in stream: manifest_type = 'hls' elif '.ism' in stream: manifest_type = 'ism' else: manifest_type = 'mpd' log_debug('Activating MPEG-DASH for this url: ' + stream) else: manifest_type = '' try: if '.mpd' in stream: directory.resolve(stream, dash=dash, manifest_type=manifest_type) else: directory.resolve(stream) except: pass
def reddit_subs(action, sr_name): if action is None: action = 'sub' sleep = True else: sleep = False if sr_name is None: from tulip.bookmarks import get bookmarks = get(file_=saved_subrs) if not bookmarks: return sr_name = ','.join([i['sr_name'] for i in bookmarks]) post_data = {'action': action, 'sr_name': sr_name} result = client.request(base_link() + '/api/subscribe', post=post_data, headers=request_headers(), output='response') if control.setting('debugging.toggle') == 'true': log_debug(result) if action == 'unsub' or sleep: if sleep: control.sleep(200) control.refresh()
def events(self, url): self.list = cache.get(self.event_list, 12, url) if self.list is None: log_debug( 'Events section failed to load, try resetting indexer methods') return for item in self.list: bookmark = dict( (k, v) for k, v in iteritems(item) if not k == 'next') bookmark['bookmark'] = item['url'] bookmark_cm = { 'title': 30080, 'query': { 'action': 'addBookmark', 'url': json.dumps(bookmark) } } item.update({ 'cm': [bookmark_cm], 'action': 'play', 'isFolder': 'False' }) directory.add(self.list)
def resolve_live(self, lang): result = client.request(self.live_link.format(lang), error=True) result = json.loads(result)['url'] if result.startswith('//'): result = 'http:' + result result = client.request(result, error=True) _json = json.loads(result) try: if _json.get('status') == 'ko': control.infoDialog(_json.get('msg').capitalize(), time=5000) log_debug(_json.get('msg').capitalize()) return except Exception: return if control.setting('backup_live') == 'false': stream = _json['primary'] else: stream = _json['backup'] if stream.startswith('//'): stream = ''.join(['http:', stream]) if control.setting('quality_live') in ['0', '2']: return stream else: from resources.lib.loader import m3u8_picker return m3u8_picker(stream)
def checkpoint(): check = time() + 10800 try: new_version_prompt = control.setting('new_version_prompt') == 'true' and remote_version() > int(control.version().replace('.', '')) except ValueError: # will fail if version install is alpha or beta new_version_prompt = False if new_version(): # if control.yesnoDialog(control.lang(30267)): # changelog() welcome() cache_clear(notify=False) reset_idx(notify=False) if control.setting('debug') == 'true' or control.setting('toggler') == 'true': from tulip.log import log_debug log_debug('Debug settings have been reset, please do not touch these settings manually,' ' they are *only* meant to help developer test various aspects.') control.setSetting('debug', 'false') control.setSetting('toggler', 'false') control.setSetting('last_check', str(check)) elif new_version_prompt and time() > float(control.setting('last_check')): prompt() control.setSetting('last_check', str(check))
def sl_session(url): session = streamlink.session.Streamlink() custom_plugins = control.join(control.addonPath, 'resources', 'lib', 'resolvers', 'sl_plugins') session.load_plugins(custom_plugins) if 'omegatv' in url: session.set_plugin_option('omegacy', 'parse_hls', 'false') elif 'ant1.com.cy' in url: session.set_plugin_option('ant1cy', 'parse_hls', 'false') elif 'antenna.gr/Live' in url: session.set_plugin_option('ant1gr', 'parse_hls', 'false') elif 'star.gr/tv/live-stream/' in url: session.set_plugin_option('stargr', 'parse_hls', 'false') plugin = session.resolve_url(url) streams = plugin.streams() try: return streams except (NoPluginError, NoStreamsError) as e: log.log_debug('Streamlink failed due to following reason: ' + e) return
def download(self, path, url): try: cookie = None anonymous = (self.user == '' or self.password == '') code, result = client.request(url, output='response', error=True) if code == '429' and anonymous is True: control.dialog.ok(str('xsubs.tv'), str(result), str('')) return elif anonymous is False: cookie = self.cookie() result, headers, content, cookie = client.request( url, cookie=cookie, output='extended') subtitle = content['Content-Disposition'] subtitle = re.findall('"(.+?)"', subtitle)[0] try: subtitle = subtitle.decode('utf-8') except Exception: pass subtitle = control.join(path, subtitle) if not subtitle.endswith('.srt'): raise Exception() with open(subtitle, 'wb') as subFile: subFile.write(result) fileparts = os_split(subtitle)[1].split('.') result = control.join( os_split(subtitle)[0], 'subtitles.' + fileparts[len(fileparts) - 1]) rename(subtitle, result) return result except Exception as e: _, __, tb = sys.exc_info() print(traceback.print_tb(tb)) log_debug( 'Xsubstv subtitle download failed for the following reason: ' + str(e)) return
def episodes(self, url): if CACHE_DEBUG: self.list = self.epeisodia(url) else: self.list = cache.get(self.epeisodia, 12, url) if self.list is None: log_debug( 'Episode section failed to load, try resetting indexer methods' ) return for item in self.list: item.update({'action': 'play', 'isFolder': 'False'}) for item in self.list: refresh_cm = {'title': 30054, 'query': {'action': 'refresh'}} item.update({'cm': [refresh_cm]}) if control.setting('episodes_reverse') == 'true': self.list = sorted( self.list, key=lambda k: k['group'] if k['group'] in ['1bynumber', '2bydate'] else k['title'], reverse=True)[::-1] else: self.list = sorted(self.list, key=lambda k: k['group']) if len(self.list) > int( control.setting('pagination_integer')) and control.setting( 'paginate_items') == 'true': try: pages = list_divider( self.list, int(control.setting('pagination_integer'))) self.list = pages[int(control.setting('page'))] reset = False except Exception: pages = list_divider( self.list, int(control.setting('pagination_integer'))) self.list = pages[0] reset = True self.list.insert(0, page_menu(len(pages), reset=reset)) control.sortmethods() # control.sortmethods('title') # control.sortmethods('year') directory.add(self.list, content='episodes')
def memoizer(*args, **kwargs): if args: klass, real_args = args[0], args[1:] full_name = '%s.%s.%s' % (klass.__module__, klass.__class__.__name__, func.__name__) else: full_name = func.__name__ real_args = args in_cache, result = self._get_func(full_name, real_args, kwargs, cache_limit=cache_limit) if in_cache: if control: log_debug( 'Using method cache for: |{0}|{1}|{2}| -> |{3}|'. format( full_name, args, kwargs, len( pickle.dumps( result, protocol=pickle.HIGHEST_PROTOCOL)))) else: print('Using method cache for: |{0}|{1}|{2}| -> |{3}|'. format( full_name, args, kwargs, len( pickle.dumps( result, protocol=pickle.HIGHEST_PROTOCOL)))) return result else: if control: log_debug( 'Calling cached method: |{0}|{1}|{2}|'.format( full_name, args, kwargs)) else: print('Calling cached method: |{0}|{1}|{2}|'.format( full_name, args, kwargs)) result = func(*args, **kwargs) self._save_func(full_name, real_args, kwargs, result) return result
def check_stream(stream_list, shuffle_list=False, start_from=0, show_pd=False, cycle_list=True): if not stream_list: return if shuffle_list: shuffle(stream_list) for (c, (h, stream)) in list(enumerate(stream_list[start_from:])): if stream.endswith('blank.mp4'): return stream if show_pd: pd = control.progressDialog pd.create(control.name(), ''.join([control.lang(30459), h.partition(': ')[2]])) try: resolved = conditionals(stream) except Exception: resolved = None if resolved is not None: if show_pd: pd.close() return resolved elif show_pd and pd.iscanceled(): return elif c == len(stream_list[start_from:]) and not resolved: control.infoDialog(control.lang(30411)) if show_pd: pd.close() elif resolved is None: if cycle_list: log_debug('Removing unplayable stream: {0}'.format(stream)) stream_list.remove((h, stream)) return check_stream(stream_list) else: if show_pd: _percent = percent(c, len(stream_list[start_from:])) pd.update( _percent, ''.join([control.lang(30459), h.partition(': ')[2]])) control.sleep(1000) continue
def bookmarks(self): self.data = bookmarks.get() if not self.data: log_debug('Bookmarks list is empty') na = [{'title': 30033, 'action': None, 'icon': iconname('empty')}] directory.add(na) else: for i in self.data: if i['url'].startswith( (movies_link, theater_link, shortfilms_link)): if control.setting('action_type') == '1': try: del i['isFolder'] except: pass action = 'directory' elif control.setting( 'action_type') == '2' and control.setting( 'auto_play') == 'false': try: del i['isFolder'] except: pass action = i['action'] else: action = i['action'] else: action = i['action'] i['action'] = action item = dict((k, v) for k, v in iteritems(i) if not k == 'next') item['delbookmark'] = i['url'] i.update({ 'cm': [{ 'title': 30081, 'query': { 'action': 'deleteBookmark', 'url': json.dumps(item) } }] }) self.list = sorted(self.data, key=lambda k: k['title'].lower()) directory.add(self.list, argv=self.argv)
def play(url, meta=None, quality=None): if meta: control.busy() stream = resolver(url, quality) try: isa_enabled = control.addon_details('inputstream.adaptive').get( 'enabled') except KeyError: isa_enabled = False dash = ('.mpd' in stream or 'dash' in stream or '.ism' in stream or '.hls' in stream or '.m3u8' in stream) and isa_enabled mimetype = None if isinstance(meta, dict): control.idle() if meta['title'] == 'custom': title = control.inputDialog() meta['title'] = title if dash and control.setting('disable_mpd') == 'false': if '.hls' in stream or 'm3u8' in stream: manifest_type = 'hls' mimetype = 'application/vnd.apple.mpegurl' elif '.ism' in stream: manifest_type = 'ism' else: manifest_type = 'mpd' log_debug('Activating MPEG-DASH for this url: ' + stream) directory.resolve(stream, meta=meta, dash=dash, manifest_type=manifest_type, mimetype=mimetype, resolved_mode=meta is None) else: directory.resolve(stream, meta=meta, resolved_mode=meta is None)
def _playlist(self, url, limit): try: result = client.request(url) result = json.loads(result) items = result['items'] except Exception: log_debug( 'Youtube: Could not fetch items from the cdn, invalid key or no quota left' ) return for i in list(range(1, limit)): try: if not 'nextPageToken' in result: raise Exception next = url + '&pageToken=' + result['nextPageToken'] result = client.request(next) result = json.loads(result) items += result['items'] except Exception: pass for item in items: try: title = item['snippet']['title'] try: title = py2_enc(title) except AttributeError: pass url = item['id'] try: url = py2_enc(url) except AttributeError: pass image = item['snippet']['thumbnails']['high']['url'] if '/default.jpg' in image: raise Exception try: image = py2_enc(image) except AttributeError: pass self.list.append({'title': title, 'url': url, 'image': image}) except Exception: pass return self.list
def yt(uri): if uri.startswith('plugin://'): return uri if len(uri) == 11: uri = YT_URL + uri try: return youtube.wrapper(uri) except YouTubeException as exp: log_debug('Youtube resolver failure, reason: ' + repr(exp)) return
def reset_cache(self, notify=False, label_success=30402): try: shutil.rmtree(cache_path) if notify: control.infoDialog(control.lang(label_success).encode('utf-8')) return True except Exception as e: if control: log_debug('Failed to create cache: {0}: {1}'.format( cache_path, e)) else: print('Failed to create cache: {0}: {1}'.format(cache_path, e)) return False
def reset_idx(notify=True, force=False): if control.setting('reset_idx') == 'true' or force: if control.setting('reset_live') == 'true' or force: control.setSetting('live_group', '0') control.setSetting('vod_group', '30213') control.setSetting('papers_group', '0') if notify: control.infoDialog(message=control.lang(30402), time=3000) log_debug('Indexers have been reset')
def artist_index(self, url): self.list = cache.get(self.music_list, 48, url) if self.list is None: log_debug('Artist\'s section failed to load') return for item in self.list: bookmark = dict((k, v) for k, v in iteritems(item) if not k == 'next') bookmark['bookmark'] = item['url'] bookmark_cm = {'title': 30080, 'query': {'action': 'addBookmark', 'url': json.dumps(bookmark)}} item.update({'cm': [bookmark_cm], 'action': 'album_index'}) directory.add(self.list, argv=self.argv)
def reddit_save(action, thing_id): url = reddit_url('/api/{0}'.format(action)) post_data = {'id': thing_id} response = client.request(url, post=post_data, output='extended', headers=request_headers()) if control.setting('debugging.toggle') == 'true': log_debug(response) if action == 'unsave': refresh()
def album_index(self, url): self.list = cache.get(self.music_list, 48, url) if self.list is None: log_debug('Album index section failed to load') return for item in self.list: item.update( { 'action': 'songs_index', 'name': item['title'].partition(' (')[0], 'year': int(item['title'].partition(' (')[2][:-1]) } ) directory.add(self.list, content=self.content, infotype=self.infotype, argv=self.argv)
def songs_index(self, url, album): self.list = cache.get(self.music_list, 48, url) if self.list is None: log_debug('Songs section failed to load') return for item in self.list: item.update({'action': 'play', 'isFolder': 'False'}) for count, item in list(enumerate(self.list, start=1)): add_to_playlist = {'title': 30226, 'query': {'action': 'add_to_playlist'}} clear_playlist = {'title': 30227, 'query': {'action': 'clear_playlist'}} item.update({'cm': [add_to_playlist, clear_playlist], 'album': album.encode('latin-1'), 'tracknumber': count}) directory.add(self.list, content=self.content, infotype=self.infotype, argv=self.argv)
def reddit_server(): if control.setting('debugging.toggle') == 'true': log_debug('Starting http server') ip_address = control.setting('ip.address') if ip_address == '0.0.0.0': ip_address = '127.0.0.1' server = ThreadedServer((ip_address, int(control.setting('ip.port'))), BaseServer) server.handle_request() if control.setting('debugging.toggle') == 'true': log_debug('Stopped http server')
def check_connection(url="1.1.1.1", timeout=3): conn = httplib.HTTPConnection(url, timeout=timeout) try: conn.request("HEAD", "/") conn.close() return True except Exception as e: if log_debug: log_debug(e) else: print(e) return False
def debugging_toggle(): if not control.get_a_setting('debug.showloginfo')['result']['value']: control.execute('ToggleDebug') if control.setting('debugging.toggle') == 'false': yes = control.yesnoDialog(control.lang(30016)) if yes: control.setSetting('debugging.toggle', 'true') log_debug('Debugging activated') else: control.setSetting('debugging.toggle', 'false') control.execute('ToggleDebug')
def bookmarks(self): self.data = bookmarks.get() if not self.data: log_debug('Bookmarks list is empty') na = [{'title': 30033, 'action': None, 'icon': iconname('empty')}] directory.add(na) else: for i in self.data: item = dict((k, v) for k, v in iteritems(i) if not k == 'next') item['delbookmark'] = i['url'] i.update({ 'cm': [{ 'title': 30081, 'query': { 'action': 'deleteBookmark', 'url': json.dumps(item) } }] }) self.list = sorted(self.data, key=lambda k: strip_accents(k['title'].lower())) if setting('show_clear_bookmarks') == 'true': clear_all = { 'title': 30274, 'action': 'clear_bookmarks', 'icon': iconname('empty') } self.list.insert(0, clear_all) directory.add(self.list)
def miscellany(self): if control.setting('debug') == 'true': self.data = cache.get(self.misc_list, int(control.setting('cache_period'))) else: self.data = cache.get(self.misc_list, 24) if self.data is None: log_debug('Misc channels list did not load successfully') return self.list = [] for item in self.data: if control.setting('lang_split') == '0': if 'Greek' in control.infoLabel('System.Language'): li = control.item(label=item['title'].partition(' - ')[2]) elif 'English' in control.infoLabel('System.Language'): li = control.item(label=item['title'].partition(' - ')[0]) else: li = control.item(label=item['title']) elif control.setting('lang_split') == '1': li = control.item(label=item['title'].partition(' - ')[0]) elif control.setting('lang_split') == '2': li = control.item(label=item['title'].partition(' - ')[2]) else: li = control.item(label=item['title']) li.setArt({ 'icon': item['icon'], 'fanart': control.addonInfo('fanart') }) url = item['url'] isFolder = True self.list.append((url, li, isFolder)) control.addItems(self.syshandle, self.list) control.directory(self.syshandle)
def top50_list(self, url): self.list = self._top50(url) if self.list is None: log_debug('Developer\'s picks section failed to load') return for count, item in list(enumerate(self.list, start=1)): add_to_playlist = { 'title': 30226, 'query': { 'action': 'add_to_playlist' } } clear_playlist = { 'title': 30227, 'query': { 'action': 'clear_playlist' } } item.update({ 'action': 'play', 'isFolder': 'False', 'cm': [add_to_playlist, clear_playlist], 'album': control.lang(30269), 'fanart': 'https://i.ytimg.com/vi/vtjL9IeowUs/maxresdefault.jpg', 'tracknumber': count, 'code': count, 'artist': [item['label'].partition(' - ')[0]] }) if control.setting( 'audio_only') == 'true' and control.condVisibility( 'Window.IsVisible(music)'): item['artist'] = item['artist'][0] control.sortmethods('tracknum', mask='%A') directory.add(self.list, content=self.content, infotype=self.infotype)
def revoke(): yesno = control.yesnoDialog(control.lang(30079)) if yesno: post = {'token': control.setting('access.token')} headers = {'User-Agent': user_agent()} username, password = (client_id, '') result = client.request(api_link('revoke_token'), post=post, headers=headers, username=username, password=password, output='response') if control.setting('debugging.toggle') == 'true': log_debug('Revoking tokens, response: ' + result[0]) tokens_reset() control.refresh()