import os import json import elevate import subprocess from PySide6.QtCore import Qt, QFileInfo import Kikka from Kikka.KikkaConst import * from Kikka.Utils.Singleton import singleton from Kikka.KikkaMemory import Storageable, KikkaMemory class Action: def __init__(self, data): self.name = data[0] self.type = data[1] self.path = data[2] self.icon = data[3] self.param = data[4] self.work_dir = data[5] self.run_as_admin = data[6] self.open_as_private = data[7] self.color = data[8] self.shortcut = data[9] self.remark = data[10] def toList(self): return [ self.name, self.type, self.path, self.icon, self.param, self.work_dir, self.run_as_admin, self.open_as_private, self.color, self.shortcut, self.remark ] class SubCategory(Storageable): def __init__(self, name, type): self.name = name self.type = type self.actions = [] def __str__(self): return "SubCategory(%s) %s" % (self.name, self.type) def toDict(self): return { 'name': self.name, 'type': self.type, 'actions': [a.toList() for a in self.actions] } class MainCategory(Storageable): def __init__(self, name): self.name = name self.sub_categories = {} def __getitem__(self, item): return self.sub_categories[item] def __str__(self): return "MainCategory(%s)" % self.name def toDict(self): return { 'name': self.name, 'sub_categories': [s.toDict() for _, s in self.sub_categories.items()] } @singleton class KikkaAction(): def __init__(self): self._data = None @property def data(self): return self._data def load(self): data = {} action_data = Kikka.memory.getAction() for col, main_category_data in enumerate(action_data.values()): main_name = main_category_data['name'] main_category = MainCategory(main_name) data[col] = main_category for row, sub_category_data in enumerate(main_category_data['sub_categories']): sub_name = sub_category_data['name'] sub_category = SubCategory(sub_name, sub_category_data['type']) main_category.sub_categories[row] = sub_category actions = sub_category_data['actions'] for action_data in actions: action = Action(action_data) sub_category.actions.append(action) self._data = data return data def save(self): Kikka.memory.updateAction(self._data) @staticmethod def createAction(name='', type='', path='', icon='', param='', work_dir='', run_as_admin=False, open_as_private=False, color='', shortcut='', remark=''): data = [name, type, path, icon, param, work_dir, run_as_admin, open_as_private, color, shortcut, remark] action = Action(data) return action def addAction(self, action, column, row): self._data[column].sub_categories[row].actions.append(action) self.save() # region Action Operation def actionOperation(self, operation, param): if operation == EActionOperation.RunAction: self._runAction(param['action']) elif operation == EActionOperation.NewAction: self._newAction(param['filepath'], param['column'], param['row']) def _runAction(self, action, run_as_admin=False, run_for_new_console=False): run_as_admin = run_as_admin or action.run_as_admin if run_as_admin: elevate.elevate() cmd = action.path + " " + action.param work_dir = action.work_dir try: proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=work_dir, shell=True) if proc.returncode != 0: print(proc.stderr) except Exception as e: print(e) pass def _newAction(self, filepath, column, row): file_info = QFileInfo(filepath) ext = file_info.suffix().lower() if ext in ["exe", "bat", "cmd", "ps1", "sh"]: # executable action = self.createAction( type="executable", name=file_info.baseName(), path=file_info.filePath(), work_dir=file_info.path(), ) KikkaAction().addAction(action, column, row) pass # endregion