#ifndef MYX_CORE_PATHS_CPP_ #define MYX_CORE_PATHS_CPP_ #include #include #include #include #include namespace myx { namespace filesystem { MYXLIB_INLINE Paths::Paths() : m_binDirRegex ( QStringLiteral( "/s*bin$" ) ), m_unityBinDirRegex( QStringLiteral( "/bin/unity$" ) ) { QFileInfo procSelfExe( QStringLiteral( "/proc/self/exe" ) ); QFileInfo currentExecutable = procSelfExe.canonicalFilePath(); m_executableName = currentExecutable.fileName(); m_executableFilePath = currentExecutable.absoluteFilePath(); m_executableDirectory = currentExecutable.absolutePath(); // Инициализация значениями по умолчанию init(); } MYXLIB_INLINE bool Paths::init( bool autodetect ) { m_autodetect = autodetect; m_homeDirectory = QDir::homePath(); m_tempDirectory = QDir::tempPath(); m_configDirectory = QString::fromLocal8Bit( qgetenv( "XDG_CONFIG_HOME" ) ); if ( m_configDirectory.isEmpty() ) { m_configDirectory = m_homeDirectory + "/.config"; } m_dataDirectory = QString::fromLocal8Bit( qgetenv( "XDG_DATA_HOME" ) ); if ( m_dataDirectory.isEmpty() ) { m_dataDirectory = m_homeDirectory + "/.local/share"; } if ( m_projectName.isEmpty() ) { m_projectName = m_executableName; } m_hierarchyType = getHierarchyType(); calculatePaths( m_hierarchyType ); return( true ); } // Paths::init MYXLIB_INLINE void Paths::setupSystemDirectories( const QString& projectDir, const QString& etcDir, const QString& constDataDir, const QString& varDataDir, const QString& logDir ) { QFileInfo prefixDirInfo { projectDir }; if ( prefixDirInfo.isDir() && prefixDirInfo.isReadable() ) { m_projectDirectory = projectDir; } else { m_projectDirectory = QStringLiteral( "." ); } QFileInfo etcDirInfo { etcDir }; if ( etcDirInfo.isDir() && etcDirInfo.isReadable() ) { m_systemConfigDirectory = etcDir; } else { m_systemConfigDirectory = m_userConfigDirectory; } QFileInfo constDataDirInfo { constDataDir }; if ( constDataDirInfo.isDir() && constDataDirInfo.isReadable() ) { m_systemConstDataDirectory = constDataDir; } else { m_systemConstDataDirectory = m_userConstDataDirectory; } QFileInfo varDataDirInfo { varDataDir }; if ( varDataDirInfo.isDir() && varDataDirInfo.isWritable() ) { m_systemVarDataDirectory = varDataDir; } else { m_systemVarDataDirectory = m_userVarDataDirectory; } QFileInfo logDirInfo { logDir }; if ( logDirInfo.isDir() && logDirInfo.isWritable() ) { m_systemLogDirectory = logDir; } else { m_systemLogDirectory = m_userLogDirectory; } if ( !m_organizationName.isEmpty() && !m_themeName.isEmpty() ) { m_systemThemeDirectory = "/opt/" + m_organizationName + "-" + m_themeName; } } // Paths::setupSystemDirectories MYXLIB_INLINE void Paths::setupUserDirectories() { QString prefix; if ( !m_organizationName.isEmpty() ) { prefix = "/" + m_organizationName; if ( !m_themeName.isEmpty() ) { prefix.append( "-" + m_themeName ); m_userThemeDirectory = m_dataDirectory + prefix; } } prefix.append( "/" + m_projectName ); m_userConfigDirectory = m_configDirectory + prefix; m_userConstDataDirectory = m_dataDirectory + prefix + "/share"; m_userVarDataDirectory = m_dataDirectory + prefix + "/var"; m_userLogDirectory = m_dataDirectory + prefix + "/log"; } MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType() { if ( m_unityBinDirRegex.match( m_executableDirectory ).hasMatch() ) { return ( HierarchyType::kDevelopment ); } if ( !m_binDirRegex.match( m_executableDirectory ).hasMatch() ) { return ( HierarchyType::kFlat ); } if ( m_executableDirectory.startsWith( QStringLiteral( "/opt/" ) ) ) { return ( HierarchyType::kOpt ); } if ( m_executableDirectory.startsWith( QStringLiteral( "/usr/local/bin/" ) ) ) { return ( HierarchyType::kUsrLocal ); } if ( m_executableDirectory.startsWith( QStringLiteral( "/usr/local/" ) ) ) { return ( HierarchyType::kUsrLocalOrg ); } if ( m_executableDirectory.startsWith( QStringLiteral( "/usr/bin/" ) ) ) { return ( HierarchyType::kUsr ); } if ( m_executableDirectory.startsWith( m_homeDirectory + "/.local/bin/" ) || m_executableDirectory.startsWith( m_homeDirectory + "/bin/" ) ) { return( HierarchyType::kHome ); } return ( HierarchyType::kDevelopment ); } // Paths::getHierarchyType MYXLIB_INLINE void Paths::calculatePaths( HierarchyType hType ) { auto directory = m_executableDirectory; setupUserDirectories(); switch ( hType ) { case HierarchyType::kFlat: setupSystemDirectories( directory, directory, directory, directory, directory ); break; case HierarchyType::kOpt: processOptHierarhy(); break; case HierarchyType::kUsr: setupSystemDirectories( QStringLiteral( "/usr" ), "/etc/" + m_projectName, "/usr/share/" + m_projectName, "/var/lib/" + m_projectName, "/var/log/" + m_projectName ); break; case HierarchyType::kUsrLocal: setupSystemDirectories( QStringLiteral( "/usr/local" ), "/usr/local/etc/" + m_projectName, "/usr/local/share/" + m_projectName, "/var/lib/" + m_projectName, "/var/log/" + m_projectName ); break; case HierarchyType::kUsrLocalOrg: directory.remove( m_binDirRegex ); setupSystemDirectories( directory, directory + "/etc", directory + "/share", directory + "/var", directory + "/log" ); break; case HierarchyType::kHome: setupSystemDirectories( m_homeDirectory, m_userConfigDirectory, m_userConstDataDirectory, m_userVarDataDirectory, m_userLogDirectory ); break; case HierarchyType::kDevelopment: directory.remove( m_unityBinDirRegex ); directory.remove( m_binDirRegex ); setupSystemDirectories( directory, directory + "/etc", directory + "/share", directory + "/var", directory + "/log" ); break; case HierarchyType::kUndefined: ; } // switch setupUserDirectories(); } // Paths::calculatePaths MYXLIB_INLINE void Paths::processOptHierarhy() { auto directory = m_executableDirectory; if ( m_autodetect ) { QRegularExpression regex( QStringLiteral( "^/opt/(.+?)/(.+?)/" ) ); QRegularExpressionMatch match = regex.match( m_executableDirectory ); if ( match.hasMatch() ) { m_organizationName = match.captured( 1 ); m_projectName = match.captured( 2 ); QRegularExpression themeRegex( QStringLiteral( "(.+?)-(.+)" ) ); QRegularExpressionMatch themeMatch = themeRegex.match( m_organizationName ); if ( themeMatch.hasMatch() ) { m_themeName = themeMatch.captured( 2 ); m_organizationName = themeMatch.captured( 1 ); } QRegularExpression versionRegex( QStringLiteral( "(.+?)\\.(.+)" ) ); QRegularExpressionMatch versionMatch = versionRegex.match( m_projectName ); if ( versionMatch.hasMatch() ) { m_projectName = versionMatch.captured( 1 ); m_version = versionMatch.captured( 2 ); } } } directory.remove( m_binDirRegex ); setupSystemDirectories( directory, directory + "/etc", directory + "/share", directory + "/var", directory + "/log" ); setupUserDirectories(); } // Paths::processOptHierarhy MYXLIB_INLINE bool Paths::makeDefaultSystemDirectories() { bool status = true; QDir dir; if ( !dir.mkpath( m_systemConstDataDirectory ) ) { status = false; } if ( !dir.mkpath( m_systemLogDirectory ) ) { status = false; } if ( !dir.mkpath( m_systemConfigDirectory ) ) { status = false; } if ( !dir.mkpath( m_systemVarDataDirectory ) ) { status = false; } return( status ); } MYXLIB_INLINE bool Paths::makeDefaultUserDirectories() { bool status = true; QDir dir; if ( !dir.mkpath( m_userConstDataDirectory ) ) { status = false; } if ( !dir.mkpath( m_userLogDirectory ) ) { status = false; } if ( !dir.mkpath( m_userConfigDirectory ) ) { status = false; } if ( !dir.mkpath( m_userVarDataDirectory ) ) { status = false; } return( status ); } MYXLIB_INLINE bool Paths::makeDefaultDirectories() { return ( makeDefaultSystemDirectories() && makeDefaultUserDirectories() ); } MYXLIB_INLINE QString Paths::findConfigFile( const QString& configFileName ) { if ( !configFileName.isEmpty() && QFileInfo( configFileName ).isReadable() ) { return( configFileName ); } auto fileName = QString::fromLocal8Bit( qgetenv( QCoreApplication::applicationName() .toUpper().toUtf8() + "_CONFIG" ) ); if ( QFileInfo( fileName ).isReadable() ) { return( fileName ); } QString autoConfigFile = m_systemConfigDirectory + "/" + m_executableName; if ( QFileInfo( autoConfigFile ).isReadable() ) { return( configFileName ); } return( QString() ); } // Paths::findConfigFile MYXLIB_INLINE const QString& Paths::userConfigDirectory() const { return( m_userConfigDirectory ); } MYXLIB_INLINE const QString& Paths::systemConfigDirectory() const { return( m_systemConfigDirectory ); } MYXLIB_INLINE const QString& Paths::userThemeDirectory() const { return( m_userThemeDirectory ); } MYXLIB_INLINE const QString& Paths::systemThemeDirectory() const { return( m_systemThemeDirectory ); } MYXLIB_INLINE const QString& Paths::userVarDataDirectory() const { return( m_userVarDataDirectory ); } MYXLIB_INLINE const QString& Paths::systemVarDataDirectory() const { return( m_systemVarDataDirectory ); } MYXLIB_INLINE const QString& Paths::userConstDataDirectory() const { return( m_userConstDataDirectory ); } MYXLIB_INLINE const QString& Paths::systemConstDataDirectory() const { return( m_systemConstDataDirectory ); } MYXLIB_INLINE const QString& Paths::userLogDirectory() const { return( m_userLogDirectory ); } MYXLIB_INLINE const QString& Paths::systemLogDirectory() const { return( m_systemLogDirectory ); } MYXLIB_INLINE const QString& Paths::tempDirectory() const { return( m_tempDirectory ); } MYXLIB_INLINE const QString& Paths::homeDirectory() const { return( m_homeDirectory ); } MYXLIB_INLINE const QString& Paths::projectName() const { return( m_projectName ); } MYXLIB_INLINE void Paths::setProjectName( const QString& name ) { m_projectName = name; } MYXLIB_INLINE const QString& Paths::organizationName() const { return( m_organizationName ); } MYXLIB_INLINE void Paths::setOrganizationName( const QString& name ) { m_organizationName = name; } MYXLIB_INLINE const QString& Paths::themeName() const { return( m_themeName ); } MYXLIB_INLINE void Paths::setThemeName( const QString& name ) { m_themeName = name; } MYXLIB_INLINE const QString& Paths::executableName() const { return( m_executableName ); } MYXLIB_INLINE const QString& Paths::executableFilePath() const { return( m_executableFilePath ); } MYXLIB_INLINE const QString& Paths::executableDirectory() const { return( m_executableDirectory ); } MYXLIB_INLINE const QString& Paths::projectDirectory() const { return( m_projectDirectory ); } } // namespace filesystem } // namespace myx #endif // MYX_CORE_PATHS_CPP_