103 lines
No EOL
5.1 KiB
Python
Executable file
103 lines
No EOL
5.1 KiB
Python
Executable file
#!/usr/bin/env python2
|
|
"A web browser that will never exceed 128 lines of code. (not counting blanks)"
|
|
|
|
import sys, os, json, tempfile
|
|
from PyQt4 import QtGui, QtCore, QtWebKit, QtNetwork
|
|
|
|
settings = QtCore.QSettings("ralsina", "devicenzo")
|
|
|
|
|
|
class MainWindow(QtGui.QMainWindow):
|
|
def __init__(self):
|
|
QtGui.QMainWindow.__init__(self)
|
|
self.addAction(QtGui.QAction("Full Screen", self, checkable=True, toggled=lambda v: self.showFullScreen() if v else self.showNormal(), shortcut="F11"))
|
|
self.history = self.get("history", [])
|
|
self.restoreGeometry(QtCore.QByteArray.fromRawData(settings.value("geometry").toByteArray()))
|
|
self.restoreState(QtCore.QByteArray.fromRawData(settings.value("state").toByteArray()))
|
|
|
|
# Use a app-wide, persistent cookiejar
|
|
self.cookies = QtNetwork.QNetworkCookieJar(QtCore.QCoreApplication.instance())
|
|
self.cookies.setAllCookies([QtNetwork.QNetworkCookie.parseCookies(c)[0] for c in self.get("cookiejar", [])])
|
|
|
|
# Proxy support
|
|
proxy_url = QtCore.QUrl(os.environ.get('http_proxy', ''))
|
|
QtNetwork.QNetworkProxy.setApplicationProxy(QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.HttpProxy if unicode(proxy_url.scheme()).startswith('http') else QtNetwork.QNetworkProxy.Socks5Proxy, proxy_url.host(), proxy_url.port(), proxy_url.userName(), proxy_url.password())) if 'http_proxy' in os.environ else None
|
|
|
|
progress = lambda self, received, total: self.bars[unicode(self.sender().url().toString())][0].setValue(100. * received / total)
|
|
|
|
def closeEvent(self, ev):
|
|
self.put("history", self.history)
|
|
self.put("cookiejar", [str(c.toRawForm()) for c in self.cookies.allCookies()])
|
|
settings.setValue("geometry", self.saveGeometry())
|
|
settings.setValue("state", self.saveState())
|
|
return QtGui.QMainWindow.closeEvent(self, ev)
|
|
|
|
def put(self, key, value):
|
|
"Persist an object somewhere under a given key"
|
|
settings.setValue(key, json.dumps(value))
|
|
settings.sync()
|
|
|
|
def get(self, key, default=None):
|
|
"Get the object stored under 'key' in persistent storage, or the default value"
|
|
v = settings.value(key)
|
|
return json.loads(unicode(v.toString())) if v.isValid() else default
|
|
|
|
def setTab(self, url=QtCore.QUrl("")):
|
|
self.tab = Tab(url, self)
|
|
self.setCentralWidget(self.tab)
|
|
return self.tab
|
|
|
|
def addToHistory(self, url):
|
|
self.history.append(url)
|
|
|
|
|
|
class Tab(QtGui.QWidget):
|
|
def __init__(self, url, container):
|
|
self.container = container
|
|
QtGui.QWidget.__init__(self)
|
|
self.wb = QtWebKit.QWebView(titleChanged=lambda t: container.setWindowTitle(t))
|
|
self.wb.page().networkAccessManager().setCookieJar(container.cookies)
|
|
self.wb.page().setLinkDelegationPolicy(QtWebKit.QWebPage.DelegateExternalLinks)
|
|
self.wb.linkClicked.connect(lambda url: QtGui.QDesktopServices.openUrl(url))
|
|
|
|
self.setLayout(QtGui.QVBoxLayout(spacing=0))
|
|
self.layout().setContentsMargins(0, 0, 0, 0)
|
|
self.tb = QtGui.QToolBar("Main Toolbar", self)
|
|
#self.layout().addWidget(self.tb)
|
|
self.layout().addWidget(self.wb)
|
|
for a, sc in [[QtWebKit.QWebPage.Back, "Alt+Left"], [QtWebKit.QWebPage.Forward, "Alt+Right"], [QtWebKit.QWebPage.Reload, "Ctrl+r"]]:
|
|
self.tb.addAction(self.wb.pageAction(a))
|
|
self.wb.pageAction(a).setShortcut(sc)
|
|
|
|
self.wb.urlChanged.connect(lambda u: container.addToHistory(unicode(u.toString())))
|
|
|
|
self.search = QtGui.QLineEdit(visible=False, maximumWidth=200, returnPressed=lambda: self.wb.findText(self.search.text()), textChanged=lambda: self.wb.findText(self.search.text()))
|
|
self.showSearch = QtGui.QShortcut("Ctrl+F", self, activated=lambda: self.search.show())
|
|
self.hideSearch = QtGui.QShortcut("Esc", self, activated=self.search.hide)
|
|
|
|
self.wb.setLayout(QtGui.QVBoxLayout(spacing=0))
|
|
self.wb.layout().addWidget(self.search, 0, QtCore.Qt.AlignRight)
|
|
self.wb.layout().addStretch()
|
|
self.wb.layout().setContentsMargins(3, 3, 25, 3)
|
|
|
|
self.do_close = QtGui.QShortcut("Ctrl+W", self, activated=lambda: container.close())
|
|
self.do_quit = QtGui.QShortcut("Ctrl+q", self, activated=lambda: container.close())
|
|
self.zoomIn = QtGui.QShortcut("Ctrl++", self, activated=lambda: self.wb.setZoomFactor(self.wb.zoomFactor() + 0.2))
|
|
self.zoomOut = QtGui.QShortcut("Ctrl+-", self, activated=lambda: self.wb.setZoomFactor(self.wb.zoomFactor() - 0.2))
|
|
self.zoomOne = QtGui.QShortcut("Ctrl+0", self, activated=lambda: self.wb.setZoomFactor(1))
|
|
|
|
self.previewer = QtGui.QPrintPreviewDialog(paintRequested=self.wb.print_)
|
|
self.do_print = QtGui.QShortcut("Ctrl+p", self, activated=self.previewer.exec_)
|
|
self.wb.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled, True)
|
|
self.wb.settings().setIconDatabasePath(tempfile.mkdtemp())
|
|
|
|
self.wb.load(url)
|
|
|
|
createWindow = lambda self, windowType: self.container.addTab()
|
|
|
|
if __name__ == "__main__":
|
|
app = QtGui.QApplication(sys.argv)
|
|
wb = MainWindow()
|
|
wb.setTab(QtCore.QUrl('http://facebook.com'))
|
|
wb.show()
|
|
sys.exit(app.exec_()) |