from MainWindow import MainWindow from PyQt5.QtWidgets import QApplication import sys import platform if __name__ == '__main__': app = QApplication(sys.argv) app.setStyle('Fusion') main_window = MainWindow() main_window.show() if platform.system() != "Linux": main_window.show_error("Not Linux") main_window.close() sys.exit() app.exec_() sys.exit()
class Controller: def __init__(self): self.setup_window = SetupWindow() self.setup_window.switch_window.connect(self.show_parse_window) self.setup_window.show() def show_parse_window(self): try: self.parse_window = ParseWindow(self.setup_window.savegame_list, self.setup_window.playertags) self.parse_window.switch_back.connect(self.back_to_setup) self.parse_window.switch_edit_nations.connect( self.show_edit_nations) self.parse_window.switch_configure_nations.connect( self.show_configure_nations) self.parse_window.switch_main_window.connect(self.show_main_window) self.parse_window.show() self.setup_window.close() except AttributeError as err: self.setup_window.show() self.setup_window.status.showMessage( "Error:{}. Select two Savegames".format(err)) def back_to_setup(self): self.setup_window.savegame_list = [[], []] self.setup_window.line1.setText("") self.setup_window.line2.setText("") self.setup_window.show() self.parse_window.close() def show_edit_nations(self, b): self.edit_nations_window = EditNations(b, self.parse_window.playertags, self.parse_window.tag_list) self.edit_nations_window.set_playertags.connect(self.set_playertags) self.edit_nations_window.show() def set_playertags(self): self.parse_window.playertags_table.clear() self.parse_window.playertags_table.setRowCount( len(self.parse_window.playertags)) for i in range(len(self.parse_window.playertags)): item = Widgets.QTableWidgetItem() item.setData(Core.Qt.DisplayRole, self.parse_window.playertags[i]) item.setFlags(Core.Qt.ItemIsEnabled) self.parse_window.playertags_table.setItem(i, 0, item) self.parse_window.playertags_table.setHorizontalHeaderLabels( ["Player-Tags"]) if self.parse_window.playertags: self.parse_window.remove_all_button.setEnabled(True) self.parse_window.remove_button.setEnabled(True) else: self.parse_window.remove_all_button.setEnabled(False) self.parse_window.remove_button.setEnabled(False) def show_configure_nations(self): self.configure_window = ConfigureNationFormations( self.parse_window.savegame_list, self.setup_window.old_nations_list, self.setup_window.new_nations_list, self.parse_window.formable_nations_dict) self.configure_window.set_nation_formations.connect( self.set_nation_formations) self.configure_window.show() def set_nation_formations(self, formable_nations_dict): self.parse_window.formable_nations_dict = formable_nations_dict for label in self.parse_window.label_list: label.clear() for (key, value), label in zip( self.parse_window.formable_nations_dict.items(), self.parse_window.label_list): label.setText("{0} {1} {2}".format(value, chr(10230), key)) def show_main_window(self): self.main_window = MainWindow(self.parse_window.savegame_list,\ self.parse_window.formable_nations_dict, self.parse_window.playertags) self.main_window.main.switch_table_window.connect( self.show_table_window) self.main_window.main.switch_province_table_window.connect( self.show_province_table_window) self.main_window.main.back_to_parse_window.connect( self.back_to_parse_window) self.main_window.main.switch_overview_window.connect( self.show_overview_window) self.main_window.main.switch_monarch_table_window.connect( self.show_monarch_table_window) self.main_window.main.switch_error_window.connect( self.show_error_window) self.main_window.main.switch_nation_profile.connect( self.show_nation_profile) self.main_window.show() self.parse_window.close() def show_table_window(self, data, title): self.table_window = TableWindow(self.parse_window.savegame_list, data, title) self.table_window.switch_nation_selecter.connect( self.show_nation_selecter) self.table_window.switch_commander_selecter.connect( self.show_commander_selecter) self.table_window.switch_war_selecter.connect(self.show_war_selecter) self.table_window.switch_to_individual_war.connect( self.show_individual_war) self.table_window.show() def show_province_table_window(self, data, title): self.province_table_window = ProvinceTableWindow( self.parse_window.savegame_list, data, title) self.province_table_window.switch_province_filter.connect( self.show_province_filter) self.province_table_window.switch_nation_selecter.connect( self.show_nation_selecter) self.province_table_window.show() def show_nation_selecter(self, data): self.nation_select_window = NationSelecter( data, self.parse_window.savegame_list) self.nation_select_window.update_table.connect(self.update_table) self.nation_select_window.show() def show_commander_selecter(self): self.commander_select_window = CommanderSelecter( self.table_window.data, self.parse_window.savegame_list) self.commander_select_window.update_table.connect(self.update_table) self.commander_select_window.show() def show_war_selecter(self): self.war_select_window = WarSelecter(self.table_window.data, self.parse_window.savegame_list) self.war_select_window.update_table.connect(self.update_table) self.war_select_window.show() def show_province_filter(self, number, data): self.province_filter = ProvinceFilter(number, data) self.province_filter.update_table.connect(self.update_table) self.province_filter.show() def show_individual_war(self, war): self.individual_war_window = IndividualWarTable( self.parse_window.savegame_list[1].war_dict[war], war, self.parse_window.savegame_list) self.individual_war_window.back_to_table_window.connect( self.back_to_table_window) self.individual_war_window.show() self.table_window.close() def back_to_table_window(self): self.table_window.show() self.individual_war_window.close() def update_table(self, category, data): if category == "army": self.table_window.armyTable(data) if category == "navy": self.table_window.navyTable(data) if category == "province": self.province_table_window.provinceTable(data) def show_overview_window(self, title, categories, colormap_options, header_labels, data): self.overview_window = OverviewTable(self.parse_window.savegame_list, self.parse_window.playertags, title, categories, colormap_options, header_labels, data) self.overview_window.show() def show_monarch_table_window(self, title, data, labels): self.monarch_table_window = MonarchTableWindow( title, data, labels, self.parse_window.savegame_list[1].color_dict) self.monarch_table_window.show() def show_error_window(self, e): self.error_window = ErrorWindow(e) self.error_window.show() def show_nation_profile(self, tag): self.nation_profile = ProfileWindow( tag, self.setup_window.localisation_dict) def back_to_parse_window(self): self.parse_window.show() self.main_window.close()
class ProjectController(): def __init__(self): icon_path = os.path.join(RESOURCES_DIR, 'icons', 'app_icon.png') qApp.setWindowIcon(QtGui.QIcon(icon_path)) if not os.path.exists(PROJECTS_DIR): os.mkdir(PROJECTS_DIR) if not os.path.exists(SETTINGS_DIR): self.createSettingsFile() self.loadSettings() self.sw = StarterWindow(self) self.mw = None def loadSettings(self): ''' Load default user settings ''' with open(SETTINGS_PATH, 'rt') as f: self.settings = json.loads(f.read()) self.loadTheme(self.settings.get('Theme')) def saveSettings(self): ''' Save updated settings data ''' try: with open(SETTINGS_PATH, 'w+') as f: f.write(json.dumps(self.settings)) except: return False else: return True def loadTheme(self, theme=None): ''' Load given theme and save to settings file ''' if theme: theme_path = os.path.join(RESOURCES_DIR, f'stylesheet_{theme}.css') with open(theme_path, 'rt') as f: qApp.setStyleSheet(f.read()) else: qApp.setStyleSheet(None) self.settings['Theme'] = theme self.saveSettings() def setAPI(self, api_key): ''' Save api key to settings file ''' self.settings['API'] = api_key return self.saveSettings() def createSettingsFile(self): ''' Create settings directory and settings.json file if it doesn't exist this function should only be called on first launch of application ''' default_data = {'Theme': None, 'API': None} os.mkdir(SETTINGS_DIR) with open(SETTINGS_PATH, 'w+') as f: f.write(json.dumps(default_data)) def newProject(self, window_ref): ''' window_ref: (QDialog) reference to the window that function is called from ''' self.npw = NewProjectWizard() if self.npw.exec_(): project_name = self.npw.dataPage.getProjectName() ref = self.npw.dataPage.getReferencePoint() if project_name and ref: self.createProject(window_ref, project_name, ref) def createProject(self, window_ref, project_name, ref): ''' window_ref: (QDialog) reference to the window that function is called from project_name: (str) name of new project ref: (tuple) reference point ''' project_file = os.path.join(PROJECTS_DIR, project_name, 'project_data.json') created_date = QDateTime().currentDateTime().toString( 'MM-dd-yyyy hh:mm:ss ap') default_data = { 'ProjectName': project_name, 'Created': created_date, 'LastAccessed': created_date, 'Reference': ref, 'Scale': 0, 'Units': '', 'Points': [] } try: os.makedirs(os.path.join(PROJECTS_DIR, project_name, 'Reports')) with open(project_file, 'w+') as f: f.write(json.dumps(default_data)) except FileExistsError: QMessageBox.critical(window_ref, 'Project Creation Error', f'Invalid project name: {project_name}') else: window_ref.close() self.mw = MainWindow(project_name, self, openExisting=True, api=self.settings.get('API')) def closeProject(self): ''' Close the currently open projects and redisplay starter window ''' self.mw.close() self.sw = StarterWindow(self) def browseProjectsDir(self, window_ref): fileDialog = QFileDialog(window_ref, 'Projects', PROJECTS_DIR) fileDialog.setFileMode(QFileDialog.DirectoryOnly) fileDialog.setAttribute(Qt.WA_QuitOnClose, False) #If a valid path is returned from file dialog screen if fileDialog.exec_(): selected_path = fileDialog.selectedFiles()[0] #Check if json data file is in selected folder projectName = selected_path.split('/')[-1] self.openProject(projectName, window_ref) def openProject(self, project_name, window_ref): ''' window_ref: (QDialog) a reference to the window that called this function ''' path = os.path.join(PROJECTS_DIR, project_name, 'project_data.json') if os.path.exists(path): window_ref.close() self.mw = MainWindow(project_name, self, openExisting=True, api=self.settings.get('API')) #alert for invalid project and return to main window or starter screen else: QMessageBox.critical(window_ref, 'Export File', f'{project_name} file failed to be created') def saveProject(self, project_name, project_data): ''' Saves the project data in json format and writes to a file ''' project_path = os.path.join(PROJECTS_DIR, project_name, 'project_data.json') try: with open(project_path, 'w+') as f: f.write(json.dumps(project_data, indent=2)) except: return False else: return True def setProjectName(self, old_name, new_name): ''' Rename project ''' old_path = os.path.join(PROJECTS_DIR, old_name) new_path = os.path.join(PROJECTS_DIR, new_name) try: os.rename(old_path, new_path) except: return False else: return True def exportProjectData(self, project_name, data, file_type): ''' ''' df = pd.DataFrame(data) path = os.path.join( PROJECTS_DIR, project_name, 'Reports', QDate.currentDate().toString("MM-dd-yy") + f'_Report.{file_type}') try: if file_type == 'csv': df.to_csv(path, index=False) elif file_type == 'json': df.to_json(path) elif file_type == 'xlsx': df.to_excel(path, index=False) elif file_type == 'html': df.to_html(path, index=False) else: raise ValueError except: return False else: return True def getProjectData(self, project_name): path = os.path.join(PROJECTS_DIR, project_name, 'project_data.json') try: with open(path, 'r') as f: data = json.loads(f.read()) except: return False else: return data def getAllProjectData(self): project_names = self.getProjects() data = [] for name in project_names: data.append(self.getProjectData(name)) return data def getProjects(self): ''' Return list of project names within Projects directory ''' return [f.name for f in os.scandir(PROJECTS_DIR) if f.is_dir()]
class Main: wMain = None client = None waitClientTerminate_thread = None def __init__(self): config.init('./config.cfg') logfile = config.get('logfile', None) loglevel = config.get('loglevel', None) if loglevel == 'crit': loglevel = logging.CRITICAL pass elif loglevel == 'error': loglevel = logging.ERROR pass elif loglevel == 'warn': loglevel = logging.WARNING pass elif loglevel == 'info': loglevel = logging.INFO pass elif loglevel == 'debug': loglevel = logging.DEBUG pass else: loglevel = None logging.basicConfig(filename=logfile, level=loglevel, format='%(asctime)-15s %(message)s') logging.debug('main thread id: %s', threading.get_ident()) self.wMain = MainWindow() self.wMain.onOk = self.onWndOk self.wMain.onCancel = self.onWndCancel self.wMain.start() pass def wait(self): pass #def wndLock(self): # if self.wMain: # self.wMain.lock() # pass def wndUnlock(self): if self.wMain: self.wMain.unlock() pass def wndSetStatus(self, text): if self.wMain: self.wMain.setStatus(text) pass def onWndOk(self, username, passwd, printer, shares, keyauth, key=None): self.wMain.lock() clientParams = {'user': username, 'printer': printer, 'shares': shares} if (keyauth and not key): keyfilename = '%s.key' % username if not os.path.isfile(keyfilename): self.wMain.onNewpassOk = functools.partial(self.onNewpassOk, username=username, passwd=passwd, printer=printer, shares=shares) self.wMain.showNewpassModal() return #f = open('.pem','r') #s = f.read() #keydata = StringIO.StringIO(s) #key = paramiko.RSAKey.from_private_key(keydata) try: key = paramiko.RSAKey.from_private_key_file( keyfilename, passwd) except paramiko.ssh_exception.PasswordRequiredException as e: logging.debug('password required for key') messagebox.showerror( message='Требуется ввести пароль упрощенной авторизации!') return except paramiko.ssh_exception.SSHException as e: logging.debug('incorrect password for key') messagebox.showerror( message='Неверный пароль упрощенной авторизации!') return except Exception: logging.debug('auth key readinind error') messagebox.showerror(message='Ошибка упрощенной авторизации!') return clientParams['authkey'] = key else: if (keyauth): clientParams['authkey'] = key clientParams['password'] = passwd self.wMain.showStatusModal() self.paramsForSave = { 'username': username, 'printer': printer, 'shares': shares, 'keyauth': keyauth } #'password':passwd, self.client = X2goClient(**clientParams) self.client.onChangeStatus = self.onClientChangeStatus self.client.onError = self.onClientError self.client.onStarted = self.onClientStarted self.client.start() pass def onNewpassOk(self, username, printer, shares, passwd, keypasswd): keyfilename = '%s.key' % username RSAKEY_STRENGTH = 4096 key = paramiko.RSAKey.generate(RSAKEY_STRENGTH) key.write_private_key_file(keyfilename, keypasswd) self.onWndOk(username=username, passwd=passwd, printer=printer, shares=shares, keyauth=1, key=key) pass def waitClientTerminate(self): a = True while a: self.client.join() a = self.client.is_alive() logging.debug('client thread is_alive: %s', a) time.sleep(3) if a else None self.client = None self.waitClientTerminate_thread = None self.wndUnlock() pass def onWndCancel(self): if (self.client and not self.waitClientTerminate_thread): self.wndSetStatus('Отмена соединения...') self.client.stop() self.waitClientTerminate_thread = threading.Thread( target=self.waitClientTerminate) self.waitClientTerminate_thread.start() else: self.wMain.close() pass def onClientChangeStatus(self, text): self.wndSetStatus(text) pass def onClientError(self, error): self.wndSetStatus(error) self.client = None self.wndUnlock() pass def onClientStarted(self): self.wMain.close() self.wMain = None config.sets(self.paramsForSave) pass
class SBrickApplication(Gtk.Application): def __init__(self, *args, **kwargs): # super(*args, **kwargs) Gtk.Application.__init__(self, *args, application_id="nz.winters.sbrickapp", flags=Gio.ApplicationFlags.NON_UNIQUE, **kwargs) self.window = None self.config = None self.configFile = "sbricks.json" self.add_main_option("config", ord("c"), GLib.OptionFlags.OPTIONAL_ARG, GLib.OptionArg.STRING, "Config File", None) self.connect('handle-local-options', self.on_handle_local_options) def do_startup(self): Gtk.Application.do_startup(self) action = Gio.SimpleAction.new("about", None) action.connect("activate", self.on_about) self.add_action(action) action = Gio.SimpleAction.new("quit", None) action.connect("activate", self.on_quit) self.add_action(action) action = Gio.SimpleAction.new("open_configuration", None) action.connect("activate", self.on_open_configuration) self.add_action(action) action = Gio.SimpleAction.new("save_configuration", None) action.connect("activate", self.on_save_configuration) self.add_action(action) action = Gio.SimpleAction.new("save_as_configuration", None) action.connect("activate", self.on_save_as_configuration) self.add_action(action) builder = Gtk.Builder.new_from_file("menu.xml", ) self.set_app_menu(builder.get_object("app-menu")) def do_activate(self): self.read_config() if not self.window: self.window = MainWindow(application=self, title="SBrick Controller", config=self.config) self.window.present() # noinspection PyUnusedLocal def on_handle_local_options(self, application, options): if options.contains("config"): self.configFile = options.lookup_value("config").get_string() return -1 # noinspection PyUnusedLocal def on_quit(self, action, param): self.quit() def read_config(self): fp = open(self.configFile) try: self.config = json.load(fp) finally: fp.close() # noinspection PyUnusedLocal def on_about(self, action, param): about_dialog = Gtk.AboutDialog(transient_for=self.window, modal=True) about_dialog.run() about_dialog.destroy() # noinspection PyUnusedLocal def on_save_configuration(self, action, param): self.save_configuration(self.configFile) def save_configuration(self, filename): fp = open(filename, mode="w+") try: self.window.write_configuration() json.dump(self.config, fp, indent=2) finally: fp.close() # noinspection PyUnusedLocal def on_save_as_configuration(self, action, param): dialog = Gtk.FileChooserDialog("Save Configuration As...", self.window, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK)) dialog.set_filename(self.configFile) self.add_filters(dialog) response = dialog.run() if response == Gtk.ResponseType.OK: self.configFile = dialog.get_filename() self.save_configuration(self.configFile) dialog.destroy() # noinspection PyUnusedLocal def on_open_configuration(self, action, param): dialog = Gtk.FileChooserDialog("Open Configuration...", self.window, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) dialog.set_filename(self.configFile) self.add_filters(dialog) response = dialog.run() if response == Gtk.ResponseType.OK: self.configFile = dialog.get_filename() self.read_config() if self.window: self.window.close() self.window = MainWindow(application=self, title="SBrick Controller", config=self.config) self.window.present() # self.save_configuration(self.configFile) dialog.destroy() @staticmethod def add_filters(dialog): filter_text = Gtk.FileFilter() filter_text.set_name("JSON files") filter_text.add_pattern("*.json") dialog.add_filter(filter_text) filter_any = Gtk.FileFilter() filter_any.set_name("Any files") filter_any.add_pattern("*") dialog.add_filter(filter_any)