Example #1
0
 def root_container(self):
     tsn = self.headers.getheader('TiVo_TCD_ID', '')
     tsnshares = config.getShares(tsn)
     tsncontainers = []
     for section, settings in tsnshares:
         try:
             mime = GetPlugin(settings['type']).CONTENT_TYPE
             if mime.split('/')[1] in ('tivo-videos', 'tivo-music',
                                       'tivo-photos'):
                 settings['content_type'] = mime
                 tsncontainers.append((section, settings))
         except Exception, msg:
             self.server.logger.error(section + ' - ' + str(msg))
Example #2
0
 def root_container(self):
     tsn = self.headers.getheader('TiVo_TCD_ID', '')
     tsnshares = config.getShares(tsn)
     tsncontainers = []
     for section, settings in tsnshares:
         try:
             mime = GetPlugin(settings['type']).CONTENT_TYPE
             if mime.split('/')[1] in ('tivo-videos', 'tivo-music',
                                       'tivo-photos'):
                 settings['content_type'] = mime
                 tsncontainers.append((section, settings))
         except Exception, msg:
             self.server.logger.error(section + ' - ' + str(msg))
Example #3
0
 def add_container(self, name, settings):
     if self.containers.has_key(name) or name == 'TiVoConnect':
         raise "Container Name in use"
     try:
         settings['content_type'] = GetPlugin(settings['type']).CONTENT_TYPE
         self.containers[name] = settings
     except KeyError:
         print 'Unable to add container', name
Example #4
0
    def handle_query(self, query, tsn):
        mname = False
        if 'Command' in query and len(query['Command']) >= 1:

            command = query['Command'][0]

            # If we are looking at the root container
            if (command == 'QueryContainer' and
                (not 'Container' in query or query['Container'][0] == '/')):
                self.root_container()
                return

            if 'Container' in query:
                # Dispatch to the container plugin
                basepath = query['Container'][0].split('/')[0]
                if self.do_command(query, command, basepath, tsn):
                    return

            elif command == 'QueryItem':
                path = query.get('Url', [''])[0]
                splitpath = [x for x in unquote_plus(path).split('/') if x]
                if splitpath and not '..' in splitpath:
                    if self.do_command(query, command, splitpath[0], tsn):
                        return

            elif (command == 'QueryFormats' and 'SourceFormat' in query
                  and query['SourceFormat'][0].startswith('video')):
                if config.is_ts_capable(tsn):
                    self.send_xml(VIDEO_FORMATS_TS)
                else:
                    self.send_xml(VIDEO_FORMATS)
                return

            elif command == 'QueryServer':
                self.send_xml(SERVER_INFO)
                return

            elif command in ('GetActiveTransferCount', 'GetTransferStatus'):
                plugin = GetPlugin('video')
                if hasattr(plugin, command):
                    method = getattr(plugin, command)
                    method(self, query)
                    return True

            elif command in ('FlushServer', 'ResetServer'):
                # Does nothing -- included for completeness
                self.send_response(200)
                self.send_header('Content-Length', '0')
                self.end_headers()
                self.wfile.flush()
                return

        # If we made it here it means we couldn't match the request to
        # anything.
        self.unsupported(query)
Example #5
0
    def handle_file(self, query, splitpath):
        if '..' not in splitpath:    # Protect against path exploits
            ## Pass it off to a plugin?
            for name, container in self.server.containers.items():
                if splitpath[0] == name:
                    self.cname = name
                    self.container = container
                    base = os.path.normpath(container['path'])
                    path = os.path.join(base, *splitpath[1:])
                    plugin = GetPlugin(container['type'])
                    plugin.send_file(self, path, query)
                    return

            ## Serve it from a "content" directory?
            base = os.path.join(SCRIPTDIR, *splitpath[:-1])
            path = os.path.join(base, 'content', splitpath[-1])

            if os.path.isfile(path):
                try:
                    handle = open(path, 'rb')
                except:
                    self.send_error(404)
                    return

                # Send the header
                mime = mimetypes.guess_type(path)[0]
                self.send_response(200)
                if mime:
                    self.send_header('Content-type', mime)
                self.send_header('Content-length', os.path.getsize(path))
                self.end_headers()

                # Send the body of the file
                try:
                    shutil.copyfileobj(handle, self.wfile)
                except:
                    pass
                handle.close()
                return

        ## Give up
        self.send_error(404)
Example #6
0
    def handle_file(self, query, splitpath):
        if '..' not in splitpath:  # Protect against path exploits
            ## Pass it off to a plugin?
            for name, container in self.server.containers.items():
                if splitpath[0] == name:
                    self.cname = name
                    self.container = container
                    base = os.path.normpath(container['path'])
                    path = os.path.join(base, *splitpath[1:])
                    plugin = GetPlugin(container['type'])
                    plugin.send_file(self, path, query)
                    return

            ## Serve it from a "content" directory?
            base = os.path.join(SCRIPTDIR, *splitpath[:-1])
            path = os.path.join(base, 'content', splitpath[-1])

            if os.path.isfile(path):
                try:
                    handle = open(path, 'rb')
                except:
                    self.send_error(404)
                    return

                # Send the header
                mime = mimetypes.guess_type(path)[0]
                self.send_response(200)
                if mime:
                    self.send_header('Content-type', mime)
                self.send_header('Content-length', os.path.getsize(path))
                self.end_headers()

                # Send the body of the file
                try:
                    shutil.copyfileobj(handle, self.wfile)
                except:
                    pass
                handle.close()
                return

        ## Give up
        self.send_error(404)
Example #7
0
 def root_container(self):
     tsn = self.headers.getheader('TiVo_TCD_ID', '')
     tsnshares = config.getShares(tsn)
     tsncontainers = {}
     for section, settings in tsnshares:
         try:
             settings['content_type'] = \
                 GetPlugin(settings['type']).CONTENT_TYPE
             tsncontainers[section] = settings
         except Exception, msg:
             print section, '-', msg
Example #8
0
 def do_command(self, query, command, target, tsn):
     for name, container in config.getShares(tsn):
         if target == name:
             plugin = GetPlugin(container['type'])
             if hasattr(plugin, command):
                 self.cname = name
                 self.container = container
                 method = getattr(plugin, command)
                 method(self, query)
                 return True
             else:
                 break
     return False
Example #9
0
 def root_container(self):
     tsn = self.headers.get('TiVo_TCD_ID', '')
     tsnshares = config.getShares(tsn)
     tsncontainers = []
     for section, settings in tsnshares:
         try:
             mime = GetPlugin(settings['type']).CONTENT_TYPE
             if mime.split('/')[1] in ('tivo-videos', 'tivo-music',
                                       'tivo-photos'):
                 settings['content_type'] = mime
                 tsncontainers.append((section, settings))
         except Exception as msg:
             self.server.logger.error('%s - %s', section, str(msg))
     t = Template(file=os.path.join(SCRIPTDIR, 'templates', 'root_container.tmpl'))
     if self.server.beacon.bd:
         t.renamed = self.server.beacon.bd.renamed
     else:
         t.renamed = {}
     t.containers = tsncontainers
     t.hostname = socket.gethostname()
     t.escape = escape
     t.quote = quote
     self.send_xml(str(t))
Example #10
0
    def handle_file(self, query, splitpath):
        if '..' not in splitpath:    # Protect against path exploits
            ## Pass it off to a plugin?
            for name, container in self.server.containers.items():
                if splitpath[0] == name:
                    self.cname = name
                    self.container = container
                    base = os.path.normpath(container['path'])
                    path = os.path.join(base, *splitpath[1:])
                    plugin = GetPlugin(container['type'])
                    plugin.send_file(self, path, query)
                    return

            ## Serve it from a "content" directory?
            base = os.path.join(SCRIPTDIR, *splitpath[:-1])
            path = os.path.join(base, 'content', splitpath[-1])

            if os.path.isfile(path):
                self.send_content_file(path)
                return

        ## Give up
        self.send_error(404)
Example #11
0
    def handle_file(self, query, splitpath):
        if '..' not in splitpath:  # Protect against path exploits
            ## Pass it off to a plugin?
            for name, container in self.server.containers.items():
                if splitpath[0] == name:
                    self.cname = name
                    self.container = container
                    base = os.path.normpath(container['path'])
                    path = os.path.join(base, *splitpath[1:])
                    plugin = GetPlugin(container['type'])
                    plugin.send_file(self, path, query)
                    return

            ## Serve it from a "content" directory?
            base = os.path.join(SCRIPTDIR, *splitpath[:-1])
            path = os.path.join(base, 'content', splitpath[-1])

            if os.path.isfile(path):
                self.send_content_file(path)
                return

        ## Give up
        self.send_error(404)
Example #12
0
def setup(in_service=False):
    config.init(sys.argv[1:])
    config.init_logging()
    sys.excepthook = exceptionLogger

    port = config.getPort()

    httpd = httpserver.TivoHTTPServer(('', int(port)),
                                      httpserver.TivoHTTPHandler)

    logger = logging.getLogger('pyTivo')
    logger.info('Last modified: ' + last_date())
    logger.info('Python: ' + platform.python_version())
    logger.info('System: ' + platform.platform())

    for section, settings in config.getShares():
        httpd.add_container(section, settings)
        # Precaching of files: does a recursive list of base path
        if settings.get('precache', 'False').lower() == 'true':
            plugin = GetPlugin(settings.get('type'))
            if hasattr(plugin, 'pre_cache'):
                logger.info('Pre-caching the ' + section + ' share.')
                pre_cache_filter = getattr(plugin, 'pre_cache')

                def build_recursive_list(path):
                    try:
                        for f in os.listdir(path):
                            f = os.path.join(path, f)
                            if os.path.isdir(f):
                                build_recursive_list(f)
                            else:
                                pre_cache_filter(f)
                    except:
                        pass

                build_recursive_list(settings.get('path'))

    b = beacon.Beacon()
    b.add_service('TiVoMediaServer:%s/http' % port)
    b.start()
    if 'listen' in config.getBeaconAddresses():
        b.listen()

    httpd.set_beacon(b)
    httpd.set_service_status(in_service)

    logger.info('pyTivo is ready.')
    return httpd
Example #13
0
    def do_GET(self):
        tsn = self.headers.getheader('TiVo_TCD_ID', self.headers.getheader('tsn', ''))
        ip = self.address_string()
        self.tivos[tsn] = ip
               
        basepath = unquote_plus(self.path).split('/')[1]

        ## Get File
        for name, container in self.server.containers.items():
            if basepath == name:
                plugin = GetPlugin(container['type'])
                plugin.send_file(self, container, name)
                return

        ## Not a file not a TiVo command f**k them
        if not self.path.startswith('/TiVoConnect'):
            self.infopage()
            return

        o = urlparse("http://fake.host" + self.path)
        query = parse_qs(o[4])

        mname = False
        if query.has_key('Command') and len(query['Command']) >= 1:

            command = query['Command'][0]

            # If we are looking at the root container
            if command == "QueryContainer" and \
               (not query.has_key('Container') or query['Container'][0] == '/'):
                self.root_container()
                return 

            if query.has_key('Container'):
                # Dispatch to the container plugin
                basepath = unquote(query['Container'][0].split('/')[0])
                for name, container in self.server.containers.items():
                    if basepath == name:
                        plugin = GetPlugin(container['type'])
                        if hasattr(plugin, command):
                            method = getattr(plugin, command)
                            method(self, query)
                            return
                        else:
                            break

        # If we made it here it means we couldn't match the request to 
        # anything.
        self.unsupported(query)
Example #14
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 = ''

        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 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>')
            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))
Example #15
0
    def unsupported(self, query):
        if hack83 and 'Command' in query and 'Filter' in query:
            debug_write(__name__, fn_attr(), ['Unsupported request,',
                         'checking to see if it is video.'])
            command = query['Command'][0]
            plugin = GetPlugin('video')
            if ''.join(query['Filter']).find('video') >= 0 and \
               hasattr(plugin, command):
                debug_write(__name__, fn_attr(), ['Unsupported request,',
                             'yup it is video',
                             'send to video plugin for it to sort out.'])
                method = getattr(plugin, command)
                method(self, query)
                return

        self.send_response(404)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        t = Template(file=os.path.join(SCRIPTDIR, 'templates',
                                       'unsupported.tmpl'))
        t.query = query
        self.wfile.write(t)
Example #16
0
#!/usr/bin/env python

import beacon, httpserver, os, sys
import config
from plugin import GetPlugin

port = config.getPort()

httpd = httpserver.TivoHTTPServer(('', int(port)), httpserver.TivoHTTPHandler)

for section, settings in config.getShares():
    httpd.add_container(section, settings)
    # Precaching of files: does a recursive list of base path
    if settings.get('precache', 'False').lower() == 'true':
        plugin = GetPlugin(settings.get('type'))
        if hasattr(plugin, 'pre_cache'):
            print 'Pre-caching the', section, 'share.'
            pre_cache_filter = getattr(plugin, 'pre_cache')

            def build_recursive_list(path):
                try:
                    for f in os.listdir(path):
                        f = os.path.join(path, f)
                        if os.path.isdir(f):
                            build_recursive_list(f)
                        else:
                            pre_cache_filter(f)
                except:
                    pass

            build_recursive_list(settings.get('path'))