def start(): restart_queued = False while not monitor.waitForAbort(2): forced = ADDON_DEV or xbmc.getInfoLabel( 'Skin.String({})'.format(ADDON_ID)) == FORCE_RUN_FLAG if forced or (settings.getBool('auto_merge', True) and time.time() - userdata.get('last_run', 0) > settings.getInt('reload_time_mins', 10) * 60): xbmc.executebuiltin('Skin.SetString({},{})'.format( ADDON_ID, FORCE_RUN_FLAG)) try: run_merge([Source.PLAYLIST, Source.EPG]) except Exception as e: result = False log.exception(e) else: result = True userdata.set('last_run', int(time.time())) xbmc.executebuiltin('Skin.SetString({},)'.format(ADDON_ID)) if result: restart_queued = True if forced: gui.notification(_.MERGE_COMPLETE) elif forced: gui.exception() if restart_queued and ( forced or (settings.getBool('restart_pvr', False) and not xbmc.getCondVisibility('Pvr.IsPlayingTv') and not xbmc.getCondVisibility('Pvr.IsPlayingRadio'))): restart_queued = False xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":false}}}}' .format(IPTV_SIMPLE_ID)) monitor.waitForAbort(2) xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":true}}}}' .format(IPTV_SIMPLE_ID)) if ADDON_DEV: break
def login(self, username, password): device_id = hashlib.md5(username).hexdigest() data = { "deviceDetails": "test", "deviceID": device_id, "deviceIP": DEVICE_IP, "password": password, "username": username } resp = self._session.post(AUTH_URL, json=data) data = resp.json() if resp.status_code != 200 or 'sessiontoken' not in data: raise APIError(_(_.LOGIN_ERROR, message=data.get('message'))) userdata.set('access_token', data['sessiontoken']) userdata.set('device_id', device_id) if settings.getBool('save_password', False): userdata.set('pswd', password) self._set_authentication() data = self._session.get(SUBSCRIPTIONS_URL.format(data['profileId'])).json() userdata.set('subscriptions', data['onlineSubscriptions'])
def _process_media(row): if settings.getBool('child_friendly', False) and not row.get('is_child_friendly', False): #maybe just block playback and add label, so pagination still correct return None is_published = row.get('is_published', True) is_collection = row.get('is_collection', False) is_free = row.get('is_free', False) is_series = row.get('is_numbered_series', False) duration = row.get('duration', 0) if plugin.logged_in or is_free else PREVIEW_LENGTH context = [] if plugin.logged_in and not is_collection: user_media = row.get('user_media') or {} in_watchlist = user_media.get('is_bookmarked', False) if in_watchlist: context.append((_.REMOVE_WATCHLIST, "XBMC.RunPlugin({})".format(plugin.url_for(remove_watchlist, id=row['id'], title=row['title'])))) else: context.append((_.ADD_WATCHLIST, "XBMC.RunPlugin({})".format(plugin.url_for(add_watchlist, id=row['id'], title=row['title'])))) if is_collection: path = plugin.url_for(series, id=row['id']) else: path = plugin.url_for(play, id=row['id']) return plugin.Item( label = row.get('title'), info = {'plot': row['description'], 'duration': duration, 'year': row.get('year_produced')}, art = {'thumb': _image(row, 'image_medium')}, path = path, context = context, playable = not is_collection, )
def play(id, **kwargs): data = api.media(id) item = _process_media(data) if settings.getBool('subtitles', True): item.subtitles = api.get_subtitles(data.get('closed_captions', [])) item.path = data['encodings'][0]['master_playlist_url'] item.inputstream = inputstream.HLS() return item
def _load(self): try: with codecs.open(os.path.join(ADDON_PROFILE, CHANNELS_FILE), 'r', encoding='utf8') as f: self._channels = json.load(f) except: log.debug('Failed to load channels file') self._channels = [] try: with codecs.open(os.path.join(ADDON_PROFILE, OVERRIDE_FILE), 'r', encoding='utf8') as f: self._overrides = json.load(f) except: log.debug('Failed to load overrides file') self._overrides = {} for key in self._overrides: if self._overrides[key].get('_added'): self._channels.append({ '_url': key, '_name': '', '_source': '' }) last_chn_no = 0 for channel in self._channels: channel['_id'] = channel.get('tvg-id') or channel['_url'] channel['_hidden'] = settings.getBool('default_hidden', False) channel['_modified'] = False try: channel['tvg-chno'] = int(channel['tvg-chno']) last_chn_no = channel['tvg-chno'] except: last_chn_no += 1 channel['tvg-chno'] = last_chn_no overrides = None if 'tvg-id' in channel: overrides = self._overrides.get(channel['tvg-id']) if not overrides: overrides = self._overrides.get(channel['_url']) if overrides: channel['_modified'] = True channel.update(overrides)
def _landing(name, sport=None): items = [] for row in api.landing(name, sport=sport, profile=userdata.get('profile')): if row['panelType'] == 'hero-carousel' and row.get('contents') and settings.getBool('show_hero_contents', True): items.extend(_parse_contents(row['contents'])) elif row['panelType'] != 'hero-carousel' and 'id' in row: items.append(plugin.Item( label = row['title'], path = plugin.url_for(panel, id=row['id'], sport=sport), )) return items
def play(slug, **kwargs): channel = get_channels()[slug] item = plugin.Item( path=channel['master_url'], headers=channel['headers'], info={'plot': channel.get('description')}, video=channel.get('video', {}), audio=channel.get('audio', {}), art={'thumb': channel.get('logo')}, ) if channel.get('hls', False) and settings.getBool('use_ia_hls', False): item.inputstream = inputstream.HLS() return item
def start(): monitor = xbmc.Monitor() restart_required = False while not monitor.waitForAbort(5): forced = xbmc.getInfoLabel( 'Skin.String({})'.format(ADDON_ID)) == FORCE_RUN_FLAG xbmc.executebuiltin('Skin.SetString({},)'.format(ADDON_ID)) if forced or time.time() - userdata.get( 'last_run', 0) > settings.getInt('reload_time_mins') * 60: try: run_merge() except Exception as e: result = False log.exception(e) else: result = True userdata.set('last_run', int(time.time())) if result: restart_required = settings.getBool('restart_pvr', False) if forced: gui.notification(_.MERGE_COMPLETE) elif forced: gui.exception() if restart_required and not xbmc.getCondVisibility( 'Pvr.IsPlayingTv') and not xbmc.getCondVisibility( 'Pvr.IsPlayingRadio'): restart_required = False addon_id = PVR_ADDON_IDS[settings.getInt('unused_pvr_id')] xbmc.executebuiltin('InstallAddon({})'.format(addon_id), True) xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":true}}}}' .format(addon_id)) xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":false}}}}' .format(addon_id))
def _get_channels(): subscriptions = userdata.get('subscriptions', []) channels = [] rows = api.channels() def _get_play_url(content): for row in content: if 'SkyGoStream' in row['plfile$assetTypes']: return row['plfile$streamingUrl'] return None for row in sorted(rows, key=lambda r: float(r.get('sky$liveChannelOrder', 'inf'))): if 'Live' not in row.get('sky$channelType', []): continue channel_id = row['plmedia$publicUrl'].rsplit('/')[-1] label = row['title'] subscribed = _is_subscribed(subscriptions, row.get('media$categories')) play_url = _get_play_url(row.get('media$content')) if not subscribed: label = _(_.LOCKED, label=label) elif 'faxs' in play_url: label = _(_.ADOBE_DRM, label=label) if settings.getBool('hide_unplayable', False) and (not subscribed or 'faxs' in play_url): continue channels.append({ 'label': label, 'channel': row.get('sky$skyGOChannelID', ''), 'description': row.get('description'), 'image': _get_image(row), 'path': plugin.url_for(play_channel, id=channel_id, _is_live=True), }) return channels
def _process_content(rows): items = [] subscriptions = userdata.get('subscriptions', []) for row in rows: if row['suspended']: continue label = row['title'] if 'subCode' in row and subscriptions and row['subCode'] not in subscriptions: label = _(_.LOCKED, label=label) if settings.getBool('hide_unplayable', False): continue if row['type'] == 'movie': items.append(plugin.Item( label = label, info = { 'plot': row.get('synopsis'), 'duration': int(row.get('duration', '0 mins').strip(' mins')) * 60, 'mediatype': 'movie', }, art = {'thumb': IMAGE_URL.format(row['images'].get('MP',''))}, path = plugin.url_for(play, id=row['mediaId']), playable = True, )) elif row['type'] == 'season': items.append(plugin.Item( label = label, art = {'thumb': IMAGE_URL.format(row['images'].get('MP',''))}, path = plugin.url_for(series, id=row['id']), )) return items
def _landing(name, sport=None): items = [] for row in api.landing(name, sport=sport, profile=userdata.get('profile')): if row['panelType'] == 'hero-carousel' and row.get( 'contents') and settings.getBool('show_hero_contents', True): items.extend(_parse_contents(row['contents'])) elif row['panelType'] != 'hero-carousel' and row.get('contents'): items.append( plugin.Item( label=row['title'], path=plugin.url_for(panel, id=row['id'], sport=sport), art={ 'thumb': _get_image(row['contents'][0]['data']['asset'], 'panel', 'thumb'), 'fanart': _get_image(row['contents'][0]['data']['asset'], 'panel', 'fanart'), }, )) return items
def channels(**kwargs): folder = plugin.Folder(title=_.CHANNELS) subscriptions = userdata.get('subscriptions', []) for row in sorted(api.channels(), key=lambda row: row['title']): label = row['title'] subscribed = _is_subscribed(subscriptions, row.get('media$categories')) if not subscribed: label = _(_.LOCKED, label=label) if settings.getBool('hide_unplayable', False) and not subscribed: continue folder.add_item( label = label, info = {'description': row.get('description')}, art = {'thumb': _get_image(row)}, path = plugin.url_for(content, label=row['title'], sortby='TITLE', title='', channels=row.get('sky$skyGOChannelID', '')), ) return folder
def before_dispatch(): api.new_session() plugin.logged_in = api.logged_in cache.enabled = settings.getBool('use_cache', True)
def merge_playlists(playlists, output_dir): log.debug('Merging {} Playlists...'.format(len(playlists))) merged_path = os.path.join(output_dir, '.iptv_merge_playlist') channels = [] last_chn_no = 0 for playlist in playlists: try: file_path = os.path.join(output_dir, '.iptv_merge_tmp') remove_file(file_path) process_file(playlist, METHOD_PLAYLIST, file_path) log.debug('Processing: {}'.format(playlist.path)) with codecs.open(file_path, 'r', encoding='utf8') as infile: found = None for line in infile: line = line.strip() if line.startswith('#EXTINF'): found = line elif found and line and not line.startswith('#'): data = { '_url': line, '_name': '', '_source': playlist.id } parse = urlparse(data['_url']) if not parse.scheme or not parse.netloc: found = None continue colon = found.find(':', 0) comma = found.rfind(',', 0) if colon >= 0 and comma >= 0 and comma > colon: data['_name'] = found[comma + 1:].strip() for key, value in re.findall('([\w-]+)="([^"]*)"', found): data[key] = value.strip() channels.append(data) found = None except Exception as e: log.debug('Skipping failed Playlist: {}'.format(playlist.path)) log.exception(e) remove_file(file_path) Channels.set_channels(channels) with codecs.open(merged_path, 'w', encoding='utf8') as outfile: outfile.write(u'#EXTM3U') for channel in Channels().playlist(): id = channel.pop('_id') hidden = channel.pop('_hidden', settings.getBool('default_hidden', False)) url = channel.pop('_url', '') name = channel.pop('_name', '') modified = channel.pop('_modified') source = channel.pop('_source', None) added = channel.pop('_added', None) if hidden: continue outfile.write(u'\n#EXTINF:-1') for key in channel: outfile.write(u' {}="{}"'.format(key, channel[key])) outfile.write(u',{}\n{}'.format(name, url)) return merged_path