예제 #1
0
def play(asset, play_type=PLAY_FROM_LIVE, **kwargs):
    play_type = int(play_type)

    from_start = False
    if play_type == PLAY_FROM_START or (
            play_type == PLAY_FROM_ASK
            and not gui.yes_no(_.PLAY_FROM,
                               yeslabel=_.PLAY_FROM_LIVE,
                               nolabel=_.PLAY_FROM_START)):
        from_start = True

    stream = api.play(asset, True)

    item = plugin.Item(
        path=stream['url'],
        inputstream=inputstream.Widevine(
            license_key=stream['license']['@uri']),
        headers=HEADERS,
    )

    drm_data = stream['license'].get('drmData')
    if drm_data:
        item.headers['x-axdrm-message'] = drm_data

    if from_start:
        item.resume_from = 1

    return item
예제 #2
0
def play(livestream=None, brightcoveId=None, channel=None, **kwargs):
    if brightcoveId:
        item = api.get_brightcove_src(brightcoveId)

    elif livestream:
        item = plugin.Item(path=livestream,
                           art=False,
                           inputstream=inputstream.HLS(live=True))

        if kwargs.get(ROUTE_LIVE_TAG) == ROUTE_LIVE_SUFFIX and not gui.yes_no(
                _.PLAY_FROM, yeslabel=_.PLAY_FROM_LIVE,
                nolabel=_.PLAY_FROM_START):
            item.properties['ResumeTime'] = '1'
            item.properties['TotalTime'] = '1'

            item.inputstream = inputstream.HLS(force=True, live=True)
            if not item.inputstream.check():
                plugin.exception(_.LIVE_HLS_REQUIRED)

    elif channel:
        data = api.channel(channel)
        item = plugin.Item(path=data['publisherMetadata']['liveStreamUrl'],
                           art=False,
                           inputstream=inputstream.HLS(live=True))

    item.headers = HEADERS

    return item
예제 #3
0
def logout(**kwargs):
    if not gui.yes_no(_.LOGOUT_YES_NO):
        return

    api.logout()
    userdata.delete('kid_lockdown')
    gui.refresh()
예제 #4
0
def _add_profile(taken_names, taken_avatars):
    ## PROFILE AVATAR ##
    options = [
        plugin.Item(label=_(_.RANDOM_AVATAR, _bold=True)),
    ]
    values = [
        ['_random', None],
    ]
    avatars = []
    unused = []

    for icon_set in api.profile_icons():
        for row in icon_set['icons']:
            icon_info = [icon_set['iconSet'], row['iconIndex']]

            values.append(icon_info)
            avatars.append(icon_info)

            if row['iconImage'] in taken_avatars:
                label = _(_.AVATAR_USED, label=icon_set['label'])
            else:
                label = icon_set['label']
                unused.append(icon_info)

            options.append(
                plugin.Item(label=label, art={'thumb': row['iconImage']}))

    index = gui.select(_.SELECT_AVATAR, options=options, useDetails=True)
    if index < 0:
        return

    avatar = values[index]
    if avatar[0] == '_random':
        avatar = random.choice(unused or avatars)

    ## PROFLE KIDS ##
    kids = gui.yes_no(_.KIDS_PROFILE_INFO, heading=_.KIDS_PROFILE)

    ## PROFILE NAME ##
    name = ''
    while True:
        name = gui.input(_.PROFILE_NAME, default=name).strip()
        if not name:
            return

        elif name.lower() in taken_names:
            gui.notification(_(_.PROFILE_NAME_TAKEN, name=name))

        else:
            break

    ## ADD PROFILE ##
    profile = api.add_profile(name,
                              icon_set=avatar[0],
                              icon_index=avatar[1],
                              kids=kids)
    if 'message' in profile:
        raise PluginError(profile['message'])

    _set_profile(profile)
예제 #5
0
def _play(program_id, play_type=None, is_live=False):
    play_type = int(play_type) if play_type else None
    program_data, play_data = api.play(program_id)

    headers = HEADERS.copy()
    headers['dt-custom-data'] = play_data['drm']['customData']

    item = plugin.Item(
        path=play_data['videoUrl'],
        headers=headers,
        inputstream=inputstream.Widevine(
            license_key=play_data['drm']['licenseServerUrl'],
            license_data=play_data['drm']['init_data'],
            response='JBlicense',
        ),
    )

    if is_live and (
            play_type == PLAY_FROM_START or
        (play_type == PLAY_FROM_ASK and not gui.yes_no(
            _.PLAY_FROM, yeslabel=_.PLAY_FROM_LIVE, nolabel=_.PLAY_FROM_START))
    ):
        item.resume_from = 1

    for row in play_data.get('captions', []):
        item.subtitles.append([row['url'], row['language']])

    # for chapter in program_data.get('chapters', []):
    #     if chapter['name'] == 'Intro':
    #         item.resume_from = str(chapter['end']/1000 - 1)
    #     elif chapter['name'] == 'Credits':
    #         item.play_next = {'time': chapter['start']/1000}

    return item
예제 #6
0
def check_alerts():
    alerts = userdata.get('alerts', [])
    if not alerts: return

    for game in Game.select().where(Game.id << alerts):
        if game.state == Game.LIVE:
            alerts.remove(game.id)

            _to_start = game.start - arrow.utcnow().timestamp

            if settings.getInt('alert_when') == Alert.STREAM_START:
                message = _.STREAM_STARTED
            elif settings.getInt('alert_when') == Alert.KICK_OFF and _to_start > 0 and _to_start <= SERVICE_TIME:
                message = _.KICKOFF
            else:
                continue

            if settings.getInt('alert_type') == Alert.NOTIFICATION:
                gui.notification(message, heading=game.title, time=5000, icon=game.image)

            elif gui.yes_no(message, heading=game.title, yeslabel=_.WATCH, nolabel=_.CLOSE):
                _get_play_item(game, Game.FULL, play_type=settings.getEnum('live_play_type', PLAY_FROM_TYPES, default=PLAY_FROM_ASK)).play()

        elif game.state != Game.UPCOMING:
            alerts.remove(game.id)

    userdata.set('alerts', alerts)
예제 #7
0
def play(asset, play_type=PLAY_FROM_LIVE, **kwargs):
    play_type = int(play_type)

    from_start = False
    if play_type == PLAY_FROM_START or (
            play_type == PLAY_FROM_ASK
            and not gui.yes_no(_.PLAY_FROM,
                               yeslabel=_.PLAY_FROM_LIVE,
                               nolabel=_.PLAY_FROM_START)):
        from_start = True

    stream = api.play(asset, True)

    item = plugin.Item(
        path=stream['url'],
        inputstream=inputstream.Widevine(
            license_key=stream['license']['@uri']),
        headers=HEADERS,
    )

    drm_data = stream['license'].get('drmData')
    if drm_data:
        item.headers['x-axdrm-message'] = drm_data

    if from_start:
        item.properties['ResumeTime'] = '1'
        item.properties['TotalTime'] = '1'

    if kwargs.get(ROUTE_LIVE_TAG):
        item.inputstream.properties['manifest_update_parameter'] = 'full'

    return item
예제 #8
0
def service():
    alerts = userdata.get('alerts', [])
    if not alerts:
        return

    now = arrow.now()
    notify = []
    _alerts = []

    for id in alerts:
        asset = api.asset(id)
        if 'broadcastStartTime' not in asset:
            continue

        start = arrow.get(asset['broadcastStartTime'])

        if now > start and (now - start).total_seconds() <= 60 * 10:
            notify.append(asset)
        elif now < start:
            _alerts.append(id)

    userdata.set('alerts', _alerts)

    for asset in notify:
        if not gui.yes_no(_(_.EVENT_STARTED, event=asset['title']),
                          yeslabel=_.WATCH,
                          nolabel=_.CLOSE):
            continue

        with signals.throwable():
            play(asset['id'])
예제 #9
0
def service():
    api.refresh_token()
    alerts = userdata.get('alerts', [])
    if not alerts:
        return

    now = arrow.now()
    notify = []
    _alerts = []

    for id in alerts:
        entity = api.entitiy(id)
        if not entity:
            continue

        start = arrow.get(entity.get('startTime'))

        if now > start and (now - start).total_seconds() <= 60 * 10:
            notify.append(entity)
        elif now < start:
            _alerts.append(id)

    userdata.set('alerts', _alerts)

    for entity in notify:
        if not gui.yes_no(_(_.EVENT_STARTED, event=entity['name']),
                          yeslabel=_.WATCH,
                          nolabel=_.CLOSE):
            continue

        with signals.throwable():
            play(id=entity['id'],
                 play_type=settings.getEnum('live_play_type',
                                            LIVE_PLAY_TYPES,
                                            default=FROM_CHOOSE))
예제 #10
0
def service():
    alerts = userdata.get('alerts', [])
    if not alerts:
        return

    data = api.live_matches()
    if not data['live']:
        return

    notify = []

    for row in data['live']:
        if row['mid'] in alerts:
            alerts.remove(row['mid'])
            notify.append(row)

    userdata.set('alerts', alerts)

    for row in notify:
        if not gui.yes_no(_(_.MATCH_STARTED, match=row['subtitle']),
                          yeslabel=_.WATCH,
                          nolabel=_.CLOSE):
            continue

        with signals.throwable():
            sources = row['stream']['video_sources']
            priority = sources[0]['priority']

            item = _play_live(match_id=row['mid'], priority=1)
            item.play()
예제 #11
0
def logout(**kwargs):
    if not gui.yes_no(_.LOGOUT_YES_NO):
        return

    api.logout()
    mem_cache.empty()
    gui.refresh()
예제 #12
0
        def _interact_thread():
            if gui.yes_no(news['message'], news.get('heading', _.NEWS_HEADING)):
                addon = get_addon(news['addon_id'], install=True)
                if not addon:
                    return

                url = router.url_for('', _addon_id=news['addon_id'])
                xbmc.executebuiltin('ActivateWindow(Videos,{})'.format(url))
예제 #13
0
def install_service(**kwargs):
    with gui.progress(_.INSTALL_SERVICE, percent=100) as progress:
        restart_required = gpio.install()

    if restart_required and gui.yes_no(_.RESTART_REQUIRED):
        plugin.reboot()

    gui.refresh()
예제 #14
0
def delete_epg(epg_id, **kwargs):
    if not gui.yes_no('Are you sure you want to delete this EPG?'):
        return

    epg_id = int(epg_id)
    epg = EPG.get_by_id(epg_id)
    epg.delete_instance()

    gui.refresh()
예제 #15
0
def logout(**kwargs):
    if not gui.yes_no(_.LOGOUT_YES_NO):
        return

    api.logout()
    userdata.delete('avatar')
    userdata.delete('profile')
    userdata.delete('profile_name')
    gui.refresh()
예제 #16
0
def delete_epg(epg_id, **kwargs):
    if not gui.yes_no(_.CONF_DELETE_EPG):
        return

    epg_id = int(epg_id)
    epg = EPG.get_by_id(epg_id)
    epg.delete_instance()

    gui.refresh()
예제 #17
0
def _add_profile(taken_names, taken_avatars):
    ## PROFILE AVATAR ##
    options = [plugin.Item(label=_(_.RANDOM_AVATAR, _bold=True)),]
    values  = ['_random',]
    avatars = {}
    unused  = []

    data = api.collection_by_slug('avatars', 'avatars')
    for container in data['containers']:
        if container['set']['contentClass'] == 'hidden':
            continue

        category = _get_text(container['set']['texts'], 'title', 'set')

        for row in container['set'].get('items', []):
            if row['images'][0]['url'] in taken_avatars:
                label = _(_.AVATAR_USED, label=category)
            else:
                label = category
                unused.append(row['avatarId'])

            options.append(plugin.Item(label=label, art={'thumb': row['images'][0]['url']}))
            values.append(row['avatarId'])
            avatars[row['avatarId']] = row['images'][0]['url']

    index = gui.select(_.SELECT_AVATAR, options=options, useDetails=True)
    if index < 0:
        return

    avatar = values[index]
    if avatar == '_random':
        avatar = random.choice(unused or avatars.keys())

    ## PROFLE KIDS ##
    kids = gui.yes_no(_.KIDS_PROFILE_INFO, heading=_.KIDS_PROFILE)

    ## PROFILE NAME ##
    name = ''
    while True:
        name = gui.input(_.PROFILE_NAME, default=name).strip()
        if not name:
            return

        elif name in taken_names:
            gui.notification(_(_.PROFILE_NAME_TAKEN, name=name))

        else:
            break

    profile = api.add_profile(name, kids=kids, avatar=avatar)
    profile['_avatar'] = avatars[avatar]

    if 'errors' in profile:
        raise PluginError(profile['errors'][0].get('description'))

    _set_profile(profile)
예제 #18
0
def delete_playlist(playlist_id, **kwargs):
    if not gui.yes_no('Are you sure you want to delete this playlist?'):
        return

    playlist_id = int(playlist_id)
    playlist = Playlist.get_by_id(playlist_id)
    playlist.delete_instance()
    Playlist.update(order = Playlist.order - 1).where(Playlist.order >= playlist.order).execute()

    gui.refresh()
예제 #19
0
def delete_playlist(playlist_id, **kwargs):
    if not gui.yes_no(_.CONF_DELETE_PLAYLIST):
        return

    playlist_id = int(playlist_id)
    playlist = Playlist.get_by_id(playlist_id)
    playlist.delete_instance()
    Playlist.update(order = Playlist.order - 1).where(Playlist.order >= playlist.order).execute()

    gui.refresh()
예제 #20
0
def play(slug, play_type=PLAY_FROM_LIVE, **kwargs):
    item = api.play(slug)

    if ROUTE_LIVE_TAG in kwargs and item.inputstream:
        item.inputstream.live = True

    play_type = int(play_type)
    if play_type == PLAY_FROM_LIVE or (play_type == PLAY_FROM_ASK and not gui.yes_no(_.PLAY_FROM, yeslabel=_.PLAY_FROM_LIVE, nolabel=_.PLAY_FROM_START)):
        item.resume_from = 1

    return item
예제 #21
0
def login(**kwargs):
    if config.has_device_link and gui.yes_no(
            _.LOGIN_WITH, yeslabel=_.DEVICE_LINK, nolabel=_.EMAIL_PASSWORD):
        result = _device_link()
    else:
        result = _email_password()

    if not result:
        return

    _select_profile()
    gui.refresh()
예제 #22
0
def reset_channel(slug, **kwargs):
    channel = Channel.get_by_id(slug)

    if channel.custom:
        if not gui.yes_no(_.CONF_DELETE_CHANNEL):
            return

        channel.delete_instance()

    Override.delete().where(Override.slug == channel.slug).execute()

    gui.refresh()
예제 #23
0
def _delete_profile(profiles):
    options = []
    for index, profile in enumerate(profiles):
        options.append(plugin.Item(label=profile['name'], art={'thumb': profile['iconImage']['url']}))

    index = gui.select(_.SELECT_DELETE_PROFILE, options=options, useDetails=True)
    if index < 0:
        return

    selected = profiles[index]
    if gui.yes_no(_.DELETE_PROFILE_INFO, heading=_(_.DELTE_PROFILE_HEADER, name=selected['name'])) and api.delete_profile(selected['id']):
        gui.notification(_.PROFILE_DELETED, heading=selected['name'], icon=selected['iconImage']['url'])
예제 #24
0
def reset_channel(slug, **kwargs):
    channel = Channel.get_by_id(slug)

    if channel.custom:
        if not gui.yes_no('Are you sure you want to delete this channel?'):
            return

        channel.delete_instance()

    Override.delete().where(Override.slug == channel.slug).execute()

    gui.refresh()
예제 #25
0
    def do_POST(self):
        url = self._get_url('POST')
        response = self._proxy_request('POST', url)

        if response.status_code in (406, ) and url == self._session.get(
                'license_url') and not xbmc.getCondVisibility(
                    'System.Platform.Android') and gui.yes_no(_.WV_FAILED):
            thread = threading.Thread(target=inputstream.install_widevine,
                                      kwargs={'reinstall': True})
            thread.start()

        self._output_response(response)
예제 #26
0
def new_epg(**kwargs):
    epg = EPG.user_create()
    if not epg:
        return

    if settings.getBool(
            'ask_to_add',
            True) and epg.source_type != EPG.TYPE_ADDON and gui.yes_no(
                _.ADD_PLAYLIST):
        Playlist.user_create()

    gui.refresh()
예제 #27
0
def login(**kwargs):
    if gui.yes_no(_.LOGIN_WITH,
                  yeslabel=_.DEVICE_LINK,
                  nolabel=_.EMAIL_PASSWORD):
        result = _device_link()
    else:
        result = _email_password()

    if not result:
        return

    gui.refresh()
예제 #28
0
def _get_play_item(game, game_type, play_type=PLAY_FROM_LIVE):
    play_type = int(play_type)
    item      = parse_game(game)
    is_live   = game.state == Game.LIVE

    item.inputstream = inputstream.HLS(live=is_live)

    if play_type == PLAY_FROM_START or (play_type == PLAY_FROM_ASK and not gui.yes_no(_.PLAY_FROM, yeslabel=_.PLAY_FROM_LIVE, nolabel=_.PLAY_FROM_START)):
        item.properties['ResumeTime'] = '1'
        item.properties['TotalTime']  = '1'
        if is_live and not item.inputstream.check():
            raise PluginError(_.HLS_REQUIRED)

    item.path = api.get_play_url(game, game_type)

    return item
예제 #29
0
    def toggle_enabled(self):
        if self.enabled:
            self.enabled = False
        else:
            pin_used = Button.select(
                Button.id).where(Button.id != self.id, Button.pin == self.pin,
                                 Button.enabled == True).exists()
            if pin_used:
                if not gui.yes_no(_.DISABLE_OTHER_BTN):
                    return False

                Button.update(enabled=False).where(
                    Button.pin == self.pin).execute()

            self.enabled = True

        return True
예제 #30
0
def _add_profile(taken_names, taken_avatars):
    ## PROFILE AVATAR ##
    options = [
        plugin.Item(label=_(_.RANDOM_AVATAR, _bold=True)),
    ]
    values = [
        '_random',
    ]
    unused = []

    for key in AVATARS:
        label = ''
        if key in taken_avatars:
            label = _(_.AVATAR_USED, label=label)
        else:
            unused.append(key)

        options.append(plugin.Item(label=label, art={'thumb': AVATARS[key]}))
        values.append(key)

    index = gui.select(_.SELECT_AVATAR, options=options, useDetails=True)
    if index < 0:
        return

    avatar = values[index]
    if avatar == '_random':
        avatar = random.choice(unused or AVATARS.keys())

    ## PROFLE KIDS ##
    kids = gui.yes_no(_.KIDS_PROFILE_INFO, heading=_.KIDS_PROFILE)

    ## PROFILE NAME ##
    name = ''
    while True:
        name = gui.input(_.PROFILE_NAME, default=name).strip()
        if not name:
            return

        elif name in taken_names:
            gui.notification(_(_.PROFILE_NAME_TAKEN, name=name))

        else:
            break

    profile = api.add_profile(name, kids, avatar)
    _set_profile(profile)