示例#1
0
文件: stage.py 项目: freevo/kaa-candy
 def _start_backend(self):
     # spawn the backend process
     args = [ 'python', os.path.dirname(__file__) + '/backend/main.py', self.name, self.logfile ]
     self._candy_dirty = True
     self.server = subprocess.Popen(args, stdout=sys.stdout, stderr=sys.stderr)
     retry = 50
     if os.path.exists(kaa.tempfile(self.name)):
         os.unlink(kaa.tempfile(self.name))
     while True:
         try:
             self.ipc = kaa.rpc.connect(self.name)
             yield kaa.inprogress(self.ipc)
             break
         except Exception, e:
             retry -= 1
             if retry == 0:
                 raise e
             time.sleep(0.1)
示例#2
0
 def _update_series(self, id):
     info = self._db.query_one(type='series', tvdb=id)
     if info:
         signals['sync'].emit(info.get('name'))
     else:
         signals['sync'].emit()
     # download thetvdb information
     f = open(kaa.tempfile('thetvdb-%s.zip' % id), 'w')
     f.write((yield download(self.api + 'series/%s/all/en.zip' % id)))
     f.close()
     # load zip data
     z = zipfile.ZipFile(f.name)
     parent = None
     for name, data in (yield parse(z.open('en.xml')))[1]:
         if name == 'Series':
             objid = self._update_db('series', int(data.get('id')), name=data.get('SeriesName'), data=data)
             parent = ('series', objid)
         elif name == 'Episode':
             if not parent:
                 raise ValueError('Unexpected parse error: got Episode element before Series')
             self._update_db('episode', int(data.get('id')), name=data.get('EpisodeName'), parent=parent,
                 season=int(data.get('SeasonNumber')), episode=int(data.get('EpisodeNumber')),
                 data=data)
         else:
             log.error('unknown element: %s', name)
     self._db.commit()
     # load image information
     for name, data in (yield parse(z.open('banners.xml')))[1]:
         if name == 'Banner':
             self._update_db('banner', int(data.get('id')), btype=data.get('BannerType'),
                 data=data, parent=parent)
         else:
             log.error('unknown element: %s', name)
     self._db.commit()
     os.unlink(f.name)
     # download metadata images
     info = self._db.query_one(type='series', tvdb=id)
     if not info:
         yield None
     serie = Series(self, info)
     if serie.image and not os.path.isfile(serie.image):
         data = yield serie.get_all_images()[0].fetch()
         open(serie.image, 'w').write(data)
     if serie.poster and not os.path.isfile(serie.poster):
         data = yield serie.get_all_posters()[0].fetch()
         open(serie.poster, 'w').write(data)
     if serie.banner and not os.path.isfile(serie.banner):
         data = yield serie.get_all_banners()[0].fetch()
         open(serie.banner, 'w').write(data)
     for season in serie.seasons:
         if season.poster and season.get_all_posters() and not os.path.isfile(season.poster):
             data = yield season.get_all_posters()[0].fetch()
             open(season.poster, 'w').write(data)
         if season.banner and season.get_all_banners() and not os.path.isfile(season.banner):
             data = yield season.get_all_banners()[0].fetch()
             open(season.banner, 'w').write(data)
示例#3
0
文件: xmltv.py 项目: clones/kaa
def update(epg, xmltv_file=None):
    """
    Interface to source_xmltv.
    """
    if not xmltv_file and config.xmltv.grabber:
        log.info('grabbing listings using %s', config.xmltv.grabber)
        xmltv_file = kaa.tempfile('TV.xml')
        if config.xmltv.data_file:
            xmltv_file = config.xmltv.data_file
        log_file = kaa.tempfile('TV.xml.log')
        # using os.system is ugly because it blocks ... but we are inside a thread so it
        # seems to be ok.
        ec = os.system('%s --output %s --days %s >%s 2>%s' % \
                       (config.xmltv.grabber, xmltv_file, config.days, log_file, log_file))
        if not os.path.exists(xmltv_file) or ec:
            log.error('grabber failed, see %s', log_file)
            return
        if config.xmltv.sort:
            log.info('sorting listings')
            shutil.move(xmltv_file, xmltv_file + '.tmp')
            os.system('%s --output %s %s.tmp >>%s 2>>%s' % \
                      (config.xmltv.sort, xmltv_file, xmltv_file, log_file, log_file))
            os.unlink(xmltv_file + '.tmp')
            if not os.path.exists(xmltv_file):
                log.error('sorting failed, see %s', log_file)
                return
        else:
            log.info('not configured to use tv_sort, skipping')
    elif not xmltv_file:
        xmltv_file = config.xmltv.data_file
    # Now we have a xmltv file and need to parse it
    parser = XmltvParser()
    parser.add_channel = epg.add_channel
    parser.add_program = epg.add_program
    parser.parse(xmltv_file)
    return True
示例#4
0
文件: thumbnailer.py 项目: clones/kaa
def create(config_dir, scheduler=None):
    """
    Create thumbnail Unix socket and object
    """
    # create tmp dir and change directory to it
    tmpdir = kaa.tempfile('thumb')
    if not os.path.isdir(tmpdir):
        os.mkdir(tmpdir)
    os.chdir(tmpdir)
    try:
        return Thumbnailer(tmpdir, config_dir, scheduler)
    except IOError, e:
        log.error('thumbnail: %s' % e)
        time.sleep(0.1)
        sys.exit(0)
示例#5
0
 def _start_backend(self):
     # spawn the backend process
     args = [
         'python',
         os.path.dirname(__file__) + '/backend/main.py', self.name,
         self.logfile
     ]
     self._candy_dirty = True
     self.server = subprocess.Popen(args,
                                    stdout=sys.stdout,
                                    stderr=sys.stderr)
     retry = 50
     if os.path.exists(kaa.tempfile(self.name)):
         os.unlink(kaa.tempfile(self.name))
     while True:
         try:
             self.ipc = kaa.rpc.connect(self.name)
             yield kaa.inprogress(self.ipc)
             break
         except Exception, e:
             retry -= 1
             if retry == 0:
                 raise e
             time.sleep(0.1)
示例#6
0
def update(epg, xmltv_file=None):
    """
    Interface to source_xmltv.
    """
    if not xmltv_file and config.xmltv.grabber:
        log.info('grabbing listings using %s', config.xmltv.grabber)
        xmltv_file = kaa.tempfile('TV.xml')
        if config.xmltv.data_file:
            xmltv_file = config.xmltv.data_file
        log_file = kaa.tempfile('TV.xml.log')
        # using os.system is ugly because it blocks ... but we are inside a thread so it
        # seems to be ok.
        ec = os.system('%s --output %s --days %s >%s 2>%s' % \
                       (config.xmltv.grabber, xmltv_file, config.days, log_file, log_file))
        if not os.path.exists(xmltv_file) or ec:
            log.error('grabber failed, see %s', log_file)
            return
        if config.xmltv.sort:
            log.info('sorting listings')
            shutil.move(xmltv_file, xmltv_file + '.tmp')
            os.system('%s --output %s %s.tmp >>%s 2>>%s' % \
                      (config.xmltv.sort, xmltv_file, xmltv_file, log_file, log_file))
            os.unlink(xmltv_file + '.tmp')
            if not os.path.exists(xmltv_file):
                log.error('sorting failed, see %s', log_file)
                return
        else:
            log.info('not configured to use tv_sort, skipping')
    elif not xmltv_file:
        xmltv_file = config.xmltv.data_file
    # Now we have a xmltv file and need to parse it
    parser = XmltvParser()
    parser.add_channel = epg.add_channel
    parser.add_program = epg.add_program
    parser.parse(xmltv_file)
    return True
示例#7
0
def create(config_dir, scheduler=None):
    """
    Create thumbnail Unix socket and object
    """
    # create tmp dir and change directory to it
    tmpdir = kaa.tempfile('thumb')
    if not os.path.isdir(tmpdir):
        os.mkdir(tmpdir)
    os.chdir(tmpdir)
    try:
        return Thumbnailer(tmpdir, config_dir, scheduler)
    except IOError, e:
        log.error('thumbnail: %s' % e)
        time.sleep(0.1)
        sys.exit(0)
示例#8
0
文件: ibb.py 项目: clones/kaa
 def _create(self, sid, blocksize, stream):
     """
     Create the FIFO and return the kaa.Socket and the IBBSocket object.
     """
     # Make a kaa.Socket to kaa.Socket connection. One socket will be
     # given to the outside, the other one will be used to communicate
     # with the IBBSocket.
     filename = kaa.tempfile('ibb', unique=True)
     socket1 = kaa.net.tls.TLSSocket()
     wait = kaa.inprogress(socket1.signals['new-client'])
     socket2 = kaa.Socket()
     socket1.listen(filename)
     yield socket2.connect(filename)
     socket1 = yield wait
     socket1.sid = sid
     socket2.signals['closed'].connect(self._app_close, sid)
     yield socket1, IBBSocket(socket2, self.remote.iqset, sid, blocksize, stream)
示例#9
0
    def _get_api_zipfile(self, url):
        STAY_LOCAL = os.getenv('STAY_LOCAL', 0)
        tmpname = kaa.tempfile(hashlib.md5(kaa.py3_b(url, fs=True)).hexdigest() + '.zip')
        url = self._apiurl + url

        if STAY_LOCAL and os.path.exists(tmpname):
            status = 200
        else:
            # Try 3 times before giving up, unless it's a permanent error
            log.debug('fetching zip file %s', url)
            status, curl = yield download(url, tmpname, retry=3, resume=False)
        if status != 200:
            if os.path.exists(tmpname):
                os.unlink(tmpname)
            raise ProviderError('thetvdb gave status %d for %s' % (status, url))

        try:
            z = zipfile.ZipFile(tmpname)
        except zipfile.BadZipfile:
            os.unlink(tmpname)
            raise ProviderError('invalid zip file from thetvdb at %s' % url)

        yield z
示例#10
0
文件: thetvdb.py 项目: clones/kaa
 def _update_series(self, id):
     tmp = kaa.tempfile('thetvdb/%s' % id)
     if not os.path.isdir(tmp):
         os.mkdir(tmp)
         return
     f = open('%s/en.zip' % tmp, 'w')
     f.write((yield download(self.api + 'series/%s/all/en.zip' % id)))
     f.close()
     z = zipfile.ZipFile('%s/en.zip' % tmp)
     z.extract('en.xml', tmp)
     z.extract('banners.xml', tmp)
     os.unlink(tmp + '/en.zip')
     parent = None
     for name, data in (yield parse(open(tmp + '/en.xml')))[1]:
         if name == 'Series':
             s = self._update_db('series', int(data.get('id')), name=data.get('SeriesName'), data=data)
             parent = ('series', s)
         elif name == 'Episode':
             if not parent:
                 raise RuntimeError()
             self._update_db('episode', int(data.get('id')), name=data.get('EpisodeName'), parent=parent,
                 season=int(data.get('SeasonNumber')), episode=int(data.get('EpisodeNumber')),
                 data=data)
         else:
             log.error('unknown element: %s', name)
     self._db.commit()
     os.unlink(tmp + '/en.xml')
     for name, data in (yield parse(open(tmp + '/banners.xml')))[1]:
         if name == 'Banner':
             self._update_db('banner', int(data.get('id')), btype=data.get('BannerType'),
                 data=data, parent=parent)
         else:
             log.error('unknown element: %s', name)
     self._db.commit()
     os.unlink(tmp + '/banners.xml')
     os.rmdir(tmp)
示例#11
0
文件: player.py 项目: clones/kaa
    def play(self):
        """
        Start playback.
        """
        log.debug('mplayer start playback')

        # we know that self._mp_info has to be there or the object would
        # not be selected by the generic one. FIXME: verify that!
        assert(self._mp_info)

        # create mplayer object
        self._mplayer = ChildProcess(self._mp_cmd, gdb = log.getEffectiveLevel() == logging.DEBUG)

        # get argument and filter list
        args, filters = self._mplayer.args, self._mplayer.filters

        if 'x11' in self._mp_info['video_drivers']:
            args.append('-nomouseinput')

        #if 'outbuf' in self._mp_info['video_filters']:
        #    filters.append("outbuf=%s:yv12" % self._frame_shmkey)

        if self._properties['deinterlace'] == True or \
               (self._properties['deinterlace'] == 'auto' and \
                self._media.get('interlaced')):
            # add deinterlacer
            filters.append(config.mplayer.deinterlacer)


        if self._media.get('corrupt'):
            # File marked as corrupt. This happens for avi and mkv files
            # with no index. To make seeking work, add -idx
            args.append('-idx')
            
        # FIXME: self._filters_pre / add doesn't get included if no window.
        if self._window:
            self.configure_video()
        else:
            args.add(vo='null')

        self.configure_audio()

        # There is no way to make MPlayer ignore keys from the X11 window.  So
        # this hack makes a temp input file that maps all keys to a dummy (and
        # non-existent) command which causes MPlayer not to react to any key
        # presses, allowing us to implement our own handlers.  The temp file is
        # deleted once MPlayer has read it.
        tempfile = kaa.tempfile('popcorn/mplayer-input.conf')
        if not os.path.isfile(tempfile):
            keys = filter(lambda x: x not in string.whitespace, string.printable)
            keys = list(keys) + self._mp_info["keylist"]
            fd = open(tempfile, 'w')
            for key in keys:
                fd.write("%s noop\n" % key)
            fd.close()
        # only prevent input if the player is embedded
        if config.mplayer.embedded:
            args.add(input='conf=%s' % tempfile)

        # set properties subtitle filename and subtitle track
        if self._properties.get('subtitle-filename'):
            sub = self._properties.get('subtitle-filename')
            if os.path.splitext(sub)[1].lower() in ('.ifo', '.idx', '.sub'):
                args.add(vobsub=os.path.splitext(sub)[0],
                         vobsubid=self._properties.get('subtitle-track'))
            else:
                args.add(subfile=sub)
        elif self._properties.get('subtitle-track') != None:
            args.add(sid=self._properties.get('subtitle-track'))

        if self._properties.get('cache') == 'auto':
            if self._media.scheme == "dvd":
                args.add(cache=8192)
            if self._media.scheme == "vcd":
                args.add(cache=4096)
            if self._media.scheme == "dvb":
                args.add(cache=1024)
            if self._media.scheme == "http":
                args.add(cache=8192, cache_min=5)
            else:
                args.add(cache=5000)
        else:
            args.add(cache=self._properties.get('cache'))

        # connect to signals
        self._mplayer.signals['readline'].connect_weak(self._child_handle_line)

        # start playback
        self._mplayer.start(self._media).connect_weak(self._child_exited)
示例#12
0
文件: image.py 项目: freevo/kaa-candy
 def get_cachefile(self, url):
     """
     Return the cache filename for the given url
     """
     base = hashlib.md5(url).hexdigest() + os.path.splitext(url)[1]
     return kaa.tempfile('candy-images/' + base)
示例#13
0
def update(epg):
    """
    Interface to source_epgdata.
    """
    if not config.epgdata.pin:
        log.error('PIN for epgdata.com is missing in tvserver.conf')
        return False

    # create a tempdir as working area
    tempdir = kaa.tempfile('epgdata')
    if not os.path.isdir(tempdir):
        os.mkdir(tempdir)
    # and clear it if needed
    for i in glob.glob(os.path.join(tempdir, '*')):
        os.remove(i)

    # temp file
    tmpfile = os.path.join(tempdir, 'temp.zip')
    # logfile
    logfile = kaa.tempfile('epgdata.log')

    # empty list for the xml docs
    docs = []
    # count of the nodes that have to be parsed
    nodes = 0

    # create download adresse for meta data
    address = 'http://www.epgdata.com/index.php'
    address += '?action=sendInclude&iLang=de&iOEM=xml&iCountry=de'
    address += '&pin=%s' % config.epgdata.pin
    address += '&dataType=xml'

    # remove old file if needed
    try:
        os.remove(tmpfile)
    except OSError:
        pass
    # download the meta data file
    log.info('Downloading meta data')
    # FIXME: don't rely on wget
    exit = os.system('wget -N -O %s "%s" >>%s 2>>%s' %
                     (tmpfile, address, logfile, logfile))
    if not os.path.exists(tmpfile) or exit:
        log.error('Cannot get file from epgdata.com, see %s' % logfile)
        return False
    # and unzip the zip file
    log.info('Unzipping data for meta data')
    # FIXME: don't rely on unzip (can probably use zipfile module)
    exit = os.system('unzip -uo -d %s %s >>%s 2>>%s' %
                     (tempdir, tmpfile, logfile, logfile))
    if exit:
        log.error('Cannot unzip the downloaded file, see %s' % logfile)
        return False

    # list of channel info xml files
    chfiles = glob.glob(os.path.join(tempdir, 'channel*.xml'))
    if len(chfiles) == 0:
        log.error('no channel xml files for parsing')
        return False

    # parse this files
    channels = ChannelParser()
    channels.add_channel = epg.add_channel
    for xmlfile in chfiles:
        # return the list of channels from the config file
        channels.parse(xmlfile)

    metadata = MetaParser()
    metadata.parse(os.path.join(tempdir, 'genre.xml'))
    metadata.parse(os.path.join(tempdir, 'category.xml'))

    # create download adresse for programm files
    address = 'http://www.epgdata.com/index.php'
    address += '?action=sendPackage&iLang=de&iOEM=xml&iCountry=de'
    address += '&pin=%s' % config.epgdata.pin
    address += '&dayOffset=%s&dataType=xml'

    # get the file for each day
    for i in range(0, int(config.days)):
        # remove old file if needed
        try:
            os.remove(tmpfile)
        except OSError:
            pass
        # download the zip file
        log.info('Getting data for day %s' % (i + 1))
        exit = os.system('wget -N -O %s "%s" >>%s 2>>%s' %
                         (tmpfile, address % i, logfile, logfile))
        if not os.path.exists(tmpfile) or exit:
            log.error('Cannot get file from epgdata.com, see %s' % logfile)
            return False
        # and unzip the zip file
        log.info('Unzipping data for day %s' % (i + 1))
        exit = os.system('unzip -uo -d %s %s >>%s 2>>%s' %
                         (tempdir, tmpfile, logfile, logfile))
        if exit:
            log.error('Cannot unzip the downloaded file, see %s' % logfile)
            return False

    # list of program xml files that must be parsed
    progfiles = glob.glob(os.path.join(tempdir, '*de_q[a-z].xml'))
    if len(progfiles) == 0:
        log.warning('no progam xml files for parsing')

    # parse the progam xml files
    prgparser = ProgramParser()
    prgparser.channels = channels
    prgparser.metadata = metadata
    prgparser.add_program = epg.add_program
    log.info('found %s files' % len(progfiles))
    for xmlfile in progfiles:
        log.info('process %s' % xmlfile)
        prgparser.parse(xmlfile)
    return True
示例#14
0
def update(epg):
    """
    Interface to source_epgdata.
    """
    if not config.epgdata.pin:
        log.error('PIN for epgdata.com is missing in tvserver.conf')
        return False

    # create a tempdir as working area
    tempdir = kaa.tempfile('epgdata')
    if not os.path.isdir(tempdir):
        os.mkdir(tempdir)
    # and clear it if needed
    for i in glob.glob(os.path.join(tempdir,'*')):
       os.remove(i)

    # temp file
    tmpfile = os.path.join(tempdir,'temp.zip')
    # logfile
    logfile = kaa.tempfile('epgdata.log')

    # empty list for the xml docs
    docs = []
    # count of the nodes that have to be parsed
    nodes = 0


    # create download adresse for meta data
    address = 'http://www.epgdata.com/index.php'
    address+= '?action=sendInclude&iLang=de&iOEM=xml&iCountry=de'
    address+= '&pin=%s' % config.epgdata.pin
    address+= '&dataType=xml'

    # remove old file if needed
    try:
        os.remove(tmpfile)
    except OSError:
         pass
    # download the meta data file
    log.info ('Downloading meta data')
    # FIXME: don't rely on wget
    exit = os.system('wget -N -O %s "%s" >>%s 2>>%s'
                    %(tmpfile, address, logfile, logfile))
    if not os.path.exists(tmpfile) or exit:
        log.error('Cannot get file from epgdata.com, see %s' %logfile)
        return False
    # and unzip the zip file
    log.info('Unzipping data for meta data')
    # FIXME: don't rely on unzip (can probably use zipfile module)
    exit = os.system('unzip -uo -d %s %s >>%s 2>>%s'
                    %(tempdir, tmpfile, logfile, logfile))
    if exit:
        log.error('Cannot unzip the downloaded file, see %s' %logfile)
        return False

    # list of channel info xml files
    chfiles = glob.glob(os.path.join(tempdir,'channel*.xml'))
    if len(chfiles)==0:
        log.error('no channel xml files for parsing')
        return False

    # parse this files
    channels = ChannelParser()
    channels.add_channel = epg.add_channel
    for xmlfile in chfiles:
        # return the list of channels from the config file
        channels.parse(xmlfile)

    metadata = MetaParser()
    metadata.parse(os.path.join(tempdir, 'genre.xml'))
    metadata.parse(os.path.join(tempdir, 'category.xml'))

    # create download adresse for programm files
    address = 'http://www.epgdata.com/index.php'
    address+= '?action=sendPackage&iLang=de&iOEM=xml&iCountry=de'
    address+= '&pin=%s' % config.epgdata.pin
    address+= '&dayOffset=%s&dataType=xml'

    # get the file for each day
    for i in range(0, int(config.days)):
            # remove old file if needed
            try:
                os.remove(tmpfile)
            except OSError:
                pass
            # download the zip file
            log.info('Getting data for day %s' %(i+1))
            exit = os.system('wget -N -O %s "%s" >>%s 2>>%s'
                            %(tmpfile, address %i, logfile, logfile))
            if not os.path.exists(tmpfile) or exit:
                log.error('Cannot get file from epgdata.com, see %s' %logfile)
                return False
            # and unzip the zip file
            log.info('Unzipping data for day %s' %(i+1))
            exit = os.system('unzip -uo -d %s %s >>%s 2>>%s'
                            %(tempdir, tmpfile, logfile, logfile))
            if exit:
                log.error('Cannot unzip the downloaded file, see %s' %logfile)
                return False

    # list of program xml files that must be parsed
    progfiles = glob.glob(os.path.join(tempdir,'*de_q[a-z].xml'))
    if len(progfiles)==0:
        log.warning('no progam xml files for parsing')

    # parse the progam xml files
    prgparser = ProgramParser()
    prgparser.channels = channels
    prgparser.metadata = metadata
    prgparser.add_program = epg.add_program
    log.info('found %s files' % len(progfiles))
    for xmlfile in progfiles:
        log.info('process %s' % xmlfile)
        prgparser.parse(xmlfile)
    return True
示例#15
0
 def get_cachefile(self, url):
     """
     Return the cache filename for the given url
     """
     base = hashlib.md5(url).hexdigest() + os.path.splitext(url)[1]
     return kaa.tempfile('candy-images/' + base)
示例#16
0
文件: player.py 项目: clones/kaa
    def play(self):
        config = self._proxy._config
        vf = []
        args = self._media._mplayer_args[:]
        args.extend('-slave -v -osdlevel 0 -fixed-vo -demuxer lavf')

        if self.audio_delay:
            args.add(delay=self.audio_delay)
        if self.cache == 0:
            args.add(nocache=True)
        elif isinstance(self.cache, (long, float, int)) or self.cache.isdigit():
            args.add(cache=self.cache)
        if self._ss_seek:
            args.add(ss=self._ss_seek)
            self._ss_seek = None

        if self._media.get('corrupt'):
            # Index for the given file is corrupt.  Must add -idx to allow
            # seeking.  FIXME: for large filesthis can take a while.  We
            # should: 1. provide progress feedback, 2. use -saveidx to keep
            # the index for next time.
            args.append('-idx')

        window = self._proxy.window
        if window is None:
            args.add(vo='null')
        elif config.video.vdpau.enabled and 'vdpau' in self._mp_info['video_drivers']:
            deint = {'cheap': 1, 'good': 2, 'better': 3, 'best': 4}.get(config.video.deinterlacing.method, 3)
            args.add(vo='vdpau:deint=%d,xv,x11' % deint)

            # Decide which codecs to enable based on what the user specified.  We do
            # a simple substring match.
            regexp = '|'.join('.*%s.*vdpau' % c for c in config.video.vdpau.formats.replace(' ', '').split(','))
            args.add(vc=','.join(codec for codec in self._mp_info['video_codecs'] if re.search(regexp, codec)) + ',')

            # If the display rate is less than the frame rate, -framedrop is
            # needed or else the audio will continually drift.
            # TODO: we could decide to add this only if the above condition is 
            args.append('-framedrop')
        else:
            args.add(vo='xv,x11')
            vf.append(getattr(config.mplayer.deinterlacer, config.video.deinterlacing.method))

        if isinstance(window, kaa.display.X11Window):
            # Create a new inner window.  We must do this each time we start
            # MPlayer because MPlayer destroys the window (even the ones it
            # doesn't manage [!!]) at exit.
            inner = self._proxy._window_inner = kaa.display.X11Window(size=(1,1), parent=window)
            inner.show()
            # Set owner to False so we don't try to destroy the window.
            inner.owner = False
            args.add(wid=hex(inner.id).rstrip('L'))
            window.resize(self.width, self.height)

        if vf:
            args.add(vf=','.join(vf))

        # MPlayer has issues with interlaced h264 inside transport streams that
        # can be fixed with -nocorrect-pts (and -demuxer lavf, which we're
        # already forcing).  Unfortunately, kaa.metadata doesn't support these
        # files yet, nor can we tell if the content is interlaced.  So we guess
        # based on file extension.  Luckily -nocorrect-pts doesn't seem to hurt
        # progressive content.
        ext = os.path.splitext(self.uri)[1].lower()
        if self.vfourcc == 'H264' and ext in ('.ts', '.m2ts'):
            args.append('-nocorrect-pts')

        # Audio settings
        # XXX Currently only passthrough is handled here. All the
        # XXX other options and what device to use are ignored.
        if config.audio.passthrough:
            args.add(ac='hwac3,hwdts,')
        
        # There is no way to make MPlayer ignore keys from the X11 window.  So
        # this hack makes a temp input file that maps all keys to a dummy (and
        # non-existent) command which causes MPlayer not to react to any key
        # presses, allowing us to implement our own handlers.
        tempfile = kaa.tempfile('popcorn/mplayer-input.conf')
        if not os.path.isfile(tempfile):
            keys = filter(lambda x: x not in string.whitespace, string.printable)
            keys = list(keys) + self._mp_info['keylist']
            fd = open(tempfile, 'w')
            for key in keys:
                fd.write("%s noop\n" % key)
            fd.close()
        args.add(input='conf=%s' % tempfile)

        log.debug('Starting MPlayer with args: %s', ' '.join(args))
        self.state = STATE_STARTING
        self._spawn(args, interactive=True)

        yield self._wait_for_signals('play', task='Play')

        # Play has begun successfully.  _handle_child_line() will already
        # have set state to STATE_PLAYING.
        if isinstance(window, kaa.display.X11Window):
            # XXX: is it reasonable to automatically show the window now?
            # Maybe we should have an autoshow property?
            window.show()
示例#17
0
 def _update_series(self, id):
     info = self._db.query_one(type='series', tvdb=id)
     if info:
         signals['sync'].emit(info.get('name'))
     else:
         signals['sync'].emit()
     # download thetvdb information
     f = open(kaa.tempfile('thetvdb-%s.zip' % id), 'w')
     f.write((yield download(self.api + 'series/%s/all/en.zip' % id)))
     f.close()
     # load zip data
     z = zipfile.ZipFile(f.name)
     parent = None
     for name, data in (yield parse(z.open('en.xml')))[1]:
         if name == 'Series':
             objid = self._update_db('series',
                                     int(data.get('id')),
                                     name=data.get('SeriesName'),
                                     data=data)
             parent = ('series', objid)
             # delete old entries
             for e in self._db.query(type='episode', parent=parent):
                 self._db.delete(e)
         elif name == 'Episode':
             if not parent:
                 raise ValueError(
                     'Unexpected parse error: got Episode element before Series'
                 )
             self._update_db('episode',
                             int(data.get('id')),
                             name=data.get('EpisodeName'),
                             parent=parent,
                             season=int(data.get('SeasonNumber')),
                             episode=int(data.get('EpisodeNumber')),
                             date=data.get('FirstAired', None),
                             data=data)
         else:
             log.error('unknown element: %s', name)
     self._db.commit()
     # load image information
     for name, data in (yield parse(z.open('banners.xml')))[1]:
         if name == 'Banner':
             self._update_db('banner',
                             int(data.get('id')),
                             btype=data.get('BannerType'),
                             data=data,
                             parent=parent)
         else:
             log.error('unknown element: %s', name)
     self._db.commit()
     os.unlink(f.name)
     # download metadata images
     info = self._db.query_one(type='series', tvdb=id)
     if not info:
         yield None
     serie = Series(self, info)
     if serie.image and not os.path.isfile(serie.image):
         data = yield serie.get_all_images()[0].fetch()
         open(serie.image, 'w').write(data)
     if serie.poster and not os.path.isfile(serie.poster):
         data = yield serie.get_all_posters()[0].fetch()
         open(serie.poster, 'w').write(data)
     if serie.banner and not os.path.isfile(serie.banner):
         data = yield serie.get_all_banners()[0].fetch()
         open(serie.banner, 'w').write(data)
     for season in serie.seasons:
         if season.poster and season.get_all_posters(
         ) and not os.path.isfile(season.poster):
             data = yield season.get_all_posters()[0].fetch()
             open(season.poster, 'w').write(data)
         if season.banner and season.get_all_banners(
         ) and not os.path.isfile(season.banner):
             data = yield season.get_all_banners()[0].fetch()
             open(season.banner, 'w').write(data)