Exemplo n.º 1
0
def set_state(pin, state):
    if not INSTALLED:
        return

    log.debug('Set pin {} to {}'.format(pin, state))
    out_pin = gpiozero.Device.pin_factory.pin(int(pin))
    out_pin.output_with_state(int(state))
Exemplo n.º 2
0
    def _login(self, url, payload, params=None):
        data = self._session.post(url, data=payload, params=params).json()

        if 'errors' in data:
            try:
                msg = data['errors'][0]['code']
                if msg == 'Streamco.Login.VPNDetected':
                    msg = _.IP_ADDRESS_ERROR
            except:
                msg = ''

            raise APIError(_(_.LOGIN_ERROR, msg=msg))

        userdata.set('token', data['jwToken'])
        userdata.set('expires',
                     int(time.time() + (data['renew'] - data['now']) - 30))
        userdata.set('user_id', data['userId'])

        userdata.set('profile_id', data['profile']['id'])
        userdata.set('profile_name', data['profile']['name'])
        userdata.set('profile_icon', data['profile']['iconImage']['url'])
        userdata.set('profile_kids',
                     int(data['profile'].get('isKidsProfile', False)))

        self._set_authentication()

        try:
            log.debug('Token Data: {}'.format(
                json.dumps(jwt_data(userdata.get('token')))))
        except:
            pass
Exemplo n.º 3
0
    def _refresh_token(self, force=False):
        if not force and userdata.get('expires',
                                      0) > time() or not self.logged_in:
            return

        log.debug('Refreshing token')
        self._set_profile(userdata.get('profile_id'))
Exemplo n.º 4
0
            def process_attrib(attrib):
                if attrib not in e.attributes.keys():
                    return

                url = e.getAttribute(attrib)
                if '://' in url:
                    e.setAttribute(attrib, PROXY_PATH + url)
                else:
                    ## Fixed with https://github.com/xbmc/inputstream.adaptive/pull/606
                    base_url = get_parent_node(e, 'BaseURL')
                    if base_url and not base_url.firstChild.nodeValue.endswith(
                            '/'):
                        base_url.firstChild.nodeValue = base_url.firstChild.nodeValue + '/'
                        log.debug('Dash Fix: base_url / fixed')

                    # Fixed with https://github.com/xbmc/inputstream.adaptive/pull/668
                    parent_template = get_parent_node(e,
                                                      'SegmentTemplate',
                                                      levels=2)
                    if parent_template:
                        for key in parent_template.attributes.keys():
                            if key not in e.attributes.keys():
                                e.setAttribute(
                                    key, parent_template.getAttribute(key))

                        parent_template.parentNode.removeChild(parent_template)
                        log.debug('Dash Fix: Double SegmentTemplate removed')
Exemplo n.º 5
0
    def play_channel(self, channel_id):
        variables = {
            'deviceId': '',
            'assetId': channel_id,
            'channelId': channel_id,
            # 'playbackDevice': {
            #     'platform': 'Windows',
            #     'osVersion': '10',
            #     'drmType': 'WIDEVINE',
            #     'drmLevel': 'SW_SECURE_DECODE'
            # }
        }

        data = self._query_request(queries.START_LINEAR,
                                   variables)['data']['startLinearPlayback']

        if data['__typename'] == 'SubscriptionNeeded':
            raise APIError('{} Subscription Required'.format(
                data['subscriptions'][0]['title']))
        elif data['__typename'] == 'Geoblocked':
            raise APIError(_.GEO_ERROR)
        elif data['__typename'] != 'LinearPlaybackSources':
            raise APIError('Unkown error: {}'.format(data['__typename']))

        try:
            self._query_request(queries.STOP_LINEAR,
                                variables)['data']['stopLinearPlayback']
        except:
            log.debug('Stop Linear Failed')

        return data['playbackSource']['streamUri'], data['playbackSource'][
            'drmLicense']['licenseUri']
    def merged(cls):
        channel_updates = set()

        for override in Override.select(Override, Channel).join(
                Channel, on=(Channel.slug == Override.slug), attr='channel'):
            channel = override.channel

            for key in override.fields:
                if hasattr(channel, key):
                    setattr(channel, key, override.fields[key])
                else:
                    log.debug('Skipping unknown override key: {}'.format(key))

            channel.modified = True if not channel.custom else False
            channel.attribs.update(override.attribs)
            channel.properties.update(override.properties)
            channel_updates.add(channel)

        if not channel_updates:
            yield
            return

        with database.db.atomic() as transaction:
            try:
                Channel.bulk_update(channel_updates,
                                    fields=Channel._meta.fields)
                yield
                transaction.rollback()
            except Exception as e:
                transaction.rollback()
                raise
Exemplo n.º 7
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')
Exemplo n.º 8
0
def _parse_elements(elements, from_menu=False):
    entitlements = _get_entitlements()

    items = []
    for elem in elements:
        elem['locked'] = entitlements and elem['channelCode'] not in entitlements

        if elem['locked'] and settings.getBool('hide_locked'):
            continue

        if elem['type'] == 'movie':
            item = _parse_movie(elem)

        elif elem['type'] == 'episode':
            item = _parse_episode(elem, from_menu=from_menu)

        elif elem['type'] == 'show':
            item = _parse_show(elem)

        elif elem['type']  == 'series':
            log.debug('Series! You should no longer see this. Let me know if you do...')
            continue

        else:
            continue

        items.append(item)

    return items
Exemplo n.º 9
0
def episodes(series, season, **kwargs):
    series = api.series(series)
    folder = plugin.Folder(series['title'],
                           fanart=_get_image(series['images'], 'fanart'),
                           sort_methods=[
                               xbmcplugin.SORT_METHOD_EPISODE,
                               xbmcplugin.SORT_METHOD_UNSORTED,
                               xbmcplugin.SORT_METHOD_LABEL,
                               xbmcplugin.SORT_METHOD_DATEADDED
                           ])

    for row in series['seasons']:
        if int(row['seasonNumber']) != int(season):
            continue

        for video in row['videos']:
            if not video['seasonEpisode']:
                log.debug('Skipping info video item: {}'.format(
                    video['title']))
                continue

            item = _process_video(video)
            folder.add_items(item)

        break

    return folder
Exemplo n.º 10
0
    def _manifest_middleware(self, data):
        url = self._session.get('manifest_middleware')
        if not url:
            return data

        data_path = xbmc.translatePath('special://temp/proxy.manifest')
        with open(data_path, 'wb') as f:
            f.write(data.encode('utf8'))

        url = add_url_args(url,
                           _data_path=data_path,
                           _headers=json.dumps(self._headers))

        log.debug('PLUGIN MANIFEST MIDDLEWARE REQUEST: {}'.format(url))
        dirs, files = run_plugin(url, wait=True)
        if not files:
            raise Exception('No data returned from plugin')

        path = unquote_plus(files[0])
        split = path.split('|')
        data_path = split[0]

        if len(split) > 1:
            self._plugin_headers = dict(
                parse_qsl(u'{}'.format(split[1]), keep_blank_values=True))

        with open(data_path, 'rb') as f:
            data = f.read().decode('utf8')

        if not ADDON_DEV:
            remove_file(data_path)

        return data
Exemplo n.º 11
0
def start():
    log.debug('Shared Service: Started')

    player = Player()
    proxy = Proxy()

    try:
        proxy.start()
    except Exception as e:
        log.error('Failed to start proxy server')
        log.exception(e)

    ## Inital wait on boot
    monitor.waitForAbort(5)

    try:
        while not monitor.abortRequested():
            try: _check_news()
            except Exception as e: log.exception(e)

            try: _check_updates()
            except Exception as e: log.exception(e)

            if monitor.waitForAbort(5):
                break
    except KeyboardInterrupt:
        pass
    except Exception as e:
        log.exception(e)

    try: proxy.stop()
    except: pass

    log.debug('Shared Service: Stopped')
def _seek_file(f, index, truncate=True):
    cur_index = f.tell()
    if cur_index != index:
        log.debug('{} seeking from {} to {}'.format(f.name, cur_index, index))
        f.seek(index, os.SEEK_SET)
        if truncate:
            f.truncate()
Exemplo n.º 13
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
Exemplo n.º 14
0
    def device_login(self):
        device_id = self._device_id()

        payload = {
            'deviceId': device_id,
        }

        data = self._request_json(DEVICE_REGISTER,
                                  type='post',
                                  json=payload,
                                  refresh_token=False)
        code = data['userCode']

        log.debug('Device ID: {} | Device Code: {}'.format(device_id, code))

        login = DeviceLogin(device_id, code)

        try:
            yield login
        finally:
            login.stop()

        if login.result:
            token_data = login.token_data()
            self._parse_tokens(token_data['accessToken'],
                               token_data['idToken'])
Exemplo n.º 15
0
    def _get_url(self, method):
        url = self.path.lstrip('/').strip('\\')
        log.debug('{} IN: {}'.format(method, url))

        self._headers = {}
        for header in self.headers:
            if header.lower() not in REMOVE_IN_HEADERS:
                self._headers[header.lower()] = self.headers[header]

        length = int(self._headers.get('content-length', 0))
        self._post_data = self.rfile.read(length) if length else None

        self._session = PROXY_GLOBAL['session']

        try:
            proxy_data = json.loads(get_kodi_string('_slyguy_quality'))
            if self._session.get('session_id') != proxy_data['session_id']:
                self._session = {}

            self._session.update(proxy_data)
            set_kodi_string('_slyguy_quality', '')
        except:
            pass

        PROXY_GLOBAL['session'] = self._session

        url = self._session.get('path_subs', {}).get(url) or url

        if url.lower().startswith('plugin'):
            url = self._update_urls(url, self._plugin_request(url))

        return url
Exemplo n.º 16
0
def get_integrations():
    try:
        return Session().gz_json(INTEGRATIONS_URL)
    except Exception as e:
        log.debug('Failed to get integrations')
        log.exception(e)
        return {}
Exemplo n.º 17
0
 def _market_id(self):
     try:
         return self._session.get(MARKET_ID_URL, params={
             'apikey': 'web'
         }).json()['_id']
     except:
         log.debug('Failed to get market id')
         return '-1'
Exemplo n.º 18
0
    def _refresh_token(self, force=False):
        if not force and userdata.get('expires', 0) > time() or not self.logged_in:
            return

        log.debug('Refreshing token')

        data = self._session.get(API_URL+'identity/refresh/{}'.format(userdata.get('refresh_token'))).json()
        self._process_token(data)
Exemplo n.º 19
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)
Exemplo n.º 20
0
    def _plugin_request(self, url):
        log.debug('PLUGIN REQUEST: {}'.format(url))
        dirs, files = run_plugin(url, wait=True)
        if not files:
            raise Exception('No data returned from plugin')

        data = json.loads(unquote_plus(files[0]))
        self._headers.update(data.get('headers', {}))
        return data['url']
Exemplo n.º 21
0
    def _process_source(self, source, method_name, file_path):
        remove_file(file_path)

        path = source.path.strip()
        source_type = source.source_type
        archive_type = source.archive_type

        if source_type == Source.TYPE_ADDON:
            addon_id = path
            addon, data = merge_info(addon_id, self.integrations, merging=True)

            if method_name not in data:
                raise Error('{} could not be found for {}'.format(
                    method_name, addon_id))

            template_tags = {
                '$ID': addon_id,
                '$FILE': file_path,
                '$IP': xbmc.getIPAddress(),
            }

            path = data[method_name]
            for tag in template_tags:
                path = path.replace(tag, template_tags[tag])

            path = path.strip()
            if path.lower().startswith('plugin'):
                self._call_addon_method(path)
                return

            if path.lower().startswith('http'):
                source_type = Source.TYPE_URL
            else:
                source_type = Source.TYPE_FILE

            archive_extensions = {
                '.gz': Source.ARCHIVE_GZIP,
                '.xz': Source.ARCHIVE_XZ,
            }

            name, ext = os.path.splitext(path.lower())
            archive_type = archive_extensions.get(ext, Source.ARCHIVE_NONE)

        if source_type == Source.TYPE_URL and path.lower().startswith('http'):
            log.debug('Downloading: {} > {}'.format(path, file_path))
            Session().chunked_dl(path, file_path)
        elif not xbmcvfs.exists(path):
            raise Error(_(_.LOCAL_PATH_MISSING, path=path))
        else:
            log.debug('Copying local file: {} > {}'.format(path, file_path))
            xbmcvfs.copy(path, file_path)

        if archive_type == Source.ARCHIVE_GZIP:
            gzip_extract(file_path)
        elif archive_type == Source.ARCHIVE_XZ:
            xz_extract(file_path)
Exemplo n.º 22
0
    def stop(self):
        if not self.started:
            return

        self._server.shutdown()
        self._server.server_close()
        self._server.socket.close()
        self._httpd_thread.join()
        self.started = False
        log.debug("Proxy: Stopped")
Exemplo n.º 23
0
    def _parse_m3u8(self, response):
        m3u8 = response.stream.content.decode('utf8')

        is_master = False
        if '#EXTM3U' not in m3u8:
            raise Exception('Invalid m3u8')

        if '#EXT-X-STREAM-INF' in m3u8:
            is_master = True
            file_name = 'master'
        else:
            file_name = 'sub'

        if ADDON_DEV:
            start = time.time()
            _m3u8 = m3u8.encode('utf8')
            _m3u8 = b"\n".join(
                [ll.rstrip() for ll in _m3u8.splitlines() if ll.strip()])
            with open(
                    xbmc.translatePath('special://temp/' + file_name +
                                       '-in.m3u8'), 'wb') as f:
                f.write(_m3u8)

        if is_master:
            m3u8 = self._manifest_middleware(m3u8)
            m3u8 = self._parse_m3u8_master(m3u8, response.url)
        else:
            m3u8 = self._parse_m3u8_sub(m3u8, response.url)

        base_url = urljoin(response.url, '/')

        m3u8 = re.sub(r'^/', r'{}'.format(base_url), m3u8, flags=re.I | re.M)
        m3u8 = re.sub(r'URI="/',
                      r'URI="{}'.format(base_url),
                      m3u8,
                      flags=re.I | re.M)

        ## Convert to proxy paths
        m3u8 = re.sub(r'(https?)://',
                      r'{}\1://'.format(PROXY_PATH),
                      m3u8,
                      flags=re.I)

        m3u8 = m3u8.encode('utf8')

        if ADDON_DEV:
            m3u8 = b"\n".join(
                [ll.rstrip() for ll in m3u8.splitlines() if ll.strip()])
            log.debug('Time taken: {}'.format(time.time() - start))
            with open(
                    xbmc.translatePath('special://temp/' + file_name +
                                       '-out.m3u8'), 'wb') as f:
                f.write(m3u8)

        response.stream.content = m3u8
Exemplo n.º 24
0
    def _middleware(self, url, response):
        if url not in self._session.get('middleware', {}):
            return

        middleware = self._session['middleware'][url].copy()

        _type = middleware.pop('type')
        if _type not in middlewares:
            return

        log.debug('MIDDLEWARE: {}'.format(_type))
        return middlewares[_type](response, **middleware)
    def stop(self):
        if not self.started:
            return

        self._server.shutdown()
        self._server.server_close()
        self._server.socket.close()
        self._httpd_thread.join()
        self.started = False
        log.debug("API: Stopped")
        userdata.set('_playlist_url', '')
        userdata.set('_epg_url', '')
Exemplo n.º 26
0
    def setup_buttons():
        log.debug('Setting up buttons')

        try:
            database.connect()

            Button.update(status=Button.Status.INACTIVE,
                          error=None).where(Button.enabled == True).execute()
            Button.update(status=Button.Status.DISABLED,
                          error=None).where(Button.enabled == False).execute()
            btns = list(Button.select().where(Button.enabled == True))

            buttons = []
            for btn in btns:
                if not btn.has_callbacks():
                    continue

                try:
                    button = gpiozero.Button(btn.pin,
                                             pull_up=btn.pull_up,
                                             bounce_time=btn.bounce_time
                                             or None,
                                             hold_time=btn.hold_time,
                                             hold_repeat=btn.hold_repeat)

                    if btn.when_pressed:
                        button.when_pressed = lambda function=btn.when_pressed: callback(
                            function)

                    if btn.when_released:
                        button.when_released = lambda function=btn.when_released: callback(
                            function)

                    if btn.when_held:
                        button.when_held = lambda function=btn.when_held: callback(
                            function)
                except Exception as e:
                    log.exception(e)
                    btn.status = Button.Status.ERROR
                    btn.error = e
                else:
                    btn.status = Button.Status.ACTIVE
                    buttons.append(button)

                btn.save()

            return buttons
        except Exception as e:
            log.debug(e)
            return []
        finally:
            database.close()
Exemplo n.º 27
0
    def _refresh_token(self, force=False):
        if not force and userdata.get('expires',
                                      0) > time() or not self.logged_in:
            return

        log.debug('Refreshing token')

        payload = {
            'platformId': 'android',
            'regsource': '7plus',
            'refreshToken': userdata.get('refresh_token'),
        }

        self._oauth_token(payload)
Exemplo n.º 28
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
Exemplo n.º 29
0
    def _parse_m3u8_sub(self, m3u8, master_url):
        lines = []

        for line in m3u8.splitlines():
            if not line.startswith('#') and '/beacon?' in line.lower():
                parse = urlparse(line)
                params = dict(parse_qsl(parse.query))
                for key in params:
                    if key.lower() == 'redirect_path':
                        line = params[key]
                        log.debug('M3U8 Fix: Beacon removed')

            lines.append(line)

        return '\n'.join(lines)
Exemplo n.º 30
0
    def _refresh_token(self, force=False):
        if not force and userdata.get('expires',
                                      0) > time() or not self.logged_in:
            return

        log.debug('Refreshing token')

        payload = {
            'client_id': CLIENT_ID,
            'refresh_token': userdata.get('refresh_token'),
            'grant_type': 'refresh_token',
            'scope': 'openid profile email offline_access',
        }

        self._oauth_token(payload)