Repos / mcross / 47d59759fc
commit 47d59759fc32e80a0ffa5ecc32f17d1f026b6ca5
Author: Bùi Thành Nhân <hi@imnhan.com>
Date:   Thu May 14 00:53:15 2020 +0700

    mvp gui

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a295864
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.pyc
+__pycache__
diff --git a/README.md b/README.md
index 22118dc..0d2a282 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,10 @@
+# WIP
+
 Developed against gemini://gemini.circumlunar.space/ because apparently
 it's the only one if a valid TLS cert.
 
+It currently looks like this: https://junk.imnhan.com/beans.mp4
+
 # Server bugs/surprises
 
 ## Forces gemini:// in request
diff --git a/client.py b/client.py
index ebdef02..8b252d6 100644
--- a/client.py
+++ b/client.py
@@ -53,5 +53,4 @@ def parse_absolute_url(absolute_url):
     # TODO: this is not exactly safe. Do proper parsing later.
     assert absolute_url.startswith("gemini://"), f"Malformed url: {absolute_url}"
     parsed = urlparse(absolute_url)
-    print("Parsed url:", parsed)
     return parsed
diff --git a/gui.py b/gui.py
new file mode 100644
index 0000000..c357d57
--- /dev/null
+++ b/gui.py
@@ -0,0 +1,113 @@
+import sys
+from tkinter import Text, Tk, ttk
+
+import client
+
+
+class Model:
+    plaintext = "Nothing to see here... yet."
+
+
+class View:
+    model: Model
+    address_bar: ttk.Entry
+    go_button: ttk.Button
+    viewport: ttk.Frame
+    text: Text
+
+    go_callback = None
+
+    def __init__(self, root: Tk, model: Model):
+        self.model = model
+
+        # first row - address bar + button
+        row1 = ttk.Frame(root)
+        row1.pack(fill="x")
+
+        # second row - web viewport
+        row2 = ttk.Frame(root)
+        row2.pack(fill="both", expand=True)
+
+        # Address bar prefix
+        address_prefix = ttk.Label(row1, text="gemini://")
+        address_prefix.pack(side="left")
+
+        # Address bar
+        address_bar = ttk.Entry(row1)
+        address_bar.insert(0, "gemini.circumlunar.space/")
+        self.address_bar = address_bar
+        address_bar.pack(side="left", fill="both", expand=True, padx=3, pady=3)
+        address_bar.bind("<Return>", self._on_go)
+        address_bar.focus_set()
+
+        # Go button
+        go_button = ttk.Button(row1, text="go", command=self._on_go)
+        self.go_button = go_button
+        go_button.pack(side="left", pady=3)
+
+        # Web viewport
+        viewport = ttk.Frame(row2)
+        self.viewport = viewport
+        viewport.pack(fill="both", expand=True)
+
+        # Viewport content: just do text for now
+        text = Text(viewport)
+        self.text = text
+        self.render_page()
+        text.pack(fill="both", expand=True)
+
+        style = ttk.Style()
+        if sys.platform == "win32":
+            style.theme_use("vista")
+        elif sys.platform == "darwin":
+            style.theme_use("aqua")
+        else:
+            style.theme_use("clam")
+
+    def _on_go(self, ev=None):
+        if self.go_callback is not None:
+            self.go_callback("gemini://" + self.address_bar.get())
+
+    def render_page(self):
+        self.text.config(state="normal")
+        self.text.delete("1.0", "end")
+        self.text.insert("end", self.model.plaintext)
+        self.text.config(state="disabled")
+
+
+class Controller:
+    def __init__(self):
+        self.root = Tk()
+        self.model = Model()
+        self.view = View(self.root, self.model)
+        self.view.go_callback = self.go_callback
+
+    def run(self):
+        self.root.title("Beans Browser")
+        self.root.geometry("800x600")
+        self.root.mainloop()
+
+    def go_callback(self, url: str):
+        # TODO more visual indications
+        # TODO url validation
+
+        print("Requesting", url)
+
+        resp = client.get(url)
+        if resp.status.startswith("2"):
+            self.model.plaintext = resp.body.decode()
+        else:
+            self.model.plaintext = "\n".join(
+                [
+                    "Error:",
+                    f"{resp.status} {resp.meta}",
+                    resp.body.decode() if resp.body else "",
+                ]
+            )
+
+        print("Received", resp)
+        self.view.render_page()
+
+
+c = Controller()
+c.run()