Пример #1
0
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
Пример #2
0
    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)
Пример #6
0
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
Пример #7
0
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
Пример #8
0
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))
Пример #9
0
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
Пример #10
0
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
Пример #11
0
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
Пример #12
0
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
Пример #13
0
def before_dispatch():
    api.new_session()
    plugin.logged_in = api.logged_in
    cache.enabled    = settings.getBool('use_cache', True)
Пример #14
0
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