151 lines
5.3 KiB
Python
151 lines
5.3 KiB
Python
# Copyright 2020 Romain de Laage
|
|
#
|
|
# This file is part of tkGemini.
|
|
#
|
|
# tkGemini is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# any later version.
|
|
#
|
|
# tkGemini is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with tkGemini. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
import tkinter as tk
|
|
import tkinter.messagebox
|
|
import tkinter.simpledialog
|
|
import gemini
|
|
import renderEngine
|
|
import urllib.parse
|
|
|
|
class Application():
|
|
def __init__(self):
|
|
# Some global definitions
|
|
self.root = tk.Tk()
|
|
self.nav_bar = NavBar(self)
|
|
self.content = Content(self)
|
|
self.current_URL = "about:home"
|
|
|
|
# Set window title
|
|
self.root.title("tkGemini")
|
|
|
|
# App main loop
|
|
self.root.mainloop()
|
|
|
|
def updateContent(self):
|
|
# Get url asked
|
|
url=self.nav_bar.getURL()
|
|
|
|
# Is it a Gemini URL
|
|
if not(verifyURL(url)):
|
|
tkinter.messagebox.showerror("URL error", url+" is not a correct Gemini URL ! (HTTP/S is not supported, please use a web browser instead)")
|
|
return
|
|
|
|
self.current_URL = self.nav_bar.getURL()
|
|
|
|
# New request
|
|
r = gemini.Request(self.current_URL)
|
|
status = r.makeRequest()
|
|
|
|
# The server asked for user input
|
|
if status[0] == "1":
|
|
user_input = tkinter.simpledialog.askstring("User input", "The server asked for " + r.meta + ".")
|
|
self.nav_bar.URL_var.set(self.current_URL + "?" + user_input)
|
|
self.updateContent()
|
|
# If server asked for redirection
|
|
elif status[0] == "3":
|
|
# Ask to user
|
|
confirm = tkinter.messagebox.askyesno("Server redirection", "This server ask for redirection to " + r.meta + ". Follow ?")
|
|
# If he accepted
|
|
if confirm:
|
|
self.nav_bar.URL_var.set(r.meta)
|
|
self.updateContent()
|
|
# The server asked for client certificate, unsupported
|
|
elif status[0] == "6":
|
|
tkinter.messagebox.showerror("Client certificate required", "Error " + status + " : " + r.meta)
|
|
else:
|
|
self.content.setContent(r.content)
|
|
|
|
def linkClick(self, url):
|
|
# Check if it is an absolute URL
|
|
if "://" in url:
|
|
# Check if it is a gemini URL
|
|
if verifyURL(url):
|
|
self.nav_bar.URL_var.set(url)
|
|
self.updateContent()
|
|
# Else show error
|
|
else:
|
|
tkinter.messagebox.showerror("URL error", url+" is not a correct Gemini URL ! (HTTP/S is not supported, please use a web browser instead)")
|
|
# It is relative
|
|
else:
|
|
# Join current URL and relative path
|
|
base = self.current_URL
|
|
base = base.replace("gemini://","http://")
|
|
url = urllib.parse.urljoin(base, url)
|
|
url = url.replace("http://", "gemini://")
|
|
|
|
# We can verify because sometime there is errors (mailto:)
|
|
if verifyURL(url):
|
|
self.nav_bar.URL_var.set(url)
|
|
self.updateContent()
|
|
else:
|
|
tkinter.messagebox.showerror("URL error", url+" is not a correct Gemini URL ! (HTTP/S is not supported, please use a web browser instead)")
|
|
|
|
def verifyURL(url):
|
|
# Is it an absolute path ?
|
|
if "://" in url:
|
|
parsed_url = urllib.parse.urlparse(url)
|
|
# Is this path supported ?
|
|
if parsed_url.scheme == "gemini":
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
class NavBar():
|
|
def __init__(self, parent):
|
|
# Some global definitions
|
|
self.parent = parent
|
|
|
|
# All widgets are in a frame
|
|
self.root = tk.Frame(self.parent.root)
|
|
self.root.grid(column=0, row=0)
|
|
|
|
# Define URL bar and variable
|
|
self.URL_var = tk.StringVar()
|
|
self.URL_bar = tk.Entry(self.root, textvariable=self.URL_var)
|
|
self.URL_var.set("about:home")
|
|
self.URL_bar.grid(column=0, row=0)
|
|
|
|
# Define go button with action
|
|
self.go_button = tk.Button(self.root, text='Go !', command=self.parent.updateContent)
|
|
self.go_button.grid(column=1, row=0)
|
|
|
|
def getURL(self):
|
|
# Get URL from URL bar variable
|
|
return self.URL_var.get()
|
|
|
|
class Content():
|
|
def __init__(self, parent):
|
|
self.parent = parent
|
|
|
|
# Text container with home page
|
|
self.root = renderEngine.Renderer(self.parent, "#Home page\nWelcome on tkGemini, a browser software for Gemini protocole\n=>gemini://rdelaage.ovh My gemini space")
|
|
self.root.parse()
|
|
self.root.content.grid(column=0, row=1)
|
|
|
|
# Scrollbar beside to the text container
|
|
self.scroll_bar = tk.Scrollbar(command=self.root.content.yview, orient='vertical')
|
|
self.scroll_bar.grid(column=1, row=1)
|
|
self.root.content['yscrollcommand'] = self.scroll_bar.set
|
|
|
|
# When content is updated
|
|
def setContent(self, new_content):
|
|
self.root.text = new_content
|
|
self.root.parse()
|
|
|
|
app = Application()
|