BirdyNet/BirdyNet.py
2021-03-20 17:24:16 +01:00

204 lines
5.5 KiB
Python

#!/usr/bin/env python3
import sys
oldexcepthook = sys.excepthook
def newexcepthook(type,value,traceback):
oldexcepthook(type,value,traceback)
#input("Press ENTER to quit.") # - this causes issues with Qt's input hook
sys.excepthook = newexcepthook
import os
p = os.path.join
pUp = os.path.dirname
s = False
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
s = os.path.realpath(sys.executable)
else:
s = os.path.realpath(__file__)
sp = pUp(s)
# script start
import qtpy
import qtpy.QtGui as QtGui
from qtpy.QtGui import *
from qtpy.QtWidgets import *
from qtpy.QtCore import *
from qtpy.QtMultimedia import QSound
import configparser
import json
import time
browserWindows = []
os.chdir(sp)
distro = os.path.splitext(s.rsplit(os.path.sep)[-1])[0]
version = {
"major": 0,
"minor": 5,
"patch": 0,
"stage": "dev"
}
versionString = ".".join(map(str,[version["major"],version["minor"]]))
versionStringExt = ".".join(map(str,[version["major"],version["minor"],version["patch"]])) + " " + version["stage"]
def runCode(str, lcs = False, description = "loose-code"):
if lcs == False: lcs = {}
code = compile(str,description,"exec")
exec(code,globals(),lcs)
return lcs
def runScript(sf, lcs = False):
if lcs == False: lcs = {}
with open(sf) as script:
runCode(script.read(),lcs,sf)
return lcs
def getDataDir(appName):
basePath = False
if sys.platform.startswith("win"):
if "appdata" in os.environ: basePath = os.environ["appdata"]
elif sys.platform.startswith("linux"):
if "XDG_DATA_HOME" in os.environ:
basePath = os.environ["XDG_DATA_HOME"]
else:
if "HOME" in os.environ: basePath = p(os.environ["HOME"],".config")
elif sys.platform.startswith("darwin"):
if "HOME" in os.environ: basePath = p(os.environ["HOME"],"Library","Application Support")
if not basePath: raise
return p(basePath,appName)
def prettyJson(ls):
return json.dumps(ls,indent=2)
class browserWindow(QMainWindow):
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.cTitle = "Hello World - " +distro+ " " +versionStringExt
self.cWidth = 640
self.cHeight = 480
self.setWindowTitle(self.cTitle)
self.resize(self.cWidth,self.cHeight)
self.cDocumentInfo = {
"url": "",
"body": "",
"headers": {},
# additional info:
"baseUrl": ""
}
self.cUserAgent = config["default"]["useragent"].replace("$OS",sys.platform).replace("$VER",versionString).replace("$DIST",distro)
self.cCreateElements()
def cCreateElements(self):
self.cMenuBar = self.menuBar()
self.cFileMenu = self.cMenuBar.addMenu("&File")
self.cNewWindowButton = self.cFileMenu.addAction("New &window")
self.cNewWindowButton.triggered.connect(self.cNewWindow)
self.cViewMenu = self.cMenuBar.addMenu("&View")
self.cUrlBar = QLineEdit(config["default"]["home"],self)
self.cUrlBar.returnPressed.connect(self.cNavigate)
self.cButtonGo = QPushButton("Go",self)
self.cButtonGo.clicked.connect(self.cNavigate)
self.cDoc = browserDoc(self)
self.cStatusBar = QStatusBar(self)
self.cStatusBar.showMessage("Please wait...")
self.cResizeElements()
self.show()
self.cNavigate()
self.cUrlBar.setFocus()
def cResizeElements(self):
barSize = 22
mb = self.cMenuBar.height()
self.cUrlBar.move(0,mb)
self.cUrlBar.resize(self.cWidth - barSize,barSize)
self.cButtonGo.move(self.cWidth - barSize,mb)
self.cButtonGo.resize(barSize,barSize)
self.cDoc.move(0,mb + barSize)
self.cDoc.resize(self.cWidth,self.cHeight - barSize - mb - mb)
self.cStatusBar.move(0,self.cHeight - mb)
self.cStatusBar.resize(self.cWidth,mb)
def resizeEvent(self,event):
self.cWidth = self.width()
self.cHeight = self.height()
self.cResizeElements()
def closeEvent(self,event):
browserWindows.remove(self)
event.accept()
def cNavigate(self,event = None):
try:
#print(prettyJson(parseUrl(self.cUrlBar.text())))
self.cStatusBar.showMessage("Downloading...")
self.update()
start = time.time()
response = downloadPage(self.cUrlBar.text(),{"User-Agent": self.cUserAgent})
self.cUrlBar.setText(response["url"])
end = time.time()
print("Downloading page: " +str(end - start))
infoFetcher(response)
self.cDocumentInfo = response
self.cStatusBar.showMessage("Rendering...")
self.update()
start = time.time()
self.cDoc.cRenderHtml(response["body"].decode("utf-8",errors="ignore"))
end = time.time()
print("Rendering page: " +str(end - start))
self.cDoc.setFocus()
self.cStatusBar.showMessage("Ready")
self.update()
#print(prettyJson(response["headers"]))
except Exception as e:
self.cDoc.cRenderHtml(str(e))
raise
def cNewWindow(self):
w = browserWindow()
browserWindows.append(w)
w.show()
def main():
# load program default addons
addonDir = p(sp,"addons")
for root,dirs,files in os.walk(addonDir):
for file in files:
ffile = p(root,file)
lfile = ffile.replace(addonDir + os.path.sep,"",1)
if lfile[0] == "-": continue
print("Running addon: " +lfile)
runScript(ffile)
break
global dataDir
dataDir = getDataDir(distro)
global config
config = configparser.ConfigParser()
# read program default config
config.read(distro + ".ini")
# read user config
if os.path.isfile(p(dataDir,"config.ini")):
config.read(p(dataDir,"config.ini"))
app = QApplication(sys.argv)
try:
app.setWindowIcon(QtGui.QIcon("assets/BirdyNet-XP.ico"))
except Exception as e:
print("Could not set window icon: " +print(e))
browserWindows.append(browserWindow())
sys.exit(app.exec_())
if __name__ == '__main__':
main()