Compare commits

..

No commits in common. "843a88659f2497928a84451293cf73767a8e5146" and "00d5e51e2f58c3a1fa3107a1451cddeb7c7fae53" have entirely different histories.

8 changed files with 20 additions and 51 deletions

View file

@ -99,12 +99,12 @@ class Browser:
return self.dim[1] return self.dim[1]
@property @property
def current_url(self) -> str: def current_url(self):
"""Return the current URL.""" """Return the current URL."""
return self._current_url return self._current_url
@current_url.setter @current_url.setter
def current_url(self, url: str): def current_url(self, url):
"""Set the current URL and show it in the status line.""" """Set the current URL and show it in the status line."""
self._current_url = url self._current_url = url
self.set_status(url) self.set_status(url)
@ -244,7 +244,7 @@ class Browser:
elif char == ord("o"): elif char == ord("o"):
self.quick_command("open") self.quick_command("open")
elif char == ord("O"): elif char == ord("O"):
self.quick_command(f"open {self.current_url}") self.open_last_download()
elif char == ord("p"): elif char == ord("p"):
self.go_back() self.go_back()
elif char == ord("u"): elif char == ord("u"):
@ -291,8 +291,6 @@ class Browser:
self.scroll_page_vertically(-1) self.scroll_page_vertically(-1)
elif char == ord("l"): elif char == ord("l"):
self.scroll_page_horizontally(1) self.scroll_page_horizontally(1)
elif char == ord("o"):
self.open_last_download()
@property @property
def page_pad_size(self): def page_pad_size(self):
@ -388,18 +386,11 @@ class Browser:
elif command == "set-render-mode": elif command == "set-render-mode":
self.set_render_mode(words[1]) self.set_render_mode(words[1])
def get_user_text_input(self, status_text, char, prefix="", strip=False, def get_user_text_input(self, status_text, char, prefix="", strip=False):
escape_to_none=False):
"""Get user input from the command-line.""" """Get user input from the command-line."""
self.set_status(status_text) self.set_status(status_text)
result = self.command_line.focus( result = self.command_line.focus(char, prefix=prefix)
char,
prefix=prefix,
escape_to_none=escape_to_none
)
self.reset_status() self.reset_status()
if result is None:
return None
if strip: if strip:
result = result.strip() result = result.strip()
return result return result

View file

@ -35,11 +35,7 @@ def open_file(browser: Browser, filepath: str, encoding="utf-8"):
except (OSError, ValueError) as exc: except (OSError, ValueError) as exc:
browser.set_status_error(f"Failed to open file: {exc}") browser.set_status_error(f"Failed to open file: {exc}")
return None return None
if path.suffix == ".gmi": browser.load_page(Page.from_text(text))
page = Page.from_gemtext(text, browser.config["text_width"])
else:
page = Page.from_text(text)
browser.load_page(page)
elif path.is_dir(): elif path.is_dir():
gemtext = str(path) + "\n\n" gemtext = str(path) + "\n\n"
for entry in sorted(path.iterdir()): for entry in sorted(path.iterdir()):

View file

@ -294,7 +294,7 @@ def _handle_cert_required(
url_identities = get_identities_for_url(browser.identities, url) url_identities = get_identities_for_url(browser.identities, url)
if not url_identities: if not url_identities:
identity = create_identity(browser, url, reason=response.meta) identity = create_identity(browser, url)
if not identity: if not identity:
return None return None
browser.identities[url] = [identity] browser.identities[url] = [identity]
@ -317,27 +317,23 @@ def select_identity(identities: list):
return identities[0] if identities else None return identities[0] if identities else None
def create_identity(browser: Browser, url: str, reason: Optional[str] =None): def create_identity(browser: Browser, url: str):
"""Walk the user through identity creation. """Walk the user through identity creation.
Returns: Returns:
The created identity on success (already registered in identities The created identity on success (already registered in identities
""" """
prompt_text = "Create client certificate?" key = browser.prompt("Create client certificate?")
if reason:
prompt_text += f" Reason: {reason}"
key = browser.prompt(prompt_text)
if key != "y": if key != "y":
browser.reset_status() browser.reset_status()
return None return None
common_name = browser.get_user_text_input( common_name = browser.get_user_text_input(
"Name? The server may use it as your username.", "Name? The server will see this, you can leave it empty.",
CommandLine.CHAR_TEXT, CommandLine.CHAR_TEXT,
strip=True, strip=True,
escape_to_none=True
) )
if common_name is None: if not common_name:
browser.reset_status() browser.reset_status()
return None return None

View file

@ -22,7 +22,6 @@ DEFAULT_CONFIG = {
"-nodes", "-nodes",
"-keyform", "PEM", "-keyform", "PEM",
"-keyout", "{key_path}", "-keyout", "{key_path}",
"-utf8",
"-x509", "-x509",
"-days", "28140", # https://www.youtube.com/watch?v=F9L4q-0Pi4E "-days", "28140", # https://www.youtube.com/watch?v=F9L4q-0Pi4E
"-outform", "PEM", "-outform", "PEM",

View file

@ -27,8 +27,7 @@ Keybinds using the SHIFT key are written uppercase. Keybinds using the ALT (or M
* gg: go to the top of the page * gg: go to the top of the page
* G: go to the bottom of the page * G: go to the bottom of the page
* o: open an URL * o: open an URL
* O: edit current URL * O: open last download with an external command
* M-o: open last download with an external command
* p: go to the previous page * p: go to the previous page
* u: go to the parent page (up a level in URL) * u: go to the parent page (up a level in URL)
* U: go to the root page (root URL for the current domain) * U: go to the root page (root URL for the current domain)

View file

@ -3,9 +3,6 @@
In Bebop we use a list of elements as produced by our parser. These elements are In Bebop we use a list of elements as produced by our parser. These elements are
converted into so-called "metalines", which are the text lines as they will be converted into so-called "metalines", which are the text lines as they will be
displayed, along with associated meta-data such as its type or a link's URL. displayed, along with associated meta-data such as its type or a link's URL.
Note that metalines can be generated by custom functions without relying on the
elements classes as they are quite coupled to Gemtext parsing/rendering.
""" """
import string import string
@ -36,7 +33,6 @@ class LineType(IntEnum):
PREFORMATTED = 6 PREFORMATTED = 6
BLOCKQUOTE = 7 BLOCKQUOTE = 7
LIST_ITEM = 8 LIST_ITEM = 8
ERROR = 9 # Not part of Gemtext but useful internally.
def generate_metalines(elements, width, dumb=False): def generate_metalines(elements, width, dumb=False):

View file

@ -70,7 +70,5 @@ def get_base_line_attributes(line_type) -> int:
return curses.color_pair(ColorPair.PREFORMATTED) return curses.color_pair(ColorPair.PREFORMATTED)
elif line_type == LineType.BLOCKQUOTE: elif line_type == LineType.BLOCKQUOTE:
return curses.color_pair(ColorPair.BLOCKQUOTE) | A_ITALIC return curses.color_pair(ColorPair.BLOCKQUOTE) | A_ITALIC
elif line_type == LineType.ERROR:
return curses.color_pair(ColorPair.ERROR) | curses.A_BOLD
else: # includes LineType.PARAGRAPH else: # includes LineType.PARAGRAPH
return curses.color_pair(ColorPair.NORMAL) return curses.color_pair(ColorPair.NORMAL)

View file

@ -53,6 +53,7 @@ USER_FRIENDLY_TYPES = {t.name.lower(): t for t in ItemType}
ICONS = { ICONS = {
ItemType.FILE: "📄", ItemType.FILE: "📄",
ItemType.DIR: "📂", ItemType.DIR: "📂",
ItemType.ERROR: "",
ItemType.SEARCH: "", ItemType.SEARCH: "",
ItemType.HTML: "🌐", ItemType.HTML: "🌐",
} }
@ -255,26 +256,19 @@ def parse_source(source: str, item_type: ItemType):
break break
parts = tline.split("\t") parts = tline.split("\t")
# If the map is poorly formatted and parts are missing, pad with if len(parts) != 4:
# empty parts. # TODO move me away
while len(parts) < 4: # Does not seem to be split by tabs, may be a file.
parts.append("") metalines.append(({"type": LineType.PARAGRAPH}, line))
continue
item_type = ItemType(ltype) item_type = ItemType(ltype)
label, path, host, port = parts label, path, host, port = parts
# INFO: render as a simple text line.
if item_type == ItemType.INFO: if item_type == ItemType.INFO:
metalines.append(({"type": LineType.PARAGRAPH}, label)) meta = {"type": LineType.PARAGRAPH}
metalines.append((meta, label))
continue continue
# ERROR: render as an error line.
if item_type == ItemType.ERROR:
metalines.append(({"type": LineType.ERROR}, label))
continue
# Other item types are rendered as links, with a special case for
# "URL:"-type selectors in HTML items.
if item_type == ItemType.HTML and path[:4].upper() == "URL:": if item_type == ItemType.HTML and path[:4].upper() == "URL:":
link_url = path[4:] link_url = path[4:]
else: else: