#! /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, access, W_OK, R_OK, rmdir from subprocess import check_output from shutil import move as shutil_move from sys import exit as sysexit from sys import argv as sysargv from uuid import uuid4 #Third Party from PyQt5 import QtCore, QtGui, QtWidgets logger.info(f"PyQt Version: {QtCore.PYQT_VERSION_STR}") def nsmVersionGreater160()->bool: maj, min, patch = check_output(["nsmd", "--version"]).decode().split(" ")[1].rstrip("\n").split(".") maj = int(maj) min = int(min) if maj <= 1 and min < 6: return False else: return True def xdgVersionChange(qtApp): """Before we start the engine: nsmd >= 1.6.0 changed the default session root from ~/NSM Sessions to XDG. It will still prioritize the old path, if found. We ask the user to move his files to the correct location now so that the engine can use it this run. This check can be made independently from any --session-root parameter and without nsmd started. """ if any("--session-root" in param for param in sysargv): #This is not our problem anymore. return if not nsmVersionGreater160(): return #see docstring parent = qtApp.desktop() try: oldexists = pathlib.Path("~/NSM Sessions").expanduser().exists() except RuntimeError: #no home dir! oldexists = False xdgdatahome = getenv("XDG_DATA_HOME") if not xdgdatahome: try: xdgdatahome = pathlib.Path("~/.local/share").expanduser() except RuntimeError: #If there is no xdg env and no home dir let us crash and exit. logger.error("There is neither $XDG_DATA_HOME nor a home directory! Cannot start in this environment") #self._callSysExit(). Do not use this because it stores window settings, in a settings dir which might not be available under the circumstances above. sysexit(0) #directly afterwards @atexit is handled, but this function does not return. if not oldexists: return olddir = pathlib.Path("~/NSM Sessions").expanduser() if not olddir.is_dir(): logger.error(f"{olddir} exists but it not a directory. Cannot continue with moving session directories. Please handle it yourself.") errorString = QtCore.QCoreApplication.translate("movesessionroot", "{} exists but it not a directory. Cannot continue with moving session directories. Please handle it yourself.".format(olddir)) QtWidgets.QMessageBox.critical(parent, errorString) return newdir = pathlib.Path(xdgdatahome, "nsm") newexists = newdir.exists() title = QtCore.QCoreApplication.translate("movesessionroot", "Default session directory changed") if newexists: #Must merge. text = QtCore.QCoreApplication.translate("movesessionroot", "Detected both the new NSM 1.6.0 official session directory:\n{}\nAND the old one:\n{}\n\nDo you want Agordejo to move your old files and try to merge them with the new sessions? (Recommended)\n\nYou now have the chance to manually make a backup of your files before pressing 'Yes'".format(newdir, olddir)) else: #Simply move. text = QtCore.QCoreApplication.translate("movesessionroot", "With NSM version 1.6.0 the official session directory moved to:\n{}\nYou are still using the old one:\n{}\n\nDo you want Agordejo to move your files? (Recommended)\n\nYou now have the chance to manually make a backup of your files before pressing 'Yes'".format(newdir, olddir)) userAllowedMove = QtWidgets.QMessageBox.warning(parent, title, text, QtWidgets.QMessageBox.Yes|QtWidgets.QMessageBox.No) if not userAllowedMove == QtWidgets.QMessageBox.Yes: return #Test for read and write permissions if not access(olddir, R_OK): logger.error(f"{olddir} doesn't have READ permissions. Cannot continue with moving session directories. Please handle it yourself.") t = QtCore.QCoreApplication.translate("movesessionroot", "{} doesn't have READ permissions.\nCannot continue moving session directories. Please handle it yourself.".format(olddir)) QtWidgets.QMessageBox.critical(parent, title, t, QtWidgets.QMessageBox.Ok) return if not access(olddir, W_OK): logger.error(f"{olddir} doesn't have WRITE permissions. Cannot continue with moving session directories. Please handle it yourself.") t = QtCore.QCoreApplication.translate("movesessionroot", "{} doesn't have WRITE permissions.\nCannot continue moving session directories. Please handle it yourself.".format(olddir)) QtWidgets.QMessageBox.critical(parent, title, t, QtWidgets.QMessageBox.Ok) return if newexists and not access(newdir, R_OK): logger.error(f"{newdir} doesn't have READ permissions. Cannot continue with moving session directories. Please handle it yourself.") t = QtCore.QCoreApplication.translate("movesessionroot", "{} doesn't have READ permissions.\nCannot continue moving session directories. Please handle it yourself.".format(newdir)) QtWidgets.QMessageBox.critical(parent, title, t, QtWidgets.QMessageBox.Ok) return if newexists and not access(newdir, W_OK): logger.error(f"{newdir} doesn't have WRITE permissions. Cannot continue with moving session directories. Please handle it yourself.") t = QtCore.QCoreApplication.translate("movesessionroot", "{} doesn't have WRITE permissions.\nCannot continue moving session directories. Please handle it yourself.".format(newdir)) QtWidgets.QMessageBox.critical(parent, title, t, QtWidgets.QMessageBox.Ok) return #Tests done. Attempting to actually move the dir. if newexists: #We need to merge two directories if not newdir.is_dir(): logger.error(f"{newdir} exists but it not a directory. Cannot continue with moving session directories. Please handle it yourself.") t = QtCore.QCoreApplication.translate("movesessionroot", "{} exists but it not a directory.\nCannot continue moving session directories. Please handle it yourself.".format(newdir)) QtWidgets.QMessageBox.critical(parent, title, t, QtWidgets.QMessageBox.Ok) return #Are the file conflicts? oldlist = listdir(olddir) newlist = listdir(newdir) if set(oldlist).intersection( set(newlist) ): #Same sessions in both directory. We take the easy way out. unique_newdir = pathlib.Path(newdir, "backup-" + str(uuid4())) logger.info(f"Moving and renaming {olddir} to {unique_newdir} as new session root") shutil_move(olddir, unique_newdir) #this moves and renames the old ~/NSM Sessions. It will disappear from the home dir. else: #no. we can just move. But we need to move the contents, not the olddir itself into the newdir for oldsession in oldlist: shutil_move(pathlib.Path(olddir, oldsession), newdir) #this moves and renames the old ~/NSM Sessions. It will disappear from the home dir. else: #the new directory does not exist yet. We can move it. logger.info(f"Moving and renaming {olddir} to {newdir} as new session root") shutil_move(olddir, newdir) #this moves and renames the old ~/NSM Sessions. It will disappear from the home dir. #If for some reason the old dir is empty and still exists, do this: if olddir.exists(): try: rmdir(olddir) #will raise OSError if not empty. except OSError: logger.error(f"We tried to move and merge {olddir} to {newdir} but afterwards the source directory was not empty. There is nothing we can do here. Please handle it yourself. Please look out for incomplete data.") t = QtCore.QCoreApplication.translate("movesessionroot", "We tried to move and merge {} to {} but afterwards the source directory was not empty. There is nothing we can do here. Please handle it yourself. Please look out for incomplete data.".format(olddir, newdir)) QtWidgets.QMessageBox.critical(parent, title, t, QtWidgets.QMessageBox.Ok) return