예제 #1
0
    def display(self):
        handle = _handle()
        items = [i for i in self.items if i]

        if not items and self.no_items_label:
            items.append(
                Item(
                    label=_(self.no_items_label, _label=True),
                    is_folder=False,
                ))

        for item in items:
            item.art['thumb'] = item.art.get('thumb') or self.thumb
            item.art['fanart'] = item.art.get('fanart') or self.fanart

            li = item.get_li()
            xbmcplugin.addDirectoryItem(handle, item.path, li, item.is_folder)

        if self.content: xbmcplugin.setContent(handle, self.content)
        if self.title: xbmcplugin.setPluginCategory(handle, self.title)

        for sort_method in self.sort_methods:
            xbmcplugin.addSortMethod(handle, sort_method)

        xbmcplugin.endOfDirectory(handle,
                                  succeeded=True,
                                  updateListing=self.updateListing,
                                  cacheToDisc=self.cacheToDisc)
예제 #2
0
def _error(e):
    try:
        error = str(e)
    except:
        error = e.message.encode('utf-8')

    if not hasattr(e, 'heading') or not e.heading:
        e.heading = _(_.PLUGIN_ERROR, addon=ADDON_NAME)

    log.error(error)
    _close()

    gui.ok(error, heading=e.heading)
    resolve()
예제 #3
0
def exception(heading=None):
    if not heading:
        heading = _(_.PLUGIN_EXCEPTION, addon=ADDON_NAME)

    exc_type, exc_value, exc_traceback = sys.exc_info()

    tb = []
    for trace in reversed(traceback.extract_tb(exc_traceback)):
        if ADDON_ID in trace[0]:
            trace = list(trace)
            trace[0] = trace[0].split(ADDON_ID)[1]
            tb.append(trace)

    error = '{}\n{}'.format(
        ''.join(traceback.format_exception_only(exc_type, exc_value)),
        ''.join(traceback.format_list(tb)))

    text(error, heading=heading)
예제 #4
0
def parse_url(url):
    if url.startswith('?'):
        params = dict(parse_qsl(url.lstrip('?'), keep_blank_values=True))
        for key in params:
            params[key] = unquote(params[key])

        _url = params.pop('_', '')
    else:
        params = {}
        _url = url

    params['_url'] = url

    function = _routes.get(_url)

    if not function:
        raise RouterError(_(_.ROUTER_NO_FUNCTION, raw_url=url,
                            parsed_url=_url))

    log.debug('Router Parsed: \'{0}\' => {1} {2}'.format(
        url, function.__name__, params))

    return function, params
예제 #5
0
def _download(url, dst, dst_path, arch, md5=None):
    filename = url.split('/')[-1]
    tmp = ADDON_PROFILE + "tmp" + os.sep + "widevine"
    downloaded = 0

    if os.path.exists(dst_path):
        if md5 and md5sum(dst_path) == md5:
            log.debug('MD5 of local file {} same. Skipping download'.format(
                filename))
            return True
        elif not gui.yes_no(_.NEW_IA_VERSION):
            return False
        else:
            if os.path.exists(dst_path):
                os.remove(dst_path)

    from .session import Session

    with gui.progress(_(_.IA_DOWNLOADING_FILE, url=filename),
                      heading=_.IA_WIDEVINE_DRM) as progress:
        resp = Session().get(url, stream=True)
        if resp.status_code != 200:
            raise InputStreamError(
                _(_.ERROR_DOWNLOADING_FILE, filename=filename))

        total_length = float(resp.headers.get('content-length', 1))

        with open(tmp, 'wb') as f:
            for chunk in resp.iter_content(chunk_size=SESSION_CHUNKSIZE):
                f.write(chunk)
                downloaded += len(chunk)
                downloadperc = int(downloaded) * 100
                downloadperc2 = int(downloadperc) // int(total_length)
                percent = int(downloadperc2)

                if progress.iscanceled():
                    progress.close()
                    resp.close()

                progress.update(percent)

        if os.path.isfile(tmp):
            if 'arm' in arch:
                with open(tmp, "rb") as encoded_file:
                    decoded_string = base64.b64decode(encoded_file.read())

                with open(dst_path, "wb") as decoded_file:
                    decoded_file.write(decoded_string)
            else:
                with ZipFile(tmp, 'r') as zipObj:
                    zipObj.extractall(ADDON_PROFILE + "tmp" + os.sep)

                if os.path.isfile(ADDON_PROFILE + "tmp" + os.sep + dst):
                    shutil.copy(ADDON_PROFILE + "tmp" + os.sep + dst, dst_path)

    for file in glob.glob(ADDON_PROFILE + "tmp" + os.sep + "*"):
        os.remove(file)

    if progress.iscanceled():
        return False

    checksum = md5sum(dst_path)
    if checksum != md5:
        if os.path.exists(dst_path):
            os.remove(dst_path)

        raise InputStreamError(
            _(_.MD5_MISMATCH,
              filename=filename,
              local_md5=checksum,
              remote_md5=md5))

    return True
예제 #6
0
def install_widevine(reinstall=False):
    ia_addon = get_ia_addon(required=True)
    system, arch = _get_system_arch()
    kodi_version = get_kodi_version()

    if kodi_version < 18:
        raise InputStreamError(_(_.IA_KODI18_REQUIRED, system=system))

    elif system == 'Android':
        return True

    elif system == 'UWP':
        raise InputStreamError(_.IA_UWP_ERROR)

    elif 'aarch64' in arch or 'arm64' in arch:
        raise InputStreamError(_.IA_AARCH64_ERROR)

    last_check = int(ia_addon.getSetting('_last_check') or 0)
    ver_slug = system + arch + str(kodi_version) + ia_addon.getAddonInfo(
        'version')

    if ver_slug != ia_addon.getSetting(IA_VERSION_KEY):
        reinstall = True

    if not reinstall and time.time() - last_check < 86400:
        return True

    ia_addon.setSetting(IA_VERSION_KEY, '')
    ia_addon.setSetting('_last_check', str(int(time.time())))

    r = load_file(file="settings.json", isJSON=True)

    widevine = r['widevine']['widevine']
    wv_platform = widevine['platforms'].get(system + arch, None)

    if not wv_platform:
        raise InputStreamError(
            _(_.IA_NOT_SUPPORTED,
              system=system,
              arch=arch,
              kodi_version=kodi_version))

    decryptpath = xbmc.translatePath(ia_addon.getSetting('DECRYPTERPATH'))

    if sys.version_info < (3, 0):
        decryptpath = decryptpath.decode("utf-8")

    if 'arm' in arch:
        url = wv_platform['zip']
    else:
        url = widevine['base_url'] + wv_platform['zip']

    wv_path = os.path.join(decryptpath, wv_platform['dst'])

    if not os.path.isdir(decryptpath):
        os.makedirs(decryptpath)

    if not os.path.isdir(ADDON_PROFILE + "tmp"):
        os.makedirs(ADDON_PROFILE + "tmp")

    if not _download(url, wv_platform['dst'], wv_path, arch,
                     wv_platform['md5']):
        return False

    ia_addon.setSetting(IA_VERSION_KEY, ver_slug)

    if reinstall:
        gui.ok(_.IA_WV_INSTALL_OK)

    return True
예제 #7
0
def url_for_func(func, **kwargs):
    for url in _routes:
        if _routes[url].__name__ == func.__name__:
            return build_url(url, **kwargs)

    raise RouterError(_(_.ROUTER_NO_URL, function_name=func.__name__))