Compare commits

..

No commits in common. "84764644df64aee8d7d107c87b9f89df8bbf8b42" and "62619f29fb2175cb258480c218e42cdf6d3af696" have entirely different histories.

4 changed files with 7 additions and 68 deletions

View file

@ -1,45 +0,0 @@
Bebop
=====
Bebop is a [Gemini][gemini] browser for the terminal, focusing on practicality
and speed. It is a personal project to learn how to use ncurses and try new
ways to explore the Geminispace. It borrows some ideas from [Amfora][amfora],
another great terminal browser, Vim for interactivity and tries to support mouse
usage decently.
[gemini]: https://gemini.circumlunar.space/
[amfora]: https://github.com/makeworld-the-better-one/amfora
If you are interested in Gemini and looking for a client, I recommend trying a
graphical one like the excellent [Lagrange][lagrange] or [Kristall][kristall],
or Amfora if you're feeling more at home in the terminal. Bebop won't attempt
to support every feature other clients might have.
[lagrange]: https://git.skyjake.fi/skyjake/lagrange
[kristall]: https://kristall.random-projects.net/
It passes the Conman's client test but not Egsam's for now.
Features
--------
### What works
- Basic browsing: scrolling, follow links, redirections, Web links.
### What is planned
- Handle more content types.
- Great config options.
- Identity management with temporary and managed certificates.
- Buffers (or tabs if you prefer).
- Home page.
- Bookmarks.
### What is not planned for now
- 256-colors mode and themes.
- Subscriptions. I have no need for them as I prefer to use a browser-agnostic
aggregator at the moment.

View file

@ -222,11 +222,7 @@ class Browser:
else: else:
pass # TODO pass # TODO
data = req.proceed() response = Response.parse(req.proceed())
if not data:
self.set_status_error(f"Server did not respond in time ({url}).")
return
response = Response.parse(data)
if not response: if not response:
self.set_status_error(f"Server response parsing failed ({url}).") self.set_status_error(f"Server response parsing failed ({url}).")
return return

View file

@ -81,7 +81,7 @@ class Request:
self.payload += LINE_TERM self.payload += LINE_TERM
try: try:
sock = socket.create_connection((hostname, port), timeout=10) sock = socket.create_connection((hostname, port))
except OSError as exc: except OSError as exc:
self.state = Request.STATE_CONNECTION_FAILED self.state = Request.STATE_CONNECTION_FAILED
self.error = exc.strerror self.error = exc.strerror
@ -124,10 +124,7 @@ class Request:
self.ssock.sendall(self.payload) self.ssock.sendall(self.payload)
response = b"" response = b""
while True: while True:
try:
buf = self.ssock.recv(4096) buf = self.ssock.recv(4096)
except socket.timeout:
buf = None
if not buf: if not buf:
return response return response
response += buf response += buf
@ -175,7 +172,6 @@ class Response:
content: bytes = b"" content: bytes = b""
HEADER_RE = re.compile(r"(\d{2}) (.*)") HEADER_RE = re.compile(r"(\d{2}) (.*)")
MAX_META_LEN = 1024
@property @property
def generic_code(self): def generic_code(self):
@ -193,8 +189,6 @@ class Response:
if not match: if not match:
return None return None
code, meta = match.groups() code, meta = match.groups()
if len(meta) > Response.MAX_META_LEN:
return None
response = Response(StatusCode(int(code)), meta=meta) response = Response(StatusCode(int(code)), meta=meta)
if response.generic_code == StatusCode.SUCCESS: if response.generic_code == StatusCode.SUCCESS:
content_offset = response_header_len + len(LINE_TERM) content_offset = response_header_len + len(LINE_TERM)

View file

@ -215,13 +215,10 @@ def render_lines(metalines, window, max_width):
- max_width: line length limit for the pad. - max_width: line length limit for the pad.
Return: Return:
The tuple of integers (error, height, width), error being a non-zero value The tuple (height, width) of the resized window.
if an error occured during rendering, and height and width being the new
dimensions of the resized window.
""" """
num_lines = len(metalines) num_lines = len(metalines)
new_dimensions = num_lines, max_width window.resize(num_lines, max_width)
window.resize(*new_dimensions)
for line_index, metaline in enumerate(metalines): for line_index, metaline in enumerate(metalines):
meta, line = metaline meta, line = metaline
line = line[:max_width - 1] line = line[:max_width - 1]
@ -240,10 +237,7 @@ def render_lines(metalines, window, max_width):
attr = curses.color_pair(ColorPair.BLOCKQUOTE) | curses.A_ITALIC attr = curses.color_pair(ColorPair.BLOCKQUOTE) | curses.A_ITALIC
else: # includes LineType.PARAGRAPH else: # includes LineType.PARAGRAPH
attr = curses.color_pair(ColorPair.NORMAL) attr = curses.color_pair(ColorPair.NORMAL)
try:
window.addstr(line, attr) window.addstr(line, attr)
except ValueError:
return new_dimensions
if line_index < num_lines - 1: if line_index < num_lines - 1:
window.addstr("\n") window.addstr("\n")
return new_dimensions return num_lines, max_width