Music production session manager
https://www.laborejo.org
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
8.8 KiB
160 lines
8.8 KiB
#! /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 <http://www.gnu.org/licenses/>.
|
|
"""
|
|
|
|
|
|
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
|
|
|