#! /usr/bin/env python3 # -*- coding: utf-8 -*- """ Copyright 2022, Nils Hilbricht, Germany ( https://www.hilbricht.net ) This file is part of the Laborejo Software Suite ( https://www.laborejo.org ). This application is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ import logging; logger = logging.getLogger(__name__); logger.info("import") #Standard Library import pathlib from os import getenv, listdir from sys import argv as sysargv #Third Party from PyQt5 import QtCore, QtGui, QtWidgets #Our own files from .movesessionroot import nsmVersionGreater160 def checkForRunningNsmd(qtApp, PATHS:dict): """Before we start the engine with our own nsmd server: nsmd >= 1.6.0 introduced run file discovery of sessions and empty nsmd. Ask the user if they want to connect to one of these. Injects the path into PATHS["url"], which is used by engine.api.startEngine() """ if PATHS["url"] or any("url" in param for param in sysargv): #this is really the same test twice... #This is not our problem anymore. return if not nsmVersionGreater160(): return #see docstring parent = qtApp.desktop() if not getenv("XDG_RUNTIME_DIR"): logger.warning("Your system has no environment variable $XDG_RUNTIME_DIR. That is unusual for Linux. Automatic detection of already running sessions deactivated.") return #On Linux that should exist. But if not, no reason to crash. logger.info("Detecting if there are already nsmd or sessions running under this user") session_rundir = pathlib.Path(getenv("XDG_RUNTIME_DIR"), "nsm") logger.info(f"Supposed nsmd session rundir: {session_rundir}") nsmd_rundir = pathlib.Path(getenv("XDG_RUNTIME_DIR"), "nsm", "d") logger.info(f"Supposed nsmd server rundir: {nsmd_rundir}") if not session_rundir.exists() or not session_rundir.is_dir(): logger.info("nsmd rundir does not exist. Continue.") return existing_daemons = listdir(nsmd_rundir) existing_sessions = listdir(session_rundir) if existing_sessions: existing_sessions.remove("d") #Remove the daemon subdir if not existing_daemons: logger.info("nsmd rundir exist, but is empty. Continue.") return #if there are no daemons there are no sessions. #There are nsmd running under this user, maybe even open sessions. #Now build a list for the user to choose from. #If a session is running on an nsmd show this, otherwise show the empty nsmd sessions = [] nsmd_pids = set() for s in existing_sessions: res = {} sessions.append(res) with open(pathlib.Path(session_rundir, s), "r") as f: res["hashName"] = s #name of the lockfile. has hash postfix. res["path"] = pathlib.Path(f.readline().strip("\n")) #file path in ~/.local/share/nsm res["name"] = res["path"].name #present this to the user. res["url"] = f.readline().strip("\n") #nsmd url res["pid"] = int(f.readline().strip("\n")) #nsmd pid nsmd_pids.add(res["pid"]) daemons = [] for d in existing_daemons: #d is a file with a PID as name. e.g. 9627 #inside is the NSM_URL. if int(d) in nsmd_pids: #we already have a running session on this server continue else: #empty nsmd. res = {} daemons.append(res) with open(pathlib.Path(nsmd_rundir, d), "r") as f: res["pid"] = d res["url"] = f.readline().strip("\n") #just the first line res["name"] = QtCore.QCoreApplication.translate("StartChooseRunningSession", "Empty Server") + " " + res["url"] #We now have all empty nsmd in var daemons assert sessions or daemons PATHS["url"] = ChooseSessionWidget(qtApp, sessions+daemons).url #"Global Variable" class ChooseSessionWidget(QtWidgets.QDialog): """return value in self.url. Might be None""" def __init__(self, qtApp, sessionDicts:list): super().__init__() #QDialog can't parent to qtApp self.qtApp = qtApp self.setModal(True) #block until closed self.layout = QtWidgets.QVBoxLayout() self.setLayout(self.layout) self.label = QtWidgets.QLabel(self) self.label.setText(QtCore.QCoreApplication.translate("StartChooseRunningSession", "Select session or server to connect to.\nCancel to start our own server.")) self.layout.addWidget(self.label) self.comboBox = QtWidgets.QComboBox(self) self.layout.addWidget(self.comboBox) for s in sessionDicts: self.comboBox.addItem(s["name"], s["url"]) #Show name, use url as data. self.buttonBox = QtWidgets.QDialogButtonBox(self) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) self.buttonBox.setObjectName("buttonBox") self.layout.addWidget(self.buttonBox) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.exec() def accept(self): self.url = self.comboBox.currentData() #easy abstraction so that the caller does not need to know our widget name super().accept() def reject(self): self.url = None super().reject()