This repository has been archived on 2021-12-22. You can view files and clone it, but cannot push or open issues or pull requests.
tkGemini/main.py

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()