mirror of
				https://github.com/nixietab/picodulce.git
				synced 2025-11-03 23:10:59 +00:00 
			
		
		
		
	
		
			Some checks failed
		
		
	
	Version Change Action / version-release (push) Has been cancelled
				
			* Initial commit of the replace * Delete .github/workflows/Bleeding-Job.yaml * remove picomc * Update README.md * Update version.json
		
			
				
	
	
		
			232 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			232 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import os
 | 
						|
import json
 | 
						|
import shutil
 | 
						|
import modulecli
 | 
						|
from PyQt5.QtWidgets import QApplication, QDialog, QVBoxLayout, QLabel, QProgressBar
 | 
						|
from PyQt5.QtCore import Qt, QThread, pyqtSignal
 | 
						|
import sys
 | 
						|
 | 
						|
class CopyThread(QThread):
 | 
						|
    progress_changed = pyqtSignal(int)
 | 
						|
    finished = pyqtSignal()
 | 
						|
 | 
						|
    def __init__(self, src_dir, dst_dir):
 | 
						|
        super().__init__()
 | 
						|
        self.src_dir = src_dir
 | 
						|
        self.dst_dir = dst_dir
 | 
						|
 | 
						|
    def run(self):
 | 
						|
        # Gather all files recursively
 | 
						|
        files_to_copy = []
 | 
						|
        for root, dirs, files in os.walk(self.src_dir):
 | 
						|
            for f in files:
 | 
						|
                full_path = os.path.join(root, f)
 | 
						|
                relative_path = os.path.relpath(full_path, self.src_dir)
 | 
						|
                files_to_copy.append(relative_path)
 | 
						|
 | 
						|
        total_files = len(files_to_copy)
 | 
						|
        copied_files = 0
 | 
						|
 | 
						|
        for relative_path in files_to_copy:
 | 
						|
            src_path = os.path.join(self.src_dir, relative_path)
 | 
						|
            dst_path = os.path.join(self.dst_dir, relative_path)
 | 
						|
            dst_folder = os.path.dirname(dst_path)
 | 
						|
 | 
						|
            if not os.path.exists(dst_folder):
 | 
						|
                try:
 | 
						|
                    os.makedirs(dst_folder)
 | 
						|
                except PermissionError:
 | 
						|
                    print(f"Skipping folder {dst_folder} (permission denied)")
 | 
						|
                    continue
 | 
						|
 | 
						|
            try:
 | 
						|
                shutil.copy2(src_path, dst_path)
 | 
						|
            except PermissionError:
 | 
						|
                print(f"Skipping file {dst_path} (permission denied)")
 | 
						|
 | 
						|
            copied_files += 1
 | 
						|
            progress_percent = int((copied_files / total_files) * 100)
 | 
						|
            self.progress_changed.emit(progress_percent)
 | 
						|
 | 
						|
        self.finished.emit()
 | 
						|
 | 
						|
 | 
						|
class HealthCheck:
 | 
						|
    def __init__(self):
 | 
						|
        self.config = None
 | 
						|
 | 
						|
    def check_config_file(self):
 | 
						|
        config_path = "config.json"
 | 
						|
        default_config = {
 | 
						|
            "IsRCPenabled": False,
 | 
						|
            "CheckUpdate": False,
 | 
						|
            "IsBleeding": False,
 | 
						|
            "LastPlayed": "",
 | 
						|
            "TotalPlaytime": 0,
 | 
						|
            "IsFirstLaunch": True,
 | 
						|
            "Instance": "default",
 | 
						|
            "Theme": "Dark.json",
 | 
						|
            "ThemeBackground": True,
 | 
						|
            "ThemeRepository": "https://raw.githubusercontent.com/nixietab/picodulce-themes/main/repo.json",
 | 
						|
            "Locale": "en",
 | 
						|
            "ManageJava": False,
 | 
						|
            "MaxRAM": "2G",
 | 
						|
            "JavaPath": "",
 | 
						|
            "ZucaroCheck": False,
 | 
						|
        }
 | 
						|
 | 
						|
        if not os.path.exists(config_path):
 | 
						|
            with open(config_path, "w") as config_file:
 | 
						|
                json.dump(default_config, config_file, indent=4)
 | 
						|
            self.config = default_config
 | 
						|
            return
 | 
						|
 | 
						|
        try:
 | 
						|
            with open(config_path, "r") as config_file:
 | 
						|
                self.config = json.load(config_file)
 | 
						|
        except (json.JSONDecodeError, ValueError):
 | 
						|
            with open(config_path, "w") as config_file:
 | 
						|
                json.dump(default_config, config_file, indent=4)
 | 
						|
            self.config = default_config
 | 
						|
            return
 | 
						|
 | 
						|
        updated = False
 | 
						|
        for key, value in default_config.items():
 | 
						|
            if key not in self.config:
 | 
						|
                self.config[key] = value
 | 
						|
                updated = True
 | 
						|
 | 
						|
        if updated:
 | 
						|
            with open(config_path, "w") as config_file:
 | 
						|
                json.dump(self.config, config_file, indent=4)
 | 
						|
 | 
						|
    def get_folder_size(self, folder_path):
 | 
						|
        total_size = 0
 | 
						|
        for dirpath, dirnames, filenames in os.walk(folder_path):
 | 
						|
            for f in filenames:
 | 
						|
                fp = os.path.join(dirpath, f)
 | 
						|
                if os.path.isfile(fp):
 | 
						|
                    total_size += os.path.getsize(fp)
 | 
						|
        return total_size
 | 
						|
 | 
						|
    def zucaro_health_check(self):
 | 
						|
        if self.config.get("ZucaroCheck"):
 | 
						|
            return
 | 
						|
 | 
						|
        output = modulecli.run_command("instance dir").strip()
 | 
						|
        instance_dir = os.path.abspath(output)
 | 
						|
        base_dir = os.path.abspath(os.path.join(instance_dir, "..", ".."))
 | 
						|
 | 
						|
        possible_zucaro = [os.path.join(base_dir, "zucaro"), os.path.join(base_dir, ".zucaro")]
 | 
						|
        possible_picomc = [os.path.join(base_dir, "picomc"), os.path.join(base_dir, ".picomc")]
 | 
						|
 | 
						|
        zucaro_dir = next((d for d in possible_zucaro if os.path.exists(d)), None)
 | 
						|
        picomc_dir = next((d for d in possible_picomc if os.path.exists(d)), None)
 | 
						|
 | 
						|
        if picomc_dir is None or zucaro_dir is None:
 | 
						|
            print("Required directories not found. Skipping copy.")
 | 
						|
            # Mark the check as done so it wont run again
 | 
						|
            self.config["ZucaroCheck"] = True
 | 
						|
            with open("config.json", "w") as f:
 | 
						|
                json.dump(self.config, f, indent=4)
 | 
						|
            return
 | 
						|
 | 
						|
        picomc_size = self.get_folder_size(picomc_dir)
 | 
						|
        zucaro_size = self.get_folder_size(zucaro_dir)
 | 
						|
 | 
						|
        if picomc_size <= zucaro_size:
 | 
						|
            print("No action needed. Zucaro folder is not smaller than Picomc.")
 | 
						|
            # Update config so the check is considered done
 | 
						|
            self.config["ZucaroCheck"] = True
 | 
						|
            with open("config.json", "w") as f:
 | 
						|
                json.dump(self.config, f, indent=4)
 | 
						|
            return
 | 
						|
 | 
						|
        print(f"Copying Picomc ({picomc_size} bytes) to Zucaro ({zucaro_size} bytes)...")
 | 
						|
 | 
						|
        app = QApplication.instance() or QApplication(sys.argv)
 | 
						|
        dialog = QDialog()
 | 
						|
        dialog.setWindowTitle("Working...")
 | 
						|
        dialog.setWindowModality(Qt.ApplicationModal)
 | 
						|
        layout = QVBoxLayout()
 | 
						|
        label = QLabel("Working on stuff, please wait...")
 | 
						|
        progress = QProgressBar()
 | 
						|
        progress.setValue(0)
 | 
						|
        layout.addWidget(label)
 | 
						|
        layout.addWidget(progress)
 | 
						|
        dialog.setLayout(layout)
 | 
						|
 | 
						|
        # Setup copy thread
 | 
						|
        thread = CopyThread(picomc_dir, zucaro_dir)
 | 
						|
        thread.progress_changed.connect(progress.setValue)
 | 
						|
        thread.finished.connect(dialog.accept)
 | 
						|
        thread.start()
 | 
						|
 | 
						|
        dialog.exec_()  # Runs the modal event loop
 | 
						|
 | 
						|
        # Mark as done
 | 
						|
        self.config["ZucaroCheck"] = True
 | 
						|
        with open("config.json", "w") as f:
 | 
						|
            json.dump(self.config, f, indent=4)
 | 
						|
 | 
						|
        print("Copy completed.")
 | 
						|
 | 
						|
    def themes_integrity(self):
 | 
						|
        themes_folder = "themes"
 | 
						|
        dark_theme_file = os.path.join(themes_folder, "Dark.json")
 | 
						|
        native_theme_file = os.path.join(themes_folder, "Native.json")
 | 
						|
 | 
						|
        dark_theme_content = {
 | 
						|
            "manifest": {
 | 
						|
                "name": "Dark",
 | 
						|
                "description": "The default picodulce launcher theme",
 | 
						|
                "author": "Nixietab",
 | 
						|
                "license": "MIT"
 | 
						|
            },
 | 
						|
            "palette": {
 | 
						|
                "Window": "#353535",
 | 
						|
                "WindowText": "#ffffff",
 | 
						|
                "Base": "#191919",
 | 
						|
                "AlternateBase": "#353535",
 | 
						|
                "ToolTipBase": "#ffffff",
 | 
						|
                "ToolTipText": "#ffffff",
 | 
						|
                "Text": "#ffffff",
 | 
						|
                "Button": "#353535",
 | 
						|
                "ButtonText": "#ffffff",
 | 
						|
                "BrightText": "#ff0000",
 | 
						|
                "Link": "#2a82da",
 | 
						|
                "Highlight": "#4bb679",
 | 
						|
                "HighlightedText": "#ffffff"
 | 
						|
            },
 | 
						|
            "background_image_base64": ""
 | 
						|
        }
 | 
						|
 | 
						|
        native_theme_content = {
 | 
						|
            "manifest": {
 | 
						|
                "name": "Native",
 | 
						|
                "description": "The native looks of your OS",
 | 
						|
                "author": "Your Qt Style",
 | 
						|
                "license": "Any"
 | 
						|
            },
 | 
						|
            "palette": {}
 | 
						|
        }
 | 
						|
 | 
						|
        if not os.path.exists(themes_folder):
 | 
						|
            print(f"Creating folder: {themes_folder}")
 | 
						|
            os.makedirs(themes_folder)
 | 
						|
 | 
						|
        if not os.path.isfile(dark_theme_file):
 | 
						|
            print(f"Creating file: {dark_theme_file}")
 | 
						|
            with open(dark_theme_file, "w", encoding="utf-8") as file:
 | 
						|
                json.dump(dark_theme_content, file, indent=2)
 | 
						|
            print("Dark.json has been created successfully.")
 | 
						|
 | 
						|
        if not os.path.isfile(native_theme_file):
 | 
						|
            print(f"Creating file: {native_theme_file}")
 | 
						|
            with open(native_theme_file, "w", encoding="utf-8") as file:
 | 
						|
                json.dump(native_theme_content, file, indent=2)
 | 
						|
            print("Native.json has been created successfully.")
 | 
						|
 | 
						|
        if os.path.isfile(dark_theme_file) and os.path.isfile(native_theme_file):
 | 
						|
            print("Theme Integrity OK")
 |