Fast File Selection

I don’t love the folder navigation interface in the FileSelector widget, so I built a separate widget for when I need to quickly navigate directories AND only need to select one file:

import pathlib
import param
import panel as pn

class FastFileSelector(param.Parameterized):
    current_dir = param.String(default = '/')
    filter = param.String(default = '*')
    selection = param.Selector(default = '')
    _contents_map = param.Dict()

    @param.depends('selection', watch = True)
    def change_dir(self):
        if self.selection and self.selection[-1] == '/':
            self.current_dir = str(self._contents_map[self.selection])

    @param.depends('current_dir', 'filter', watch = True, on_init = True)
    def refesh_list(self):
        contents = {}
        if self.current_dir and self.filter:
            
            self.param['selection'].objects = ['']
            contents[''] = None
            contents['../'] = pathlib.Path(self.current_dir).parent
            try:
                for i in pathlib.Path(self.current_dir).iterdir():
                    if i.is_dir():
                        contents['./' + i.name + '/'] = i
                for i in pathlib.Path(self.current_dir).glob(self.filter):
                    if not i.is_dir():
                        contents[i.name] = i
            except Exception as e:
                contents[str(e)] = pathlib.Path(self.current_dir)

            self._contents_map = dict(sorted(contents.items()))
            self.param['selection'].objects = list(sorted(contents.keys()))
        self.selection = ''

def create_panel(current_dir = '/', filter = '*'):

    ffs = FastFileSelector(
        current_dir = current_dir,
        filter = filter
    )
    return pn.Param(
        ffs.param,
        parameters = ['current_dir','filter','selection']
    )

if __name__ == '__main__':
    
    pn.serve(create_panel)

4 Likes

Another tool in the armory for loading data, thanks for sharing @riziles, I will find useful.

Thanks, Carl.

1 Like