You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Bebop/bebop/browser/file.py

56 lines
1.8 KiB

"""Local files browser."""
import logging
from pathlib import Path
from urllib.parse import quote, unquote
from bebop.browser.browser import Browser
from bebop.page import Page
def open_file(browser: Browser, filepath: str, encoding="utf-8"):
"""Open a file and render it.
This should be used only text files or directories. Anything else will
produce garbage and may crash the program. In the future this should be able
to use a different parser according to a MIME type or something.
Arguments:
- browser: Browser object making the request.
- filepath: a text file path on disk.
- encoding: file's encoding.
Returns:
The loaded file URI on success, None otherwise (e.g. file not found).
"""
path = Path(unquote(filepath))
if not path.exists():
logging.error(f"File {path} does not exist.")
return None
if path.is_file():
try:
with open(path, "rt", encoding=encoding) as f:
text = f.read()
except (OSError, ValueError) as exc:
browser.set_status_error(f"Failed to open file: {exc}")
return None
if path.suffix == ".gmi":
page = Page.from_gemtext(text, browser.config["text_width"])
else:
page = Page.from_text(text)
browser.load_page(page)
elif path.is_dir():
gemtext = str(path) + "\n\n"
for entry in sorted(path.iterdir()):
entry_path = quote(str(entry.absolute()))
name = entry.name
if entry.is_dir():
name += "/"
gemtext += f"=> {entry_path} {name}\n"
wrap_at = browser.config["text_width"]
browser.load_page(Page.from_gemtext(gemtext, wrap_at))
file_url = f"file://{path}"
browser.current_url = file_url
return file_url