From c8db302d5f983f92a7b2163b3a771de55017a724 Mon Sep 17 00:00:00 2001
From: Niklas20114552 <83753407+Niklas20114552@users.noreply.github.com>
Date: Wed, 20 Dec 2023 20:47:29 +0100
Subject: [PATCH] Update to 0.05.4 : see changelog.md
---
changelog.md | 32 ++
error.html | 48 +--
errorfile.html | 38 ++-
home.html | 76 ++++-
homeupdate.html | 99 ++++--
lang/de.json | 66 +++-
lang/en.json | 62 +++-
linux_setup.py | 8 +-
main.py | 794 ++++++++++++++++++++++++++++++------------------
9 files changed, 837 insertions(+), 386 deletions(-)
diff --git a/changelog.md b/changelog.md
index e86d224..45f09e5 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,37 @@
# Changelog
+## 0.05.4 : 20.12.2030
+
+By: [@Niklas20114552](https://github.com/Niklas20114552)
+
+(Merry Christmas)
+
+Changed:
+
+- ```error.html``` has now aditional tips for the troubleshooting
+- ```error.html``` and ```errorfile.html``` are now using flex-containers to center the content.
+- Made the english translation more consistant in debug messages
+- Configparser now uses functions to read and create options, to reduce the code amount.
+- The "Failed to load Tabs" Error Message in console now only shows in debugmode
+
+Added:
+
+- Google Safe Browsing now warns about Potentially Unwanted Software (PuP)
+- Added Userscript Manager (like Tampermonkey) and Custom CSS Manager
+- Added the ability to hide hte search bar
+- Removed ```https://inv.makerlab.tech``` as an Invidious-Option for ES, as it doesn't exist anymore
+- Regex-Filter to allow auto completing URLs. e.g.:
+ - ```google.com``` → ```https://google.com/```
+ - ```www.github.com``` → ```https://www.github.com/```
+- Added a Mute-Button to the tabs, when the tab is playing audio or the tab is muted
+- Added a little security badge on the left hand side of the address bar, that shows a lock in https, a open lock with text in http, a globe with the text Brapy on a Brapy-Page and a open lock with text when a certificate issue occurred.
+- You can now Fullscreen the entire Page by pressing ```F11```
+
+Removed:
+
+- Removed the Mute-Button in the top right corner, as it is replaced by the mute button in the tab.
+
+
## 0.05.3 : 21.09.2023
By: [@Niklas20114552](https://github.com/Niklas20114552)
diff --git a/error.html b/error.html
index 271a420..7cd340c 100644
--- a/error.html
+++ b/error.html
@@ -3,16 +3,14 @@
Fehler :(
-
-
+
+
-Falls sie etwas suchen wollten, verwenden Sie die Suchleiste oben rechts.
+Bitte überprüfen Sie, dass Sie die richtige Addresse eingeben haben.
+Wenn Sie die Richtige Addresse eingeben haben:
+
+Versuchen Sie es später erneut.
+Überprüfen Sie ihre Internetverbindung
+Versuchen Sie, den Adblocker zu deaktivieren (wenn nicht bereits getan).
+Überprüfen Sie (wenn vorhanden), ob DNS-Filter wie PiHole oder AdGuard Home diese Seite blockieren.
+Überprüfen Sie, ob Brapy die Berechtigungen hat, auf das Internet zuzugreifen (Sie sind möglicherweise verbunden, aber hinter einer Firewall).
+
Neu laden
-
+
diff --git a/home.html b/home.html
index 945a045..d05b69f 100644
--- a/home.html
+++ b/home.html
@@ -4,28 +4,76 @@
Neuer Tab
-
-
-
Brapy
-
+
+ Brapy
Suchen
-
+
diff --git a/lang/de.json b/lang/de.json
index 74bc77a..583460d 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -8,6 +8,7 @@
"title2": "Sicherheit",
"title3": "Adblocker",
"title4": "Features",
+ "title5": "Userscript Manager",
"adblockl1": "Whiteliste: (Jede URL in eine neue Zeile)",
"adblockl2": "Blackliste: (Jede URL in eine neue Zeile)",
"featl1": "Dieses Land verwenden:",
@@ -18,11 +19,16 @@
"https": "HTTPS erzwingen",
"safebrowsing": "Google Safe Browsing verwenden",
"enadblock": "Adblocker aktiviert",
- "openyoutube": "Youtube auf Invidious umleiten"
+ "openyoutube": "Youtube auf Invidious umleiten",
+ "show_search": "Suchleiste anzeigen (Erfordert Neustart)",
+ "ujs_enabled": "Userscript Manager aktivieren (Erfordert Neustart)",
+ "ujs_addfile": "JS-Skript/Themedatei hinzufügen",
+ "ujs_filetypes": "Javascript Datei(*.js);;Themedatei(*.css)",
+ "ujs_managefiles": "Skripte und Themes verwalten"
}
},
"webview_tab": {
- "adress_barp": "Adresse eingeben",
+ "address_barp": "Mit DuckDuckGo suchen oder Adresse eingeben",
"search_barp": "Mit DuckDuckGo suchen"
},
"malware_ahead": {
@@ -30,7 +36,7 @@
"cancel_load": "Laden Abbrechen",
"show_details": "Details...",
"malware" : {
- "wtitle": "Malware auf folgender Website!",
+ "wtitle": "Warnung vor Malware",
"title": "Malware auf nachfolgender Website",
"text1a": "Zurzeit auf",
"text1b": "befindliche Hacker könnten versuchen,",
@@ -41,7 +47,7 @@
"detail2": "Websites, die in der Regel sicher sind, können gelegentlich mit Malware infiziert sein."
},
"phishing": {
- "wtitle": "Bei der Aufgerufenen Seite besteht Phishing-Verdacht!",
+ "wtitle": "Warnung vor Phishing",
"title": "Bei der Aufgerufenen Seite besteht Phishing-Verdacht!",
"text1a": "Hacker könnten auf",
"text1b": "etwa versuchen, Sie zur Installation von Software",
@@ -50,6 +56,17 @@
"detail1a": "Google Safe Browsing hat kürzlich Phishing-Methoden auf ",
"detail1b": " gefunden.",
"detail2": "Phsihing Seiten tun so, als ob sie andere Seiten seien, um sie zu täuschen."
+ },
+ "pup": {
+ "wtitle": "Warnung vor schädlichen Programmen",
+ "title": "Die Website, die du aufrufen möchtest, enthält schädliche Programme",
+ "text1a": "Hacker könnten auf",
+ "text1b": "versuchen, dich zur Installation von Programmen zu bewegen, die sich ",
+ "text2": "nachteilig auf deine Browsernutzung mit anderen Browsern auswirken. Dabei kann zum",
+ "text3": "Beispiel deine Startseite geändert werden oder es erscheint zusätzliche Werbung auf von dir besuchten Websites.",
+ "detail1a": "Google Safe Browsing hat vor Kurzem schädliche Programme auf ",
+ "detail1b": " gefunden.",
+ "detail2": "Schädliche Programme können die Nutzung des Computers beeinträchtigen."
}
},
"adblock_menu": {
@@ -87,12 +104,13 @@
"failed_download": "Download fehlgschlagen"
},
"general": {
- "yes": "Yes",
- "no": "No",
+ "yes": "Ja",
+ "no": "Nein",
"okay": "Okay",
- "cancel": "Cancel",
+ "cancel": "Abbrechen",
"of": "von",
- "to": "nach"
+ "to": "nach",
+ "deleted": "Gelöscht"
},
"pending_downloads": {
"title": "Laufende Downloads",
@@ -121,7 +139,7 @@
"country_detected2": " erkannt.",
"invidious_settings": "Sie können einen bestimmten Server in den Einstellungen einstellen.",
"country_available": "Die verfügbaren Server sind:",
- "country_list": "DE, FR, CL, US, RO, LU, FI, SE, SG, ES, IN, NL, JP, LT",
+ "country_list": "DE, FR, CL, US, RO, LU, FI, SE, SG, IN, NL, JP, LT",
"creating_adlist": "Adliste wird erstellt...",
"creating_adlist2": "Die Adliste für den Adblocker wird erstellt..."
},
@@ -144,10 +162,15 @@
"confirm_close": "Schließen bestätigen",
"really_quit": "Möchten sie Brapy wirklich beenden?"
},
- "adress_bar": {
+ "address_bar": {
"view-source": "Seitenquelltext von ",
- "error-url": "Fehler beim Laden der Webseite",
- "error-file": "Fehler beim Laden der Datei"
+ "error_url": "Fehler beim Laden der Webseite",
+ "error_file": "Fehler beim Laden der Datei",
+ "local_file": "Lokale Datei",
+ "locale_page": "Lokale Seite",
+ "cert_error": "Zertifikat fehler",
+ "sourcecode": "Quelltext",
+ "not_safe": "Nicht Gesichert"
},
"download_dialog": {
"title": "Datei Herunterladen...",
@@ -160,5 +183,24 @@
"still_continue": "Möchten sie wirklich fortfahren?",
"save_file": "Datei Speichern...",
"all_files": "Alle Dateien"
+ },
+ "page": {
+ "title": "Zertifikat fehler",
+ "text1a": "Das Laden von ",
+ "text1b": " wurde abgebrochen.",
+ "text2": "Es wurde ein Zertifikatfehler erkannt.",
+ "text3": "Falls Sie die Website besuchen, könnten Angreifer versuchen, Passwörter, E-Mails oder Kreditkartendaten zu stehlen.",
+ "text4": "Möchten sie wirklich fortfahren?"
+ },
+ "userscript_manager": {
+ "loadtypes": ["Beim Laden", "Normal", "Verzögert"],
+ "jsname": "Skriptname",
+ "cssname": "Themename",
+ "jsfile": "Skriptdatei",
+ "cssfile": "Themedatei",
+ "jsloadtype": "Ladezeitpunkt",
+ "continuejs": "Möchten sie die Skriptdatei hinzufügen?",
+ "continuecss": "Möchten sie die Themedatei hinzufügen?",
+ "nowapplied": "Bitte beachten Sie, dass die Änderungen jetzt übernommen werden und nicht erst nach Betätigung des Übernehmen-Buttons."
}
}
\ No newline at end of file
diff --git a/lang/en.json b/lang/en.json
index f317253..c8cd9c5 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -8,6 +8,7 @@
"title2": "Security",
"title3": "Adblocker",
"title4": "Features",
+ "title5": "Userscript Manager",
"adblockl1": "Whiteliste: (Each URL in a new line)",
"adblockl2": "Blackliste: (Each URL in a new line)",
"featl1": "Use this Country:",
@@ -18,11 +19,16 @@
"https": "Enforce HTTPS",
"safebrowsing": "Use Google Safe Browsing",
"enadblock": "Enable Adblocker",
- "openyoutube": "Redirect Youtube to Invidious"
+ "openyoutube": "Redirect Youtube to Invidious",
+ "show_search": "Show Searchbar (Requires Restart)",
+ "ujs_enabled": "Enable Userscript Manager (Requires Restart)",
+ "ujs_addfile": "Add JS-Script/Themefile",
+ "ujs_filetypes": "Javascript File(*.js);;Themefile(*.css)",
+ "ujs_managefiles": "Manage Scripts and Themes"
}
},
"webview_tab": {
- "adress_barp": "Enter Address",
+ "address_barp": "Search with DuckDuckGo or enter Address",
"search_barp": "Search with DuckDuckGo"
},
"malware_ahead": {
@@ -30,7 +36,7 @@
"cancel_load": "Cancel Loading",
"show_details": "Details...",
"malware" : {
- "wtitle": "The Site ahead contains malware",
+ "wtitle": "Malware warning",
"title": "The Site ahead contains malware!",
"text1a": "Attackers currently on",
"text1b": "might attempt to install dangerous programs on",
@@ -41,7 +47,7 @@
"detail2": "Websites that are generally safe can occasionally be infected with malware."
},
"phishing": {
- "wtitle": "Phishing attack ahead",
+ "wtitle": "Phishing warning",
"title": "Phishing attack ahead!",
"text1a": "Attackers on",
"text1b": "might trick you to steal",
@@ -50,6 +56,17 @@
"detail1a": "Google Safe Browsing recently detected phishing on ",
"detail1b": ".",
"detail2": "Phishing sites pretend to be other websites to trick you."
+ },
+ "pup": {
+ "wtitle": "Malicious program warning",
+ "title": "The website you are trying to access contains malicious programs",
+ "text1a": "Hackers on",
+ "text1b": "may try to get you to install programs ",
+ "text2": "that adversely affect your browsing experience with other browsers. For example, your homepage",
+ "text3": " may be changedor additional advertising may appear on websites you visit.",
+ "detail1a": "Google Safe Browsing recently found malicious programs on ",
+ "detail1b": ".",
+ "detail2": "Malicious programs can affect your use of your computer."
}
},
"adblock_menu": {
@@ -77,7 +94,7 @@
"1_download": "1 Download",
"multi_download": " Downloads",
"cancel_download": "Cancel Download",
- "copy_download": "Copy Downloadadress",
+ "copy_download": "Copy Downloadaddress",
"open_download": "Open Destination",
"pause_download": "Pause Download",
"waiting_download": "Waiting to start...",
@@ -91,8 +108,9 @@
"no": "No",
"okay": "Okay",
"cancel": "Cancel",
- "of": "von",
- "to": "nach"
+ "of": "of",
+ "to": "to",
+ "deleted": "Deleted"
},
"pending_downloads": {
"title": "Running Downloads",
@@ -121,7 +139,7 @@
"country_detected2": ".",
"invidious_settings": "You can set a specific server in the settings.",
"country_available": "The available servers are:",
- "country_list": "DE, FR, CL, US, RO, LU, FI, SE, SG, ES, IN, NL, JP, LT",
+ "country_list": "DE, FR, CL, US, RO, LU, FI, SE, SG, IN, NL, JP, LT",
"creating_adlist": "Adlist is being created...",
"creating_adlist2": "The adlist for the adblocker is being created..."
},
@@ -144,10 +162,15 @@
"confirm_close": "Confirm Close",
"really_quit": "Do you really want to close Brapy?"
},
- "adress_bar": {
+ "address_bar": {
"view-source": "Source Code of ",
"error_url": "Error while Loading the Website",
- "error_file": "Error while Loading the File"
+ "error_file": "Error while Loading the File",
+ "local_file": "Local File",
+ "locale_page": "Local Page",
+ "cert_error": "Certificate error",
+ "sourcecode": "Source Code",
+ "not_safe": "Not safe"
},
"download_dialog": {
"title": "Download File...",
@@ -160,5 +183,24 @@
"still_continue": "Dou you really want to continue?",
"save_file": "Save File...",
"all_files": "All Files"
+ },
+ "page": {
+ "title": "Certificate error",
+ "text1a": "The loading of ",
+ "text1b": " was aborted.",
+ "text2": "A certificate error was detected.",
+ "text3": "If you visit the website, attackers may attempt to steal passwords, emails or credit card information.",
+ "text4": "Do you really want to continue?"
+ },
+ "userscript_manager": {
+ "loadtypes": ["Preload", "Normal", "Delayed"],
+ "jsname": "Scriptname",
+ "cssname": "Themename",
+ "jsfile": "Scriptfile",
+ "cssfile": "Themefile",
+ "jsloadtype": "Loadtime",
+ "continuejs": "Would you like to add the script file?",
+ "continuecss": "Would you like to add the theme file?",
+ "nowapplied": "Please note, that the changes are applied now and not after pressing the apply-button."
}
}
\ No newline at end of file
diff --git a/linux_setup.py b/linux_setup.py
index 947fe1f..5392f59 100755
--- a/linux_setup.py
+++ b/linux_setup.py
@@ -25,7 +25,7 @@ class ProgressUpdater(QObject):
installfailed = pyqtSignal(str)
APP_NAME = "Brapy Setup"
-APP_VERSION = "0.2"
+APP_VERSION = "0.3"
class MainWindow(QMainWindow):
def __init__(self, return_code):
super().__init__()
@@ -279,7 +279,7 @@ def update_progress_bar(value):
elif value == 9:
log1.append("Kopiere upgrade.html nach /usr/local/share/brapy/upgrade.html")
elif value == 10:
- log1.append("Kopiere upgrade.sh nach /usr/local/share/brapy/upgrade.sh")
+ log1.append("Kopiere upgrade.sh nach /usr/local/share/brapy/upgrade")
elif value == 11:
log1.append("Kopiere main.py nach /usr/local/bin/brapy")
elif value == 12:
@@ -347,7 +347,7 @@ def run_installation():
progress_updater.update_progress.emit(9)
copyfile("upgrade.html", "/tmp/brapy/upgrade.html")
progress_updater.update_progress.emit(10)
- copyfile("upgrade.sh", "/tmp/brapy/upgrade.sh")
+ copyfile("upgrade.sh", "/tmp/brapy/upgrade")
progress_updater.update_progress.emit(11)
copyfile("main.py", "/tmp/brapy-bin/brapy")
progress_updater.update_progress.emit(12)
@@ -367,7 +367,7 @@ def run_installation():
if not "Material Icons Outlined" in fonts:
copyfileobj(requests.get("https://github.com/google/material-design-icons/raw/master/font/MaterialIconsOutlined-Regular.otf", stream=True).raw, open("/tmp/MaterialIconsOutlined-Regular.otf", 'wb'))
progress_updater.update_progress.emit(18)
- process = subprocess.Popen("pkexec bash -c 'mkdir -p {/usr/local/share/brapy,/usr/local/bin}; mv /tmp/brapy/* /usr/local/share/brapy/; mv /tmp/brapy-bin/* /usr/local/bin/; mv /tmp/brapy.desktop /usr/share/applications/; [ -f /tmp/MaterialIcons-Regular.ttf ] && mv /tmp/MaterialIcons-Regular.ttf /usr/share/fonts/; [ -f /tmp/MaterialIconsOutlined-Regular.otf ] && mv /tmp/MaterialIconsOutlined-Regular.otf /usr/share/fonts/; chown -R root:root {/usr/local/bin/,/usr/local/share/brapy,/usr/share/applications,/usr/share/fonts}; chmod +x /usr/local/bin/{brapy,brapy-uninstaller}; chmod +x /usr/local/share/brapy/genadlist.py'", shell=True)
+ process = subprocess.Popen("pkexec bash -c 'mkdir -p {/usr/local/share/brapy,/usr/local/bin}; [[ -d /usr/local/share/brapy/lang ]] && rm -f /usr/local/share/brapy/lang/*; mv /tmp/brapy/* /usr/local/share/brapy/; mv /tmp/brapy-bin/* /usr/local/bin/; mv /tmp/brapy.desktop /usr/share/applications/; [ -f /tmp/MaterialIcons-Regular.ttf ] && mv /tmp/MaterialIcons-Regular.ttf /usr/share/fonts/; [ -f /tmp/MaterialIconsOutlined-Regular.otf ] && mv /tmp/MaterialIconsOutlined-Regular.otf /usr/share/fonts/; chown -R root:root {/usr/local/bin/,/usr/local/share/brapy,/usr/share/applications,/usr/share/fonts}; chmod +x /usr/local/bin/{brapy,brapy-uninstaller}; chmod +x /usr/local/share/brapy/genadlist.py'", shell=True)
stdoutdata, stderrdata = process.communicate()
if process.returncode == 127:
progress_updater.installfailed.emit("Der Nutzer hat den Vorgang abgebrochen.")
diff --git a/main.py b/main.py
index 417ebe9..f0e8762 100755
--- a/main.py
+++ b/main.py
@@ -2,24 +2,24 @@
import sys, requests, os, json, getopt, re, subprocess, ast, urllib3, pyperclip, math, webbrowser
from PyQt5.QtCore import Qt, QUrl, QDir, QTimer, QThread, pyqtSignal, QSize
from PyQt5.QtWidgets import QApplication, QMainWindow, QLineEdit, QHBoxLayout, QVBoxLayout, QWidget, QTextEdit, QPushButton, QTabWidget, QTabBar, QMenu, QAction, QDialog, QLabel, QFileDialog, QProgressBar, QScrollArea, QFrame, QCheckBox, QComboBox
-from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineProfile, QWebEnginePage, QWebEngineSettings, QWebEngineDownloadItem
+from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineProfile, QWebEnginePage, QWebEngineSettings, QWebEngineDownloadItem, QWebEngineScript
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor, QWebEngineUrlRequestInfo
-from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
-from PyQt5.QtGui import QKeySequence, QFont, QFocusEvent, QCursor, QIcon
+# from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
+from PyQt5.QtGui import QKeySequence, QFont, QFocusEvent, QKeyEvent, QIcon
from shutil import copyfile
from urllib.parse import urlparse
from configparser import ConfigParser
from requests.packages.urllib3.exceptions import InsecureRequestWarning
-from plyer import notification
+# from plyer import notification
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
config = ConfigParser()
-APP_VERSION: str = "0.05.3"
+APP_VERSION: str = "0.05.4"
APP_VERSION_ISBETA: bool = False
APP_VERSION_BETA: int = 0
APP_NAME: str = "Brapy"
-APP_DESCR: str = APP_NAME + " ist ein auf Qt5 (PyQt5) in Python geschriebender Webbrowser."
+APP_DESCR: str = APP_NAME + " is a simple Qt5 (PyQt5) Python based Webbrowser."
APP_MANUAL_INSTALLED: bool = True
APP_LOCALE = None
@@ -112,7 +112,7 @@ def __init__(self, url, type, translation):
self.text12 = QLabel()
backbutton = QPushButton(self.translation['malware_ahead']['cancel_load'])
backbutton.clicked.connect(self.reject)
- backbutton.setStyleSheet('background-color: white; color: #de312e;')
+ backbutton.setStyleSheet('background-color: white; color: #c32b29;')
self.detailsbutton = QPushButton(self.translation['malware_ahead']['show_details'])
self.detailsbutton.setFixedWidth(150)
self.detailsbutton.clicked.connect(self.showDetails)
@@ -135,6 +135,14 @@ def __init__(self, url, type, translation):
text3.setText(self.translation['malware_ahead']['phishing']['text3'])
self.text11.setText(self.translation['malware_ahead']['phishing']['detail1a'] + url + self.translation['malware_ahead']['phishing']['detail1b'])
self.text12.setText(self.translation['malware_ahead']['phishing']['detail2'])
+ elif type == "pup":
+ self.setWindowTitle(self.translation['malware_ahead']['pup']['wtitle'])
+ title.setText(self.translation['malware_ahead']['pup']['title'])
+ text1.setText(self.translation['malware_ahead']['pup']['text1a'] + " " + url + " " + self.translation['malware_ahead']['pup']['text1b'])
+ text2.setText(self.translation['malware_ahead']['pup']['text2'])
+ text3.setText(self.translation['malware_ahead']['pup']['text3'])
+ self.text11.setText(self.translation['malware_ahead']['pup']['detail1a'] + url + self.translation['malware_ahead']['pup']['detail1b'])
+ self.text12.setText(self.translation['malware_ahead']['pup']['detail2'])
title.setFont(QFont(title.font().family(), 20))
text1.setFont(QFont(text1.font().family(), 11))
@@ -240,6 +248,7 @@ def __init__(self, downloads, locale):
self.scroll_area.setWidget(self.scroll_widget)
self.scroll_layout = QVBoxLayout()
self.scroll_widget.setLayout(self.scroll_layout)
+ self.setWindowIcon(QIcon('/usr/local/share/brapy/brapy_logo.png'))
self.locale = locale
h1layout = QHBoxLayout()
@@ -494,7 +503,7 @@ def __init__(self, locale, url, file_name, parent=None):
def accept_download(self):
path = self.path_lineedit.text()
if os.path.exists(path):
- dialog = YesNoDialog('yesno', self.locale, self.locale['download_dialog']['file_conflict'], self.locale['download_dialog']['already_exists'], self.locale['download_dialog']['may_overwrite'], self.locale['download_dialog']['still_continue'])
+ dialog = YesNoDialog(self.locale, 'yesno', self.locale['download_dialog']['file_conflict'], self.locale['download_dialog']['already_exists'], self.locale['download_dialog']['may_overwrite'], self.locale['download_dialog']['still_continue'])
if dialog.exec_() == QDialog.Accepted:
self.accept()
else:
@@ -564,7 +573,7 @@ def get_safebrowsing_result(self, url):
"clientVersion": APP_VERSION
},
"threatInfo": {
- "threatTypes": ["MALWARE", "SOCIAL_ENGINEERING"],
+ "threatTypes": ["MALWARE", "SOCIAL_ENGINEERING", "UNWANTED_SOFTWARE", "POTENTIALLY_HARMFUL_APPLICATION"],
"platformTypes": ["ANY_PLATFORM"],
"threatEntryTypes": ["URL"],
"threatEntries": [{"url": url}]
@@ -574,10 +583,12 @@ def get_safebrowsing_result(self, url):
if response.status_code == 200:
data = json.loads(response.text)
if "matches" in data:
- if data["matches"][0]["threatType"] == "MALWARE":
+ if data["matches"][0]["threatType"] in ["MALWARE", "POTENTIALLY_HARMFUL_APPLICATION"]:
return "malware"
- elif data["matches"][0]["threatType"] == "MALWARE":
- return "phishing"
+ elif data["matches"][0]["threatType"] == "SOCIAL_ENGINEERING":
+ return "phish"
+ elif data["matches"][0]["threatType"] == "UNWANTED_SOFTWARE":
+ return "pup"
else:
return "clean"
else:
@@ -611,7 +622,7 @@ def interceptRequest(self, info: QWebEngineUrlRequestInfo):
info.block(True)
if self.debugged:
print("[INTERCEPTOR] Blocked (Username): " + url)
- dialog = YesNoDialog("okcancel", self.locale, "Sicherheitswarnung", 'Das Laden von "' + hostname + '" wurde abgebrochen.', 'In der URL wurde der Benutzername "' + username + '" angegeben.', 'Dies könnte ein Versuch sein, sie zu täuschen, um Anmeldedaten zu stehlen.', 'Klicken sie OK um trotzdem fort zu fahren.')
+ dialog = YesNoDialog(self.locale_file, "okcancel", "Sicherheitswarnung", 'Das Laden von "' + hostname + '" wurde abgebrochen.', 'In der URL wurde der Benutzername "' + username + '" angegeben.', 'Dies könnte ein Versuch sein, sie zu täuschen, um Anmeldedaten zu stehlen.', 'Klicken sie OK um trotzdem fort zu fahren.')
if dialog.exec_() == QDialog.Accepted:
info.block(False)
else:
@@ -636,13 +647,13 @@ def interceptRequest(self, info: QWebEngineUrlRequestInfo):
if self.config_httpsrewrite == True and url.startswith("http://") and not hostname in self.norewrite:
new_url = url.replace("http://", "https://", 1)
try:
- response = requests.head(new_url, timeout=1)
+ requests.head(new_url, timeout=1)
info.redirect(QUrl(new_url))
if self.debugged:
print("[INTERCEPTOR] Redirected to HTTPS: " + url)
except requests.exceptions.RequestException as e:
info.block(True)
- dialog = YesNoDialog("yesno", self.locale, "HTTPS-Variante nicht verfügbar", "Die HTTPS Variante von " + hostname + " ist nicht verfügbar.", "Möchten sie den HTTPS-Rewrite für diese Seite temporär deaktivieren?")
+ dialog = YesNoDialog(self.locale, "yesno", "HTTPS-Variante nicht verfügbar", "Die HTTPS Variante von " + hostname + " ist nicht verfügbar.", "Möchten sie den HTTPS-Rewrite für diese Seite temporär deaktivieren?")
if dialog.exec_() == QDialog.Accepted:
self.norewrite.append(hostname)
info.block(False)
@@ -666,14 +677,17 @@ def interceptRequest(self, info: QWebEngineUrlRequestInfo):
elif safebrowsing == "malware":
if self.debugged:
ColorPrint("[INTERCEPTOR] Safe-Browsing Return for " + url + ": MALWARE", "yellow")
- elif safebrowsing == "phishing":
+ elif safebrowsing == "phish":
if self.debugged:
ColorPrint("[INTERCEPTOR] Safe-Browsing Return for " + url + ": PHISHING", "yellow")
+ elif safebrowsing == "pup":
+ if self.debugged:
+ ColorPrint("[INTERCEPTOR] Safe-Browsing Return for " + url + ": POTENTIAL_UNWANTED_SOFTWARE", "yellow")
elif safebrowsing == "clean":
if self.debugged:
print("[INTERCEPTOR] Safe-Browsing Return for " + url + ": CLEAN")
self.resultlist.append({'hostname': url_without_arg, 'result': safebrowsing})
- if safebrowsing == "malware" or safebrowsing == "phishing":
+ if safebrowsing in ["malware", "phish", "pup"]:
info.block(True)
dialog = MalwareAhead(hostname, safebrowsing, self.translation)
if dialog.exec_() == QDialog.Accepted:
@@ -682,10 +696,16 @@ def interceptRequest(self, info: QWebEngineUrlRequestInfo):
if safebrowsing == "malware":
if self.debugged:
ColorPrint("[INTERCEPTOR] Safe-Browsing Return for " + url + ": MALWARE (offline check)", "yellow")
- elif safebrowsing == "phishing":
+ elif safebrowsing == "phish":
if self.debugged:
ColorPrint("[INTERCEPTOR] Safe-Browsing Return for " + url + ": PHISHING (offline check)", "yellow")
- if safebrowsing == "malware" or safebrowsing == "phishing":
+ elif safebrowsing == "pup":
+ if self.debugged:
+ ColorPrint("[INTERCEPTOR] Safe-Browsing Return for " + url + ": POTENTIAL_UNWANTED_SOFTWARE (offline check)", "yellow")
+ elif safebrowsing == "clean":
+ if self.debugged:
+ print("[INTERCEPTOR] Safe-Browsing Return for " + url + ": CLEAN (offline check)")
+ if safebrowsing in ["malware", "phishing", "pup"]:
info.block(True)
dialog = MalwareAhead(hostname, safebrowsing, self.translation)
if dialog.exec_() == QDialog.Accepted:
@@ -836,7 +856,7 @@ def certificateError(self, error):
url = error.url().toString()
hostname = urlparse(url).hostname
if not APP_LOCALE == None:
- dialog = YesNoDialog("yesno", self.locale, "Zertifikatfehler", f"Das Laden von {hostname} wurde abgebrochen.", "Es wurde ein Zertifikatfehler erkannt.", "Falls Sie die Website besuchen, könnten Angreifer versuchen, Passwörter, E-Mails oder Kreditkartendaten zu stehlen.", "Möchten sie wirklich fortfahren?")
+ dialog = YesNoDialog(APP_LOCALE, "yesno", APP_LOCALE['page']['title'], f"{APP_LOCALE['page']['text1a']}{hostname}{APP_LOCALE['page']['text1b']}", APP_LOCALE['page']['text2'], APP_LOCALE['page']['text3'], APP_LOCALE['page']['text4'])
if dialog.exec_() == QDialog.Accepted:
error.ignoreCertificateError()
return True
@@ -844,6 +864,7 @@ def certificateError(self, error):
return super().certificateError(error)
else:
return super().certificateError(error)
+
class BrapyEngine(QWebEngineView):
def __init__(self, locale, homeurl, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -851,7 +872,7 @@ def __init__(self, locale, homeurl, *args, **kwargs):
self.customContextMenuRequested.connect(self.showContextMenu)
self.homeurl = homeurl
self.locale = locale
-
+
settings = self.settings()
settings.setAttribute(QWebEngineSettings.JavascriptEnabled, True)
settings.setAttribute(QWebEngineSettings.JavascriptCanOpenWindows, True)
@@ -879,6 +900,161 @@ def showContextMenu(self, pos):
menu.exec_(self.mapToGlobal(pos))
+class UJS_AddFileDialog(QDialog):
+ def __init__(self, defaultname, isjs, locale):
+ super().__init__()
+ self.locale = locale
+ self.setWindowIcon(QIcon('/usr/local/share/brapy/brapy_logo.png'))
+ self.setWindowTitle(self.locale['custom_tab']['brapy:settings']['ujs_addfile'])
+ self.setMinimumWidth(600)
+ self.setMaximumWidth(1600)
+
+ self.main_layout = QVBoxLayout(self)
+
+ self.filenamebar = QLineEdit()
+ self.filenamebar.setText(defaultname)
+
+ hlayout1 = QHBoxLayout()
+ hlayout2 = QHBoxLayout()
+ hlayout3 = QHBoxLayout()
+
+ self.yesbutton = QPushButton(self.locale['general']['yes'])
+ self.nobutton = QPushButton(self.locale['general']['no'])
+ self.appliedlabel = QLabel(self.locale['userscript_manager']['nowapplied'])
+
+ self.loadlabel = QLabel(self.locale['userscript_manager']['jsloadtype'])
+ self.loadtype = QComboBox()
+ self.loadtype.addItems(self.locale['userscript_manager']['loadtypes'])
+ if isjs:
+ self.filenamelabel = QLabel(self.locale['userscript_manager']['jsname'])
+ self.confirmlabel = QLabel(self.locale['userscript_manager']['continuejs'])
+ else:
+ self.filenamelabel = QLabel(self.locale['userscript_manager']['cssname'])
+ self.confirmlabel = QLabel(self.locale['userscript_manager']['continuecss'])
+ self.loadlabel.setDisabled(True)
+ self.loadtype.setCurrentIndex(1)
+ self.loadtype.setDisabled(True)
+
+ hlayout1.addWidget(self.filenamelabel)
+ hlayout1.addWidget(self.filenamebar)
+ hlayout2.addWidget(self.loadlabel)
+ hlayout2.addWidget(self.loadtype)
+ hlayout3.addWidget(self.nobutton)
+ hlayout3.addWidget(self.yesbutton)
+
+ self.main_layout.addLayout(hlayout1)
+ self.main_layout.addLayout(hlayout2)
+ self.main_layout.addWidget(self.confirmlabel)
+ self.main_layout.addLayout(hlayout3)
+
+ self.yesbutton.clicked.connect(self.accept)
+ self.nobutton.clicked.connect(self.reject)
+
+class UJS_Manage(QDialog):
+ def __init__(self, locale):
+ super().__init__()
+ self.locale = locale
+ self.main_layout = QVBoxLayout(self)
+ self.scroll_area = QScrollArea()
+ self.main_layout.addWidget(self.scroll_area)
+ self.scroll_layout = QVBoxLayout()
+ self.scroll_area.setLayout(self.scroll_layout)
+ self.setMinimumWidth(600)
+ self.setMaximumWidth(1600)
+ self.setWindowIcon(QIcon('/usr/local/share/brapy/brapy_logo.png'))
+ self.setWindowTitle(self.locale['custom_tab']['brapy:settings']['ujs_managefiles'])
+
+ self.layouts = {}
+ self.renames = []
+ self.files = os.listdir(os.path.expanduser('~/.config/brapy/ujs_files'))
+
+ for file in self.files:
+ hlayout = QHBoxLayout()
+
+ isjs = re.match(r'.*\.js\.[0-3]', file)
+ if isjs:
+ name = re.sub(r'\.js\.[0-3]', '', file)
+ type = self.locale['userscript_manager']['jsfile']
+ else:
+ name = file.removesuffix('.css')
+ type = self.locale['userscript_manager']['cssfile']
+
+ namelabel = QLabel(name)
+ typelabel = QLabel(type)
+ deletebutton = QPushButton('')
+ deletebutton.clicked.connect(lambda: self.del_file(file))
+ deletebutton.setFont(QFont("Material Icons Outlined", 12))
+ deletebutton.setFixedSize(30, 26)
+ loadtypebox = QComboBox()
+ loadtypebox.addItems(self.locale['userscript_manager']['loadtypes'])
+ if not isjs:
+ loadtypebox.setCurrentIndex(1)
+ loadtypebox.setDisabled(True)
+ splittedname = [None, 1]
+ else:
+ splittedname = file.split('.js.', 1)
+ loadtypebox.setCurrentIndex(int(splittedname[1]))
+ loadtypebox.currentIndexChanged.connect(self.update_list)
+
+ hlayout.addWidget(namelabel)
+ hlayout.addStretch()
+ hlayout.addWidget(typelabel)
+ hlayout.addStretch()
+ hlayout.addWidget(loadtypebox)
+ hlayout.addWidget(deletebutton)
+
+ self.scroll_layout.addLayout(hlayout)
+ self.layouts[file] = {
+ "namelabel": namelabel,
+ "typelabel": typelabel,
+ "deletebutton": deletebutton,
+ "loadtypebox": loadtypebox,
+ "isjs": isjs,
+ "previndex": int(splittedname[1])
+ }
+ self.scroll_layout.addStretch()
+ self.update_list()
+
+ def update_list(self):
+ for filename in self.layouts:
+ layout = self.layouts[filename]
+
+ if layout['loadtypebox'].currentIndex() != layout['previndex']:
+ self.update_file(filename)
+ layout['previndex'] = layout['loadtypebox'].currentIndex()
+
+ if not os.path.exists(os.path.expanduser('~/.config/brapy/ujs_files/' + filename)):
+ if layout['deletebutton'].isEnabled():
+ layout['deletebutton'].setDisabled(True)
+ layout['loadtypebox'].setDisabled(True)
+ layout['typelabel'].setText(layout['typelabel'].text() + ' (' + self.locale['general']['deleted'] + ')')
+
+ def update_file(self, filename):
+ layout = self.layouts[filename]
+ index = layout['loadtypebox'].currentIndex()
+ home = os.path.expanduser('~/.config/brapy/ujs_files/')
+ filewithoutending = re.sub(r'[0-3]', '', filename)
+ self.renames.append({"from": home + filename, "to": home + filewithoutending + str(index)})
+
+ def closeEvent(self, event):
+ self.exit()
+ super().closeEvent(event)
+
+ def keyPressEvent(self, event: QKeyEvent):
+ if event.key() == Qt.Key_Escape:
+ self.exit()
+ else:
+ super().keyPressEvent(event)
+
+ def exit(self):
+ for rename in self.renames:
+ os.rename(rename['from'], rename['to'])
+ self.reject()
+
+ def del_file(self, filename):
+ os.remove(os.path.expanduser('~/.config/brapy/ujs_files/' + filename))
+ self.update_list()
+
class WebBrowser(QMainWindow):
def __init__(self, debugmode):
super().__init__()
@@ -906,13 +1082,14 @@ def __init__(self, debugmode):
# self.updateavailable = True
if self.is_version_greater(self.lastversion, APP_VERSION):
self.homeurl = f"file:///usr/local/share/brapy/homeupdate.html?old={APP_VERSION}&new={self.lastversion}"
+ ColorPrint(f"[UPDATER] An Update to {APP_NAME.lower()} {self.lastversion} is available.", "green")
self.updateavailable = True
else:
self.homeurl = "file:///usr/local/share/brapy/home.html"
self.updateavailable = False
if self.debugmode:
- print("[BROWSER] Fenstertitel und -Symbol wird gesetzen")
+ print("[BROWSER] Set Windowtitle and symbol")
self.setWindowTitle(APP_NAME)
self.setWindowIcon(QIcon('/usr/local/share/brapy/brapy_logo.png'))
@@ -920,7 +1097,7 @@ def __init__(self, debugmode):
layout = QVBoxLayout()
if self.debugmode:
- print("[BROWSER] UI wird erstellt")
+ print("[BROWSER] UI created")
# Tableiste erstellen
self.tab_widget = QTabWidget()
@@ -934,11 +1111,6 @@ def __init__(self, debugmode):
self.new_tab_button.setFixedSize(30, 30) # Größe des Knopfs anpassen
self.new_tab_button.clicked.connect(lambda: self.add_new_tab(self.homeurl, "Neuer Tab"))
- self.mute_tab_button = QPushButton("")
- self.mute_tab_button.setFont(QFont('Material Icons', 12))
- self.mute_tab_button.setFixedSize(30, 30) # Größe des Knopfs anpassen
- self.mute_tab_button.clicked.connect(self.toggle_mute_tab)
-
self.download_button = QPushButton("")
self.download_button.setFont(QFont('Material Icons', 12))
self.download_button.setFixedSize(30, 30) # Größe des Knopfs anpassen
@@ -950,11 +1122,9 @@ def __init__(self, debugmode):
self.settings_button.clicked.connect(lambda: self.add_custom_tab("brapy:settings"))
corner_layout = QHBoxLayout()
- corner_layout.addWidget(self.mute_tab_button)
corner_layout.addWidget(self.new_tab_button)
corner_layout.addWidget(self.download_button)
corner_layout.addWidget(self.settings_button)
- corner_layout.addWidget
corner_widget = QWidget()
corner_widget.setLayout(corner_layout)
@@ -964,7 +1134,6 @@ def __init__(self, debugmode):
self.tab_widget.setCornerWidget(corner_widget)
self.load_tabs()
- self.upmutebutton()
# Hauptwidget erstellen und dem Hauptfenster zuweisen
self.main_widget = QWidget()
self.main_widget.setLayout(layout)
@@ -980,18 +1149,6 @@ def __init__(self, debugmode):
close_action.triggered.connect(self.quitq)
self.addAction(close_action)
- fullscreen_action = QAction("Toggle Fullscreen", self)
- fullscreen_action.setShortcut(QKeySequence(Qt.Key_F11))
- fullscreen_action.triggered.connect(self.toggle_fullscreen)
- self.addAction(fullscreen_action)
-
- location_action = QAction("Location", self)
- location_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_L))
- location_action.triggered.connect(lambda: self.new_tab_address_bar.setFocus())
- self.addAction(location_action)
-
- self.tab_widget.currentChanged.connect(self.upmutebutton)
-
def expand_lang(self, lang):
if lang == 'DE':
return 'DE - Deutsch'
@@ -1014,13 +1171,44 @@ def replace_interceptor(self):
print("[CONFIG_RELAOD] Specialtab " + str(index) + " was skipped")
def update_config(self):
+ def create_section(sectionname):
+ if not config.has_section(sectionname):
+ if self.debugmode:
+ print(f"[CONFIG] Section {sectionname} does not exist. Create {sectionname}")
+ config.add_section(sectionname)
+
+ def create_option(section, option, defaultvalue):
+ if not config.has_option(section, option):
+ if self.debugmode:
+ print(f"[CONFIG] Option {option} does not exist. Create {option}")
+ if defaultvalue == None:
+ config.set(section, option, '')
+ else:
+ config.set(section, option, str(defaultvalue))
+ return defaultvalue
+
+ def get_truefalseoption(section, option, defaultvalue):
+ if config.get(section, option) == "True":
+ return True
+ elif config.get(section, option) == "False":
+ return False
+ else:
+ if self.debugmode:
+ ColorPrint(f"[CONFIG] Option {option} contains an error. Resetting...", "red")
+ config.set(section, option, str(defaultvalue))
+ return defaultvalue
+
if self.debugmode:
print("[CONFIG] Load Configuration")
if not os.path.exists(os.path.expanduser('~/.config/brapy')):
if self.debugmode:
- print("[CONFIG] Configurationfolder does not exist. Make Configurationfolder")
+ print("[CONFIG] Configurationfolder does not exist. Create Configurationfolder")
os.makedirs(os.path.expanduser('~/.config/brapy'), exist_ok=True)
+ if not os.path.exists(os.path.expanduser('~/.config/brapy/ujs_files')):
+ if self.debugmode:
+ print("[CONFIG] Configurationfolder for Userscript Manager does not exist. Create Configurationfolder for Userscript Manager")
+ os.makedirs(os.path.expanduser('~/.config/brapy/ujs_files'), exist_ok=True)
config.read(os.path.expanduser('~/.config/brapy/brapy.ini'))
if not os.path.exists(os.path.expanduser('~/.config/brapy/brapy.ini')):
@@ -1033,6 +1221,7 @@ def update_config(self):
config.add_section('Window')
config.set('Window', 'confirm_close_with_ctrl+q', 'True')
config.set('Window', 'language', 'EN')
+ config.set('Window', 'show_searchbar', 'False')
config.add_section('Features')
config.set('Features', 'enable_adblocker', 'True')
config.set('Features', 'adblocker_whitelist', "['canyoublockit.com']")
@@ -1043,150 +1232,34 @@ def update_config(self):
with open(os.path.expanduser('~/.config/brapy/brapy.ini'), 'w') as f:
config.write(f)
- if not config.has_section('Security'):
- if self.debugmode:
- print("[CONFIG] Section Security does not exist. Create Security")
- config.add_section('Security')
-
- if not config.has_section('Window'):
- if self.debugmode:
- print("[CONFIG] Section Window does not exist. Create Window")
- config.add_section('Window')
-
- if not config.has_section('Features'):
- if self.debugmode:
- print("[CONFIG] Section Features does not exist. Create Features")
- config.add_section('Features')
-
- if not config.has_option('Security', 'allow_usernames_in_url'):
- if self.debugmode:
- print("[CONFIG] Option allow_username_in_url does not exist. Create allow_username_in_url")
- config.set('Security', 'allow_usernames_in_url', 'False')
- self.config_allowusernamesinurl = False
-
- if not config.has_option('Security', 'do_not_track_enabled'):
- if self.debugmode:
- print("[CONFIG] Option do_not_track_enabled does not exist. Create do_not_track_enabled")
- config.set('Security', 'do_not_track_enabled', 'True')
- self.config_dnt = True
-
- if not config.has_option('Security', 'enable_google_safe_browsing'):
- if self.debugmode:
- print("[CONFIG] Option enable_google_safe_browsing does not exist. Create enable_google_safe_browsing")
- config.set('Security', 'enable_google_safe_browsing', 'True')
- self.config_safebrowse = True
-
- if not config.has_option('Window', 'confirm_close_with_ctrl+q'):
- if self.debugmode:
- print("[CONFIG] Option confirm_close_with_ctrl+q does not exist. Create confirm_close_with_ctrl+q")
- config.set('Window', 'confirm_close_with_ctrl+q', 'True')
- self.config_confirmclosewithctrlq = True
-
- if not config.has_option('Window', 'language'):
- if self.debugmode:
- print("[CONFIG] Option confirm_close_with_ctrl+q does not exist. Create confirm_close_with_ctrl+q")
- config.set('Window', 'language', 'EN')
- self.language = 'EN'
-
- if not config.has_option('Features', 'enable_adblocker'):
- if self.debugmode:
- print("[CONFIG] Option enable_adblocker does not exist. Create enable_adblocker")
- config.set('Features', 'enable_adblocker', 'True')
- self.config_enableadblocker = True
-
- if not config.has_option('Features', 'adblocker_whitelist'):
- if self.debugmode:
- print("[CONFIG] Option adblocker_whitelist does not exist. Create adblocker_whitelist")
- config.set('Features', 'adblocker_whitelist', "['canyoublockit.com']")
- self.config_adblockwhitelist = ['canyoublockit.com']
-
- if not config.has_option('Features', 'adblocker_blacklist'):
- if self.debugmode:
- print("[CONFIG] Option adblocker_blacklist does not exist. Create adblocker_blacklist")
- config.set('Features', 'adblocker_blacklist', "[]")
- self.config_adblockblacklist = []
-
- if not config.has_option('Features', 'redirect_youtube_to_invidious'):
- if self.debugmode:
- print("[CONFIG] Option redirect_youtube_to_invidious does not exist. Create redirect_youtube_to_invidious")
- config.set('Features', 'redirect_youtube_to_invidious', "False")
- self.config_rediyoutube = False
-
- if not config.has_option('Features', 'override_country'):
- if self.debugmode:
- print("[CONFIG] Option override_country does not exist. Create override_country")
- config.set('Features', 'override_country', "")
- self.config_countryoverride = None
-
- if not config.has_option('Features', 'rewrite_to_https'):
- if self.debugmode:
- print("[CONFIG] Option rewrite_to_https does not exist. Create rewrite_to_https")
- config.set('Features', 'rewrite_to_https', "False")
- self.config_httpsrewrite = False
-
- if config.get('Security', 'allow_usernames_in_url') == "True":
- self.config_allowusernamesinurl = True
- elif config.get('Security', 'allow_usernames_in_url') == "False":
- self.config_allowusernamesinurl = False
- else:
- if self.debugmode:
- ColorPrint("[CONFIG] Option allow_usernames_in_url contains an error. Resetting...", "red")
- config.set('Security', 'allow_usernames_in_url', 'False')
- self.config_allowusernamesinurl = False
-
- if config.get('Security', 'do_not_track_enabled') == "True":
- self.config_dnt = True
- elif config.get('Security', 'do_not_track_enabled') == "False":
- self.config_dnt = False
- else:
- if self.debugmode:
- ColorPrint("[CONFIG] Option do_not_track_enabled contains an error. Resetting...", "red")
- config.set('Security', 'do_not_track_enabled', 'True')
- self.config_dnt = True
-
- if config.get('Security', 'enable_google_safe_browsing') == "True":
- self.config_safebrowse = True
- elif config.get('Security', 'enable_google_safe_browsing') == "False":
- self.config_safebrowse = False
- else:
- if self.debugmode:
- ColorPrint("[CONFIG] Option enable_google_safe_browsing contains an error. Resetting...", "red")
- config.set('Security', 'enable_google_safe_browsing', 'True')
- self.config_safebrowse = True
-
- if config.get('Window', 'confirm_close_with_ctrl+q') == "True":
- self.config_confirmclosewithctrlq = True
- elif config.get('Window', 'confirm_close_with_ctrl+q') == "False":
- self.config_confirmclosewithctrlq = False
- else:
- if self.debugmode:
- ColorPrint("[CONFIG] Option confirm_close_with_ctrl+q contains an error. Resetting...", "red")
- config.set('Window', 'confirm_close_with_ctrl+q', 'True')
- self.config_confirmclosewithctrlq = True
-
+ create_section('Security')
+ create_section('Window')
+ create_section('Features')
+
+ self.config_allowusernamesinurl = create_option('Security', 'allow_usernames_in_url', False)
+ self.config_dnt = create_option('Security', 'do_not_track_enabled', True)
+ self.config_safebrowse = create_option('Security', 'enable_google_safe_browsing', True)
+ self.config_confirmclosewithctrlq = create_option('Window', 'confirm_close_with_ctrl+q', True)
+ self.language = create_option('Window', 'language', 'EN')
+ self.config_showsearchbar = create_option('Window', 'show_searchbar', False)
+ self.config_enableadblocker = create_option('Features', 'enable_adblocker', True)
+ self.config_adblockwhitelist = create_option('Features', 'adblocker_whitelist', ['canyoublockit.com'])
+ self.config_adblockblacklist = create_option('Features', 'adblocker_blacklist', [])
+ self.config_rediyoutube = create_option('Features', 'redirect_youtube_to_invidious', False)
+ self.config_countryoverride = create_option('Features', 'override_country', None)
+ self.config_httpsrewrite = create_option('Features', 'rewrite_to_https', False)
+ self.config_ujsenabled = create_option('Features', 'enable_userscript_manager', False)
+
+ self.config_allowusernamesinurl = get_truefalseoption('Security', 'allow_usernames_in_url', False)
+ self.config_dnt = get_truefalseoption('Security', 'do_not_track_enabled', True)
+ self.config_safebrowse = get_truefalseoption('Security', 'enable_google_safe_browsing', True)
+ self.config_confirmclosewithctrlq = get_truefalseoption('Window', 'confirm_close_with_ctrl+q', True)
+ self.config_showsearchbar = get_truefalseoption('Window', 'show_searchbar', False)
self.language = config.get('Window', 'language')
-
- if config.get('Features', 'enable_adblocker') == "True":
- self.config_enableadblocker = True
- elif config.get('Features', 'enable_adblocker') == "False":
- self.config_enableadblocker = False
- else:
- if self.debugmode:
- ColorPrint("[CONFIG] Option enable_adblocker contains an error. Resetting...", "red")
- config.set('Features', 'enable_adblocker', 'True')
- self.config_enableadblocker = True
-
- if config.get('Features', 'redirect_youtube_to_invidious') == "True":
- self.config_rediyoutube = True
- elif config.get('Features', 'redirect_youtube_to_invidious') == "False":
- self.config_rediyoutube = False
- else:
- if self.debugmode:
- ColorPrint("[CONFIG] Option redirect_youtube_to_invidious contains an error. Resetting...", "red")
- config.set('Features', 'redirect_youtube_to_invidious', 'False')
- self.config_rediyoutube = False
-
+ self.config_enableadblocker = get_truefalseoption('Features', 'enable_adblocker', True)
+ self.config_rediyoutube = get_truefalseoption('Features', 'redirect_youtube_to_invidious', False)
self.config_countryoverride = config.get('Features', 'override_country')
+ self.config_ujsenabled = get_truefalseoption('Features', 'enable_userscript_manager', False)
try:
self.config_adblockwhitelist = ast.literal_eval(config.get('Features', 'adblocker_whitelist'))
@@ -1258,8 +1331,8 @@ def update_config(self):
self.invidious_url = "https://invidious.no-logs.com/"
case "SG":
self.invidious_url = "https://vid.priv.au/"
- case "ES":
- self.invidious_url = "https://inv.makerlab.tech/" # No popular list
+ # case "ES":
+ # self.invidious_url = "https://inv.makerlab.tech/" Doesn't exists anymore
case "IN":
self.invidious_url = "https://inv.in.projectsegfau.lt/"
case "NL":
@@ -1402,7 +1475,8 @@ def load_tabs(self):
title = tab_data["title"]
self.add_new_tab(url, title)
else:
- ColorPrint("[BROWSER] Failed to load Tabs: " + "KeyError: " + str(e), "red")
+ if self.debugmode:
+ ColorPrint("[BROWSER] Failed to load Tabs: " + "KeyError: " + str(e), "red")
dialog = OkDialog(self.locale_file['general']['okay'], self.locale_file['tabs_loading']['error_while'], self.locale_file['tabs_loading']['couldnt_restore'], "KeyError: " + str(e))
dialog.exec_()
else:
@@ -1412,12 +1486,6 @@ def load_tabs(self):
else:
self.add_new_tab(self.homeurl, "Neuer Tab")
- def toggle_fullscreen(self):
- if self.isFullScreen():
- self.showNormal()
- else:
- self.showFullScreen()
-
def save_tabs(self):
tabs_data = []
for i in range(self.tab_widget.count()):
@@ -1437,34 +1505,6 @@ def save_tabs(self):
with open(tabs_file_path, "w") as tabs_file:
json.dump(tabs_data, tabs_file)
- def upmutebutton(self):
- if not self.tab_widget.count() == 0:
- current_tab_index = self.tab_widget.currentIndex()
- tab_widget = self.tab_widget.widget(current_tab_index)
- if not tab_widget.new_tab_specialtab:
- web_view = tab_widget.findChild(QWebEngineView)
- is_muted = web_view.page().isAudioMuted()
- title = web_view.page().title()
- self.setWindowTitle(title + " - " + APP_NAME)
- self.mute_tab_button.setDisabled(False)
- if is_muted:
- self.mute_tab_button.setText("")
- self.tab_widget.setTabText(current_tab_index, f" {title}")
- else:
- self.mute_tab_button.setText("")
- self.tab_widget.setTabText(current_tab_index, title)
- else:
- self.mute_tab_button.setDisabled(True)
- self.mute_tab_button.setText("")
-
- def toggle_mute_tab(self):
- current_tab_index = self.tab_widget.currentIndex()
- tab_widget = self.tab_widget.widget(current_tab_index)
- web_view = tab_widget.findChild(QWebEngineView)
- if not tab_widget.new_tab_specialtab:
- is_muted = web_view.page().isAudioMuted()
- web_view.page().setAudioMuted(not is_muted)
-
def closeEvent(self, event):
if self.debugmode:
print("[CLOSE_EVENT] Checking for unfinished downloads...")
@@ -1506,7 +1546,7 @@ def quit(self):
def quitq(self):
if self.config_confirmclosewithctrlq:
- dialog = YesNoDialog("yesno", self.locale_file, self.locale_file['ctrlq_close']['confirm_close'], self.locale_file['ctrlq_close']['really_quit'])
+ dialog = YesNoDialog(self.locale_file, "yesno", self.locale_file['ctrlq_close']['confirm_close'], self.locale_file['ctrlq_close']['really_quit'])
if dialog.exec_() == QDialog.Accepted:
self.quit()
else:
@@ -1552,8 +1592,10 @@ def check_file_existence(url_string):
else:
return f"file:///usr/local/share/brapy/errorfile.html?file={path}"
- def load_url():
- url = self.new_tab_address_bar.text()
+ def load_url(url=None):
+ if url == None:
+ url = new_tab_address_bar.text()
+ url_filter = re.compile(r'^(https?://)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|([\w\.-]+\.[a-z]{2,6})|localhost)(:\d+)?(/[\w@.-]*)*/?(\?.*)?$', re.IGNORECASE)
if url.startswith("file://"):
if '?' in url:
url = url.rsplit('?', 1)
@@ -1572,34 +1614,16 @@ def load_url():
return
else:
new_tab_webview.load(QUrl(f'file:///usr/local/share/brapy/extraerror.html?eurl={url}&code=b02'))
+ elif url.startswith("www."):
+ new_tab_webview.load(QUrl(check_url_existence(f"https://{url}")))
+ elif url.startswith(self.locale_file['address_bar']['view-source']):
+ new_tab_webview.load(QUrl("view-source:" + url.removeprefix(self.locale_file['address_bar']['view-source'])))
+ elif re.match(url_filter, url):
+ if not url.startswith('https://') and not url.startswith('http://'):
+ url = "https://" + url
+ new_tab_webview.load(QUrl(check_url_existence(url)))
else:
- if url.startswith("www."):
- url = f"https://{url}"
- elif not url.startswith("https://" or "http://"):
- url = f"https://{url}"
- qeurl = check_url_existence(url)
- new_tab_webview.load(QUrl(qeurl))
-
-
- def load_curl(url):
- if url.startswith("file://"):
- if '?' in url:
- url = url.rsplit('?', 1)
- qeurl = check_file_existence(url[0])
- if not qeurl.startswith("file:///usr/local/share/brapy/errorfile.html"):
- qeurl = qeurl + "?" + url[1]
- else:
- qeurl = check_file_existence(url)
- new_tab_webview.load(QUrl(qeurl))
- elif url.startswith("view-source:"):
- new_tab_webview.load(QUrl(url))
- else:
- if url.startswith("www."):
- url = f"https://{url}"
- elif not url.startswith("https://" or "http://"):
- url = f"https://{url}"
- qeurl = check_url_existence(url)
- new_tab_webview.load(QUrl(qeurl))
+ new_tab_webview.load(QUrl(check_url_existence(f"https://duckduckgo.com/?q={url}")))
def gohome():
new_tab_webview.load(QUrl(self.homeurl))
@@ -1607,17 +1631,14 @@ def gohome():
def search():
search_query = new_tab_search_bar.text()
url = f"https://duckduckgo.com/?q={search_query}"
- load_curl(url)
+ load_url(url)
def update_tab_title():
title = new_tab_webview.page().title()
if title.startswith("view-source:"):
- title = f"{self.locale_file['adress_bar']['view-source']}{title.split(':', 1)[1].split('?', 1)[0]}"
+ title = f"{self.locale_file['address_bar']['view-source']}{title.split(':', 1)[1].split('?', 1)[0]}"
index = self.tab_widget.currentIndex()
- if new_tab_webview.page().isAudioMuted():
- self.tab_widget.setTabText(index, " " + title)
- else:
- self.tab_widget.setTabText(index, title)
+ self.tab_widget.setTabText(index, title)
self.setWindowTitle(title + " - " + APP_NAME)
def update_tab_icon():
@@ -1630,9 +1651,9 @@ def update_address_bar(url):
url_text = url.toString()
orig_url = url_text
if url_text.startswith("file:///usr/local/share/brapy/error.html" or "file:///usr/local/share/brapy/extraerror.html"):
- url_text = self.locale_file['adress_bar']['error_url']
+ url_text = self.locale_file['address_bar']['error_url']
elif url_text.startswith("file:///usr/local/share/brapy/errorfile.html"):
- url_text = self.locale_file['adress_bar']['error_file']
+ url_text = self.locale_file['address_bar']['error_file']
elif url_text.startswith("file:///usr/local/share/brapy/upgrade.html"):
url_text = self.locale_file['upgrade']['done']
elif url_text == "file:///usr/local/share/brapy/home.html" or url_text.startswith("file:///usr/local/share/brapy/homeupdate.html"):
@@ -1641,15 +1662,49 @@ def update_address_bar(url):
url_text = check_file_existence(url_text)
if url_text.startswith("file:///usr/local/share/brapy/errorfile.html"):
new_tab_webview.load(QUrl(url_text))
- elif url_text.startswith("https://" or "http://"):
+ elif url_text.startswith("https://"):
+ url_text = check_url_existence(url_text)
+ if url_text.startswith("file:///usr/local/share/brapy/error.html" or "file:///usr/local/share/brapy/extraerror.html"):
+ new_tab_webview.load(QUrl(url_text))
+ elif url_text.startswith("http://"):
url_text = check_url_existence(url_text)
if url_text.startswith("file:///usr/local/share/brapy/error.html" or "file:///usr/local/share/brapy/extraerror.html"):
new_tab_webview.load(QUrl(url_text))
elif url_text.startswith("view-source:"):
- url_text = f"{self.locale_file['adress_bar']['view-source']}{url_text.split(':', 1)[1].split('?', 1)[0]}"
- self.new_tab_address_bar.setText(url_text)
- self.new_tab_address_bar.setCursorPosition(0)
+ url_text = f"{self.locale_file['address_bar']['view-source']}{url_text.split(':', 1)[1].split('?', 1)[0]}"
+ new_tab_address_bar.setText(url_text)
+ new_tab_address_bar.setCursorPosition(0)
update_adblock_icon(orig_url)
+ update_certificate_symbol(orig_url)
+
+ def update_certificate_symbol(url=None):
+ if url == None:
+ new_tab_webview.page().url().toString()
+ hostname = urlparse(url).hostname
+ new_tab_certificate_text.setVisible(True)
+ if url.split('?', 1)[0] in BrowserFiles:
+ new_tab_certificate_symbol.setText('')
+ new_tab_certificate_text.setText(APP_NAME)
+ elif url.startswith('file://'):
+ new_tab_certificate_symbol.setText('')
+ new_tab_certificate_text.setText(self.locale_file['address_bar']['local_file'])
+ elif url.startswith('view-source:'):
+ new_tab_certificate_symbol.setText('')
+ new_tab_certificate_text.setText(self.locale_file['address_bar']['sourcecode'])
+ elif hostname == ('localhost' or '127.0.0.1'):
+ new_tab_certificate_symbol.setText('')
+ new_tab_certificate_text.setText(self.locale_file['address_bar']['local_page'])
+ elif url.startswith('http://'):
+ new_tab_certificate_symbol.setText('')
+ new_tab_certificate_text.setText(self.locale_file['address_bar']['not_safe'])
+ elif url.startswith('https://'):
+ try:
+ requests.head(url)
+ new_tab_certificate_symbol.setText('')
+ new_tab_certificate_text.setVisible(False)
+ except requests.exceptions.SSLError:
+ new_tab_certificate_symbol.setText('')
+ new_tab_certificate_text.setText('' + self.locale_file['address_bar']['cert_error'] + ' ')
def update_adblock_icon(url=None):
if url == None:
@@ -1668,7 +1723,6 @@ def update_adblock_icon(url=None):
def close_tab(index):
tab = self.tab_widget.widget(index)
web_view = tab.findChild(QWebEngineView)
- web_view.stop()
tab.deleteLater()
self.tab_widget.removeTab(index)
tabs_file_path = os.path.expanduser("~/.config/brapy/tabs.json")
@@ -1700,22 +1754,53 @@ def download_requested(download):
download.accept()
# download.stateChanged.connect(self.handle_updated_download_state)
self.downloads.append(download)
-
+
def show_adblockmenu():
current_url = new_tab_webview.page().url().toString()
dialog = AdblockMenu(self.config_enableadblocker, self.final_adlist, self.config_adblockwhitelist, current_url, self.config_adblockblacklist, self.locale_file)
if dialog.exec_() == QDialog.Accepted:
self.add_custom_tab("brapy:settings")
-
+
def FullscreenRequest(request):
request.accept()
- if request.toggleOn():
+ if request.toggleOn() and not new_tab_webview.isFullScreen():
new_tab_webview.setParent(None)
new_tab_webview.showFullScreen()
- else:
- self.setCentralWidget(self.main_widget)
+ elif new_tab_webview.isFullScreen():
+ new_tab_webview.showNormal()
new_tab_layout.addWidget(new_tab_webview)
+
+ def toggle_fullscreen():
+ if new_tab_webview.isFullScreen():
new_tab_webview.showNormal()
+ new_tab_layout.addWidget(new_tab_webview)
+ else:
+ new_tab_webview.setParent(None)
+ new_tab_webview.showFullScreen()
+
+ def toggle_mute():
+ is_muted = new_tab_webview.page().isAudioMuted()
+ new_tab_webview.page().setAudioMuted(not is_muted)
+
+ def update_mutebutton():
+ if new_tab_webview.page().isAudioMuted():
+ mute_button.setText("")
+ mute_button.setFixedSize(20, 20)
+ mute_button.setVisible(True)
+ elif new_tab_webview.page().recentlyAudible():
+ mute_button.setText("")
+ mute_button.setFixedSize(20, 20)
+ mute_button.setVisible(True)
+ else:
+ mute_button.setVisible(False)
+ mute_button.setFixedSize(20, 20)
+
+ def loaded(ok):
+ if ok:
+ for file in os.listdir(os.path.expanduser('~/.config/brapy/ujs_files')):
+ if not re.match(r'.*\.js\.[0-3]', file):
+ css = open(os.path.expanduser('~/.config/brapy/ujs_files/' + file), 'r').read()
+ new_tab_webview.page().runJavaScript(f"var style = document.createElement('style'); style.innerHTML = `{css}`; document.head.appendChild(style);")
# Widget für neue Registerkarte erstellen
new_tab_widget = QWidget()
@@ -1729,8 +1814,12 @@ def FullscreenRequest(request):
new_tab_widget.new_tab_specialtab = False
# Adressleiste zur neuen Registerkarte hinzufügen
- self.new_tab_address_bar = LineEdit()
- new_tab_search_bar = QLineEdit()
+ new_tab_certificate_symbol = QLabel()
+ new_tab_certificate_symbol.setFont(QFont('Material Icons Outlined', 12))
+ new_tab_certificate_text = QLabel()
+ new_tab_address_bar = LineEdit()
+ if self.config_showsearchbar:
+ new_tab_search_bar = QLineEdit()
new_tab_back_button = QPushButton("")
new_tab_back_button.setFont(QFont('Material Icons Outlined', 12))
new_tab_forward_button = QPushButton("")
@@ -1757,25 +1846,32 @@ def FullscreenRequest(request):
new_tab_reload_button.setFixedSize(30, 26)
new_tab_back_button.setFixedSize(30, 26)
new_tab_home_button.setFixedSize(30, 26)
+ # new_tab_certificate_symbol.setFixedSize(30, 26)
+ new_tab_certificate_text.setMinimumWidth(0)
new_tab_adblock_button.setFixedSize(30, 26)
- new_tab_search_bar.setMaximumWidth(300)
- new_tab_search_bar.setMinimumWidth(200)
+ if self.config_showsearchbar:
+ new_tab_search_bar.setMaximumWidth(300)
+ new_tab_search_bar.setMinimumWidth(200)
new_tab_upgrade_button.clicked.connect(self.upgrade)
new_tab_home_button.clicked.connect(gohome)
new_tab_back_button.clicked.connect(goback)
new_tab_reload_button.clicked.connect(reload)
new_tab_forward_button.clicked.connect(goforward)
- self.new_tab_address_bar.setPlaceholderText(self.locale_file['webview_tab']['adress_barp'])
- new_tab_search_bar.setPlaceholderText(self.locale_file['webview_tab']['search_barp'])
- self.new_tab_address_bar.returnPressed.connect(load_url)
- new_tab_search_bar.returnPressed.connect(search)
+ new_tab_address_bar.setPlaceholderText(self.locale_file['webview_tab']['address_barp'])
+ if self.config_showsearchbar:
+ new_tab_search_bar.setPlaceholderText(self.locale_file['webview_tab']['search_barp'])
+ new_tab_search_bar.returnPressed.connect(search)
+ new_tab_address_bar.returnPressed.connect(load_url)
new_tab_adblock_button.clicked.connect(show_adblockmenu)
new_tab_address_layout.addWidget(new_tab_back_button)
new_tab_address_layout.addWidget(new_tab_forward_button)
new_tab_address_layout.addWidget(new_tab_reload_button)
new_tab_address_layout.addWidget(new_tab_home_button)
- new_tab_address_layout.addWidget(self.new_tab_address_bar)
- new_tab_address_layout.addWidget(new_tab_search_bar)
+ new_tab_address_layout.addWidget(new_tab_certificate_symbol)
+ new_tab_address_layout.addWidget(new_tab_certificate_text)
+ new_tab_address_layout.addWidget(new_tab_address_bar)
+ if self.config_showsearchbar:
+ new_tab_address_layout.addWidget(new_tab_search_bar)
new_tab_address_layout.addWidget(new_tab_adblock_button)
if self.updateavailable:
new_tab_address_layout.addWidget(new_tab_upgrade_button)
@@ -1787,27 +1883,55 @@ def FullscreenRequest(request):
new_tab_webview = BrapyEngine(self.locale_file, self.homeurl)
new_tab_webview.page().profile().setUrlRequestInterceptor(self.webview_interceptor)
new_tab_webview.page().profile().setHttpUserAgent(f"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.15.14 Brapy/{APP_VERSION} Chrome/116.0.0.0 Safari/537.36")
+ new_tab_webview.loadFinished.connect(loaded)
new_tab_layout.addWidget(new_tab_webview)
new_tab_webview.setPage(brapypage)
+ new_tab_userscripts = {}
+ for file in os.listdir(os.path.expanduser('~/.config/brapy/ujs_files')):
+ if re.match(r'.*\.js\.[0-3]', file):
+ print("Inserted: " + file)
+ new_tab_userscripts[file] = QWebEngineScript()
+ loadtype = int(file.split('.js.', 1)[1])
+ if loadtype == 0:
+ print("While DocumentCreation")
+ new_tab_userscripts[file].setInjectionPoint(QWebEngineScript.DocumentCreation)
+ elif loadtype == 1:
+ new_tab_userscripts[file].setInjectionPoint(QWebEngineScript.DocumentReady)
+ else:
+ new_tab_userscripts[file].setInjectionPoint(QWebEngineScript.Deferred)
+ new_tab_userscripts[file].setRunsOnSubFrames(True)
+ new_tab_userscripts[file].setWorldId(QWebEngineScript.MainWorld)
+ new_tab_userscripts[file].setSourceCode(open(os.path.expanduser('~/.config/brapy/ujs_files/' + file), 'r').read())
+ new_tab_webview.page().profile().scripts().insert(new_tab_userscripts[file])
+
profile = QWebEngineProfile.defaultProfile()
profile.downloadRequested.connect(download_requested)
new_tab_webview.urlChanged.connect(update_address_bar)
new_tab_webview.titleChanged.connect(update_tab_title)
new_tab_webview.iconChanged.connect(update_tab_icon)
- new_tab_webview.page().audioMutedChanged.connect(self.upmutebutton)
new_tab_webview.page().fullScreenRequested.connect(FullscreenRequest)
- load_curl(url)
+ load_url(url)
self.tab_widget.setCurrentWidget(new_tab_widget)
-
+ tab_bar = self.tab_widget.tabBar()
+
# Schließen-Knopf zur Registerkarte hinzufügen
close_button = QPushButton("")
close_button.setFont(QFont('Material Icons Outlined', 12))
close_button.setFixedSize(20, 20) # Größe des Knopfs anpassen
close_button.clicked.connect(lambda: close_tab(self.tab_widget.indexOf(new_tab_widget)))
- tab_bar = self.tab_widget.tabBar()
tab_bar.setTabButton(self.tab_widget.indexOf(new_tab_widget), QTabBar.RightSide, close_button)
+ mute_button = QPushButton("")
+ mute_button.setFont(QFont('Material Icons Outlined', 12))
+ mute_button.clicked.connect(toggle_mute)
+ mute_button.setFixedSize(20, 20)
+ tab_bar.setTabButton(self.tab_widget.indexOf(new_tab_widget), QTabBar.LeftSide, mute_button)
+ mute_button.setVisible(False)
+
+ new_tab_webview.page().audioMutedChanged.connect(update_mutebutton)
+ new_tab_webview.page().recentlyAudibleChanged.connect(update_mutebutton)
+
global_settings = QWebEngineSettings.globalSettings()
global_settings.setAttribute(QWebEngineSettings.JavascriptEnabled, True)
global_settings.setAttribute(QWebEngineSettings.JavascriptCanOpenWindows, True)
@@ -1846,9 +1970,19 @@ def FullscreenRequest(request):
gohome_action.setShortcut(QKeySequence(Qt.ALT + Qt.Key_Home))
gohome_action.triggered.connect(gohome)
new_tab_webview.addAction(gohome_action)
-
+
+ location_action = QAction("Location", self)
+ location_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_L))
+ location_action.triggered.connect(lambda: new_tab_address_bar.setFocus())
+ new_tab_webview.addAction(location_action)
+
+ fullscreen_action = QAction("Toggle Fullscreen", self)
+ fullscreen_action.setShortcut(QKeySequence(Qt.Key_F11))
+ fullscreen_action.triggered.connect(toggle_fullscreen)
+ new_tab_webview.addAction(fullscreen_action)
+
if url == "file:///usr/local/share/brapy/home.html" or url.startswith("file:///usr/local/share/brapy/homeupdate.html"):
- self.new_tab_address_bar.setFocus()
+ new_tab_address_bar.setFocus()
def add_custom_tab(self, tab_url):
def close_tab(index):
@@ -1873,6 +2007,8 @@ def load_config():
new_tab_sec_gsafeb.setChecked(self.config_safebrowse)
new_tab_adbl_enable.setChecked(self.config_enableadblocker)
new_tab_feat_ytinvidious.setChecked(self.config_rediyoutube)
+ new_tab_feat_showsearch.setChecked(self.config_showsearchbar)
+ new_tab_ujs_enabled.setChecked(self.config_ujsenabled)
new_tab_allg_language.setCurrentText(self.expand_lang(self.language))
new_tab_feat_overridec.setText(self.config_countryoverride)
@@ -1893,6 +2029,9 @@ def load_config():
new_tab_feat_overridec.setDisabled(not self.config_rediyoutube)
new_tab_featurelabel1.setDisabled(not self.config_rediyoutube)
+ new_tab_ujs_addfile.setDisabled(not self.config_ujsenabled)
+ new_tab_ujs_manage.setDisabled(not self.config_ujsenabled)
+
def parse_input(text: str):
return list(filter(None, text.splitlines()))
@@ -1904,10 +2043,12 @@ def update_apply_button():
new_tab_sec_https.isChecked() == self.config_httpsrewrite and
new_tab_adbl_enable.isChecked() == self.config_enableadblocker and
new_tab_feat_ytinvidious.isChecked() == self.config_rediyoutube and
+ new_tab_feat_showsearch.isChecked() == self.config_showsearchbar and
parse_input(new_tab_adbl_whitelist.toPlainText()) == self.config_adblockwhitelist and
parse_input(new_tab_adbl_blacklist.toPlainText()) == self.config_adblockblacklist and
new_tab_feat_overridec.text() == self.config_countryoverride and
- new_tab_allg_language.currentText().split(' - ')[0] == self.language):
+ new_tab_allg_language.currentText().split(' - ')[0] == self.language and
+ new_tab_ujs_enabled.isChecked() == self.config_ujsenabled):
new_tab_settings_apply_button.setDisabled(True)
else:
new_tab_settings_apply_button.setDisabled(False)
@@ -1920,7 +2061,8 @@ def update_apply_button():
new_tab_featurelabel1.setDisabled(not new_tab_feat_ytinvidious.isChecked())
def apply_settings():
- if not new_tab_allg_language.currentText().split(' - ')[0] == self.language:
+ if not new_tab_allg_language.currentText().split(' - ')[0] == self.language or not new_tab_feat_showsearch.isChecked() == self.config_showsearchbar\
+ or not new_tab_ujs_enabled.isChecked() == self.config_ujsenabled:
dialog = OkDialog('Okay', 'Restart required', 'A restart is required to apply the settings.')
dialog.exec_()
config.read(os.path.expanduser('~/.config/brapy/brapy.ini'))
@@ -1929,18 +2071,49 @@ def apply_settings():
config.set('Security', 'enable_google_safe_browsing', str(new_tab_sec_gsafeb.isChecked()))
config.set('Window', 'confirm_close_with_ctrl+q', str(new_tab_allg_confirmq.isChecked()))
config.set('Window', 'language', new_tab_allg_language.currentText().split(' - ')[0])
+ config.set('Window', 'show_searchbar', str(new_tab_feat_showsearch.isChecked()))
config.set('Features', 'enable_adblocker', str(new_tab_adbl_enable.isChecked()))
config.set('Features', 'adblocker_whitelist', str(parse_input(new_tab_adbl_whitelist.toPlainText())))
config.set('Features', 'adblocker_blacklist', str(parse_input(new_tab_adbl_blacklist.toPlainText())))
config.set('Features', 'rewrite_to_https', str(new_tab_sec_https.isChecked()))
config.set('Features', 'redirect_youtube_to_invidious', str(new_tab_feat_ytinvidious.isChecked()))
config.set('Features', 'override_country', new_tab_feat_overridec.text())
+ config.set('Features', 'enable_userscript_manager', str(new_tab_ujs_enabled.isChecked()))
with open(os.path.expanduser('~/.config/brapy/brapy.ini'), 'w') as f:
config.write(f)
self.update_config()
load_config()
update_apply_button()
+ def ujs_addfile():
+ file_path, _ = QFileDialog.getOpenFileName(self, self.locale_file['custom_tab']['brapy:settings']['ujs_addfile'], os.path.expanduser('~'), self.locale_file['custom_tab']['brapy:settings']['ujs_filetypes'])
+ if _ == '':
+ return
+ file_name = QUrl(file_path).fileName()
+ if file_name.endswith('.js'):
+ file_name = file_name.removesuffix('.js')
+ isjs = True
+ else:
+ file_name = file_name.removesuffix('.css')
+ isjs = False
+ dialog = UJS_AddFileDialog(file_name, isjs, self.locale_file)
+ if dialog.exec_() == QDialog.Accepted:
+ if isjs:
+ file_name = dialog.filenamebar.text() + '.js'
+ load_type = str(dialog.loadtype.currentIndex())
+ copyfile(file_path, os.path.expanduser('~/.config/brapy/ujs_files/') + file_name + '.' + load_type)
+ if self.debugmode:
+ print("[USERSCRIPTS] Script " + file_name + '.' + load_type + " saved.")
+ else:
+ file_name = dialog.filenamebar.text() + '.css'
+ copyfile(file_path, os.path.expanduser('~/.config/brapy/ujs_files/') + file_name)
+ if self.debugmode:
+ print(f"[USERSCRIPT] Theme {file_name} saved.")
+
+ def ujs_manage():
+ dialog = UJS_Manage(self.locale_file)
+ dialog.exec_()
+
new_tab_widget.new_tab_specialtab_name = self.locale_file['custom_tab']['brapy:settings']['name']
new_tab_widget.new_tab_specialtab_icon = None
new_tab_layout = QVBoxLayout()
@@ -1970,6 +2143,8 @@ def apply_settings():
new_tab_title3.setFont(QFont(new_tab_title3.font().family(), 18))
new_tab_title4 = QLabel(self.locale_file['custom_tab']['brapy:settings']['title4'])
new_tab_title4.setFont(QFont(new_tab_title4.font().family(), 18))
+ new_tab_title5 = QLabel(self.locale_file['custom_tab']['brapy:settings']['title5'])
+ new_tab_title5.setFont(QFont(new_tab_title5.font().family(), 18))
new_tab_allglabel1 = QLabel('Language: (Requires Restart)')
@@ -1988,6 +2163,10 @@ def apply_settings():
new_tab_sec_gsafeb = QCheckBox(self.locale_file['custom_tab']['brapy:settings']['safebrowsing'])
new_tab_adbl_enable = QCheckBox(self.locale_file['custom_tab']['brapy:settings']['enadblock'])
new_tab_feat_ytinvidious = QCheckBox(self.locale_file['custom_tab']['brapy:settings']['openyoutube'])
+ new_tab_feat_showsearch = QCheckBox(self.locale_file['custom_tab']['brapy:settings']['show_search'])
+ new_tab_ujs_enabled = QCheckBox(self.locale_file['custom_tab']['brapy:settings']['ujs_enabled'])
+ new_tab_ujs_addfile = QPushButton(self.locale_file['custom_tab']['brapy:settings']['ujs_addfile'])
+ new_tab_ujs_manage = QPushButton(self.locale_file['custom_tab']['brapy:settings']['ujs_managefiles'])
new_tab_adbl_whitelist = QTextEdit()
new_tab_adbl_blacklist = QTextEdit()
@@ -2024,6 +2203,11 @@ def apply_settings():
new_tab_settingsv.addWidget(new_tab_feat_ytinvidious)
new_tab_settingsv.addWidget(new_tab_featurelabel1)
new_tab_settingsv.addWidget(new_tab_feat_overridec)
+ new_tab_settingsv.addWidget(new_tab_feat_showsearch)
+ new_tab_settingsv.addWidget(new_tab_title5)
+ new_tab_settingsv.addWidget(new_tab_ujs_enabled)
+ new_tab_settingsv.addWidget(new_tab_ujs_addfile)
+ new_tab_settingsv.addWidget(new_tab_ujs_manage)
new_tab_scroll_hlayout.addStretch()
new_tab_scroll_hlayout.addLayout(new_tab_settingsv)
@@ -2057,6 +2241,11 @@ def apply_settings():
new_tab_adbl_blacklist.textChanged.connect(update_apply_button)
new_tab_feat_ytinvidious.toggled.connect(update_apply_button)
new_tab_feat_overridec.textChanged.connect(update_apply_button)
+ new_tab_feat_showsearch.toggled.connect(update_apply_button)
+ new_tab_ujs_enabled.toggled.connect(update_apply_button)
+
+ new_tab_ujs_addfile.clicked.connect(ujs_addfile)
+ new_tab_ujs_manage.clicked.connect(ujs_manage)
new_tab_settings_apply_button.clicked.connect(apply_settings)
@@ -2083,13 +2272,13 @@ def show_console_help_option():
else:
print("Version: " + APP_NAME.lower() + " " + APP_VERSION)
print("")
- print("Aufruf: " + APP_NAME.lower() + " [OPTIONEN]")
+ print("Usage: " + sys.argv[0] + " [OPTIONS]")
print("")
print("Optionen:")
print(" -h, --help Show Help")
print(" -v, --version Show Application Version")
print(" -u --upgrade Update Application")
- print(" -d --debug Show Debuginformations in Console")
+ print(" -d --debug Start " + APP_NAME + " in Debug Mode")
print(" --download-adlist Update Adlist used by Adblocker")
print("")
@@ -2134,6 +2323,8 @@ def read_commandline_args(argv):
show_console_help_option()
sys.exit(2)
+ returns = {'debugmode': False}
+
for opt, arg in opts:
if opt in ("-h", "--help"):
show_console_help_option()
@@ -2169,9 +2360,9 @@ def read_commandline_args(argv):
copyfile("/usr/local/share/brapy/upgrade", "/tmp/brapy_upgrade.sh")
subprocess.run("chmod +x /tmp/brapy_upgrade.sh", shell=True)
if response == "1":
- process = subprocess.Popen("pkexec /tmp/brapy_upgrade.sh beta", shell=True)
+ process = subprocess.Popen("pkexec bash -c '/tmp/brapy_upgrade.sh beta'", shell=True)
elif response == "2":
- process = subprocess.Popen("pkexec /tmp/brapy_upgrade.sh main", shell=True)
+ process = subprocess.Popen("pkexec bash -c '/tmp/brapy_upgrade.sh main'", shell=True)
process.wait()
else:
print(f"The Upgrade can't continue, because {APP_NAME} was installed trough an Packagemanager.")
@@ -2181,27 +2372,24 @@ def read_commandline_args(argv):
sys.exit()
elif opt in ("-d", "--debug"):
ColorPrint("[Debug] " + APP_NAME + " is starting in debug mode...", "bold-white")
-
- browser = WebBrowser(True)
- print("[Debug] Fenster created")
- browser.show()
- print("[Debug] Fenster showed")
- return "debugged"
+ returns['debugmode'] = True
+ return returns
elif opt in "--download-adlist":
ColorPrint("Creating Adlist...", "yellow")
process = subprocess.Popen("/usr/local/share/brapy/genadlist.py", shell=True)
process.wait()
ColorPrint("Adlists were created!", "bold-green")
sys.exit()
+ return returns
def main(argv):
app = QApplication(sys.argv)
+ app.setDesktopFileName('brapy')
command = read_commandline_args(argv)
- if not command == "debugged":
- browser = WebBrowser(False)
- browser.show()
+ browser = WebBrowser(command['debugmode'])
+ browser.show()
return app.exec_()
if __name__ == "__main__":
- sys.exit(main(sys.argv[1:]))
\ No newline at end of file
+ sys.exit(main(sys.argv[1:]))