Source code for pimlico.cli.browser.tools.files

# This file is part of Pimlico
# Copyright (C) 2020 Mark Granroth-Wilding
# Licensed under the GNU LGPL v3.0 - https://www.gnu.org/licenses/lgpl-3.0.en.html

from __future__ import print_function
from builtins import range

import warnings

try:
    import urwid
except ImportError:
    print("Urwid is not installed: installing now")
    from pimlico.core.dependencies.python import urwid_dependency
    urwid_dependency.install({})

    try:
        import urwid
    except ImportError:
        print("Tried to install Urwid, but still not available")
        raise

PALETTE = [
    ('reversed', 'standout', ''),
    ('body', 'white', 'dark blue', 'standout'),
    ('border', 'black', 'dark blue'),
    ('shadow', 'white', 'black'),
    ('selectable', 'black', 'dark cyan'),
    ('focus', 'white', 'dark blue', 'bold'),
    ('focustext', 'light gray', 'dark blue'),
    ('popbg', 'white', 'dark blue'),
]


[docs]def browse_files(reader): """ Browser tool for NamedFileCollections. """ # Top of the screen top_widgets = [ urwid.Text("Reading files from: {}".format(reader.data_dir)), urwid.Divider(), ] def menu_item(caption, callback): button = urwid.Button(caption) urwid.connect_signal(button, 'click', callback) return urwid.AttrMap(button, None, focus_map='reversed') def selected(name): def _selected(button): show_file(name) return _selected def _file_view_keypress(key): if key == "esc": # Go back to the main menu main_loop.widget = main main_loop._unhandled_input = _keypress def show_file(filename): if filename == "Quit": _exit() path = reader.get_absolute_path(filename) # Try reading some of the file to see if it's text if is_binary_file(path): # TODO Check whether to show the file warnings.warn("{} seems to be a binary file: showing anyway for now".format(filename)) # Read in the file # If the datatype overrides the reading behaviour, use that data = reader.datatype.browse_file(reader, filename) new_box = urwid.LineBox(urwid.Frame(urwid.ListBox(urwid.SimpleListWalker([ urwid.Text(data) ])), header=urwid.Pile([ urwid.Columns([ urwid.Text("File: {}".format(filename)), urwid.Text("Esc: return to menu"), ]), urwid.Divider(), ]))) main_loop.widget = new_box main_loop._unhandled_input = _file_view_keypress # Middle: content # Get the list of filenames that this collection includes filenames = reader.filenames + ["Quit"] items = [menu_item(filename, selected(filename)) for filename in filenames] content_scrollbox = urwid.ListBox(urwid.SimpleFocusListWalker(items)) #content_scrollbox = yesno_dialog(content_scrollbox, # "This appears to be a binary file. Are you sure you want to try displaying it?") # Main layout main = urwid.LineBox( urwid.Frame( content_scrollbox, header=urwid.Pile(top_widgets), ) ) def _keypress(key): if key == "esc" or key == "q": _exit() main_loop = urwid.MainLoop(main, palette=PALETTE, unhandled_input=_keypress) content_scrollbox.set_focus(0) main_loop.run()
def _exit(*args): raise urwid.ExitMainLoop() textchars = bytearray({7,8,9,10,12,13,27} | set(range(0x20, 0x100)) - {0x7f})
[docs]def is_binary_string(bytes): return bool(bytes.translate(None, textchars))
[docs]def is_binary_file(path): """ Try reading a bit of a file to work out whether it's a binary file or text """ with open(path, "rb") as f: return is_binary_string(f.read(1024))