summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbrowser.py103
1 files changed, 47 insertions, 56 deletions
diff --git a/browser.py b/browser.py
index e77b31d..5eda3b8 100755
--- a/browser.py
+++ b/browser.py
@@ -2,55 +2,36 @@
import sys
-from PySide6 import QtCore, QtWidgets, QtGui
+from PySide6 import QtCore, QtWidgets, QtGui, QtWebEngineWidgets, QtWebEngineCore
import gemini
-class GViewport(QtWidgets.QTextBrowser):
-
- hoverUrlChanged = QtCore.Signal(str)
- resourceLoadedStatus = QtCore.Signal(str)
-
- def __init__(self, address_bar):
- self.address_bar = address_bar
- self._hover_url = None
- QtWidgets.QTextBrowser.__init__(self)
-
- def mouseMoveEvent(self, event):
- cur = self.cursorForPosition(event.localPos().toPoint())
- hover_url = cur.charFormat().anchorHref()
- if hover_url:
- hover_url = gemini.urljoin(self.address_bar.text(), hover_url)
- if hover_url != self._hover_url:
- self._hover_url = hover_url
- self.hoverUrlChanged.emit(self._hover_url)
- return super().mouseMoveEvent(event)
-
- def loadResource(self, type_, url):
- gem = gemini.get(url.toString())
- print(gem['body'])
- if 'body' in gem:
- html = gemini.gem2html(gem['body'])
- print(html)
- else:
- html = '<h1>{} {}</h1>'.format(gem['status'], gem['meta'])
- self.resourceLoadedStatus.emit(
- '{status} {meta}'.format(status=gem['status'], meta=gem['meta'])
- )
- return html
- def setSource(self, url, type_=None):
+class GeminiPage(QtWebEngineCore.QWebEnginePage):
+ def acceptNavigationRequest(self, url, navtype, mainframe):
"""
- send all unsupported urls to the OS
+ Block non-gemini page navigation and
+ send the url to the os instead
"""
if url.scheme() == 'gemini':
- if type_ is None:
- return super().setSource(url)
- return super().setSource(url, type_)
- return QtGui.QDesktopServices().openUrl(url)
+ return True
+ else:
+ QtGui.QDesktopServices().openUrl(url)
+ return False
+
+
+class GeminiSchemeHandler(QtWebEngineCore.QWebEngineUrlSchemeHandler):
+ def requestStarted(self, request):
+ print(request.requestUrl().toString())
+ gem = gemini.get(request.requestUrl().toString())
+ print(gem['status'], gem['meta'])
+ buf = QtCore.QBuffer(parent=request)
+ buf.open(QtCore.QIODevice.WriteOnly)
+ buf.write(gemini.gem2html(gem['body']).encode('utf8'))
+ buf.seek(0)
+ buf.close()
+ request.reply(b'text/html', buf)
- def setRawSource(self):
- return self.setSource(QtCore.QUrl(self.address_bar.text()))
class GUrlBar(QtWidgets.QLineEdit):
@@ -60,13 +41,16 @@ class GUrlBar(QtWidgets.QLineEdit):
def setUrl(self, url):
return self.setText(url.toDisplayString())
+
class GBrowser(QtWidgets.QMainWindow):
- def __init__(self, initial_url=None):
+ def __init__(self, initial_url=None, profile=None):
+ if initial_url is None:
+ initial_url = 'gemini://gemini.circumlunar.space/'
+ if profile is None:
+ profile = QtWebEngineCore.QWebEngineProfile.defaultProfile()
QtWidgets.QMainWindow.__init__(self)
- ## Create widgets
-
# Navigation Toolbar
back = QtWidgets.QPushButton("back")
forward = QtWidgets.QPushButton("forward")
@@ -79,7 +63,9 @@ class GBrowser(QtWidgets.QMainWindow):
self.addToolBar(toolbar)
# Main Viewport
- browser = GViewport(address)
+ browser = QtWebEngineWidgets.QWebEngineView()
+ page = GeminiPage(profile, browser)
+ browser.setPage(page)
self.setCentralWidget(browser)
# Status Bar
@@ -87,17 +73,13 @@ class GBrowser(QtWidgets.QMainWindow):
self.statusBar().addWidget(request_status)
# Connect signals
- back.clicked.connect(browser.backward)
+ back.clicked.connect(browser.back)
forward.clicked.connect(browser.forward)
- browser.sourceChanged.connect(address.setUrl)
- address.returnPressed.connect(browser.setRawSource)
- browser.hoverUrlChanged.connect(self.set_status_url)
- browser.resourceLoadedStatus.connect(request_status.setText)
+ browser.urlChanged.connect(address.setUrl)
+ address.returnPressed.connect(browser.load)
+ browser.page().linkHovered.connect(self.set_status_url)
- #
- browser.document().setDefaultStyleSheet(open('style.css').read())
-
- browser.setSource(QtCore.QUrl(initial_url or 'gemini://gemini.circumlunar.space/'))
+ browser.load(QtCore.QUrl(initial_url))
settings = QtCore.QSettings("xcolour.net", "GeminiBrowser")
self.restoreGeometry(settings.value("geometry"))
@@ -117,6 +99,15 @@ class GBrowser(QtWidgets.QMainWindow):
settings.setValue("windowState", self.saveState())
super().closeEvent(event)
+
+scheme = QtWebEngineCore.QWebEngineUrlScheme(b'gemini')
+scheme.setDefaultPort(1965)
+scheme.setFlags(QtWebEngineCore.QWebEngineUrlScheme.SecureScheme)
+QtWebEngineCore.QWebEngineUrlScheme.registerScheme(scheme)
app = QtWidgets.QApplication(sys.argv)
-ex = GBrowser(sys.argv[1] if len(sys.argv) > 1 else None)
-sys.exit(app.exec_())
+gem_handler = GeminiSchemeHandler()
+profile = QtWebEngineCore.QWebEngineProfile()
+profile.removeAllUrlSchemeHandlers()
+profile.installUrlSchemeHandler(b'gemini', gem_handler)
+ex = GBrowser(sys.argv[1] if len(sys.argv) > 1 else None, profile)
+sys.exit(app.exec())