예제 #1
0
파일: photo.py 프로젝트: armooo/pytivo
    def send_file(self, handler, container, name):

        def send_jpeg(data):
            handler.send_response(200)
            handler.send_header('Content-Type', 'image/jpeg')
            handler.send_header('Content-Length', len(data))
            handler.send_header('Connection', 'close')
            handler.end_headers()
            handler.wfile.write(data)

        path, query = handler.path.split('?')
        infile = os.path.join(os.path.normpath(container['path']),
                              unquote(path)[len(name) + 2:])
        opts = cgi.parse_qs(query)

        if 'Format' in opts and opts['Format'][0] != 'image/jpeg':
            handler.send_error(415)
            return

        try:
            attrs = self.media_data_cache[infile]
        except:
            attrs = None

        # Set rotation
        if attrs:
            rot = attrs['rotation']
        else:
            rot = 0

        if 'Rotation' in opts:
            rot = (rot - int(opts['Rotation'][0])) % 360
            if attrs:
                attrs['rotation'] = rot
                if 'thumb' in attrs:
                    del attrs['thumb']

        # Requested size
        width = int(opts.get('Width', ['0'])[0])
        height = int(opts.get('Height', ['0'])[0])

        # Return saved thumbnail?
        if attrs and 'thumb' in attrs and 0 < width < 100 and 0 < height < 100:
            send_jpeg(attrs['thumb'])
            return

        # Load
        try:
            pic = Image.open(unicode(infile, 'utf-8'))
        except Exception, msg:
            print 'Could not open', infile, '--', msg
            handler.send_error(404)
            return
예제 #2
0
    def send_file(self, handler, container, name):
        def send_jpeg(data):
            handler.send_response(200)
            handler.send_header('Content-Type', 'image/jpeg')
            handler.send_header('Content-Length', len(data))
            handler.send_header('Connection', 'close')
            handler.end_headers()
            handler.wfile.write(data)

        path, query = handler.path.split('?')
        infile = os.path.join(os.path.normpath(container['path']),
                              unquote(path)[len(name) + 2:])
        opts = cgi.parse_qs(query)

        if 'Format' in opts and opts['Format'][0] != 'image/jpeg':
            handler.send_error(415)
            return

        try:
            attrs = self.media_data_cache[infile]
        except:
            attrs = None

        # Set rotation
        if attrs:
            rot = attrs['rotation']
        else:
            rot = 0

        if 'Rotation' in opts:
            rot = (rot - int(opts['Rotation'][0])) % 360
            if attrs:
                attrs['rotation'] = rot
                if 'thumb' in attrs:
                    del attrs['thumb']

        # Requested size
        width = int(opts.get('Width', ['0'])[0])
        height = int(opts.get('Height', ['0'])[0])

        # Return saved thumbnail?
        if attrs and 'thumb' in attrs and 0 < width < 100 and 0 < height < 100:
            send_jpeg(attrs['thumb'])
            return

        # Load
        try:
            pic = Image.open(unicode(infile, 'utf-8'))
        except Exception, msg:
            print 'Could not open', infile, '--', msg
            handler.send_error(404)
            return
예제 #3
0
    def send_file(self, handler, container, name):
        seek, duration = 0, 0

        try:
            path, query = handler.path.split('?')
        except ValueError:
            path = handler.path
        else:
            opts = cgi.parse_qs(query)
            if 'Seek' in opts:
                seek = int(opts['Seek'][0])
            if 'Duration' in opts:
                seek = int(opts['Duration'][0])

        fname = os.path.join(os.path.normpath(container['path']),
                             unquote(path)[len(name) + 2:])
        fname = unicode(fname, 'utf-8')

        needs_transcode = os.path.splitext(fname)[1].lower() in TRANSCODE \
                          or seek or duration

        handler.send_response(200)
        handler.send_header('Content-Type', 'audio/mpeg')
        if not needs_transcode:
            fsize = os.path.getsize(fname)
            handler.send_header('Content-Length', fsize)
        handler.send_header('Connection', 'close')
        handler.end_headers()

        if needs_transcode:
            if mswindows:
                fname = fname.encode('iso8859-1')
            cmd = [ffmpeg_path(), '-i', fname, '-acodec', 'libmp3lame', '-ab', 
                   '320k', '-ar', '44100', '-f', 'mp3', '-']
            if seek:
                cmd[-1:] = ['-ss', '%.3f' % (seek / 1000.0), '-']
            if duration:
                cmd[-1:] = ['-t', '%.3f' % (duration / 1000.0), '-']

            ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE)
            try:
                shutil.copyfileobj(ffmpeg.stdout, handler.wfile)
            except:
                kill(ffmpeg.pid)
        else:
            f = file(fname, 'rb')
            try:
                shutil.copyfileobj(f, handler.wfile)
            except:
                pass
예제 #4
0
파일: music.py 프로젝트: pudney/pytivo
    def send_file(self, handler, container, name):
        seek, duration = 0, 0

        try:
            path, query = handler.path.split("?")
        except ValueError:
            path = handler.path
        else:
            opts = cgi.parse_qs(query)
            if "Seek" in opts:
                seek = int(opts["Seek"][0])
            if "Duration" in opts:
                seek = int(opts["Duration"][0])

        fname = os.path.join(os.path.normpath(container["path"]), unquote(path)[len(name) + 2 :])
        fname = unicode(fname, "utf-8")

        needs_transcode = os.path.splitext(fname)[1].lower() in TRANSCODE or seek or duration

        handler.send_response(200)
        handler.send_header("Content-Type", "audio/mpeg")
        if not needs_transcode:
            fsize = os.path.getsize(fname)
            handler.send_header("Content-Length", fsize)
        handler.send_header("Connection", "close")
        handler.end_headers()

        if needs_transcode:
            if mswindows:
                fname = fname.encode("iso8859-1")
            cmd = [ffmpeg_path(), "-i", fname, "-acodec", "libmp3lame", "-ab", "320k", "-ar", "44100", "-f", "mp3", "-"]
            if seek:
                cmd[-1:] = ["-ss", "%.3f" % (seek / 1000.0), "-"]
            if duration:
                cmd[-1:] = ["-t", "%.3f" % (duration / 1000.0), "-"]

            ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE)
            try:
                shutil.copyfileobj(ffmpeg.stdout, handler.wfile)
            except:
                kill(ffmpeg.pid)
        else:
            f = file(fname, "rb")
            try:
                shutil.copyfileobj(f, handler.wfile)
            except:
                pass
예제 #5
0
파일: video.py 프로젝트: armooo/pytivo
    def Push(self, handler, query):
        file = unquote(query['File'][0])
        tsn = query['tsn'][0]
        path = self.get_local_path(handler, query)
        file_path = path + file

        file_info = VideoDetails()
        file_info['valid'] = transcode.supported_format(file_path)
        if file_info['valid']:
            file_info.update(self.__metadata_full(file_path, tsn))

        import socket
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('tivo.com',123))
        ip = s.getsockname()[0]
        container = quote(query['Container'][0].split('/')[0])
        port = config.getPort()

        url = 'http://%s:%s/%s%s' % (ip, port, container, quote(file))

        print 'tsn', tsn
        print 'url', url
        print query

        username = config.getTivoUsername()
        password = config.getTivoPassword()

        if not username or not password:
            raise Exception("tivo_username and tivo_password required")

        try:
            m = mind.Mind(username, password, True)
            m.pushVideo(
                tsn = tsn, 
                url = url, 
                description = file_info['description'],
                duration = file_info['duration'] / 1000,
                size = file_info['size'],
                title = file_info['title'],
                subtitle = file_info['name'])
        except Exception, e:
            import traceback
            handler.send_response(500)
            handler.end_headers()
            handler.wfile.write('%s\n\n%s' % (e, traceback.format_exc() ))
            raise
예제 #6
0
    def Push(self, handler, query):
        file = unquote(query['File'][0])
        tsn = query['tsn'][0]
        path = self.get_local_path(handler, query)
        file_path = path + file

        file_info = VideoDetails()
        file_info['valid'] = transcode.supported_format(file_path)
        if file_info['valid']:
            file_info.update(self.__metadata_full(file_path, tsn))

        import socket
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('tivo.com', 123))
        ip = s.getsockname()[0]
        container = quote(query['Container'][0].split('/')[0])
        port = config.getPort()

        url = 'http://%s:%s/%s%s' % (ip, port, container, quote(file))

        print 'tsn', tsn
        print 'url', url
        print query

        username = config.getTivoUsername()
        password = config.getTivoPassword()

        if not username or not password:
            raise Exception("tivo_username and tivo_password required")

        try:
            m = mind.Mind(username, password, True)
            m.pushVideo(tsn=tsn,
                        url=url,
                        description=file_info['description'],
                        duration=file_info['duration'] / 1000,
                        size=file_info['size'],
                        title=file_info['title'],
                        subtitle=file_info['name'])
        except Exception, e:
            import traceback
            handler.send_response(500)
            handler.end_headers()
            handler.wfile.write('%s\n\n%s' % (e, traceback.format_exc()))
            raise
예제 #7
0
파일: video.py 프로젝트: armooo/pytivo
    def send_file(self, handler, container, name):
        if handler.headers.getheader('Range') and \
           handler.headers.getheader('Range') != 'bytes=0-':
            handler.send_response(206)
            handler.send_header('Connection', 'close')
            handler.send_header('Content-Type', 'video/x-tivo-mpeg')
            handler.send_header('Transfer-Encoding', 'chunked')
            handler.end_headers()
            handler.wfile.write("\x30\x0D\x0A")
            return

        tsn = handler.headers.getheader('tsn', '')

        o = urlparse("http://fake.host" + handler.path)
        path = unquote(o[2])
        handler.send_response(200)
        handler.end_headers()
        transcode.output_video(container['path'] + path[len(name) + 1:],
                               handler.wfile, tsn)
예제 #8
0
    def send_file(self, handler, container, name):
        if handler.headers.getheader('Range') and \
           handler.headers.getheader('Range') != 'bytes=0-':
            handler.send_response(206)
            handler.send_header('Connection', 'close')
            handler.send_header('Content-Type', 'video/x-tivo-mpeg')
            handler.send_header('Transfer-Encoding', 'chunked')
            handler.end_headers()
            handler.wfile.write("\x30\x0D\x0A")
            return

        tsn = handler.headers.getheader('tsn', '')

        o = urlparse("http://fake.host" + handler.path)
        path = unquote(o[2])
        handler.send_response(200)
        handler.end_headers()
        transcode.output_video(container['path'] + path[len(name) + 1:],
                               handler.wfile, tsn)
예제 #9
0
파일: music.py 프로젝트: Gimpson/pytivo
    def get_playlist(self, handler, query):
        subcname = query['Container'][0]
        cname = subcname.split('/')[0]

        try:
            url = subcname.index('http://')
            list_name = subcname[url:]
        except:
            list_name = self.get_local_path(handler, query)

        recurse = query.get('Recurse', ['No'])[0] == 'Yes'
        playlist = self.parse_playlist(list_name, recurse)

        # Shuffle?
        if 'Random' in query.get('SortOrder', ['Normal'])[0]:
            seed = query.get('RandomSeed', [''])[0]
            start = query.get('RandomStart', [''])[0]

            self.random_lock.acquire()
            if seed:
                random.seed(seed)
            random.shuffle(playlist)
            self.random_lock.release()
            if start:
                local_base_path = self.get_local_base_path(handler, query)
                start = unquote(start)
                start = start.replace(os.path.sep + cname,
                                      local_base_path, 1)
                filenames = [x.name for x in playlist]
                try:
                    index = filenames.index(start)
                    i = playlist.pop(index)
                    playlist.insert(0, i)
                except ValueError:
                    handler.server.logger.warning('Start not found: ' + start)

        # Trim the list
        return self.item_count(handler, query, cname, playlist)
예제 #10
0
    def get_playlist(self, handler, query):
        subcname = query['Container'][0]

        try:
            url = subcname.index('http://')
            list_name = subcname[url:]
        except:
            list_name = self.get_local_path(handler, query)

        recurse = query.get('Recurse', ['No'])[0] == 'Yes'
        playlist = self.parse_playlist(list_name, recurse)

        # Shuffle?
        if 'Random' in query.get('SortOrder', ['Normal'])[0]:
            seed = query.get('RandomSeed', [''])[0]
            start = query.get('RandomStart', [''])[0]

            self.random_lock.acquire()
            if seed:
                random.seed(seed)
            random.shuffle(playlist)
            self.random_lock.release()
            if start:
                local_base_path = self.get_local_base_path(handler, query)
                start = unquote(start)
                start = start.replace(os.path.sep + handler.cname,
                                      local_base_path, 1)
                filenames = [x.name for x in playlist]
                try:
                    index = filenames.index(start)
                    i = playlist.pop(index)
                    playlist.insert(0, i)
                except ValueError:
                    handler.server.logger.warning('Start not found: ' + start)

        # Trim the list
        return self.item_count(handler, query, handler.cname, playlist)
예제 #11
0
    def get_files(self, handler, query, filterFunction=None):
        class SortList:
            def __init__(self, files):
                self.files = files
                self.unsorted = True
                self.sortby = None
                self.last_start = 0

        def build_recursive_list(path, recurse=True):
            files = []
            path = unicode(path, 'utf-8')
            try:
                for f in os.listdir(path):
                    if f.startswith('.'):
                        continue
                    f = os.path.join(path, f)
                    isdir = os.path.isdir(f)
                    f = f.encode('utf-8')
                    if recurse and isdir:
                        files.extend(build_recursive_list(f))
                    else:
                        fd = FileData(f, isdir)
                        if recurse and fd.isplay:
                            files.extend(self.parse_playlist(f, recurse))
                        elif isdir or filterFunction(f, file_type):
                            files.append(fd)
            except:
                pass
            return files

        def dir_sort(x, y):
            if x.isdir == y.isdir:
                if x.isplay == y.isplay:
                    return name_sort(x, y)
                else:
                    return y.isplay - x.isplay
            else:
                return y.isdir - x.isdir

        def name_sort(x, y):
            return cmp(x.name, y.name)

        path = self.get_local_path(handler, query)

        file_type = query.get('Filter', [''])[0]

        recurse = query.get('Recurse', ['No'])[0] == 'Yes'

        filelist = []
        rc = self.recurse_cache
        dc = self.dir_cache
        if recurse:
            if path in rc:
                filelist = rc[path]
        else:
            updated = os.stat(unicode(path, 'utf-8'))[8]
            if path in dc and dc.mtime(path) >= updated:
                filelist = dc[path]
            for p in rc:
                if path.startswith(p) and rc.mtime(p) < updated:
                    del rc[p]

        if not filelist:
            filelist = SortList(build_recursive_list(path, recurse))

            if recurse:
                rc[path] = filelist
            else:
                dc[path] = filelist

        # Sort it
        seed = ''
        start = ''
        sortby = query.get('SortOrder', ['Normal'])[0]
        if 'Random' in sortby:
            if 'RandomSeed' in query:
                seed = query['RandomSeed'][0]
                sortby += seed
            if 'RandomStart' in query:
                start = query['RandomStart'][0]
                sortby += start

        if filelist.unsorted or filelist.sortby != sortby:
            if 'Random' in sortby:
                self.random_lock.acquire()
                if seed:
                    random.seed(seed)
                random.shuffle(filelist.files)
                self.random_lock.release()
                if start:
                    local_base_path = self.get_local_base_path(handler, query)
                    start = unquote(start)
                    start = start.replace(os.path.sep + handler.cname,
                                          local_base_path, 1)
                    filenames = [x.name for x in filelist.files]
                    try:
                        index = filenames.index(start)
                        i = filelist.files.pop(index)
                        filelist.files.insert(0, i)
                    except ValueError:
                        handler.server.logger.warning('Start not found: ' +
                                                      start)
            else:
                filelist.files.sort(dir_sort)

            filelist.sortby = sortby
            filelist.unsorted = False

        files = filelist.files[:]

        # Trim the list
        files, total, start = self.item_count(handler, query, handler.cname,
                                              files, filelist.last_start)
        filelist.last_start = start
        return files, total, start
예제 #12
0
파일: music.py 프로젝트: mlippert/pytivo
    def get_files(self, handler, query, filterFunction=None):

        class SortList:
            def __init__(self, files):
                self.files = files
                self.unsorted = True
                self.sortby = None
                self.last_start = 0

        def build_recursive_list(path, recurse=True):
            files = []
            try:
                for f in os.listdir(path):
                    if f.startswith('.'):
                        continue
                    f = os.path.join(path, f)
                    isdir = os.path.isdir(f)
                    if sys.platform == 'darwin':
                        f = unicodedata.normalize('NFC', f)
                    if recurse and isdir:
                        files.extend(build_recursive_list(f))
                    else:
                        fd = FileData(f, isdir)
                        if isdir or filterFunction(f, file_type):
                            files.append(fd)
            except:
                pass
            return files

        def dir_cmp(x, y):
            if x.isdir == y.isdir:
                if x.isplay == y.isplay:
                    if x.name < y.name:
                        return -1
                    if x.name == y.name:
                        return 0
                else:
                    return y.isplay - x.isplay
                return 1
            else:
                return y.isdir - x.isdir


        path = self.get_local_path(handler, query)

        file_type = query.get('Filter', [''])[0]

        recurse = query.get('Recurse', ['No'])[0] == 'Yes'

        filelist = []
        rc = self.recurse_cache
        dc = self.dir_cache
        if recurse:
            if path in rc:
                filelist = rc[path]
        else:
            updated = os.path.getmtime(path)
            if path in dc and dc.mtime(path) >= updated:
                filelist = dc[path]
            for p in rc:
                if path.startswith(p) and rc.mtime(p) < updated:
                    del rc[p]

        if not filelist:
            filelist = SortList(build_recursive_list(path, recurse))

            if recurse:
                rc[path] = filelist
            else:
                dc[path] = filelist

        # Sort it
        seed = ''
        start = ''
        sortby = query.get('SortOrder', ['Normal'])[0]
        if 'Random' in sortby:
            if 'RandomSeed' in query:
                seed = query['RandomSeed'][0]
                sortby += seed
            if 'RandomStart' in query:
                start = query['RandomStart'][0]
                sortby += start

        if filelist.unsorted or filelist.sortby != sortby:
            if 'Random' in sortby:
                self.random_lock.acquire()
                if seed:
                    random.seed(seed)
                random.shuffle(filelist.files)
                self.random_lock.release()
                if start:
                    local_base_path = self.get_local_base_path(handler, query)
                    start = unquote(start)
                    start = start.replace(os.path.sep + handler.cname,
                                          local_base_path, 1)
                    filenames = [x.name for x in filelist.files]
                    try:
                        index = filenames.index(start)
                        i = filelist.files.pop(index)
                        filelist.files.insert(0, i)
                    except ValueError:
                        handler.server.logger.warning('Start not found: ' +
                                                      start)
            else:
                filelist.files.sort(key = cmp_to_key(dir_cmp))

            filelist.sortby = sortby
            filelist.unsorted = False

        files = filelist.files[:]

        # Trim the list
        files, total, start = self.item_count(handler, query, handler.cname,
                                              files, filelist.last_start)
        filelist.last_start = start
        return files, total, start
예제 #13
0
    def get_files(self, handler, query, filterFunction):
        class FileData:
            def __init__(self, name, isdir):
                self.name = name
                self.isdir = isdir
                st = os.stat(name)
                self.cdate = int(st.st_ctime)
                self.mdate = int(st.st_mtime)

        class SortList:
            def __init__(self, files):
                self.files = files
                self.unsorted = True
                self.sortby = None
                self.last_start = 0
                self.lock = threading.RLock()

            def acquire(self, blocking=1):
                return self.lock.acquire(blocking)

            def release(self):
                self.lock.release()

        def build_recursive_list(path, recurse=True):
            files = []
            path = unicode(path, 'utf-8')
            try:
                for f in os.listdir(path):
                    f = os.path.join(path, f)
                    isdir = os.path.isdir(f)
                    f = f.encode('utf-8')
                    if recurse and isdir:
                        files.extend(build_recursive_list(f))
                    else:
                        if isdir or filterFunction(f):
                            files.append(FileData(f, isdir))
            except:
                pass

            return files

        def name_sort(x, y):
            return cmp(x.name, y.name)

        def cdate_sort(x, y):
            return cmp(x.cdate, y.cdate)

        def mdate_sort(x, y):
            return cmp(x.mdate, y.mdate)

        def dir_sort(x, y):
            if x.isdir == y.isdir:
                return sortfunc(x, y)
            else:
                return y.isdir - x.isdir

        subcname = query['Container'][0]
        cname = subcname.split('/')[0]
        path = self.get_local_path(handler, query)

        # Build the list
        recurse = query.get('Recurse', ['No'])[0] == 'Yes'

        if recurse and path in self.recurse_cache:
            filelist = self.recurse_cache[path]
        elif not recurse and path in self.dir_cache:
            filelist = self.dir_cache[path]
        else:
            filelist = SortList(build_recursive_list(path, recurse))

            if recurse:
                self.recurse_cache[path] = filelist
            else:
                self.dir_cache[path] = filelist

        filelist.acquire()

        # Sort it
        seed = ''
        start = ''
        sortby = query.get('SortOrder', ['Normal'])[0]
        if 'Random' in sortby:
            if 'RandomSeed' in query:
                seed = query['RandomSeed'][0]
                sortby += seed
            if 'RandomStart' in query:
                start = query['RandomStart'][0]
                sortby += start

        if filelist.unsorted or filelist.sortby != sortby:
            if 'Random' in sortby:
                self.random_lock.acquire()
                if seed:
                    random.seed(seed)
                random.shuffle(filelist.files)
                self.random_lock.release()
                if start:
                    local_base_path = self.get_local_base_path(handler, query)
                    start = unquote(start)
                    start = start.replace(os.path.sep + cname, local_base_path,
                                          1)
                    filenames = [x.name for x in filelist.files]
                    try:
                        index = filenames.index(start)
                        i = filelist.files.pop(index)
                        filelist.files.insert(0, i)
                    except ValueError:
                        print 'Start not found:', start
            else:
                if 'CaptureDate' in sortby:
                    sortfunc = cdate_sort
                elif 'LastChangeDate' in sortby:
                    sortfunc = mdate_sort
                else:
                    sortfunc = name_sort

                if 'Type' in sortby:
                    filelist.files.sort(dir_sort)
                else:
                    filelist.files.sort(sortfunc)

            filelist.sortby = sortby
            filelist.unsorted = False

        files = filelist.files[:]

        # Filter it -- this section needs work
        if 'Filter' in query:
            usedir = 'folder' in query['Filter'][0]
            useimg = 'image' in query['Filter'][0]
            if not usedir:
                files = [x for x in files if not x.isdir]
            elif usedir and not useimg:
                files = [x for x in files if x.isdir]

        files, total, start = self.item_count(handler, query, cname, files,
                                              filelist.last_start)
        filelist.last_start = start
        filelist.release()
        return files, total, start
예제 #14
0
    def get_files(self, handler, query, filterFunction):

        class FileData:
            def __init__(self, name, isdir):
                self.name = name
                self.isdir = isdir
                st = os.stat(unicode(name, 'utf-8'))
                self.cdate = int(st.st_ctime)
                self.mdate = int(st.st_mtime)

        class SortList:
            def __init__(self, files):
                self.files = files
                self.unsorted = True
                self.sortby = None
                self.last_start = 0
                self.lock = threading.RLock()

            def acquire(self, blocking=1):
                return self.lock.acquire(blocking)

            def release(self):
                self.lock.release()

        def build_recursive_list(path, recurse=True):
            files = []
            path = unicode(path, 'utf-8')
            try:
                for f in os.listdir(path):
                    if f.startswith('.'):
                        continue
                    f = os.path.join(path, f)
                    isdir = os.path.isdir(f)
                    if sys.platform == 'darwin':
                        f = unicodedata.normalize('NFC', f)
                    f = f.encode('utf-8')
                    if recurse and isdir:
                        files.extend(build_recursive_list(f))
                    else:
                       if isdir or filterFunction(f):
                           files.append(FileData(f, isdir))
            except:
                pass

            return files

        def name_sort(x, y):
            return cmp(x.name, y.name)

        def cdate_sort(x, y):
            return cmp(x.cdate, y.cdate)

        def mdate_sort(x, y):
            return cmp(x.mdate, y.mdate)

        def dir_sort(x, y):
            if x.isdir == y.isdir:
                return sortfunc(x, y)
            else:
                return y.isdir - x.isdir

        path = self.get_local_path(handler, query)

        # Build the list
        recurse = query.get('Recurse', ['No'])[0] == 'Yes'

        filelist = []
        rc = self.recurse_cache
        dc = self.dir_cache
        if recurse:
            if path in rc:
                filelist = rc[path]
        else:
            updated = os.stat(unicode(path, 'utf-8'))[8]
            if path in dc and dc.mtime(path) >= updated:
                filelist = dc[path]
            for p in rc:
                if path.startswith(p) and rc.mtime(p) < updated:
                    del rc[p]

        if not filelist:
            filelist = SortList(build_recursive_list(path, recurse))

            if recurse:
                rc[path] = filelist
            else:
                dc[path] = filelist

        filelist.acquire()

        # Sort it
        seed = ''
        start = ''
        sortby = query.get('SortOrder', ['Normal'])[0] 
        if 'Random' in sortby:
            if 'RandomSeed' in query:
                seed = query['RandomSeed'][0]
                sortby += seed
            if 'RandomStart' in query:
                start = query['RandomStart'][0]
                sortby += start

        if filelist.unsorted or filelist.sortby != sortby:
            if 'Random' in sortby:
                self.random_lock.acquire()
                if seed:
                    random.seed(seed)
                random.shuffle(filelist.files)
                self.random_lock.release()
                if start:
                    local_base_path = self.get_local_base_path(handler, query)
                    start = unquote(start)
                    start = start.replace(os.path.sep + handler.cname,
                                          local_base_path, 1)
                    filenames = [x.name for x in filelist.files]
                    try:
                        index = filenames.index(start)
                        i = filelist.files.pop(index)
                        filelist.files.insert(0, i)
                    except ValueError:
                        handler.server.logger.warning('Start not found: ' +
                                                      start)
            else:
                if 'CaptureDate' in sortby:
                    sortfunc = cdate_sort
                elif 'LastChangeDate' in sortby:
                    sortfunc = mdate_sort
                else:
                    sortfunc = name_sort

                if 'Type' in sortby:
                    filelist.files.sort(dir_sort)
                else:
                    filelist.files.sort(sortfunc)

            filelist.sortby = sortby
            filelist.unsorted = False

        files = filelist.files[:]

        # Filter it -- this section needs work
        if 'Filter' in query:
            usedir = 'folder' in query['Filter'][0]
            useimg = 'image' in query['Filter'][0]
            if not usedir:
                files = [x for x in files if not x.isdir]
            elif usedir and not useimg:
                files = [x for x in files if x.isdir]

        files, total, start = self.item_count(handler, query, handler.cname,
                                              files, filelist.last_start)
        filelist.last_start = start
        filelist.release()
        return files, total, start
예제 #15
0
파일: music.py 프로젝트: pudney/pytivo
    def get_files(self, handler, query, filterFunction=None):
        class SortList:
            def __init__(self, files):
                self.files = files
                self.unsorted = True
                self.sortby = None
                self.last_start = 0

        def build_recursive_list(path, recurse=True):
            files = []
            path = unicode(path, "utf-8")
            try:
                for f in os.listdir(path):
                    f = os.path.join(path, f)
                    isdir = os.path.isdir(f)
                    f = f.encode("utf-8")
                    if recurse and isdir:
                        files.extend(build_recursive_list(f))
                    else:
                        fd = FileData(f, isdir)
                        if recurse and fd.isplay:
                            files.extend(self.parse_playlist(f, recurse))
                        elif isdir or filterFunction(f, file_type):
                            files.append(fd)
            except:
                pass
            return files

        def dir_sort(x, y):
            if x.isdir == y.isdir:
                if x.isplay == y.isplay:
                    return name_sort(x, y)
                else:
                    return y.isplay - x.isplay
            else:
                return y.isdir - x.isdir

        def name_sort(x, y):
            return cmp(x.name, y.name)

        subcname = query["Container"][0]
        cname = subcname.split("/")[0]
        path = self.get_local_path(handler, query)

        file_type = query.get("Filter", [""])[0]

        recurse = query.get("Recurse", ["No"])[0] == "Yes"

        if recurse and path in self.recurse_cache:
            filelist = self.recurse_cache[path]
        elif not recurse and path in self.dir_cache:
            filelist = self.dir_cache[path]
        else:
            filelist = SortList(build_recursive_list(path, recurse))

            if recurse:
                self.recurse_cache[path] = filelist
            else:
                self.dir_cache[path] = filelist

        # Sort it
        seed = ""
        start = ""
        sortby = query.get("SortOrder", ["Normal"])[0]
        if "Random" in sortby:
            if "RandomSeed" in query:
                seed = query["RandomSeed"][0]
                sortby += seed
            if "RandomStart" in query:
                start = query["RandomStart"][0]
                sortby += start

        if filelist.unsorted or filelist.sortby != sortby:
            if "Random" in sortby:
                self.random_lock.acquire()
                if seed:
                    random.seed(seed)
                random.shuffle(filelist.files)
                self.random_lock.release()
                if start:
                    local_base_path = self.get_local_base_path(handler, query)
                    start = unquote(start)
                    start = start.replace(os.path.sep + cname, local_base_path, 1)
                    filenames = [x.name for x in filelist.files]
                    try:
                        index = filenames.index(start)
                        i = filelist.files.pop(index)
                        filelist.files.insert(0, i)
                    except ValueError:
                        print "Start not found:", start
            else:
                filelist.files.sort(dir_sort)

            filelist.sortby = sortby
            filelist.unsorted = False

        files = filelist.files[:]

        # Trim the list
        files, total, start = self.item_count(handler, query, cname, files, filelist.last_start)
        filelist.last_start = start
        return files, total, start