Exemplo n.º 1
0
 def ToGo(self, handler, query):
     tivo_mak = config.get_server('tivo_mak')
     togo_path = config.get_server('togo_path')
     for name, data in config.getShares():
         if togo_path == name:
             togo_path = data.get('path')
     if tivo_mak and togo_path:
         tivoIP = query['TiVo'][0]
         urls = query.get('Url', [])
         decode = 'decode' in query
         save = 'save' in query
         for theurl in urls:
             status[theurl] = {'running': False, 'error': '', 'rate': '',
                               'queued': True, 'size': 0, 'finished': False,
                               'decode': decode, 'save': save}
             if tivoIP in queue:
                 queue[tivoIP].append(theurl)
             else:
                 queue[tivoIP] = [theurl]
                 thread.start_new_thread(ToGo.process_queue,
                                         (self, tivoIP, tivo_mak, togo_path))
             logger.info('[%s] Queued "%s" for transfer to %s' %
                         (time.strftime('%d/%b/%Y %H:%M:%S'),
                          unquote(theurl), togo_path))
         urlstring = '<br>'.join([unquote(x) for x in urls])
         message = TRANS_QUEUE % (urlstring, togo_path)
     else:
         message = MISSING
     handler.redir(message, 5)
Exemplo n.º 2
0
    def infopage(self):
        t = Template(file=os.path.join(SCRIPTDIR, 'templates',
                                       'info_page.tmpl'),
                     filter=EncodeUnicode)
        t.admin = ''

        if config.get_server('tivo_mak') and config.get_server('togo_path'):
            t.togo = '<br>Pull from TiVos:<br>'
        else:
            t.togo = ''

        for section, settings in config.getShares():
            plugin_type = settings.get('type')
            if plugin_type == 'settings':
                t.admin += ('<a href="/TiVoConnect?Command=Settings&amp;' +
                            'Container=' + quote(section) +
                            '">Settings</a><br>')
            elif plugin_type == 'togo' and t.togo:
                for tsn in config.tivos:
                    if tsn and 'address' in config.tivos[tsn]:
                        t.togo += ('<a href="/TiVoConnect?' +
                            'Command=NPL&amp;Container=' + quote(section) +  
                            '&amp;TiVo=' + config.tivos[tsn]['address'] +
                            '">' + config.tivos[tsn]['name'] +
                            '</a><br>')

        self.send_html(str(t))
Exemplo n.º 3
0
def test(motor_record='XF:31IDA-OP{Tbl-Ax:X1}Mtr'):
    config.setup_logging([__name__, 'pypvserver.motor'])
    server = config.get_server()
    mrec = EpicsMotor(motor_record)

    # give the motor time to connect
    time.sleep(1.0)

    logger.info('--> PV Positioner, using put completion and a DONE pv')
    # PV positioner, put completion, done pv
    pos = PVPositioner(mrec.field_pv('VAL'),
                       readback=mrec.field_pv('RBV'),
                       done=mrec.field_pv('MOVN'), done_val=0,
                       stop=mrec.field_pv('STOP'), stop_val=1,
                       put_complete=True,
                       limits=(-2, 2),
                       )

    ppv_motor = PypvMotor('m1', pos, server=server)
    print(ppv_motor.severity)
    record_name = ppv_motor.full_pvname
    for i in range(2):
        epics.caput(record_name, i, wait=True)
        print(pos.position)
    return ppv_motor
Exemplo n.º 4
0
    def startXMPP(self):
        m = mind.getMind()
        xmpp_info = m.getXMPPLoginInfo()

        jid=xmpp.protocol.JID(xmpp_info['username'] + '/pyTivo')
        cl=xmpp.Client(
            server=xmpp_info['server'],
            port=xmpp_info['port'],
            debug=[],
        )
        self.__logger.debug('Connecting to %s:%s' % (xmpp_info['server'],
                                                     xmpp_info['port']))
        cl.connect()
        cl.RegisterHandler('message', self.processMessage)
        self.__logger.debug('Loging in as %s/pyTivo' % xmpp_info['username'])
        cl.auth(user=jid.getNode(), password=config.get_server('tivo_password'),
                resource='pyTivo')

        cl.sendInitPresence(requestRoster=0)

        for user_name in xmpp_info['presence_list']:
            self.__logger.debug('Sending presence to %s' % user_name)
            jid = xmpp.protocol.JID(user_name)
            cl.sendPresence(jid)

        t = threading.Thread(target=self.processXMPP, args=(cl,))
        t.setDaemon(True)
        t.start()
Exemplo n.º 5
0
    def push_one_file(self, f):
        file_info = VideoDetails()
        file_info['valid'] = transcode.supported_format(f['path'])

        temp_share = config.get_server('temp_share', '')
        temp_share_path = ''
        if temp_share:
            for name, data in config.getShares():
                if temp_share == name:
                    temp_share_path = data.get('path')

        mime = 'video/mpeg'
        if config.isHDtivo(f['tsn']):
            for m in ['video/mp4', 'video/bif']:
                if transcode.tivo_compatible(f['path'], f['tsn'], m)[0]:
                    mime = m
                    break

            if (mime == 'video/mpeg' and
                transcode.mp4_remuxable(f['path'], f['tsn'])):
                new_path = transcode.mp4_remux(f['path'], f['name'], f['tsn'], temp_share_path)
                if new_path:
                    mime = 'video/mp4'
                    f['name'] = new_path
                    if temp_share_path:
                        ip = config.get_ip()
                        port = config.getPort()
                        container = quote(temp_share) + '/'
                        f['url'] = 'http://%s:%s/%s' % (ip, port, container)

        if file_info['valid']:
            file_info.update(self.metadata_full(f['path'], f['tsn'], mime))

        url = f['url'] + quote(f['name'])

        title = file_info['seriesTitle']
        if not title:
            title = file_info['title']

        source = file_info['seriesId']
        if not source:
            source = title

        subtitle = file_info['episodeTitle']
        try:
            m = mind.getMind(f['tsn'])
            m.pushVideo(
                tsn = f['tsn'],
                url = url,
                description = file_info['description'],
                duration = file_info['duration'] / 1000,
                size = file_info['size'],
                title = title,
                subtitle = subtitle,
                source = source,
                mime = mime,
                tvrating = file_info['tvRating'])
        except Exception, msg:
            logger.error(msg)
Exemplo n.º 6
0
    def infopage(self):
        useragent = self.headers.getheader('User-Agent', '')
        if useragent.lower().find('mobile') > 0:
            t = Template(file=os.path.join(SCRIPTDIR, 'templates',
                                       'info_page_mob.tmpl'),
                     filter=EncodeUnicode)
        else:
            t = Template(file=os.path.join(SCRIPTDIR, 'templates',
                                       'info_page.tmpl'),
                     filter=EncodeUnicode)
        t.admin = ''

        if config.get_server('tivo_mak') and config.get_server('togo_path'):
            t.togo = '<br>Pull from TiVos:<br>'
        else:
            t.togo = ''

        if (config.get_server('tivo_username') and
            config.get_server('tivo_password')):
            t.shares = '<br>Push from video shares:<br>'
        else:
            t.shares = ''

        for section, settings in config.getShares():
            plugin_type = settings.get('type')
            if plugin_type == 'settings':
                t.admin += ('<a href="/TiVoConnect?Command=Settings&amp;' +
                            'Container=' + quote(section) +
                            '">Settings</a><br>')
            elif plugin_type == 'togo' and t.togo:
                for tsn in config.tivos:
                    if tsn:
                        t.togo += ('<a href="/TiVoConnect?' +
                            'Command=NPL&amp;Container=' + quote(section) +  
                            '&amp;TiVo=' + config.tivos[tsn] + '">' + 
                            escape(config.tivo_names[tsn]) + '</a><br>')
            elif plugin_type and t.shares:
                plugin = GetPlugin(plugin_type)
                if hasattr(plugin, 'Push'):
                    t.shares += ('<a href="/TiVoConnect?Command=' +
                                 'QueryContainer&amp;Container=' +
                                 quote(section) + '&Format=text/html">' +
                                 section + '</a><br>')

        self.send_html(str(t))
Exemplo n.º 7
0
def transcode(isQuery, inFile, outFile, tsn="", mime="", thead=""):
    vcodec = select_videocodec(inFile, tsn, mime)

    settings = select_buffsize(tsn) + vcodec
    if not vcodec[1] == "copy":
        settings += (
            select_videobr(inFile, tsn)
            + select_maxvideobr(tsn)
            + select_videofps(inFile, tsn)
            + select_aspect(inFile, tsn)
        )

    acodec = select_audiocodec(isQuery, inFile, tsn)
    settings += acodec
    if not acodec[1] == "copy":
        settings += select_audiobr(tsn) + select_audiofr(inFile, tsn) + select_audioch(inFile, tsn)

    settings += [select_audiolang(inFile, tsn), select_ffmpegprams(tsn)]

    settings += select_format(tsn, mime)

    settings = " ".join(settings).split()
    if isQuery:
        return settings

    ffmpeg_path = config.get_bin("ffmpeg")

    fname = unicode(inFile, "utf-8")
    if mswindows:
        fname = fname.encode("cp1252")

    if inFile[-5:].lower() == ".tivo":
        tivodecode_path = config.get_bin("tivodecode")
        tivo_mak = config.get_server("tivo_mak")
        tcmd = [tivodecode_path, "-m", tivo_mak, fname]
        tivodecode = subprocess.Popen(tcmd, stdout=subprocess.PIPE, bufsize=(512 * 1024))
        if tivo_compatible(inFile, tsn)[0]:
            cmd = ""
            ffmpeg = tivodecode
        else:
            cmd = [ffmpeg_path, "-i", "-"] + settings
            ffmpeg = subprocess.Popen(cmd, stdin=tivodecode.stdout, stdout=subprocess.PIPE, bufsize=(512 * 1024))
    else:
        cmd = [ffmpeg_path, "-i", fname] + settings
        ffmpeg = subprocess.Popen(cmd, bufsize=(512 * 1024), stdout=subprocess.PIPE)

    if cmd:
        debug("transcoding to tivo model " + tsn[:3] + " using ffmpeg command:")
        debug(" ".join(cmd))

    ffmpeg_procs[inFile] = {"process": ffmpeg, "start": 0, "end": 0, "last_read": time.time(), "blocks": []}
    if thead:
        ffmpeg_procs[inFile]["blocks"].append(thead)
    reap_process(inFile)
    return resume_transfer(inFile, outFile, 0)
Exemplo n.º 8
0
def transcode(isQuery, inFile, outFile, tsn='', mime='', thead=''):
    settings = {'video_codec': select_videocodec(inFile, tsn, mime),
                'video_br': select_videobr(inFile, tsn),
                'video_fps': select_videofps(inFile, tsn),
                'max_video_br': select_maxvideobr(tsn),
                'buff_size': select_buffsize(tsn),
                'aspect_ratio': ' '.join(select_aspect(inFile, tsn)),
                'audio_br': select_audiobr(tsn),
                'audio_fr': select_audiofr(inFile, tsn),
                'audio_ch': select_audioch(inFile, tsn),
                'audio_codec': select_audiocodec(isQuery, inFile, tsn),
                'audio_lang': select_audiolang(inFile, tsn),
                'ffmpeg_pram': select_ffmpegprams(tsn),
                'ffmpeg_threads': select_ffmpegthreads(),
                'format': select_format(tsn, mime)}

    if isQuery:
        return settings

    ffmpeg_path = config.get_bin('ffmpeg')
    cmd_string = config.getFFmpegTemplate(tsn) % settings
    fname = unicode(inFile, 'utf-8')
    if mswindows:
        fname = fname.encode('iso8859-1')

    if inFile[-5:].lower() == '.tivo':
        tivodecode_path = config.get_bin('tivodecode')
        tivo_mak = config.get_server('tivo_mak')
        tcmd = [tivodecode_path, '-m', tivo_mak, fname]
        tivodecode = subprocess.Popen(tcmd, stdout=subprocess.PIPE,
                                      bufsize=(512 * 1024))
        if tivo_compatible(inFile, tsn)[0]:
            cmd = ''
            ffmpeg = tivodecode
        else:
            cmd = [ffmpeg_path] + select_ffmpegthreads().split() + ['-i', '-'] + cmd_string.split()
            ffmpeg = subprocess.Popen(cmd, stdin=tivodecode.stdout,
                                      stdout=subprocess.PIPE,
                                      bufsize=(512 * 1024))
    else:
        cmd = [ffmpeg_path] + select_ffmpegthreads().split() + ['-i', fname] + cmd_string.split()
        ffmpeg = subprocess.Popen(cmd, bufsize=(512 * 1024),
                                  stdout=subprocess.PIPE)

    if cmd:
        debug('transcoding to tivo model ' + tsn[:3] + ' using ffmpeg command:')
        debug(' '.join(cmd))

    ffmpeg_procs[inFile] = {'process': ffmpeg, 'start': 0, 'end': 0,
                            'last_read': time.time(), 'blocks': []}
    if thead:
        ffmpeg_procs[inFile]['blocks'].append(thead)
    reap_process(inFile)
    return resume_transfer(inFile, outFile, 0)
Exemplo n.º 9
0
    def infopage(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html; charset=utf-8')
        self.end_headers()
        t = Template(file=os.path.join(SCRIPTDIR, 'templates',
                                       'info_page.tmpl'),
                     filter=EncodeUnicode)
        t.admin = ''

        if config.get_server('tivo_mak') and config.get_server('togo_path'):
            t.togo = '<br>Pull from TiVos:<br>'
        else:
            t.togo = ''

        if (config.get_server('tivo_username') and
            config.get_server('tivo_password')):
            t.shares = '<br>Push from video shares:<br>'
        else:
            t.shares = ''

        for section, settings in config.getShares():
            plugin_type = settings.get('type')
            if plugin_type == 'settings':
                t.admin += ('<a href="/TiVoConnect?Command=Settings&amp;' +
                            'Container=' + quote(section) +
                            '">Web Configuration</a><br>')
            elif plugin_type == 'togo' and t.togo:
                for tsn in config.tivos:
                    if tsn:
                        t.togo += ('<a href="/TiVoConnect?' +
                            'Command=NPL&amp;Container=' + quote(section) +  
                            '&amp;TiVo=' + config.tivos[tsn] + '">' + 
                            escape(config.tivo_names[tsn]) + '</a><br>')
            elif plugin_type == 'video' and t.shares:
                t.shares += ('<a href="TiVoConnect?Command=' +
                             'QueryContainer&amp;Container=' +
                             quote(section) + '&Format=text/html">' +
                             section + '</a><br>')

        self.wfile.write(t)
Exemplo n.º 10
0
    def send_packet(self, packet):
        debug('send packet:%s to for request:%d ...' % (packet, self._request))
        business = get_server(self._request)
        if business:
            if business in BUSINESS_MAP:
                conn = BUSINESS_MAP[business]
                conn.send(packet)
            else:
                warning('business server %s is not avalible' % business)
                pass
        else:
            warning('unsupported request: %d' % self._request)

        self.read_header()
Exemplo n.º 11
0
    def Push(self, handler, query):
        try:
            tsn = query['tsn'][0]
        except:
            logger.error('Push requires a TiVo Service Number')
            handler.send_error(404)
            return

        if not tsn in config.tivos:
            for key, value in config.tivos.items():
                if value.get('name') == tsn:
                    tsn = key
                    break
        try:
            tivo_name = config.tivos[tsn]['name']
        except:
            tivo_name = tsn

        container = quote(query['Container'][0].split('/')[0])
        ip = config.get_ip(tsn)
        port = config.getPort()

        baseurl = 'http://%s:%s/%s' % (ip, port, container)
        if config.getIsExternal(tsn):
            exturl = config.get_server('externalurl')
            if exturl:
                if not exturl.endswith('/'):
                    exturl += '/'
                baseurl = exturl + container
            else:
                ip = self.readip()
                baseurl = 'http://%s:%s/%s' % (ip, port, container)
 
        path = self.get_local_base_path(handler, query)

        files = query.get('File', [])
        for f in files:
            file_path = os.path.normpath(path + '/' + f)
            queue.append({'path': file_path, 'name': f, 'tsn': tsn,
                          'url': baseurl})
            if len(queue) == 1:
                thread.start_new_thread(Video.process_queue, (self,))

            logger.info('[%s] Queued "%s" for Push to %s' %
                        (time.strftime('%d/%b/%Y %H:%M:%S'),
                         unicode(file_path, 'utf-8'), tivo_name))

        files = [unicode(f, 'utf-8') for f in files]
        handler.redir(PUSHED % (tivo_name, '<br>'.join(files)), 5)
Exemplo n.º 12
0
def transcode(isQuery, inFile, outFile, tsn=""):
    settings = {
        "video_codec": select_videocodec(inFile, tsn),
        "video_br": select_videobr(inFile, tsn),
        "video_fps": select_videofps(inFile, tsn),
        "max_video_br": select_maxvideobr(tsn),
        "buff_size": select_buffsize(tsn),
        "aspect_ratio": " ".join(select_aspect(inFile, tsn)),
        "audio_br": select_audiobr(tsn),
        "audio_fr": select_audiofr(inFile, tsn),
        "audio_ch": select_audioch(tsn),
        "audio_codec": select_audiocodec(isQuery, inFile, tsn),
        "audio_lang": select_audiolang(inFile, tsn),
        "ffmpeg_pram": select_ffmpegprams(tsn),
        "format": select_format(tsn),
    }

    if isQuery:
        return settings

    ffmpeg_path = config.get_bin("ffmpeg")
    cmd_string = config.getFFmpegTemplate(tsn) % settings
    fname = unicode(inFile, "utf-8")
    if mswindows:
        fname = fname.encode("iso8859-1")

    if inFile[-5:].lower() == ".tivo":
        tivodecode_path = config.get_bin("tivodecode")
        tivo_mak = config.get_server("tivo_mak")
        tcmd = [tivodecode_path, "-m", tivo_mak, fname]
        tivodecode = subprocess.Popen(tcmd, stdout=subprocess.PIPE, bufsize=(512 * 1024))
        if tivo_compatible(inFile, tsn)[0]:
            cmd = ""
            ffmpeg = tivodecode
        else:
            cmd = [ffmpeg_path, "-i", "-"] + cmd_string.split()
            ffmpeg = subprocess.Popen(cmd, stdin=tivodecode.stdout, stdout=subprocess.PIPE, bufsize=(512 * 1024))
    else:
        cmd = [ffmpeg_path, "-i", fname] + cmd_string.split()
        ffmpeg = subprocess.Popen(cmd, bufsize=(512 * 1024), stdout=subprocess.PIPE)

    if cmd:
        debug("transcoding to tivo model " + tsn[:3] + " using ffmpeg command:")
        debug(" ".join(cmd))

    ffmpeg_procs[inFile] = {"process": ffmpeg, "start": 0, "end": 0, "last_read": time.time(), "blocks": []}
    reap_process(inFile)
    return transfer_blocks(inFile, outFile)
Exemplo n.º 13
0
    def read_body(self, body):
        logging.debug('read body(%s) from %s' % (body, self._addr_str))
        self._body = body

        business = get_server(self._request)        

        BusinessConnection.clients_lock.acquire()
        if business in BusinessConnection.clients:
            logging.debug('forward request to %s' % business)
            conn = BusinessConnection.clients[business].pop()
            BusinessConnection.clients[business].add(conn)
            conn.send(self._header + self._body, self._type, self._address[0])
        else:
            logging.debug('no %s business server is avaliable' % business)
        BusinessConnection.clients_lock.release()

        self._stream.read_bytes(Connection.header_length, self.read_header)
Exemplo n.º 14
0
def from_tivo(full_path):
    if full_path in tivo_cache:
        return tivo_cache[full_path]

    tdcat_path = config.get_bin('tdcat')
    tivo_mak = config.get_server('tivo_mak')
    if tdcat_path and tivo_mak:
        fname = unicode(full_path, 'utf-8')
        if mswindows:
            fname = fname.encode('iso8859-1')
        tcmd = [tdcat_path, '-m', tivo_mak, '-2', fname]
        tdcat = subprocess.Popen(tcmd, stdout=subprocess.PIPE)
        metadata = from_details(tdcat.stdout)
        tivo_cache[full_path] = metadata
    else:
        metadata = {}

    return metadata
Exemplo n.º 15
0
def from_tivo(full_path):
    if full_path in tivo_cache:
        return tivo_cache[full_path]

    tdcat_path = config.get_bin("tdcat")
    tivo_mak = config.get_server("tivo_mak")
    try:
        assert tivo_mak
        if tdcat_path:
            details = _tdcat_bin(tdcat_path, full_path, tivo_mak)
        else:
            details = _tdcat_py(full_path, tivo_mak)
        metadata = from_details(details)
        tivo_cache[full_path] = metadata
    except:
        metadata = {}

    return metadata
Exemplo n.º 16
0
def test():
    config.setup_logging([__name__, 'pypvserver.pv'])
    server = config.get_server()
    logger.info('Creating PV "pv1", a floating-point type')
    python_pv = PyPV('pv1', 123.0, server=server)

    # full_pvname includes the server prefix
    pvname = python_pv.full_pvname
    logger.info('... which is %s including the server prefix', pvname)

    signal = epics.PV(pvname)
    signal.add_callback(updated)

    time.sleep(0.1)

    for value in range(10):
        logger.info('Updating the value on the server-side to: %s', value)
        python_pv.value = value
        time.sleep(0.05)

    logger.info('Done')
Exemplo n.º 17
0
    def infopage(self):
        t = Template(file=os.path.join(SCRIPTDIR, 'templates', 'info_page.tmpl'))
        t.version = PYTIVO_VERSION
        t.admin = ''

        if config.get_server('tivo_mak') and config.get_togo('path'):
            t.togo = '<br>Pull from TiVos:<br>'
        else:
            t.togo = ''

        for section, settings in config.getShares():
            plugin_type = settings.get('type')
            if plugin_type == 'settings':
                t.admin += ('<a href="/TiVoConnect?Command=Settings&amp;Container={}">Settings</a><br>'
                            .format(quote(section)))
            elif plugin_type == 'togo' and t.togo:
                for tsn in config.tivos:
                    if tsn and 'address' in config.tivos[tsn]:
                        t.togo += ('<a href="/TiVoConnect?Command=NPL&amp;Container={}&amp;TiVo={}">{}</a><br>'
                                   .format(quote(section), config.tivos[tsn]['address'], config.tivos[tsn]['name']))

        self.send_html(str(t))
Exemplo n.º 18
0
    def Push(self, handler, query):
        tsn = query["tsn"][0]
        for key in config.tivo_names:
            if config.tivo_names[key] == tsn:
                tsn = key
                break
        tivo_name = config.tivo_names.get(tsn, tsn)

        container = quote(query["Container"][0].split("/")[0])
        ip = config.get_ip(tsn)
        port = config.getPort()

        baseurl = "http://%s:%s/%s" % (ip, port, container)
        if config.getIsExternal(tsn):
            exturl = config.get_server("externalurl")
            if exturl:
                if not exturl.endswith("/"):
                    exturl += "/"
                baseurl = exturl + container
            else:
                ip = self.readip()
                baseurl = "http://%s:%s/%s" % (ip, port, container)

        path = self.get_local_base_path(handler, query)

        files = query.get("File", [])
        for f in files:
            file_path = path + os.path.normpath(f)
            queue.append({"path": file_path, "name": f, "tsn": tsn, "url": baseurl})
            if len(queue) == 1:
                thread.start_new_thread(Video.process_queue, (self,))

            logger.info(
                '[%s] Queued "%s" for Push to %s'
                % (time.strftime("%d/%b/%Y %H:%M:%S"), unicode(file_path, "utf-8"), tivo_name)
            )

        files = [unicode(f, "utf-8") for f in files]
        handler.redir(PUSHED % (tivo_name, "<br>".join(files)), 5)
Exemplo n.º 19
0
    def Push(self, handler, query):
        tsn = query['tsn'][0]
        for key in config.tivo_names:
            if config.tivo_names[key] == tsn:
                tsn = key
                break
        tivo_name = config.tivo_names.get(tsn, tsn)

        container = quote(query['Container'][0].split('/')[0])
        ip = config.get_ip(tsn)
        port = config.getPort()

        baseurl = 'http://%s:%s/%s' % (ip, port, container)
        if config.getIsExternal(tsn):
            exturl = config.get_server('externalurl')
            if exturl:
                if not exturl.endswith('/'):
                    exturl += '/'
                baseurl = exturl + container
            else:
                ip = self.readip()
                baseurl = 'http://%s:%s/%s' % (ip, port, container)
 
        path = self.get_local_base_path(handler, query)

        files = query.get('File', [])
        for f in files:
            file_path = path + os.path.normpath(f)
            queue.append({'path': file_path, 'name': f, 'tsn': tsn,
                          'url': baseurl})
            if len(queue) == 1:
                thread.start_new_thread(Video.process_queue, (self,))

            logger.info('[%s] Queued "%s" for Push to %s' %
                        (time.strftime('%d/%b/%Y %H:%M:%S'),
                         unicode(file_path, 'utf-8'), tivo_name))

        files = [unicode(f, 'utf-8') for f in files]
        handler.redir(PUSHED % (tivo_name, '<br>'.join(files)), 5)
Exemplo n.º 20
0
def on_close(ws):
    print("closed")
    logging.debug("closed")


def on_open(ws):
    channels = conf.get_channels()
    for i in range(0, len(channels)):
        subscribe(ws, channels[i]["id"], channels[i]["password"])


def subscribe(ws, channel, password):
    if (password == ""):
        msg = '{"subscribe":{"channelId":\"' + channel + '\"}}'
    else:
        msg = '{"subscribe":{"channelId":\"' + channel + '\", "password":\"' + password + '\"}}'
    print(msg)
    logging.debug(msg)
    ws.send(msg)


if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp(conf.get_server() + "/websocket",
                                on_message=on_message,
                                on_error=on_error,
                                on_close=on_close)
    ws.on_open = on_open
    ws.run_forever()
Exemplo n.º 21
0
    def send_file(self, handler, path, query):
        mime = 'video/x-tivo-mpeg'
        tsn = handler.headers.getheader('tsn', '')
        try:
            assert (tsn)
            tivo_name = config.tivos[tsn].get('name', tsn)
        except:
            tivo_name = handler.address_string()

        is_tivo_file = (path[-5:].lower() == '.tivo')

        if 'Format' in query:
            mime = query['Format'][0]

        needs_tivodecode = (is_tivo_file and mime == 'video/mpeg')
        compatible = (not needs_tivodecode
                      and transcode.tivo_compatible(path, tsn, mime)[0])

        try:  # "bytes=XXX-"
            offset = int(handler.headers.getheader('Range')[6:-1])
        except:
            offset = 0

        if needs_tivodecode:
            valid = bool(
                config.get_bin('tivodecode') and config.get_server('tivo_mak'))
        else:
            valid = True

        if valid and offset:
            valid = ((compatible and offset < os.path.getsize(path)) or
                     (not compatible and transcode.is_resumable(path, offset)))

        #faking = (mime in ['video/x-tivo-mpeg-ts', 'video/x-tivo-mpeg'] and
        faking = (mime == 'video/x-tivo-mpeg'
                  and not (is_tivo_file and compatible))
        fname = unicode(path, 'utf-8')
        thead = ''
        if faking:
            thead = self.tivo_header(tsn, path, mime)
        if compatible:
            size = os.path.getsize(fname) + len(thead)
            handler.send_response(200)
            handler.send_header('Content-Length', size - offset)
            handler.send_header(
                'Content-Range',
                'bytes %d-%d/%d' % (offset, size - offset - 1, size))
        else:
            handler.send_response(206)
            handler.send_header('Transfer-Encoding', 'chunked')
        handler.send_header('Content-Type', mime)
        handler.end_headers()

        logger.info('[%s] Start sending "%s" to %s' %
                    (time.strftime('%d/%b/%Y %H:%M:%S'), fname, tivo_name))
        start = time.time()
        count = 0

        if valid:
            if compatible:
                if faking and not offset:
                    handler.wfile.write(thead)
                logger.debug('"%s" is tivo compatible' % fname)
                f = open(fname, 'rb')
                try:
                    if offset:
                        offset -= len(thead)
                        f.seek(offset)
                    while True:
                        block = f.read(512 * 1024)
                        if not block:
                            break
                        handler.wfile.write(block)
                        count += len(block)
                except Exception, msg:
                    logger.info(msg)
                f.close()
            else:
                logger.debug('"%s" is not tivo compatible' % fname)
                if offset:
                    count = transcode.resume_transfer(path, handler.wfile,
                                                      offset)
                else:
                    count = transcode.transcode(False, path, handler.wfile,
                                                tsn, mime, thead)
Exemplo n.º 22
0
details_urls = {}  # URLs for extended data, indexed by main URL


def null_cookie(name, value):
    return cookielib.Cookie(0, name, value, None, False, '', False, False, '',
                            False, False, None, False, None, None, None)


auth_handler = urllib2.HTTPPasswordMgrWithDefaultRealm()
cj = cookielib.CookieJar()
cj.set_cookie(null_cookie('sid', 'ADEADDA7EDEBAC1E'))
tivo_opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj),
                                   urllib2.HTTPBasicAuthHandler(auth_handler),
                                   urllib2.HTTPDigestAuthHandler(auth_handler))

tsn = config.get_server('togo_tsn')
if tsn:
    tivo_opener.addheaders.append(('TSN', tsn))


class ToGo(Plugin):
    CONTENT_TYPE = 'text/html'

    def tivo_open(self, url):
        # Loop just in case we get a server busy message
        while True:
            try:
                # Open the URL using our authentication/cookie opener
                return tivo_opener.open(url)

            # Do a retry if the TiVo responds that the server is busy
Exemplo n.º 23
0
from config import get_server
from jim_protocol import create_response
import json

s = get_server()
print("Server started")
client, addr = s.accept()
print("Client connected: ", client, addr)
presence = json.loads(client.recv(1024).decode("utf-8"))
client.send(json.dumps(create_response(presence)).encode("utf-8"))

while True:
    print("Waiting data")

    data = json.loads(client.recv(1024).decode("utf-8"))
    print("Data received")

    if "exit" not in data:
        print(data)
    else:
        client.close()
        s.close()
        print("Exit")
        break
Exemplo n.º 24
0
    def send_file(self, handler, path, query):
        mime = "video/x-tivo-mpeg"
        tsn = handler.headers.getheader("tsn", "")
        tivo_name = config.tivo_names.get(tsn, tsn)

        is_tivo_file = path[-5:].lower() == ".tivo"

        if "Format" in query:
            mime = query["Format"][0]

        needs_tivodecode = is_tivo_file and mime == "video/mpeg"
        compatible = not needs_tivodecode and transcode.tivo_compatible(path, tsn, mime)[0]

        try:  # "bytes=XXX-"
            offset = int(handler.headers.getheader("Range")[6:-1])
        except:
            offset = 0

        if needs_tivodecode:
            valid = bool(config.get_bin("tivodecode") and config.get_server("tivo_mak"))
        else:
            valid = True

        if valid and offset:
            valid = (compatible and offset < os.stat(path).st_size) or (
                not compatible and transcode.is_resumable(path, offset)
            )

        # faking = (mime in ['video/x-tivo-mpeg-ts', 'video/x-tivo-mpeg'] and
        faking = mime == "video/x-tivo-mpeg" and not (is_tivo_file and compatible)
        fname = unicode(path, "utf-8")
        thead = ""
        if faking:
            thead = self.tivo_header(tsn, path, mime)
        if compatible:
            size = os.stat(fname).st_size + len(thead)
            handler.send_response(200)
            handler.send_header("Content-Length", size - offset)
            handler.send_header("Content-Range", "bytes %d-%d/%d" % (offset, size - offset - 1, size))
        else:
            handler.send_response(206)
            handler.send_header("Transfer-Encoding", "chunked")
        handler.send_header("Content-Type", mime)
        handler.send_header("Connection", "close")
        handler.end_headers()

        logger.info('[%s] Start sending "%s" to %s' % (time.strftime("%d/%b/%Y %H:%M:%S"), fname, tivo_name))
        start = time.time()
        count = 0

        if valid:
            if compatible:
                if faking and not offset:
                    handler.wfile.write(thead)
                logger.debug('"%s" is tivo compatible' % fname)
                f = open(fname, "rb")
                try:
                    if mime == "video/mp4":
                        count = qtfaststart.process(f, handler.wfile, offset)
                    else:
                        if offset:
                            offset -= len(thead)
                            f.seek(offset)
                        while True:
                            block = f.read(512 * 1024)
                            if not block:
                                break
                            handler.wfile.write(block)
                            count += len(block)
                except Exception, msg:
                    logger.info(msg)
                f.close()
            else:
                logger.debug('"%s" is not tivo compatible' % fname)
                if offset:
                    count = transcode.resume_transfer(path, handler.wfile, offset)
                else:
                    count = transcode.transcode(False, path, handler.wfile, tsn, mime, thead)
Exemplo n.º 25
0
    def NPL(self, handler, query):
        global basic_meta
        shows_per_page = 50 # Change this to alter the number of shows returned
        cname = query['Container'][0].split('/')[0]
        folder = ''
        tivo_mak = config.get_server('tivo_mak')
        has_tivodecode = bool(config.get_bin('tivodecode'))

        if 'TiVo' in query:
            tivoIP = query['TiVo'][0]
            tivos_by_ip = dict([(value, key)
                                for key, value in config.tivos.items()])
            tivo_name = config.tivo_names[tivos_by_ip[tivoIP]]
            theurl = ('https://' + tivoIP +
                      '/TiVoConnect?Command=QueryContainer&ItemCount=' +
                      str(shows_per_page) + '&Container=/NowPlaying')
            if 'Folder' in query:
                folder += query['Folder'][0]
                theurl += '/' + folder
            if 'AnchorItem' in query:
                theurl += '&AnchorItem=' + quote(query['AnchorItem'][0])
            if 'AnchorOffset' in query:
                theurl += '&AnchorOffset=' + query['AnchorOffset'][0]

            if (theurl not in tivo_cache or
                (time.time() - tivo_cache[theurl]['thepage_time']) >= 60):
                # if page is not cached or old then retreive it
                auth_handler.add_password('TiVo DVR', tivoIP, 'tivo', tivo_mak)
                try:
                    page = self.tivo_open(theurl)
                except IOError, e:
                    handler.redir(UNABLE % tivoIP, 10)
                    return
                tivo_cache[theurl] = {'thepage': minidom.parse(page),
                                      'thepage_time': time.time()}
                page.close()

            xmldoc = tivo_cache[theurl]['thepage']
            items = xmldoc.getElementsByTagName('Item')
            TotalItems = tag_data(xmldoc, 'Details/TotalItems')
            ItemStart = tag_data(xmldoc, 'ItemStart')
            ItemCount = tag_data(xmldoc, 'ItemCount')
            FirstAnchor = tag_data(items[0], 'Links/Content/Url')

            data = []
            for item in items:
                entry = {}
                entry['ContentType'] = tag_data(item, 'ContentType')
                for tag in ('CopyProtected', 'UniqueId'):
                    value = tag_data(item, tag)
                    if value:
                        entry[tag] = value
                if entry['ContentType'] == 'x-tivo-container/folder':
                    entry['Title'] = tag_data(item, 'Title')
                    entry['TotalItems'] = tag_data(item, 'TotalItems')
                    lc = tag_data(item, 'LastCaptureDate')
                    if not lc:
                        lc = tag_data(item, 'LastChangeDate')
                    entry['LastChangeDate'] = time.strftime('%b %d, %Y',
                        time.localtime(int(lc, 16)))
                else:
                    keys = {'Icon': 'Links/CustomIcon/Url',
                            'Url': 'Links/Content/Url',
                            'SourceSize': 'Details/SourceSize',
                            'Duration': 'Details/Duration',
                            'CaptureDate': 'Details/CaptureDate'}
                    for key in keys:
                        value = tag_data(item, keys[key])
                        if value:
                            entry[key] = value

                    entry['SourceSize'] = ( '%.3f GB' %
                        (float(entry['SourceSize']) / (1024 ** 3)) )

                    dur = int(entry['Duration']) / 1000
                    entry['Duration'] = ( '%02d:%02d:%02d' %
                        (dur / 3600, (dur % 3600) / 60, dur % 60) )

                    entry['CaptureDate'] = time.strftime('%b %d, %Y',
                        time.localtime(int(entry['CaptureDate'], 16)))

                    url = entry['Url']
                    if url in basic_meta:
                        entry.update(basic_meta[url])
                    else:
                        basic_data = metadata.from_container(item)
                        entry.update(basic_data)
                        basic_meta[url] = basic_data

                data.append(entry)
Exemplo n.º 26
0
def check_for_blacklist(ctx):
    if ctx.guild is not None:
        server = config.get_server(ctx.guild.id)
        return not ctx.channel.id in server['blacklist']
    else:
        return True
Exemplo n.º 27
0
def transcode(isQuery, inFile, outFile, tsn='', mime='', thead=''):
    vcodec = select_videocodec(inFile, tsn, mime)

    settings = select_buffsize(tsn) + vcodec
    if not vcodec[1] == 'copy':
        settings += (select_videobr(inFile, tsn) +
                     select_maxvideobr(tsn) +
                     select_videofps(inFile, tsn) +
                     select_aspect(inFile, tsn))

    acodec = select_audiocodec(isQuery, inFile, tsn)
    settings += acodec
    if not acodec[1] == 'copy':
        settings += (select_audiobr(tsn) +
                     select_audiofr(inFile, tsn) +
                     select_audioch(inFile, tsn))

    settings += [select_audiolang(inFile, tsn),
                 select_ffmpegprams(tsn)]

    settings += select_format(tsn, mime)

    settings = ' '.join(settings).split()
    if isQuery:
        return settings

    ffmpeg_path = config.get_bin('ffmpeg')

    fname = unicode(inFile, 'utf-8')
    if mswindows:
        fname = fname.encode('cp1252')

    if inFile[-5:].lower() == '.tivo':
        tivodecode_path = config.get_bin('tivodecode')
        tivo_mak = config.get_server('tivo_mak')
        tcmd = [tivodecode_path, '-m', tivo_mak, fname]
        tivodecode = subprocess.Popen(tcmd, stdout=subprocess.PIPE,
                                      bufsize=(512 * 1024))
        if tivo_compatible(inFile, tsn)[0]:
            cmd = ''
            ffmpeg = tivodecode
        else:
            cmd = [ffmpeg_path, '-i', '-'] + settings
            ffmpeg = subprocess.Popen(cmd, stdin=tivodecode.stdout,
                                      stdout=subprocess.PIPE,
                                      bufsize=(512 * 1024))
    else:
        cmd = [ffmpeg_path, '-i', fname] + settings
        ffmpeg = subprocess.Popen(cmd, bufsize=(512 * 1024),
                                  stdout=subprocess.PIPE)

    if cmd:
        debug('transcoding to tivo model ' + tsn[:3] + ' using ffmpeg command:')
        debug(' '.join(cmd))

    ffmpeg_procs[inFile] = {'process': ffmpeg, 'start': 0, 'end': 0,
                            'last_read': time.time(), 'blocks': []}
    if thead:
        ffmpeg_procs[inFile]['blocks'].append(thead)
    reap_process(inFile)
    return resume_transfer(inFile, outFile, 0)
Exemplo n.º 28
0
def mp4_remux(inFile, basename, tsn='', temp_share_path=''):
    temp_add = config.get_server('temp_add', '')
    unique_id = ''
    if temp_add:
        unique_id = '_' + config.get_random()
    outFile = inFile  + unique_id + '.pyTivo-temp'
    newname = basename  + unique_id + '.pyTivo-temp'

    if temp_share_path:
        newname = os.path.splitext(os.path.split(basename)[1])[0]  + unique_id + '.mp4.pyTivo-temp'
        outFile = os.path.join(temp_share_path, newname)

    if os.path.exists(outFile):
        debug('File already exists.  Performing full transcode instead')
        return None

    ffmpeg_path = config.get_bin('ffmpeg')
    fname = unicode(inFile, 'utf-8')
    oname = unicode(outFile, 'utf-8')
    if mswindows:
        fname = fname.encode('iso8859-1')
        oname = oname.encode('iso8859-1')

    settings = {'video_codec': '-vcodec copy',
            'video_br': select_videobr(inFile, tsn),
            'video_fps': select_videofps(inFile, tsn),
            'max_video_br': select_maxvideobr(tsn),
            'buff_size': select_buffsize(tsn),
            'aspect_ratio': ' '.join(select_aspect(inFile, tsn)),
            'audio_br': select_audiobr(tsn),
            'audio_fr': select_audiofr(inFile, tsn),
            'audio_ch': select_audioch(inFile, tsn),
            'audio_codec': select_audiocodec(False, inFile, tsn, 'video/mp4'),
            'audio_lang': select_audiolang(inFile, tsn),
            'ffmpeg_pram': select_ffmpegprams(tsn),
            'ffmpeg_threads': select_ffmpegthreads(),
            'format': '-f mp4'}

    cmd_string = config.getFFmpegTemplate(tsn) % settings

    cmd = [ffmpeg_path] + select_ffmpegthreads().split() + ['-i', fname] + cmd_string.split() + [oname]

    debug('transcoding to tivo model ' + tsn[:3] + ' using ffmpeg command:')
    debug(' '.join(cmd))

    ffmpeg = subprocess.Popen(cmd)

    debug('remuxing ' + inFile + ' to ' + outFile)

    # attempt to overcome certain FFmpeg audio timestamp errors
    # by forcing the audio stream to be transcoded
    # works more reliably with versions of FFmpeg >= 0.11.x
    # large amounts of warnings during mux are expected

    # also bypasses ac3 stream copy regression in FFmpeg
    # error: 'codec frame size is not set'
    # 02/20/2012 - lavc ver >= 54.x.x
    # commit 16e54ac7255d47e70ba9ba60d5ce5d0a0e44b223
    if ffmpeg.wait() == 1 and 'acodec copy' in settings['audio_codec']:
        debug('FFmpeg error, attempting to transcode audio as workaround')

        settings['audio_codec'] = '-acodec ac3' # don't use -copyts
        cmd_string = config.getFFmpegTemplate(tsn) % settings
        cmd = [ffmpeg_path] + select_ffmpegthreads().split() + ['-y', '-i', fname] + cmd_string.split() + [oname]
        
        debug('transcoding to tivo model ' + tsn[:3] + ' using ffmpeg command:')
        debug(' '.join(cmd))

        ffmpeg = subprocess.Popen(cmd)

    if ffmpeg.wait():
        try:
        	os.remove(outFile)
        	debug('FFmpeg error, temp file has been removed: ' + outFile)
        except:
            logger.error('FFmpeg returned a fatal error, ' +
                         'check debug log and configuration settings')
            pass
        return None

    return newname
Exemplo n.º 29
0
    def send_file(self, handler, path, query):
        mime = 'video/x-tivo-mpeg'
        tsn = handler.headers.getheader('tsn', '')
        tivo_name = config.tivo_names.get(tsn, tsn)

        is_tivo_file = (path[-5:].lower() == '.tivo')

        if 'Format' in query:
            mime = query['Format'][0]

        needs_tivodecode = (is_tivo_file and mime == 'video/mpeg')
        compatible = (not needs_tivodecode and
                      transcode.tivo_compatible(path, tsn, mime)[0])

        try:  # "bytes=XXX-"
            offset = int(handler.headers.getheader('Range')[6:-1])
        except:
            offset = 0

        if needs_tivodecode:
            valid = bool(config.get_bin('tivodecode') and
                         config.get_server('tivo_mak'))
        else:
            valid = True

        if valid and offset:
            valid = ((compatible and offset < os.stat(path).st_size) or
                     (not compatible and transcode.is_resumable(path, offset)))

        #faking = (mime in ['video/x-tivo-mpeg-ts', 'video/x-tivo-mpeg'] and
        faking = (mime == 'video/x-tivo-mpeg' and
                  not (is_tivo_file and compatible))
        fname = unicode(path, 'utf-8')
        thead = ''
        if faking:
            thead = self.tivo_header(tsn, path, mime)
        if compatible:
            size = os.stat(fname).st_size + len(thead)
            handler.send_response(200)
            handler.send_header('Content-Length', size - offset)
            handler.send_header('Content-Range', 'bytes %d-%d/%d' % 
                                (offset, size - offset - 1, size))
        else:
            handler.send_response(206)
            handler.send_header('Transfer-Encoding', 'chunked')
        handler.send_header('Content-Type', mime)
        handler.end_headers()

        logger.info('[%s] Start sending "%s" to %s' %
                    (time.strftime('%d/%b/%Y %H:%M:%S'), fname, tivo_name))
        start = time.time()
        count = 0

        if valid:
            if compatible:
                if faking and not offset:
                    handler.wfile.write(thead)
                logger.debug('"%s" is tivo compatible' % fname)
                f = open(fname, 'rb')
                try:
                    if mime == 'video/mp4':
                        count = qtfaststart.process(f, handler.wfile, offset)
                    else:
                        if offset:
                            offset -= len(thead)
                            f.seek(offset)
                        while True:
                            block = f.read(512 * 1024)
                            if not block:
                                break
                            handler.wfile.write(block)
                            count += len(block)
                except Exception, msg:
                    logger.info(msg)
                f.close()
            else:
                logger.debug('"%s" is not tivo compatible' % fname)
                if offset:
                    count = transcode.resume_transfer(path, handler.wfile, 
                                                      offset)
                else:
                    count = transcode.transcode(False, path, handler.wfile,
                                                tsn, mime, thead)
Exemplo n.º 30
0
    def send_file(self, handler, path, query):
        global status

        self.cleanup_status() # Keep status object from getting too big

        mime = 'video/x-tivo-mpeg'
        tsn = handler.headers.get('tsn', '')

        try:
            assert(tsn)
            tivo_name = config.tivos[tsn].get('name', tsn)
        except:
            tivo_name = handler.address_string()

        if not tivo_name in status:
            status[tivo_name] = {}

        is_tivo_file = False
        tivo_header_size = 0
        is_tivo_ts = False

        try:
            with open(path, 'rb') as f:
                tivo_header = f.read(16)

            if tivo_header[0:4] == b'TiVo':
                is_tivo_file = True
                tivo_header_size = struct.unpack_from('>L', tivo_header, 10)[0]

                if (tivo_header[7] & 0x20 != 0):
                    is_tivo_ts = True
        except:
            pass

        tivo_mak = config.get_tsn('tivo_mak', tsn)
        has_tivolibre = bool(config.get_bin('tivolibre'))
        has_tivodecode = bool(config.get_bin('tivodecode'))

        use_tivolibre = False
        if has_tivolibre and bool(config.get_server('tivolibre_upload', True)):
            use_tivolibre = True

        if 'Format' in query:
            mime = query['Format'][0]

        needs_tivodecode = (((is_tivo_file and is_tivo_ts) or
                            (is_tivo_file and not has_tivolibre)) and
                           mime == 'video/mpeg')
        compatible = (not needs_tivodecode and
                      transcode.tivo_compatible(path, tsn, mime)[0])

        try:  # "bytes=XXX-"
            offset = int(handler.headers.get('Range')[6:-1])
        except:
            offset = 0

        if needs_tivodecode:
            valid = bool((has_tivodecode or has_tivolibre) and tivo_mak)
        else:
            valid = True

        if valid and offset:
            valid = ((compatible and offset < os.path.getsize(path)) or
                     (not compatible and transcode.is_resumable(path, offset)))

            if status[tivo_name][path]:
                # Don't let the TiVo loop over and over in the same spot
                valid = (offset != status[tivo_name][path]['offset'])
                status[tivo_name][path]['error'] = 'Repeat offset call'

        #faking = (mime in ['video/x-tivo-mpeg-ts', 'video/x-tivo-mpeg'] and
        faking = (mime == 'video/x-tivo-mpeg' and
                  not (is_tivo_file and compatible))
        thead = ''
        if faking:
            thead = self.tivo_header(tsn, path, mime)

        size = os.path.getsize(path) + len(thead)
        if compatible:
            handler.send_response(200)
            handler.send_header('Content-Length', size - offset)
            handler.send_header('Content-Range', 'bytes %d-%d/%d' %
                                (offset, size - offset - 1, size))
        else:
            handler.send_response(206)
            handler.send_header('Transfer-Encoding', 'chunked')
        handler.send_header('Content-Type', mime)
        handler.end_headers()

        logger.info('[%s] Start sending "%s" to %s' %
                    (time.strftime('%d/%b/%Y %H:%M:%S'), path, tivo_name))

        if valid:
            start_time = time.time()
            last_interval = start_time
            now = start_time
            count = 0
            output = 0

            if path in status[tivo_name]:
                status[tivo_name][path]['active'] = True
                status[tivo_name][path]['offset'] = offset
            else:
                status[tivo_name][path] = {'active':        True,
                                           'decrypting':    False,
                                           'transcoding':   False,
                                           'offset':        offset,
                                           'start':         start_time,
                                           'end':           start_time,
                                           'rate':          0,
                                           'size':          size,
                                           'output':        0,
                                           'error':         '',
                                          }

            if compatible:
                logger.debug('"%s" is tivo compatible' % path)
                f = open(path, 'rb')
                tivolibre = None
                if not offset:
                    if faking:
                        handler.wfile.write(thead)
                        count += len(thead)
                        output += len(thead)
                    elif tivo_header_size > 0:
                        block = f.read(tivo_header_size)
                        handler.wfile.write(block)
                        count += len(block)
                        output += len(block)
                try:
                    if is_tivo_file and use_tivolibre:
                        status[tivo_name][path]['decrypting'] = True

                        f.close()
                        tivolibre_path = config.get_bin('tivolibre')
                        tcmd = [tivolibre_path, '-m', tivo_mak, '-i', path]
                        tivolibre = subprocess.Popen(tcmd, stdout=subprocess.PIPE, bufsize=(512 * 1024))
                        f = tivolibre.stdout

                    if offset:
                        if tivolibre:
                            raise Exception('tivolibre does not support offset')
                        offset -= len(thead)
                        f.seek(offset)

                    while True:
                        block = f.read(512 * 1024)
                        if not block:
                            break
                        handler.wfile.write(block)
                        count += len(block)
                        output += len(block)

                        now = time.time()
                        elapsed = now - last_interval
                        if elapsed >= 1:
                            status[tivo_name][path]['rate'] = (count * 8.0) / elapsed
                            status[tivo_name][path]['output'] += count
                            count = 0
                            last_interval = now

                    if tivolibre:
                        tivolibre.wait()

                except Exception as msg:
                    status[tivo_name][path]['error'] = str(msg)
                    if tivolibre:
                        tivolibre.kill()
                        tivolibre.wait()

                    logger.info(msg)

                f.close()
            else:
                logger.debug('"%s" is not tivo compatible' % path)
                status[tivo_name][path]['transcoding'] = True
                if offset:
                    count = transcode.resume_transfer(path, handler.wfile,
                                                      offset, status[tivo_name][path])
                else:
                    count = transcode.transcode(False, path, handler.wfile,
                                                status[tivo_name][path], is_tivo_file,
                                                tsn, mime, thead)

            end_time = time.time()
            elapsed = end_time - status[tivo_name][path]['start']
            rate = count * 8.0 / elapsed    # bits / sec

            status[tivo_name][path]['active'] = False
            status[tivo_name][path]['end'] = end_time
            status[tivo_name][path]['rate'] = rate

            logger.info('[{timestamp:%d/%b/%Y %H:%M:%S}] Done sending "{fname}" to {tivo_name}, '
                        '{mbps[0]:.2f} {mbps[1]}B/s ({num_bytes[0]:.3f} {num_bytes[1]}Bytes / {seconds:.0f} s)'
                        .format(timestamp=datetime.fromtimestamp(end_time),
                                fname=path, tivo_name=tivo_name,
                                num_bytes=prefix_bin_qty(count),
                                mbps=prefix_bin_qty(rate / 8),
                                seconds=elapsed))

        else:
            logger.info('Invalid file "{}" requested by {}'.format(path, tivo_name))

        try:
            if not compatible:
                handler.wfile.write(b'0\r\n\r\n')
            handler.wfile.flush()
        except Exception as msg:
            logger.exception('Exception writing an empty response for an incompatible file')
Exemplo n.º 31
0
    def Push(self, handler, query):
        tsn = query['tsn'][0]
        for key in config.tivo_names:
            if config.tivo_names[key] == tsn:
                tsn = key
                break
        tivo_name = config.tivo_names.get(tsn, tsn)

        container = quote(query['Container'][0].split('/')[0])
        ip = config.get_ip()
        port = config.getPort()

        baseurl = 'http://%s:%s' % (ip, port)
        if config.getIsExternal(tsn):
            exturl = config.get_server('externalurl')
            if exturl:
                baseurl = exturl
            else:
                ip = self.readip()
                baseurl = 'http://%s:%s' % (ip, port)
 
        path = self.get_local_base_path(handler, query)

        files = query.get('File', [])
        for f in files:
            file_path = path + os.path.normpath(f)

            file_info = VideoDetails()
            file_info['valid'] = transcode.supported_format(file_path)

            mime = 'video/mpeg'
            if config.isHDtivo(tsn):
                for m in ['video/mp4', 'video/bif']:
                    if transcode.tivo_compatible(file_path, tsn, m)[0]:
                        mime = m
                        break

            if file_info['valid']:
                file_info.update(self.metadata_full(file_path, tsn, mime))

            url = baseurl + '/%s%s' % (container, quote(f))

            title = file_info['seriesTitle']
            if not title:
                title = file_info['title']

            source = file_info['seriesId']
            if not source:
                source = title

            subtitle = file_info['episodeTitle']
            try:
                m = mind.getMind(tsn)
                m.pushVideo(
                    tsn = tsn,
                    url = url,
                    description = file_info['description'],
                    duration = file_info['duration'] / 1000,
                    size = file_info['size'],
                    title = title,
                    subtitle = subtitle,
                    source = source,
                    mime = mime,
                    tvrating = file_info['tvRating'])
            except Exception, e:
                handler.send_response(500)
                handler.end_headers()
                handler.wfile.write('%s\n\n%s' % (e, traceback.format_exc() ))
                raise

            logger.info('[%s] Queued "%s" for Push to %s' %
                        (time.strftime('%d/%b/%Y %H:%M:%S'),
                         unicode(file_path, 'utf-8'), tivo_name))
Exemplo n.º 32
0
def transcode(isQuery, inFile, outFile,
              status=None, isTivoFile=False, tsn='', mime='', thead=''):

    vcodec = select_videocodec(inFile, tsn, mime)

    settings = select_buffsize(tsn) + vcodec
    if not vcodec[1] == 'copy':
        settings += (select_videobr(inFile, tsn) +
                     select_maxvideobr(tsn) +
                     select_videofps(inFile, tsn) +
                     select_aspect(inFile, tsn))

    acodec = select_audiocodec(isQuery, inFile, tsn)
    settings += acodec
    if not acodec[1] == 'copy':
        settings += (select_audiobr(tsn) +
                     select_audiofr(inFile, tsn) +
                     select_audioch(inFile, tsn))

    settings += [select_audiolang(inFile, tsn),
                 select_ffmpegprams(tsn)]

    settings += select_format(tsn, mime)

    settings = ' '.join(settings).split()
    if isQuery:
        return settings

    ffmpeg_path = config.get_bin('ffmpeg')

    fname = inFile

    if isTivoFile:
        if status:
            status['decrypting'] = True

        tivo_mak = config.get_server('tivo_mak')
        tivolibre_path = config.get_bin('tivolibre')
        # prefer tivolibre to tivodecode
        if tivolibre_path:
            decode_cmd = [tivolibre_path, '-m', tivo_mak, '-i', fname]
        else:
            tivodecode_path = config.get_bin('tivodecode')
            if not tivodecode_path:
                raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
                                        'tivodecode executable')
            decode_cmd = [tivodecode_path, '-m', tivo_mak, fname]

        tivodecode = subprocess.Popen(decode_cmd, stdout=subprocess.PIPE,
                                      bufsize=(512 * 1024))
        if tivo_compatible(inFile, tsn)[0]:
            cmd = ''
            ffmpeg = tivodecode
        else:
            cmd = [ffmpeg_path, '-hide_banner', '-i', '-'] + settings
            ffmpeg = subprocess.Popen(cmd,
                                      stdin=tivodecode.stdout,
                                      stdout=subprocess.PIPE,
                                      bufsize=(512 * 1024))
    else:
        cmd = [ffmpeg_path, '-hide_banner', '-i', fname] + settings
        ffmpeg = subprocess.Popen(cmd,
                                  stdout=subprocess.PIPE,
                                  bufsize=(512 * 1024))

    if cmd:
        debug('transcoding to tivo model {} using ffmpeg command:'.format(tsn[:3]))
        debug(' '.join(cmd))

    ffmpeg_procs[inFile] = {'process': ffmpeg, 'start': 0, 'end': 0,
                            'last_read': time.time(), 'blocks': []}
    if thead:
        ffmpeg_procs[inFile]['blocks'].append(thead)
    reap_process(inFile)
    return resume_transfer(inFile, outFile, 0)
Exemplo n.º 33
0
queue = {} # Recordings to download -- list per TiVo
basic_meta = {} # Data from NPL, parsed, indexed by progam URL
details_urls = {} # URLs for extended data, indexed by main URL

def null_cookie(name, value):
    return cookielib.Cookie(0, name, value, None, False, '', False, 
        False, '', False, False, None, False, None, None, None)

auth_handler = urllib2.HTTPPasswordMgrWithDefaultRealm()
cj = cookielib.CookieJar()
cj.set_cookie(null_cookie('sid', 'ADEADDA7EDEBAC1E'))
tivo_opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj), 
                                   urllib2.HTTPBasicAuthHandler(auth_handler),
                                   urllib2.HTTPDigestAuthHandler(auth_handler))

tsn = config.get_server('togo_tsn')
if tsn:
    tivo_opener.addheaders.append(('TSN', tsn))

class ToGo(Plugin):
    CONTENT_TYPE = 'text/html'

    def tivo_open(self, url):
        # Loop just in case we get a server busy message
        while True:
            try:
                # Open the URL using our authentication/cookie opener
                return tivo_opener.open(url)

            # Do a retry if the TiVo responds that the server is busy
            except urllib2.HTTPError, e:
Exemplo n.º 34
0
def transcode(isQuery, inFile, outFile, tsn='', mime='', thead=''):
    vcodec = select_videocodec(inFile, tsn, mime)

    settings = select_buffsize(tsn) + vcodec
    if not vcodec[1] == 'copy':
        settings += (select_videobr(inFile, tsn) + select_maxvideobr(tsn) +
                     select_videofps(inFile, tsn) + select_aspect(inFile, tsn))

    acodec = select_audiocodec(isQuery, inFile, tsn)
    settings += acodec
    if not acodec[1] == 'copy':
        settings += (select_audiobr(tsn) + select_audiofr(inFile, tsn) +
                     select_audioch(inFile, tsn))

    settings += [select_audiolang(inFile, tsn), select_ffmpegprams(tsn)]

    settings += select_format(tsn, mime)

    settings = ' '.join(settings).split()
    if isQuery:
        return settings

    ffmpeg_path = config.get_bin('ffmpeg')

    fname = unicode(inFile, 'utf-8')
    if mswindows:
        fname = fname.encode('cp1252')

    if inFile[-5:].lower() == '.tivo':
        tivodecode_path = config.get_bin('tivodecode')
        tivo_mak = config.get_server('tivo_mak')
        tcmd = [tivodecode_path, '-m', tivo_mak, fname]
        tivodecode = subprocess.Popen(tcmd,
                                      stdout=subprocess.PIPE,
                                      bufsize=(512 * 1024))
        if tivo_compatible(inFile, tsn)[0]:
            cmd = ''
            ffmpeg = tivodecode
        else:
            cmd = [ffmpeg_path, '-i', '-'] + settings
            ffmpeg = subprocess.Popen(cmd,
                                      stdin=tivodecode.stdout,
                                      stdout=subprocess.PIPE,
                                      bufsize=(512 * 1024))
    else:
        cmd = [ffmpeg_path, '-i', fname] + settings
        ffmpeg = subprocess.Popen(cmd,
                                  bufsize=(512 * 1024),
                                  stdout=subprocess.PIPE)

    if cmd:
        debug('transcoding to tivo model ' + tsn[:3] +
              ' using ffmpeg command:')
        debug(' '.join(cmd))

    ffmpeg_procs[inFile] = {
        'process': ffmpeg,
        'start': 0,
        'end': 0,
        'last_read': time.time(),
        'blocks': []
    }
    if thead:
        ffmpeg_procs[inFile]['blocks'].append(thead)
    reap_process(inFile)
    return resume_transfer(inFile, outFile, 0)
Exemplo n.º 35
0
def select_videofilter(inFile):
    vInfo = video_info(inFile)
    #legacy subtitle support to be removed
    subtitles = vInfo.get('subtitles')
    if subtitles:
        return ['-vf', subtitles]

    embed = config.get_server('embedded_subs', 'Off')
    subfile = vInfo.get('subFile')
    if not subfile:
        if embed == 'On' or (embed == 'OnlyForced' and vInfo.get('forcedSub') != None):
            subfile = inFile

    logger.info("subfile: {0}".format(subfile))

    #first select a subFile in the metadata.txt file
    #then select the subFile with the same filename as the video file (video file: video.mpg, subFile: video.mpg.srt)
    if subfile and os.path.exists(os.path.join(os.path.split(inFile)[0], subfile)):
        subfile = os.path.join(os.path.split(inFile)[0], subfile)
    elif os.path.exists(os.path.join(os.path.split(inFile)[0], os.path.basename(inFile) + '.srt')):
        subfile = os.path.join(os.path.split(inFile)[0], os.path.basename(inFile) + '.srt')
    elif os.path.exists(os.path.join(os.path.split(inFile)[0], os.path.basename(inFile) + '.ass')):
        subfile = os.path.join(os.path.split(inFile)[0], os.path.basename(inFile) + '.ass')
    elif subfile == 'self':
        subfile = inFile
    elif not subfile or not os.path.exists(subfile):
        subfile = ''

    if subfile:
        sInfo = vInfo
        if subfile != inFile:
            sInfo = video_info(subfile)
            logger.info('sInfo: %s' % sInfo)

        subType = sInfo.get('subType')
        forcedsub = sInfo.get('forcedSub')
        logger.info("subType: {0}{1}".format(subType, '' if forcedsub == None else ' (forced)'))

        #escape ffmpeg special characters
        #subfile_escape = re.sub(r"'", r"\\\\\\'", subfile_escape) #can't seem to escape ' character
        subfile_escape = re.sub(r'([\\\[\]\:@;,])', r'\\\1', subfile)

        # Use "subStream" tag to determine which subtitle stream to use
        textSubStream = ''
        picSubStream = ''
        subStream = vInfo.get('subStream', forcedsub)
        if subStream != None and re.match(r'^[0-9]+$', str(subStream)):
            logger.info("subStream: {0}".format(subStream))
            textSubStream = ":si={0}".format(subStream)
            picSubStream = ":{0}".format(subStream)

        vfilter = []
        if re.search(r'ass|ssa', subType) and subfile != inFile:
            vfilter = ['-vf', "ass=\\'{0}\\'".format(subfile_escape)]
        elif re.search(r'ass|ssa|subrip|srt|sup|sami|text|microdvd|subviewer|stl|jaco|mpl|pjs|vplayer|eia|webvtt', subType): # jacosub can also include gfx?
            vfilter = ['-vf', "subtitles=\\'{0}\\'{1}".format(subfile_escape, textSubStream)]
        elif re.search(r'pgs|vob|dvdsub|dvd_subtitle', subType):
            vfilter = ['-filter_complex', "[0:v][0:s{0}]overlay".format(picSubStream)]

        if vfilter:
            logger.info('video filter: %s' % vfilter)
            return vfilter

    return False
Exemplo n.º 36
0
    def push_one_file(self, f):
        file_info = VideoDetails()
        file_info['valid'] = transcode.supported_format(f['path'])

        temp_share = config.get_server('temp_share', '')
        temp_share_path = ''
        remux_path = os.path.dirname(f['path'])
        if temp_share:
            for name, data in config.getShares():
                if temp_share == name:
                    temp_share_path = data.get('path')
                    remux_path = temp_share_path

        mime = 'video/mpeg'
        if config.isHDtivo(f['tsn']):
            for m in ['video/mp4', 'video/bif']:
                if transcode.tivo_compatible(f['path'], f['tsn'], m)[0]:
                    mime = m
                    break

            if (mime == 'video/mpeg' and
                transcode.mp4_remuxable(f['path'], f['tsn'])):
                if config.get_freeSpace(remux_path, f['path']):
                    new_path = transcode.mp4_remux(f['path'], f['name'], f['tsn'], temp_share_path)
                    if new_path:
                        mime = 'video/mp4'
                        f['name'] = new_path
                        if temp_share_path:
                            ip = config.get_ip()
                            port = config.getPort()
                            container = quote(temp_share) + '/'
                            f['url'] = 'http://%s:%s/%s' % (ip, port, container)
                else:
                    logger.warning('Not enough disk space to perform remux, ' +
                                   'transcoding instead.')

        if file_info['valid']:
            file_info.update(self.metadata_full(f['path'], f['tsn'], mime))

        url = f['url'] + quote(f['name'])

        title = file_info['seriesTitle']
        if not title:
            title = file_info['title']

        source = file_info['seriesId']
        if not source:
            source = title

        subtitle = file_info['episodeTitle']
        try:
            m = mind.getMind(f['tsn'])
            m.pushVideo(
                tsn = f['tsn'],
                url = url,
                description = file_info['description'],
                duration = file_info['duration'] / 1000,
                size = file_info['size'],
                title = title,
                subtitle = subtitle,
                source = source,
                mime = mime,
                tvrating = file_info['tvRating'])
        except ValueError, msg:
            if 'usernamePasswordError' in msg:
                if f['name'].endswith('.pyTivo-temp'):
                    fname = os.path.join(remux_path, os.path.basename(f['name']))
                    fname = unicode(fname, 'utf-8')
                    os.remove(fname)
                    logger.debug(fname + ' has been removed')
Exemplo n.º 37
0
def transcode(isQuery, inFile, outFile, tsn='', mime='', thead=''):
    settings = {
        'video_codec': select_videocodec(inFile, tsn, mime),
        'video_br': select_videobr(inFile, tsn),
        'video_fps': select_videofps(inFile, tsn),
        'max_video_br': select_maxvideobr(tsn),
        'buff_size': select_buffsize(tsn),
        'aspect_ratio': ' '.join(select_aspect(inFile, tsn)),
        'audio_br': select_audiobr(tsn),
        'audio_fr': select_audiofr(inFile, tsn),
        'audio_ch': select_audioch(inFile, tsn),
        'audio_codec': select_audiocodec(isQuery, inFile, tsn),
        'audio_lang': select_audiolang(inFile, tsn),
        'ffmpeg_pram': select_ffmpegprams(tsn),
        'format': select_format(tsn, mime)
    }

    if isQuery:
        return settings

    ffmpeg_path = config.get_bin('ffmpeg')
    cmd_string = config.getFFmpegTemplate(tsn) % settings
    fname = unicode(inFile, 'utf-8')
    if mswindows:
        fname = fname.encode('cp1252')

    if inFile[-5:].lower() == '.tivo':
        tivodecode_path = config.get_bin('tivodecode')
        tivo_mak = config.get_server('tivo_mak')
        tcmd = [tivodecode_path, '-m', tivo_mak, fname]
        tivodecode = subprocess.Popen(tcmd,
                                      stdout=subprocess.PIPE,
                                      bufsize=(512 * 1024))
        if tivo_compatible(inFile, tsn)[0]:
            cmd = ''
            ffmpeg = tivodecode
        else:
            cmd = [ffmpeg_path, '-i', '-'] + cmd_string.split()
            ffmpeg = subprocess.Popen(cmd,
                                      stdin=tivodecode.stdout,
                                      stdout=subprocess.PIPE,
                                      bufsize=(512 * 1024))
    else:
        cmd = [ffmpeg_path, '-i', fname] + cmd_string.split()
        ffmpeg = subprocess.Popen(cmd,
                                  bufsize=(512 * 1024),
                                  stdout=subprocess.PIPE)

    if cmd:
        debug('transcoding to tivo model ' + tsn[:3] +
              ' using ffmpeg command:')
        debug(' '.join(cmd))

    ffmpeg_procs[inFile] = {
        'process': ffmpeg,
        'start': 0,
        'end': 0,
        'last_read': time.time(),
        'blocks': []
    }
    if thead:
        ffmpeg_procs[inFile]['blocks'].append(thead)
    reap_process(inFile)
    return resume_transfer(inFile, outFile, 0)