Exemple #1
0
def _check_updates():
    _time = int(time())
    if _time < settings.getInt('_last_updates_check', 0) + UPDATES_CHECK_TIME:
        return

    settings.setInt('_last_updates_check', _time)

    new_md5 = session.get(ADDONS_MD5).text.split(' ')[0]
    if new_md5 == settings.get('addon_md5'):
        return

    settings.set('_addon_md5', new_md5)

    updates = []
    slyguy_addons = session.gz_json(ADDONS_URL)
    slyguy_installed = [x['addonid'] for x in kodi_rpc('Addons.GetAddons', {'installed': True, 'enabled': True})['addons'] if x['addonid'] in slyguy_addons]

    for addon_id in slyguy_installed:
        addon = get_addon(addon_id, install=False)
        if not addon:
            continue

        cur_version = addon.getAddonInfo('version')
        new_version = slyguy_addons[addon_id]['version']

        if LooseVersion(cur_version) < LooseVersion(new_version):
            updates.append([addon_id, cur_version, new_version])

    if not updates:
        return

    log.debug('Updating repos due to {} addon updates'.format(len(updates)))
    xbmc.executebuiltin('UpdateAddonRepos')
Exemple #2
0
    def _device_id(self):
        device_id = userdata.get('device_id')
        if device_id:
            return device_id

        device_id = settings.get('device_id')

        try:
            mac_address = uuid.getnode()
            if mac_address != uuid.getnode():
                mac_address = ''
        except:
            mac_address = ''

        system, arch = get_system_arch()
        device_id = device_id.format(username=userdata.get('username'),
                                     mac_address=mac_address,
                                     system=system).strip()

        if not device_id:
            device_id = uuid.uuid4()

        log.debug('Raw device id: {}'.format(device_id))
        device_id = hash_6(device_id, length=16)
        log.debug('Hashed device id: {}'.format(device_id))

        userdata.set('device_id', device_id)
        return device_id
Exemple #3
0
    def dma(self):
        self._refresh_token()

        ip = settings.get('region_ip')
        if not ip or ip == '0.0.0.0':
            ip = self._ip()

        params = {
            'ipaddress': ip,
            'dtp': 8,  #controls quality
            'syncBackVersion': '3.0',
            'mvpdId': 'AllAccess',
            'is60FPS': 'true',
            'did': self._device_id(),
        }

        data = self._session.get('/v3.0/androidphone/dma.json',
                                 params=self._params(params)).json()
        if not data['success']:
            log.warning(
                'Failed to get local CBS channel for IP address ({}). Server message: {}'
                .format(ip, data.get('message')))
            return None

        return data['dmas'][0]
Exemple #4
0
    def login(self, username, password, kickdevice=None):
        self.logout()

        raw_id = self._format_id(settings.get('device_id')).lower()
        device_id = hashlib.sha1(raw_id.encode('utf8')).hexdigest()

        log.debug('Raw device id: {}'.format(raw_id))
        log.debug('Hashed device id: {}'.format(device_id))

        hex_password = self._hex_password(password, device_id)

        params = {
            'appID': APP_ID,
            'format': 'json',
        }

        payload = {
            'username': username,
            'password': hex_password,
            'deviceId': device_id,
            'accountType': 'foxtel',
        }

        if kickdevice:
            payload['deviceToKick'] = kickdevice
            log.debug('Kicking device: {}'.format(kickdevice))

        data = self._session.post(
            '/auth.class.api.php/logon/{site_id}'.format(site_id=VOD_SITEID),
            data=payload,
            params=params).json()

        response = data['LogonResponse']
        devices = response.get('CurrentDevices', [])
        error = response.get('Error')
        success = response.get('Success')

        if error:
            if not devices or kickdevice:
                raise APIError(_(_.LOGIN_ERROR, msg=error.get('Message')))

            options = [d['Nickname'] for d in devices]
            index = gui.select(_.DEREGISTER_CHOOSE, options)
            if index < 0:
                raise APIError(_(_.LOGIN_ERROR, msg=error.get('Message')))

            kickdevice = devices[index]['DeviceID']

            return self.login(username, password, kickdevice=kickdevice)

        userdata.set('token', success['LoginToken'])
        userdata.set('deviceid', success['DeviceId'])
        userdata.set('entitlements', success.get('Entitlements', ''))

        if settings.getBool('save_password', False):
            userdata.set('pswd', password)
            log.debug('Password Saved')

        self.logged_in = True
Exemple #5
0
def callback():
    function = settings.get('function')

    if not settings.getBool('silent', False):
        gui.notification(_(_.RUN_FUNCTION, function=function))

    log.debug('Running function: {}'.format(function))
    xbmc.executebuiltin(function)
Exemple #6
0
    def __init__(self, output_path=None, forced=False):
        self.output_path = output_path or xbmc.translatePath(
            settings.get('output_dir', '').strip() or ADDON_PROFILE)
        if not os.path.exists(self.output_path):
            os.makedirs(self.output_path)

        self.forced = forced
        self.tmp_file = os.path.join(self.output_path, 'iptv_merge_tmp')
        self.integrations = get_integrations()
        self._playlist_epgs = []
Exemple #7
0
def iptv_is_setup():
    addon = get_addon(IPTV_SIMPLE_ID, required=False, install=False)
    if not addon:
        return False

    output_dir    = settings.get('output_dir', '').strip() or ADDON_PROFILE
    playlist_path = os.path.join(output_dir, PLAYLIST_FILE_NAME)
    epg_path      = os.path.join(output_dir, EPG_FILE_NAME)

    return addon.getSetting('m3uPathType') == '0' and addon.getSetting('epgPathType') == '0' \
            and addon.getSetting('m3uPath') == playlist_path and addon.getSetting('epgPath') == epg_path
Exemple #8
0
    def new_session(self):
        self.logged_in = False

        host = settings.get('business_host') if settings.getBool(
            'business_account', False) else DEFAULT_HOST
        if host != userdata.get('host', DEFAULT_HOST):
            userdata.delete('access_token')
            userdata.set('host', host)

        self._session = Session(HEADERS, base_url=API_URL.format(host))
        self._set_authentication()
Exemple #9
0
def play(channel_id, **kwargs):
    url = api.play(channel_id)

    license_path = plugin.url_for(license_request, channel_id=channel_id)

    return plugin.Item(
        path=url,
        inputstream=inputstream.Widevine(license_key=license_path,
                                         challenge='b{SSM}',
                                         response='B'),
        headers=HEADERS,
        proxy_data={'default_language': settings.get('default_language')},
    )
Exemple #10
0
    def _device_serial(self):
        def _format_id(string):
            try:
                mac_address = uuid.getnode()
                if mac_address != uuid.getnode():
                    mac_address = ''
            except:
                mac_address = ''

            system, arch = get_system_arch()
            return str(string.format(mac_address=mac_address, system=system).strip())

        return str(uuid.uuid3(uuid.UUID(UUID_NAMESPACE), _format_id(settings.get('device_id'))))
Exemple #11
0
    def new_session(self):
        self._session = Session(HEADERS)
        self._cache_key = self._region = settings.getEnum('region', REGIONS, default=US)

        if self._region in X_FORWARDS:
            self._session.headers.update({'x-forwarded-for': X_FORWARDS[self._region]})

        elif self._region == CUSTOM:
            region_ip = settings.get('region_ip', '0.0.0.0')
            if region_ip != '0.0.0.0':
                self._session.headers.update({'x-forwarded-for': region_ip})
                self._cache_key = region_ip

        self._cache_key += str(settings.getBool('show_epg', False))
    def __init__(self, output_path=None, forced=False):
        self.working_path = ADDON_PROFILE
        self.output_path = output_path or xbmc.translatePath(
            settings.get('output_dir', '').strip() or self.working_path)

        if not xbmcvfs.exists(self.working_path):
            xbmcvfs.mkdirs(self.working_path)

        if not xbmcvfs.exists(self.output_path):
            xbmcvfs.mkdirs(self.output_path)

        self.forced = forced
        self.tmp_file = os.path.join(self.working_path, 'iptv_merge_tmp')
        self._playlist_epgs = []
Exemple #13
0
def _check_news():
    _time = int(time())
    if _time < settings.getInt('_last_news_check', 0) + NEWS_CHECK_TIME:
        return

    settings.setInt('_last_news_check', _time)

    news = Session(timeout=15).gz_json(NEWS_URL)
    if not news:
        return

    if 'id' not in news or news['id'] == settings.get('_last_news_id'):
        return

    settings.set('_last_news_id', news['id'])
    settings.set('_news', json.dumps(news))
Exemple #14
0
    def _hex_password(self, password, device_id):
        nickname = self._format_id(settings.get('device_name'))
        log.debug('Device nickname: {}'.format(nickname))

        payload = {
            'deviceId': device_id,
            'nickName': nickname,
            'format': 'json',
            'appID': 'GO2',
            'accountType': 'foxtel',
            'plt': PLT_DEVICE,
        }

        secret = self._session.post(
            '/auth.class.api.php/prelogin/{site_id}'.format(
                site_id=VOD_SITEID),
            data=payload).json()['secret']
        log.debug('Pass Secret: {}{}'.format(secret[:5],
                                             'x' * len(secret[5:])))

        try:
            #python3
            iv = bytes.fromhex(AES_IV)
        except AttributeError:
            #python2
            iv = str(bytearray.fromhex(AES_IV))

        encrypter = pyaes.Encrypter(
            pyaes.AESModeOfOperationCBC(secret.encode('utf8'), iv))

        ciphertext = encrypter.feed(password)
        ciphertext += encrypter.feed()

        try:
            #python3
            hex_password = ciphertext.hex()
        except AttributeError:
            #python2
            hex_password = ciphertext.encode('hex')

        log.debug('Hex password: {}{}'.format(hex_password[:5],
                                              'x' * len(hex_password[5:])))

        return hex_password
Exemple #15
0
def _setup(check_only=False, reinstall=True, run_merge=True):
    addon = get_addon(IPTV_SIMPLE_ID,
                      required=not check_only,
                      install=not check_only)
    if not addon:
        return False

    output_dir = settings.get('output_dir', '').strip() or ADDON_PROFILE
    playlist_path = os.path.join(output_dir, PLAYLIST_FILE_NAME)
    epg_path = os.path.join(output_dir, EPG_FILE_NAME)

    is_setup = addon.getSetting('m3uPathType') == '0' and addon.getSetting('epgPathType') == '0' \
                and addon.getSetting('m3uPath') == playlist_path and addon.getSetting('epgPath') == epg_path

    if check_only:
        return is_setup

    elif is_setup and not reinstall:
        if run_merge:
            set_kodi_string('_iptv_merge_force_run', '1')

        return True

    ## IMPORT ANY CURRENT URL SOURCES ##
    cur_epg_url = addon.getSetting('epgUrl')
    cur_epg_type = addon.getSetting('epgPathType')
    if cur_epg_url:
        epg = EPG(source_type=EPG.TYPE_URL,
                  path=cur_epg_url,
                  enabled=cur_epg_type == '1')
        try:
            epg.save()
        except:
            pass

    cur_m3u_url = addon.getSetting('m3uUrl')
    cur_m3u_type = addon.getSetting('m3uPathType')
    start_chno = int(addon.getSetting('startNum') or 1)
    #user_agent = addon.getSetting('userAgent')
    if cur_m3u_url:
        playlist = Playlist(source_type=Playlist.TYPE_URL,
                            path=cur_m3u_url,
                            enabled=cur_m3u_type == '1')
        if start_chno != 1:
            playlist.use_start_chno = True
            playlist.start_chno = start_chno

        try:
            playlist.save()
        except:
            pass
    ################################

    addon.setSetting('epgPath', epg_path)
    addon.setSetting('m3uPath', playlist_path)
    addon.setSetting('epgUrl', '')
    addon.setSetting('m3uUrl', '')
    addon.setSetting('m3uPathType', '0')
    addon.setSetting('epgPathType', '0')

    set_kodi_setting('epg.futuredaystodisplay', 7)
    #  set_kodi_setting('epg.ignoredbforclient', True)
    set_kodi_setting('pvrmanager.syncchannelgroups', True)
    set_kodi_setting('pvrmanager.preselectplayingchannel', True)
    set_kodi_setting('pvrmanager.backendchannelorder', True)
    set_kodi_setting('pvrmanager.usebackendchannelnumbers', True)

    if run_merge:
        set_kodi_string('_iptv_merge_force_run', '1')

    gui.ok(_.SETUP_IPTV_COMPLETE)

    return True
Exemple #16
0
def _setup():
    addon = get_addon(IPTV_SIMPLE_ID, required=True, install=True)

    with gui.progress(_.SETTING_UP_IPTV) as progress:
        kodi_rpc('Addons.SetAddonEnabled', {'addonid': IPTV_SIMPLE_ID, 'enabled': False})

        output_dir = settings.get('output_dir', '').strip() or ADDON_PROFILE
        playlist_path = os.path.join(output_dir, PLAYLIST_FILE_NAME)
        epg_path = os.path.join(output_dir, EPG_FILE_NAME)

        ## IMPORT ANY CURRENT URL SOURCES ##
        cur_epg_url  = addon.getSetting('epgUrl')
        cur_epg_type = addon.getSetting('epgPathType')
        if cur_epg_url:
            epg = EPG(source_type=EPG.TYPE_URL, path=cur_epg_url, enabled=cur_epg_type == '1')
            try: epg.save()
            except: pass

        cur_m3u_url  = addon.getSetting('m3uUrl')
        cur_m3u_type = addon.getSetting('m3uPathType')
        start_chno = int(addon.getSetting('startNum') or 1)
        #user_agent = addon.getSetting('userAgent')
        if cur_m3u_url:
            playlist = Playlist(source_type=Playlist.TYPE_URL, path=cur_m3u_url, enabled=cur_m3u_type == '1')
            if start_chno != 1:
                playlist.use_start_chno = True
                playlist.start_chno = start_chno

            try: playlist.save()
            except: pass
        ################################

        addon.setSetting('epgPath', epg_path)
        addon.setSetting('m3uPath', playlist_path)
        addon.setSetting('epgUrl', '')
        addon.setSetting('m3uUrl', '')
        addon.setSetting('m3uPathType', '0')
        addon.setSetting('epgPathType', '0')

        monitor = xbmc.Monitor()

        progress.update(30)

        monitor.waitForAbort(2)
        kodi_rpc('Addons.SetAddonEnabled', {'addonid': IPTV_SIMPLE_ID, 'enabled': True})

        progress.update(60)

        monitor.waitForAbort(2)

        progress.update(100)

        set_kodi_setting('epg.futuredaystodisplay', 7)
      #  set_kodi_setting('epg.ignoredbforclient', True)
        set_kodi_setting('pvrmanager.syncchannelgroups', True)
        set_kodi_setting('pvrmanager.preselectplayingchannel', True)
        set_kodi_setting('pvrmanager.backendchannelorder', True)
        set_kodi_setting('pvrmanager.usebackendchannelnumbers', True)

    set_kodi_string('_iptv_merge_force_run', '1')

    gui.ok(_.SETUP_IPTV_COMPLETE)

    return True
Exemple #17
0
def _setup():
    addon = get_addon(IPTV_SIMPLE_ID, required=True, install=True)

    with gui.progress(_.SETTING_UP_IPTV) as progress:
        kodi_rpc('Addons.SetAddonEnabled', {'addonid': IPTV_SIMPLE_ID, 'enabled': False})

        output_dir    = xbmc.translatePath(settings.get('output_dir', '').strip() or ADDON_PROFILE)
        playlist_path = os.path.join(output_dir, PLAYLIST_FILE_NAME)
        epg_path      = os.path.join(output_dir, EPG_FILE_NAME)

        if not os.path.exists(playlist_path):
            with open(playlist_path, 'w') as f:
                f.write('''#EXTM3U
#EXTINF:-1 tvg-id="iptv_merge" tvg-chno="1000" tvg-logo="{}",{}
{}'''.format(ADDON_ICON, 'IPTV Merge: Click me to run a merge!', plugin.url_for(merge)))

        if not os.path.exists(epg_path):
            with open(epg_path, 'w') as f:
                f.write('''<?xml version="1.0" encoding="utf-8" ?><tv><channel id="iptv_merge"></channel></tv>''')

        ## IMPORT ANY CURRENT SOURCES ##
        cur_epg_url  = addon.getSetting('epgUrl')
        cur_epg_path = addon.getSetting('epgPath')
        cur_epg_type = addon.getSetting('epgPathType')

        if cur_epg_path != epg_path and os.path.exists(xbmc.translatePath(cur_epg_path)):
            epg = EPG(source_type=EPG.TYPE_FILE, path=cur_epg_path, enabled=cur_epg_type == '0')
            epg.auto_archive_type()
            try: epg.save()
            except: pass

        if cur_epg_url:
            epg = EPG(source_type=EPG.TYPE_URL, path=cur_epg_url, enabled=cur_epg_type == '1')
            epg.auto_archive_type()
            try: epg.save()
            except: pass

        cur_m3u_url  = addon.getSetting('m3uUrl')
        cur_m3u_path = addon.getSetting('m3uPath')
        cur_m3u_type = addon.getSetting('m3uPathType')
        start_chno   = int(addon.getSetting('startNum') or 1)
        #user_agent   = addon.getSetting('userAgent')

        if cur_m3u_path != playlist_path and os.path.exists(xbmc.translatePath(cur_m3u_path)):
            playlist = Playlist(source_type=Playlist.TYPE_FILE, path=cur_m3u_path, enabled=cur_m3u_type == '0')
            playlist.auto_archive_type()
            if start_chno != 1:
                playlist.use_start_chno = True
                playlist.start_chno = start_chno

            try: playlist.save()
            except: pass

        if cur_m3u_url:
            playlist = Playlist(source_type=Playlist.TYPE_URL, path=cur_m3u_url, enabled=cur_m3u_type == '1')
            playlist.auto_archive_type()
            if start_chno != 1:
                playlist.use_start_chno = True
                playlist.start_chno = start_chno

            try: playlist.save()
            except: pass
        #####

        addon.setSetting('epgPath', epg_path)
        addon.setSetting('m3uPath', playlist_path)
        addon.setSetting('epgUrl', '')
        addon.setSetting('m3uUrl', '')
        addon.setSetting('m3uPathType', '0')
        addon.setSetting('epgPathType', '0')

        monitor = xbmc.Monitor()

        progress.update(30)

        monitor.waitForAbort(2)
        kodi_rpc('Addons.SetAddonEnabled', {'addonid': IPTV_SIMPLE_ID, 'enabled': True})

        progress.update(60)

        monitor.waitForAbort(2)

        progress.update(100)

        set_kodi_setting('epg.futuredaystodisplay', 7)
      #  set_kodi_setting('epg.ignoredbforclient', True)
        set_kodi_setting('pvrmanager.syncchannelgroups', True)
        set_kodi_setting('pvrmanager.preselectplayingchannel', True)
        set_kodi_setting('pvrmanager.backendchannelorder', True)
        set_kodi_setting('pvrmanager.usebackendchannelnumbers', True)

    gui.ok(_.SETUP_IPTV_COMPLETE)

    return True
    def playlists(self, refresh=True):
        playlist_path = os.path.join(self.output_path, PLAYLIST_FILE_NAME)
        working_path = os.path.join(self.working_path, PLAYLIST_FILE_NAME)

        if not refresh and xbmcvfs.exists(playlist_path) and xbmcvfs.exists(
                working_path):
            return working_path

        start_time = time.time()
        database.connect()

        try:
            progress = gui.progressbg() if self.forced else None

            playlists = list(Playlist.select().where(
                Playlist.enabled == True).order_by(Playlist.order))
            Playlist.update({
                Playlist.results: []
            }).where(Playlist.enabled == False).execute()
            Channel.delete().where(
                Channel.custom == False,
                Channel.playlist.not_in(playlists)).execute()

            for count, playlist in enumerate(playlists):
                count += 1

                if progress:
                    progress.update(
                        int(count * (100 / len(playlists))),
                        'Merging Playlist ({}/{})'.format(
                            count, len(playlists)),
                        _(playlist.label, _bold=True))

                playlist_start = time.time()

                error = None
                try:
                    log.debug('Processing: {}'.format(playlist.path))

                    if playlist.source_type != Playlist.TYPE_CUSTOM:
                        self._process_source(playlist, METHOD_PLAYLIST,
                                             self.tmp_file)

                        with database.db.atomic() as transaction:
                            try:
                                added = self._process_playlist(
                                    playlist, self.tmp_file)
                            except:
                                transaction.rollback()
                                raise
                    else:
                        added = len(playlist.channels)
                except AddonError as e:
                    error = e
                except Error as e:
                    error = e
                    log.exception(e)
                except Exception as e:
                    error = e
                    log.exception(e)
                else:
                    playlist.results.insert(0, [
                        int(time.time()), Playlist.OK,
                        '{} Channels ({:.2f}s)'.format(
                            added,
                            time.time() - playlist_start)
                    ])
                    error = None

                if error:
                    result = [int(time.time()), Playlist.ERROR, str(error)]
                    if playlist.results and playlist.results[0][
                            1] == Playlist.ERROR:
                        playlist.results[0] = result
                    else:
                        playlist.results.insert(0, result)

                remove_file(self.tmp_file)

                playlist.results = playlist.results[:3]
                playlist.save()

            count = 0
            starting_ch_no = settings.getInt('start_ch_no', 1)

            with codecs.open(working_path, 'w', encoding='utf8') as outfile:
                outfile.write(u'#EXTM3U')

                group_order = settings.get('group_order')
                if group_order:
                    outfile.write(u'\n\n#EXTGRP:{}'.format(group_order))

                chno = starting_ch_no
                tv_groups = []
                for channel in Channel.playlist_list(radio=False):
                    if channel.chno is None:
                        channel.chno = chno
                    chno = channel.chno + 1

                    tv_groups.extend(channel.groups)

                    outfile.write(u'\n\n')
                    outfile.write(channel.get_lines())
                    count += 1

                chno = starting_ch_no
                for channel in Channel.playlist_list(radio=True):
                    if channel.chno is None:
                        channel.chno = chno
                    chno = channel.chno + 1

                    new_groups = []
                    for group in channel.groups:
                        count = 1
                        while group in tv_groups:
                            group = _(_.RADIO_GROUP, group=group)
                            if count > 1:
                                group = u'{} #{}'.format(group, count)
                            count += 1
                        new_groups.append(group)

                    channel.groups = new_groups

                    outfile.write(u'\n\n')
                    outfile.write(channel.get_lines())
                    count += 1

                if count == 0:
                    outfile.write(u'\n\n#EXTINF:-1,EMPTY PLAYLIST\nhttp')

            log.debug('Wrote {} Channels'.format(count))
            Playlist.after_merge()
            _safe_copy(working_path, playlist_path)
        finally:
            database.close()
            if progress: progress.close()
            remove_file(self.tmp_file)

        log.debug('Playlist Merge Time: {0:.2f}'.format(time.time() -
                                                        start_time))

        return working_path