def _media_cache_path(cls):
     _path = os.path.join(Addon.cache_path, cls.mediaType)
     if not os.path.exists(_path):
         os.makedirs(_path)
         if not os.path.exists(_path):
             raise Error("Unable to create cache directory %s" % _path, 30322)
     cls.media_cache_path = _path
Exemplo n.º 2
0
    def player(self, subtitle=None, quality=None, **params):
        log("(Main) Creating player options")
        if settings.addon.handle > -1:
            xbmcplugin.endOfDirectory(settings.addon.handle, True, False, False)

        item = self.getSelectedItem()

        free_space = self._calculate_free_space()
        if not quality:
            waring = []
            for _q in self.mediaSettings.qualities:
                if params.get(_q):
                    if params['%ssize' %_q] > free_space:
                        if _q == '3D' and self.mediaSettings.play3d == 1 and not Dialog().yesno(line2=30011, lineStr1=' ', headingStr=item['info']['title']):
                            continue
                        quality = _q
                        break
                    waring = waring+[_q]

            if waring:
                if not quality:
                    raise Notify('There is not enough free space in %s' %self.mediaSettings.download_path, 30323, level=NOTIFYLEVEL.ERROR)

                if len(waring) > 1:
                    notify(message=__addon__.getLocalizedString(30325) %(", ".join(waring), waring.pop()), level=NOTIFYLEVEL.WARNING)
                else:
                    notify(message=__addon__.getLocalizedString(30326) %waring[0], level=NOTIFYLEVEL.WARNING)
                log('(Main) There must be a minimum of %s to play. %s available in %s' %(shortenBytes(params['%ssize' %quality]), shortenBytes(free_space), self.mediaSettings.download_path), LOGLEVEL.NOTICE)

        elif not params.get(quality):
                raise Error('%s quality was not found' %quality, 30023)
        elif params['%ssize' %quality] < free_space:
                raise Notify('There is not enough free space in %s' %self.mediaSettings.download_path, 30323, level=NOTIFYLEVEL.ERROR)

        TorrentPlayer().playTorrentFile(self.mediaSettings, build_magnetFromMeta(params[quality], "quality %s" %quality), item, subtitle)
Exemplo n.º 3
0
    def _download_path(cls):
        _path = xbmc.translatePath(
            __addon__.getSetting("%s_download_path" % cls.__name__))

        if _path:
            if _path.lower().startswith("smb://"):
                if not platform.system == "windows":
                    raise Notify(
                        "Downloading to an unmounted network share is not supported (%s)"
                        % _path, 30319, 0)
                _path.replace("smb:", "").replace("/", "\\")

            if not os.path.isdir(_path):
                raise Notify('Download path does not exist (%s)' % _path,
                             30310, 1)

            cls.download_path = _path.encode(addon.fsencoding)
        else:
            _path = os.path.join(addon.cache_path, cls.mediaType)
            if not os.path.exists(_path):
                os.makedirs(_path)
                if not os.path.exists(_path):
                    raise Error("Unable to create cache directory %s" % _path,
                                30322)
            cls.download_path = _path
Exemplo n.º 4
0
 def _cache_path(cls):
     _path = xbmc.translatePath("special://profile/addon_data/%s/cache" % cls.id)
     if not os.path.exists(_path):
         os.makedirs(_path)
         if not os.path.exists(_path):
             raise Error("Unable to create cache directory %s" % _path, 30322)
     cls.cache_path = _path.encode(cls.fsencoding)
Exemplo n.º 5
0
def ensure_exec(binary, binary_path):
    st = os.stat(binary_path)
    if not st.st_mode & stat.S_IEXEC:
        os.chmod(binary_path, st.st_mode | stat.S_IEXEC)
        st = os.stat(binary_path)
        if not st.st_mode & stat.S_IEXEC:
            raise Error(
                "Cannot make %s executable (%s)" % (binary, binary_path),
                30321)
Exemplo n.º 6
0
def run():
    try:
        log("(Main) Starting - Platform: %s %s" %(Platform.system, Platform.arch), LOGLEVEL.INFO)

        log("(Main) Platform: %s" %sys.platform)
        if hasattr(os, 'uname'):
            log("(Main) Uname: %s" %str(os.uname()))
        log("(Main) Environ: %s" %str(os.environ))

        if not Platform.system:
            raise Error("Unsupported OS", 30302)

        def _empty_dir(path):
            if os.path.isdir(path):
                for x in os.listdir(path):
                    if x in ['.', '..', 'movies', 'tvshows']:
                        continue
                    _path = os.path.join(path, x)
                    if os.path.isfile(_path):
                        os.remove(_path)
                    elif os.path.isdir(_path):
                        _empty_dir(_path)
                        os.rmdir(_path)

        params = dict(urlparse.parse_qsl(settings.addon.cur_uri))
        if not params.pop('cmd', None):
            if not settings.addon.version+"~1" == settings.addon.last_update_id:
                # Clear cache after update
                _empty_dir(settings.addon.cache_path)
                __addon__.setSetting("last_update_id", settings.addon.version+"~1")
            else:
                # Clean debris from the cache dir
                try:
                    for mediaType in ['movies', 'tvshows']:
                        if getattr(settings, mediaType).delete_files:
                            _empty_dir(os.path.join(settings.addon.cache_path, mediaType))
                except:
                    log_error()
                    sys.exc_clear()
            PopcornTime(**params)
        else:
            Cmd(**params)

    except (Error, HTTPError, ProxyError, TorrentError) as e:
        notify(e.messageID, level=NOTIFYLEVEL.ERROR)
        log_error()
    except Notify as e:
        notify(e.messageID, e.message, level=e.level)
        log("(Main) Notify: %s" %str(e), LOGLEVEL.NOTICE)
        sys.exc_clear()
    except Abort:
        log("(Main) Abort", LOGLEVEL.INFO)
        sys.exc_clear()
    except:
        notify(30308, level=NOTIFYLEVEL.ERROR)
        log_error()
Exemplo n.º 7
0
    def __call__(self, mediaType=None, endpoint=None, **params):
        self.mediaSettings = None
        if mediaType:
            self.mediaSettings = getattr(settings, mediaType)

        if not endpoint:
            endpoint = 'index'
        log("(Main) Calling %s. Params: %s" %(endpoint, str(params)))
        if not hasattr(self, endpoint):
            raise Error("'PopcornTime' class has no method '%s'" %endpoint)
        getattr(self, endpoint)(**params)
Exemplo n.º 8
0
    def playTorrentFile(self, mediaSettings, magnet, item, subtitleURL=None):
        with TorrentEngine(mediaSettings, magnet) as _TorrentEngine:
            # Loading
            log('(Torrent Player) Loading', LOGLEVEL.INFO)
            with closing(SafeDialogProgress()) as dialog:
                dialog.create(item['info']['title'])
                dialog.update(0, __addon__.getLocalizedString(30031), ' ', ' ')

                # Update progress dialog
                dialog.set_mentions((101+bool(subtitleURL)))

                def on_update(state, progressValue):
                    if state == Loader.PRELOADING:
                        dialog.update(progressValue, *self._get_status_lines(_TorrentEngine.status()))
                    elif state == Loader.CHECKING_DATA:
                        dialog.update(progressValue, __addon__.getLocalizedString(30037), ' ', ' ')
                    elif state == Loader.WAITING_FOR_PLAY_FILE:
                        dialog.update(progressValue, __addon__.getLocalizedString(30016), ' ', ' ')
                    elif state == Loader.DOWNLOADING_SUBTITLE:
                        dialog.update(progressValue, __addon__.getLocalizedString(30019), ' ', ' ')
                    elif state == Loader.FINISHED:
                        dialog.update(progressValue, __addon__.getLocalizedString(30020), ' ', ' ')

                with Loader(mediaSettings, _TorrentEngine, item, subtitleURL, on_update) as _loader:
                    while not _loader.is_done(0.100):
                        if xbmc.abortRequested or dialog.iscanceled():
                            raise Abort()

            # Starts the playback
            log('(Torrent Player) Start the playback', LOGLEVEL.INFO)
            self.play(Loader.url, xbmcItem(**item))

            # Waiting for playback to start
            log('(Torrent Player) Waiting for playback to start')
            for _ in xrange(300):
                if self.isPlaying():
                    break
                time.sleep(0.100)
            else:
                raise Error('Playback is terminated due to timeout', 30318)

            if Loader.subtitle:
                log('(Torrent Player) Add subtitle to the playback')
                self.setSubtitles(Loader.subtitle)

            with OverlayText() as self._overlay:
                while not xbmc.abortRequested and self.isPlaying():
                    if self._overlay.isShowing():
                        self._overlay.setText("\n".join(self._get_status_lines(_TorrentEngine.status())))
                        time.sleep(0.100)
                        continue
                    time.sleep(0.250)
                log('(Torrent Player) The playback has stop')
Exemplo n.º 9
0
def get_free_port(port=5001):
    """
    Check we can bind to localhost with a specified port
    On failer find a new TCP port that can be used for binding
    """
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(('127.0.0.1', port))
        s.close()
    except socket.error:
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.bind(('127.0.0.1', 0))
            port = s.getsockname()[1]
            s.close()
        except socket.error:
            raise Error("Can not find a TCP port to bind torrent2http", 30300)
    return port
Exemplo n.º 10
0
    try:
        reload(sys)
        sys.setdefaultencoding("utf-8")

        log(
            "(Main) Starting %s version %s build %s - Platform: %s %s" %
            (settings.addon.name, settings.addon.version, settings.BUILD,
             Platform.system, Platform.arch), LOGLEVEL.INFO)

        log("(Main) Platform: %s" % sys.platform)
        if hasattr(os, 'uname'):
            log("(Main) Uname: %s" % str(os.uname()))
        log("(Main) Environ: %s" % str(os.environ))

        if not Platform.system:
            raise Error("Unsupported OS", 30302)

        params = dict(urlparse.parse_qsl(settings.addon.cur_uri))
        if not params.get('cmd'):
            params = _fix(params)
            getattr(gui, params.pop('endpoint',
                                    'index'))(params.pop('mediaType',
                                                         '')).show(**params)
        else:
            getattr(gui.cmd, params.get('cmd'))()

    except (Error, HTTPError, ProxyError, TorrentError) as e:
        notify(e.messageID, level=NOTIFYLEVEL.ERROR)
        log_error()
    except Notify as e:
        notify(e.messageID, e.message, level=e.level)
Exemplo n.º 11
0
 def __init__(self, endpoint, **params):
     log("(Main) Calling %s. Params: %s" %(endpoint, str(params)), LOGLEVEL.INFO)
     if not hasattr(self, endpoint):
         raise Error("'Cmd' class has no method '%s'" %endpoint)
     getattr(self, endpoint)(**params)
Exemplo n.º 12
0
    def search(self, **params):
        log("(Main) Creating search view", LOGLEVEL.INFO)
        searchString = self.getSearchString()

        curPageNum = self.getCurPageNum()
        with closing(Cache("%s.search.query" %self.mediaSettings.mediaType, ttl=24 * 3600, last_changed=self.mediaSettings.lastchanged)) as cache:
            # Reset cache when we have different search string
            if cache and not searchString == cache['searchString']:
                log("(Main) Resetting view cache")
                cache.trunctate()

            # Reset page number if the user have cleaned the cache
            # or we have a different search string
            if not cache:
                curPageNum = 1

            if not cache or curPageNum > cache['curNumOfPages']:
                log("(Main) Reading item cache")
                items = {}
                pages = 0

                with closing(SafeDialogProgress()) as dialog:
                    dialog.create(__addon__.getLocalizedString(30028))
                    dialog.update(0, __addon__.getLocalizedString(30007), ' ', ' ')

                    _time = time.time()
                    # Getting item list
                    log("(Main) Getting item list")
                    with closing(media.List(self.mediaSettings, 'search', *(searchString, curPageNum,), **params)) as medialist:
                        while not medialist.is_done(0.100):
                            if xbmc.abortRequested or dialog.iscanceled():
                                raise Abort()
                        res = medialist.get_data()
                        if not res:
                            raise Notify("No search result", 30327, NOTIFYLEVEL.INFO)
                        items = res['items']
                        pages = res['pages']

                    # Update progress dialog
                    dialog.set_mentions(len(items)+2)
                    dialog.update(1, __addon__.getLocalizedString(30018), ' ', ' ')

                    def on_data(progressValue, oldItem, newItem):
                            label = ["%s %s" %(__addon__.getLocalizedString(30034), oldItem["label"])]
                            if newItem.get("label") and not oldItem["label"] == newItem["label"]:
                                label = label+["%s %s" %(__addon__.getLocalizedString(30035), newItem["label"])]
                            if newItem.get("stream_info", {}).get("subtitle", {}).get("language"):
                                label = label+["%s %s" %(__addon__.getLocalizedString(30012), isoToLang(newItem["stream_info"]["subtitle"]["language"]))]
                            while len(label) < 3:
                                label = label+[' ']
                            dialog.update(progressValue, *label)

                    # Getting media cache
                    log("(Main) Getting media info")
                    with closing(media.MediaCache(self.mediaSettings, on_data)) as mediadata:
                        [mediadata.submit(item) for item in items]
                        mediadata.start()
                        while not mediadata.is_done(0.100):
                            if xbmc.abortRequested or dialog.iscanceled():
                                raise Abort()
                        items = mediadata.get_data()
                        if not items:
                            raise Error("Did not receive any data", 30304)
                    log("(Main) Reading time: %s" %(time.time()-_time))

                    # Done
                    dialog.update(1, __addon__.getLocalizedString(30017), ' ', ' ')

                log("(Main) Updating view cache")
                cache.extendKey("items", items)
                cache.update({"curNumOfPages": curPageNum, "totalPages": pages, "searchString": searchString})
            pageCache = cache.copy()

        log("(Main) Adding items")
        self.addItems(self.mediaSettings.mediaType, pageCache["items"], 'player', False)

        # NOTE:
        # Add show more, but we stop at page 20... yes 20 pages sounds all right...
        # ... each page cache file can be between 2 and 3 mByt with 20 pages and will have an average of 1 mByt...
        # This can become substantial problem with movies and tv-shows pages
        if pageCache['curNumOfPages'] < pageCache['totalPages'] and pageCache['curNumOfPages'] < 21:
            self.addNextButton(**{'pageNum': pageCache['curNumOfPages']+1, 'searchString': searchString})

        update_listing = False
        if curPageNum > 1:
            update_listing = True

        self.finish(self.mediaSettings.mediaType, update_listing)
Exemplo n.º 13
0
def ensure_exec(binary_path):
    st = os.stat(binary_path)
    os.chmod(binary_path, st.st_mode | stat.S_IEXEC)
    st = os.stat(binary_path)
    if not st.st_mode & stat.S_IEXEC:
        raise Error("Cannot make torrent2http executable (%s)" % binary_path, 30321)
Exemplo n.º 14
0
def existBinary(binary_path):
    if not os.path.isfile(binary_path):
        raise Error("torrent2http binary was not found at path %s" % os.path.dirname(binary_path), 30320)
Exemplo n.º 15
0
    def _torrent_options(cls):
        binary = "torrent2http"
        if Platform.system == 'windows':
            binary = "torrent2http.exe"
        binary_path = os.path.join(__addon__.getAddonInfo('path'), 'resources',
                                   'bin',
                                   "%s_%s" % (Platform.system, Platform.arch),
                                   binary).encode(addon.fsencoding)

        if not os.path.isfile(binary_path):
            raise Error(
                "torrent2http binary (%s) was not found at path %s" %
                (os.path.dirname(binary_path), binary), 30320)

        if Platform.system == "android":
            log(
                "Trying to copy torrent2http to ext4, since the sdcard is noexec",
                LOGLEVEL.INFO)
            android_path = os.path.join(
                os.path.dirname(
                    os.path.dirname(
                        os.path.dirname(
                            xbmc.translatePath('special://xbmc')))), "files",
                __addon__.getAddonInfo('id'), binary).encode(addon.fsencoding)
            if not os.path.exists(os.path.dirname(android_path)):
                os.makedirs(os.path.dirname(android_path))
            if not os.path.exists(android_path) or int(
                    os.path.getmtime(android_path)) < int(
                        os.path.getmtime(binary_path)):
                shutil.copy2(binary_path, android_path)
            binary_path = android_path

        if not os.path.isfile(binary_path):
            raise Error(
                "torrent2http binary was not found at path %s" %
                os.path.dirname(binary_path), 30320)

        st = os.stat(binary_path)
        os.chmod(binary_path, st.st_mode | stat.S_IEXEC)
        if not st.st_mode & stat.S_IEXEC:
            raise Error(
                "Cannot make %s executable, ensure partition is in exec mode\n%s"
                % (binary, os.path.dirname(binary_path)), 30321)

        download_kbps = int(__addon__.getSetting("download_kbps"))
        if download_kbps <= 0:
            download_kbps = -1

        upload_kbps = int(__addon__.getSetting("upload_kbps"))
        if upload_kbps <= 0:
            upload_kbps = -1
        elif upload_kbps < 15:
            raise Notify(
                'Max Upload Rate must be above 15 Kilobytes per second.',
                30324, 1)
            __addon__.setSetting('upload_kbps', '15')
            upload_kbps = 15

        trackers = __addon__.getSetting('trackers')
        if trackers:
            trackers = ",".join(trackers.split(',') + PUBLIC_TRACKERS)
        else:
            trackers = ",".join(PUBLIC_TRACKERS)

        debug = __addon__.getSetting("debug")

        kwargs = {
            '--file-index':
            0,
            '--dl-path':
            cls.download_path,
            '--connections-limit':
            int(__addon__.getSetting('connections_limit')),
            '--dl-rate':
            download_kbps,
            '--ul-rate':
            upload_kbps,
            '--enable-dht':
            __addon__.getSetting('enable_dht'),
            '--enable-lsd':
            __addon__.getSetting('enable_lsd'),
            '--enable-natpmp':
            __addon__.getSetting('enable_natpmp'),
            '--enable-upnp':
            __addon__.getSetting('enable_upnp'),
            '--enable-scrape':
            __addon__.getSetting('enable_scrape'),
            '--encryption':
            int(__addon__.getSetting('encryption')),
            '--show-stats':
            debug,
            '--files-progress':
            debug,
            '--overall-progress':
            debug,
            '--pieces-progress':
            debug,
            '--listen-port':
            int(__addon__.getSetting('listen_port')),
            '--random-port':
            __addon__.getSetting('use_random_port'),
            '--keep-complete':
            str(cls.keep_complete).lower(),
            '--keep-incomplete':
            str(cls.keep_incomplete).lower(),
            '--keep-files':
            str(cls.keep_files).lower(),
            '--max-idle':
            300,
            '--no-sparse':
            'false',
            #'--resume-file':            None,
            '--user-agent':
            'torrent2http/1.0.1 libtorrent/1.0.3.0 kodipopcorntime/%s' %
            addon.version,
            #'--state-file':             None,
            '--enable-utp':
            __addon__.getSetting('enable_utp'),
            '--enable-tcp':
            __addon__.getSetting('enable_tcp'),
            '--debug-alerts':
            debug,
            '--torrent-connect-boost':
            int(__addon__.getSetting('torrent_connect_boost')),
            '--connection-speed':
            int(__addon__.getSetting('connection_speed')),
            '--peer-connect-timeout':
            int(__addon__.getSetting('peer_connect_timeout')),
            '--request-timeout':
            20,
            '--min-reconnect-time':
            int(__addon__.getSetting('min_reconnect_time')),
            '--max-failcount':
            int(__addon__.getSetting('max_failcount')),
            '--dht-routers':
            __addon__.getSetting('dht_routers') or None,
            '--trackers':
            trackers
        }

        args = [binary_path]
        for k, v in kwargs.iteritems():
            if v == 'true':
                args.append(k)
            elif v == 'false':
                args.append("%s=false" % k)
            elif v is not None:
                args.append(k)
                if isinstance(v, str):
                    args.append(v.decode('utf-8').encode(addon.fsencoding))
                else:
                    args.append(str(v))

        cls.torrent_options = args