#### Jade Application Kit # * https://codesardine.github.io/Jade-Application-Kit # * Vitor Lopes Copyright (c) 2016 - 2020 # * https://vitorlopes.me import os import re import subprocess from pathlib import Path from PyQt5.QtWidgets import QApplication register = {} def create_desktop_entry(url, title, description, icon): entry_name = title.replace(" ", "-") filename = f"{entry_name}.desktop" user_entry_path = f"{str(Path.home())}/.local/share/applications" # system_entry_path = f"/usr/share/applications/{file}" template = f""" # Created with JAK url:https://github.com/codesardine/Jade-Application-Kit [Desktop Entry] Type=Application Version=1.0 Name={title} Comment={description} Path=/usr/bin Exec=jak-cli --url {url} --title {title} --icon {icon} --online true Icon={icon} Terminal=false Categories=Network; """.strip() with open(f"{user_entry_path}/{filename}", 'w+') as file: file.write(template) print(f"Desktop entry created in:{user_entry_path}/{filename}") update_database = "update-desktop-database" if os.path.isfile(f"/usr/bin/{update_database}"): proc = subprocess.run(f"{update_database} {user_entry_path}", shell=True, check=True) if proc.returncode == 0: print("Database updated.") else: print("desktop-file-utils:Not installed\nDatabase not updated.") def getScreenGeometry(): app = QApplication.instance() return app.desktop().screenGeometry() def bindings(): environment_var = "JAK_PREFERRED_BINDING" try: preferred_bindings = os.environ[environment_var] return preferred_bindings except KeyError: user_config_path = f"{str(Path.home())}/.config/jak.conf" if os.path.isfile(user_config_path): config_file = user_config_path else: system_config_path = "/etc/jak.conf" config_file = system_config_path try: import configparser config = configparser.ConfigParser() config.read(config_file) preferred_bindings = config["bindings"][environment_var] return preferred_bindings except Exception as error: print(error) def get_current_path(): return str(Path('.').absolute()) def check_url_rules(request_type: str, url_request: str, url_rules: tuple) -> bool: """ * Search logic for url rules, we can use regex or simple match the beginning of the domain. * :param request_type: WebWindowType * :return: function, checks against a list of urls """ SCHEME = "https://" if request_type == "Block": url_rules=url_rules elif request_type == "WebBrowserTab": try: url_rules = url_rules["WebBrowserTab"] except KeyError: url_rules = "" elif request_type == "WebBrowserWindow": try: url_rules = url_rules["WebBrowserWindow"] except KeyError: url_rules = "" for rule in url_rules: pattern = re.compile(f"{SCHEME}{rule}") if url_request.startswith(f"{SCHEME}{rule}"): print(f"{SCHEME}{rule}:Method:startswith") return True elif re.search(pattern, url_request): print(f"{SCHEME}{rule}:Method:regex") return True return False class Instance: """ #### :Imports: from JAK.Utils import Instance Add object instances in a dictionary, it can be used to point to references we don,t want to be garbage collected, for usage later """ @staticmethod def get_instances() -> dict: """ * :Usage: Instance.get_instances() """ return register @staticmethod def record(name: str, _type: object) -> None: """ * :Usage: Instance.record("name", object) * Should only be used once per instance """ register[name] = _type print(f"Registering ['{name}'] Instance") @staticmethod def retrieve(name: str) -> object or str: """ * :Usage: Instance.retrieve("name") """ try: return register[name] except KeyError: print(f"Instance: ['{name}'] Not Present, to add it use -> Instance.record(['{name}', object])") return "" @staticmethod def auto(name: str, _type: object) -> object: """ * :Usage: Instance.auto("name", object) * Automatically detects if an instance is active with that name and retrieves it. If not present, creates it creates a new one and retrieves it. * Should only be used once per instance """ try: return register[name] except KeyError: register[name] = _type finally: print(f"Registering and Retrieving ['{name}'] Instance") return register[name] class JavaScript: """ * Run javascript in the webview after load is complete Injects will be logged in the inspector * :Imports: from Jak.Utils import JavaScript * :Usage: JavaScript.log(msg) """ @staticmethod def log(message: str) -> None: """ * Outputs console.log() messages in the inspector * :param message: Log message """ JavaScript.send(f"console.log('JAK log:{message}');") @staticmethod def css(styles: str, _type) -> None: """ * Insert custom styles * :param styles: CSS -> a { color: red; } """ javascript = f""" var style = document.createElement('style'); style.type = 'text/css'; style.classList.add('{_type}-custom-style'); style.innerHTML = `{JavaScript._is_file_or_string(styles)}`; document.getElementsByTagName('head')[0].appendChild(style); """ view = Instance.retrieve("view") view.page().loadFinished.connect( lambda: view.page().runJavaScript(javascript) ) @staticmethod def alert(message: str) -> None: """ * Triggers an alert message * :param message: your popcorn is ready enjoy """ JavaScript.send(f"alert('{message}');") JavaScript.log(f"JAK Alert:[{message}]") @staticmethod def send(script: str) -> None: """ * Send custom JavaScript """ try: view = Instance.retrieve("view") view.page().runJavaScript(f"{JavaScript._is_file_or_string(script)}") except Exception as err: print(err) @staticmethod def inject(page, options: dict) -> None: if bindings() == "PyQt5": from PyQt5.QtWebEngineWidgets import QWebEngineScript else: from PySide2.QtWebEngineWidgets import QWebEngineScript script = QWebEngineScript() script.setName(options["name"]) script.setWorldId(QWebEngineScript.MainWorld) script.setInjectionPoint(QWebEngineScript.DocumentCreation) script.setRunsOnSubFrames(True) script.setSourceCode(options["JavaScript"]) print(f"Injecting JavaScript {options['name']}") page.profile().scripts().insert(script) @staticmethod def _is_file_or_string(script) -> str: """ * Detect if is file or string, convert to string * :param script: file or string """ if os.path.exists(script) and os.path.isfile(script): try: with open(script, "r") as file: string = file.read() return string except Exception as err: print(err) elif isinstance(script, str): return script