openlp/openlp/core/common/applocation.py

170 lines
6.3 KiB
Python

# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2022 OpenLP Developers #
# ---------------------------------------------------------------------- #
# This program 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 <https://www.gnu.org/licenses/>. #
##########################################################################
"""
The :mod:`openlp.core.common.applocation` module provides an utility for OpenLP receiving the data path etc.
"""
import logging
import os
import sys
from pathlib import Path
import appdirs
import openlp
from openlp.core.common import get_frozen_path, is_macosx, is_win
from openlp.core.common.path import create_paths
from openlp.core.common.registry import Registry
log = logging.getLogger(__name__)
FROZEN_APP_PATH = Path(sys.argv[0]).parent
APP_PATH = Path(openlp.__file__).parent
class AppLocation(object):
"""
The :class:`AppLocation` class is a static class which retrieves a directory based on the directory type.
"""
AppDir = 1
DataDir = 2
PluginsDir = 3
VersionDir = 4
CacheDir = 5
LanguageDir = 6
@staticmethod
def get_directory(dir_type=AppDir):
"""
Return the appropriate directory according to the directory type.
:param dir_type: The directory type you want, for instance the data directory. Default *AppLocation.AppDir*
:return: The requested path
:rtype: Path
"""
if dir_type == AppLocation.AppDir or dir_type == AppLocation.VersionDir:
path = get_frozen_path(FROZEN_APP_PATH, APP_PATH)
elif dir_type == AppLocation.PluginsDir:
path = get_frozen_path(FROZEN_APP_PATH, APP_PATH) / 'plugins'
elif dir_type == AppLocation.LanguageDir:
path = get_frozen_path(FROZEN_APP_PATH, _get_os_dir_path(dir_type)) / 'i18n'
else:
path = _get_os_dir_path(dir_type)
# resolve() does not work on windows
if is_win():
return Path.cwd() / path
else:
return path.resolve()
@staticmethod
def get_data_path():
"""
Return the path OpenLP stores all its data under.
:return: The data path to use.
:rtype: Path
"""
# Check if we have a different data location.
if Registry().get('settings').contains('advanced/data path'):
path = Path(Registry().get('settings').value('advanced/data path'))
else:
path = AppLocation.get_directory(AppLocation.DataDir)
create_paths(path)
return path
@staticmethod
def get_files(section=None, extension=''):
"""
Get a list of files from the data files path.
:param None | str section: Defaults to *None*. The section of code getting the files - used to load from a
section's data subdirectory.
:param str extension: Defaults to ''. The extension to search for. For example::
'.png'
:return: List of files found.
:rtype: list[Path]
"""
path = AppLocation.get_data_path()
if section:
path = path / section
try:
file_paths = path.glob('*' + extension)
return [file_path.relative_to(path) for file_path in file_paths]
except OSError:
return []
@staticmethod
def get_section_data_path(section):
"""
Return the path a particular module stores its data under.
:param str section:
:rtype: Path
"""
path = AppLocation.get_data_path() / section
create_paths(path)
return path
def _get_os_dir_path(dir_type):
"""
Return a path based on which OS and environment we are running in.
:param dir_type: AppLocation Enum of the requested path type
:return: The requested path
:rtype: Path
"""
# If running from source, return the language directory from the source directory
if dir_type == AppLocation.LanguageDir:
directory = Path(openlp.__file__, '..', '..').resolve() / 'resources'
if directory.exists():
return directory
if is_win():
openlp_folder_path = Path(os.getenv('APPDATA'), 'openlp')
if dir_type == AppLocation.DataDir:
return openlp_folder_path / 'data'
elif dir_type == AppLocation.LanguageDir:
return Path(openlp.__file__).parent
return openlp_folder_path
dirs = appdirs.AppDirs('openlp', multipath=True)
if is_macosx():
openlp_folder_path = Path(dirs.user_data_dir)
if dir_type == AppLocation.DataDir:
return openlp_folder_path / 'Data'
elif dir_type == AppLocation.LanguageDir:
return Path(openlp.__file__).parent
return openlp_folder_path
else:
if dir_type == AppLocation.LanguageDir:
site_dirs = dirs.site_data_dir.split(os.pathsep)
directory = Path(site_dirs[0])
if directory.exists():
return directory
return Path(site_dirs[1])
if dir_type == AppLocation.DataDir:
return Path(dirs.user_data_dir)
elif dir_type == AppLocation.CacheDir:
return Path(dirs.user_cache_dir)
if dir_type == AppLocation.DataDir:
return Path(os.getenv('HOME'), '.openlp', 'data')
return Path(os.getenv('HOME'), '.openlp')