Support XDG base directory specification

Fixes #8025
This commit is contained in:
André Apitzsch 2022-03-16 20:40:16 +01:00 committed by Nick Hall
parent c5564bcd19
commit 08e9101089
13 changed files with 65 additions and 45 deletions

View File

@ -48,7 +48,8 @@ from glob import glob
#
#-------------------------------------------------------------------------
from gramps.gen.const import (LONGOPTS, SHORTOPTS, USER_PLUGINS, VERSION_DIR,
HOME_DIR, THUMB_DIR, USER_CSS)
USER_CACHE, USER_CONFIG, USER_DATA, THUMB_DIR,
USER_CSS)
from gramps.gen.utils.cast import get_type_converter
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
@ -417,16 +418,18 @@ class ArgParser:
if os.path.isfile(fil):
os.remove(fil)
if 'E' in value or 'X' in value: # clear xml reports/tools
for fil in glob(os.path.join(HOME_DIR, "*.xml")):
for fil in glob(os.path.join(USER_DATA, "*.xml")):
os.remove(fil)
if 'E' in value or 'Z' in value: # clear upgrade zips
for fil in glob(os.path.join(HOME_DIR, "*.zip")):
for fil in glob(os.path.join(USER_DATA, "*.zip")):
os.remove(fil)
if 'E' in value: # Everything else
rmtree(THUMB_DIR)
rmtree(USER_CSS)
rmtree(os.path.join(HOME_DIR, "maps"))
for fil in glob(os.path.join(HOME_DIR, "*")):
rmtree(os.path.join(USER_CACHE, "maps"))
for fil in (glob(os.path.join(USER_CACHE, "*"))
+ glob(os.path.join(USER_CONFIG, "*"))
+ glob(os.path.join(USER_DATA, "*"))):
if os.path.isfile(fil):
os.remove(fil)
sys.exit(0) # Done with Default

View File

@ -41,7 +41,7 @@ import logging
# Gramps imports
#
#---------------------------------------------------------------
from .const import HOME_DIR, USER_HOME, VERSION_DIR
from .const import USER_CONFIG, USER_DATA, USER_HOME, VERSION_DIR
from .utils.configmanager import ConfigManager
from .const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
@ -166,7 +166,7 @@ register('database.compress-backup', True)
register('database.backup-path', USER_HOME)
register('database.backup-on-exit', True)
register('database.autobackup', 0)
register('database.path', os.path.join(HOME_DIR, 'grampsdb'))
register('database.path', os.path.join(USER_DATA, 'grampsdb'))
register('database.host', '')
register('database.port', '')
@ -347,10 +347,10 @@ if __debug__: # enable a simple CLI test to see if the datestrings exist
# we can tell by seeing if there is a key file for this version:
if not os.path.exists(CONFIGMAN.filename):
# If not, let's read old if there:
if os.path.exists(os.path.join(HOME_DIR, "keys.ini")):
if os.path.exists(os.path.join(USER_CONFIG, "keys.ini")):
# read it in old style:
logging.warning("Importing old key file 'keys.ini'...")
CONFIGMAN.load(os.path.join(HOME_DIR, "keys.ini"),
CONFIGMAN.load(os.path.join(USER_CONFIG, "keys.ini"),
oldstyle=True)
logging.warning("Done importing old key file 'keys.ini'")
# other version upgrades here...

View File

@ -34,6 +34,8 @@ import os
import sys
import uuid
from gi.repository import GLib
#-------------------------------------------------------------------------
#
# Gramps modules
@ -113,22 +115,34 @@ if 'SAFEMODE' in os.environ:
HOME_DIR = get_env_var('SAFEMODE')
VERSION_DIR = os.path.join(
HOME_DIR, "gramps%s%s" % (VERSION_TUPLE[0], VERSION_TUPLE[1]))
if (os.path.exists(HOME_DIR) or 'GRAMPSHOME' in os.environ
or 'SAFEMODE' in os.environ):
USER_DATA = HOME_DIR
USER_CONFIG = HOME_DIR
USER_CACHE = HOME_DIR
else:
USER_DATA = os.path.join(GLib.get_user_data_dir(), 'gramps')
USER_CONFIG = os.path.join(GLib.get_user_config_dir(), 'gramps')
USER_CACHE = os.path.join(GLib.get_user_cache_dir(), 'gramps')
VERSION_DIR_NAME = "gramps%s%s" % (VERSION_TUPLE[0], VERSION_TUPLE[1])
VERSION_DIR = os.path.join(USER_CONFIG, VERSION_DIR_NAME)
USER_DATA_VERSION = os.path.join(USER_DATA, VERSION_DIR_NAME)
CUSTOM_FILTERS = os.path.join(VERSION_DIR, "custom_filters.xml")
REPORT_OPTIONS = os.path.join(HOME_DIR, "report_options.xml")
TOOL_OPTIONS = os.path.join(HOME_DIR, "tool_options.xml")
PLACE_FORMATS = os.path.join(HOME_DIR, "place_formats.xml")
REPORT_OPTIONS = os.path.join(USER_CONFIG, "report_options.xml")
TOOL_OPTIONS = os.path.join(USER_CONFIG, "tool_options.xml")
PLACE_FORMATS = os.path.join(USER_CONFIG, "place_formats.xml")
THUMB_DIR = os.path.join(HOME_DIR, "thumb")
THUMB_DIR = os.path.join(USER_CACHE, "thumb")
THUMB_NORMAL = os.path.join(THUMB_DIR, "normal")
THUMB_LARGE = os.path.join(THUMB_DIR, "large")
USER_PLUGINS = os.path.join(VERSION_DIR, "plugins")
USER_CSS = os.path.join(HOME_DIR, "css")
USER_PLUGINS = os.path.join(USER_DATA_VERSION, "plugins")
USER_CSS = os.path.join(USER_DATA, "css")
# dirs checked/made for each Gramps session
USER_DIRLIST = (USER_HOME, HOME_DIR, VERSION_DIR, THUMB_DIR,
THUMB_NORMAL, THUMB_LARGE, USER_PLUGINS, USER_CSS)
USER_DIRLIST = (USER_HOME, USER_CACHE, USER_CONFIG, USER_DATA, VERSION_DIR,
USER_DATA_VERSION, THUMB_DIR, THUMB_NORMAL, THUMB_LARGE,
USER_PLUGINS, USER_CSS)
#-------------------------------------------------------------------------
@ -187,10 +201,13 @@ LICENSE_FILE = os.path.join(_resources.doc_dir, 'COPYING')
#-------------------------------------------------------------------------
ENV = {
"USER_HOME": USER_HOME,
"HOME_DIR": HOME_DIR,
"USER_CACHE": USER_CACHE,
"USER_CONFIG": USER_CONFIG,
"USER_DATA": USER_DATA,
"VERSION": VERSION,
"major_version": major_version,
"VERSION_DIR": VERSION_DIR,
"USER_DATA_VERSION": USER_DATA_VERSION,
"THUMB_DIR": THUMB_DIR,
"THUMB_NORMAL": THUMB_NORMAL,
"THUMB_LARGE": THUMB_LARGE,

View File

@ -57,7 +57,7 @@ from xml.sax.saxutils import escape
#-------------------------------------------------------------------------
from ...const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from ...const import HOME_DIR
from ...const import USER_DATA
from ...utils.cast import get_type_converter_by_name, type_name
from ..docgen import StyleSheet, StyleSheetList
from .. import BasePluginManager
@ -433,7 +433,7 @@ class BookList:
self.dbase = dbase
self.bookmap = {}
self._needs_saving = None
self.file = os.path.join(HOME_DIR, filename)
self.file = os.path.join(USER_DATA, filename)
self.parse()
def delete_book(self, name):

View File

@ -59,7 +59,7 @@ LOG = logging.getLogger(".plug.report.options")
# (do not import anything from 'gui' as this is in 'gen')
#
#-------------------------------------------------------------------------
from ...const import HOME_DIR, REPORT_OPTIONS
from ...const import USER_DATA, REPORT_OPTIONS
from ...config import config
from ..docgen import PAPER_PORTRAIT
from .. import _options
@ -739,7 +739,7 @@ class OptionHandler(_options.OptionHandler):
# Get the first part of name, if it contains a comma:
# (will just be module_name, if no comma)
filename = "%s.xml" % self.module_name.split(",")[0]
return os.path.join(HOME_DIR, filename)
return os.path.join(USER_DATA, filename)
def get_default_stylesheet_name(self):
""" get the default stylesheet name """

View File

@ -37,7 +37,7 @@ try:
except ImportError:
USE_LOCK = False
from .const import HOME_DIR, GRAMPS_LOCALE as glocale
from .const import USER_DATA, GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
#-------------------------------------------------------------------------
@ -45,7 +45,7 @@ _ = glocale.translation.gettext
# Constants
#
#-------------------------------------------------------------------------
GRAMPS_FILENAME = os.path.join(HOME_DIR, "recent-files-gramps.xml")
GRAMPS_FILENAME = os.path.join(USER_DATA, "recent-files-gramps.xml")
MAX_GRAMPS_ITEMS = 10
#-------------------------------------------------------------------------

View File

@ -50,7 +50,7 @@ if "-S" in sys.argv or "--safe" in sys.argv:
# Gramps modules
#
#-------------------------------------------------------------------------
from .gen.const import APP_GRAMPS, USER_DIRLIST, HOME_DIR, ORIG_HOME_DIR
from .gen.const import APP_GRAMPS, USER_DIRLIST, USER_DATA, ORIG_HOME_DIR
from .gen.constfunc import mac
from .version import VERSION_TUPLE
from .gen.constfunc import win, get_env_var
@ -113,7 +113,7 @@ form = logging.Formatter(fmt="%(asctime)s.%(msecs).03d: %(levelname)s: "
if win():
# If running in GUI mode redirect stdout and stderr to log file
if not sys.stdout:
logfile = os.path.join(HOME_DIR,
logfile = os.path.join(USER_DATA,
"Gramps%s%s.log") % (VERSION_TUPLE[0],
VERSION_TUPLE[1])
# We now carry out the first step in build_user_paths(), to make sure
@ -122,10 +122,10 @@ if win():
# block, and any failure will be logged. However, if the creation of the
# user directory fails here, there is no way to report the failure,
# because stdout/stderr are not available, and neither is the logfile.
if os.path.islink(HOME_DIR):
if os.path.islink(USER_DATA):
pass # ok
elif not os.path.isdir(HOME_DIR):
os.makedirs(HOME_DIR)
elif not os.path.isdir(USER_DATA):
os.makedirs(USER_DATA)
sys.stdout = sys.stderr = open(logfile, "w", encoding='utf-8')
# macOS sets stderr to /dev/null when running without a terminal,
# e.g. if Gramps.app is lauched by double-clicking on it in

View File

@ -50,7 +50,7 @@ from gi.repository import Pango
#-------------------------------------------------------------------------
from gramps.gen.config import config
from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gen.const import HOME_DIR, URL_WIKISTRING, URL_MANUAL_PAGE
from gramps.gen.const import USER_DATA, URL_WIKISTRING, URL_MANUAL_PAGE
from gramps.gen.datehandler import get_date_formats
from gramps.gen.display.name import displayer as _nd
from gramps.gen.display.name import NameDisplayError
@ -2088,7 +2088,7 @@ class GrampsPreferences(ConfigureDialog):
_('_Apply'), Gtk.ResponseType.OK)
dbpath = config.get('database.path')
if not dbpath:
dbpath = os.path.join(HOME_DIR, 'grampsdb')
dbpath = os.path.join(USER_DATA, 'grampsdb')
f.set_current_folder(os.path.dirname(dbpath))
status = f.run()

View File

@ -77,7 +77,7 @@ from .utils import AvailableUpdates
from .pluginmanager import GuiPluginManager
from gramps.gen.relationship import get_relationship_calculator
from .displaystate import DisplayState, RecentDocsMenu
from gramps.gen.const import (HOME_DIR, ICON, URL_BUGTRACKER, URL_HOMEPAGE,
from gramps.gen.const import (USER_DATA, ICON, URL_BUGTRACKER, URL_HOMEPAGE,
URL_MAILINGLIST, URL_MANUAL_PAGE, URL_WIKISTRING,
WIKI_EXTRAPLUGINS, URL_BUGHOME)
from gramps.gen.constfunc import is_quartz
@ -1799,7 +1799,7 @@ class QuickBackup(ManagedWindow): # TODO move this class into its own module
_('_Apply'), Gtk.ResponseType.OK)
mpath = path_entry.get_text()
if not mpath:
mpath = HOME_DIR
mpath = USER_DATA
fdialog.set_current_folder(os.path.dirname(mpath))
fdialog.set_filename(os.path.join(mpath, "."))
status = fdialog.run()

View File

@ -29,7 +29,7 @@ import os
import gi
from gi.repository import OsmGpsMap as osmgpsmap
from gramps.gen.lib import EventType
from gramps.gen.const import HOME_DIR
from gramps.gen.const import USER_CACHE
gi.require_version('OsmGpsMap', '1.0')
@ -38,7 +38,7 @@ gi.require_version('OsmGpsMap', '1.0')
# Constants
#
#-------------------------------------------------------------------------
GEOGRAPHY_PATH = os.path.join(HOME_DIR, "maps")
GEOGRAPHY_PATH = os.path.join(USER_CACHE, "maps")
ICONS = {
EventType.BIRTH : 'gramps-geo-birth',

View File

@ -55,7 +55,7 @@ from gramps.gen.display.place import displayer as _pd
from gramps.gui.views.navigationview import NavigationView
from gramps.gen.utils.libformatting import FormattingHelper
from gramps.gen.errors import WindowActiveError
from gramps.gen.const import HOME_DIR
from gramps.gen.const import USER_HOME
from gramps.gen.config import config
from gramps.gui.editors import EditPlace, EditEvent, EditFamily, EditPerson
from gramps.gui.selectors.selectplace import SelectPlace
@ -1023,7 +1023,7 @@ class GeoGraphyView(OsmGps, NavigationView):
transient_for=self.uistate.window)
kml.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Apply'), Gtk.ResponseType.OK)
mpath = HOME_DIR
mpath = USER_HOME
kml.set_current_folder(os.path.dirname(mpath))
kml.set_filter(filtering)
@ -1388,7 +1388,7 @@ class GeoGraphyView(OsmGps, NavigationView):
_('_Apply'), Gtk.ResponseType.OK)
mpath = config.get('geography.path')
if not mpath:
mpath = HOME_DIR
mpath = USER_HOME
selected_dir.set_current_folder(os.path.dirname(mpath))
status = selected_dir.run()

View File

@ -62,7 +62,7 @@ from gi.repository import GObject
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from gramps.gen.errors import WindowActiveError
from gramps.gen.const import URL_MANUAL_PAGE, VERSION_DIR
from gramps.gen.const import URL_MANUAL_PAGE, USER_DATA_VERSION
from gramps.gen.lib import (ChildRefType, EventRoleType, EventType,
FamilyRelType, NameType, Person)
from gramps.gen.lib.date import Today
@ -595,7 +595,7 @@ class VerifyResults(ManagedWindow):
db_filename = db_filename.encode('utf-8')
md5sum = md5(db_filename)
self.ignores_filename = os.path.join(
VERSION_DIR, md5sum.hexdigest() + os.path.extsep + 'vfm')
USER_DATA_VERSION, md5sum.hexdigest() + os.path.extsep + 'vfm')
def load_ignored(self, db_filename):
""" get ready to load the file with the previously-ignored people """

View File

@ -24,7 +24,7 @@
#------------------------------------------------
import os
import re
from gramps.gen.const import VERSION_DIR, IMAGE_DIR, DATA_DIR, USER_CSS
from gramps.gen.const import USER_DATA_VERSION, IMAGE_DIR, DATA_DIR, USER_CSS
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
@ -218,10 +218,10 @@ def process_list(data):
file = row[3]
if file:
dummy_path, filename = os.path.split(file)
# is there a override file in the VERSION_DIR/webstuff?
# is there a override file in the DATA_VERSION_DIR/webstuff?
# eg, ~/.gramps/gramps34/webstuff/Web_Nebraska.css
# if so, replace this one:
override = os.path.join(VERSION_DIR, "webstuff", filename)
override = os.path.join(USER_DATA_VERSION, "webstuff", filename)
if os.path.exists(override):
row[3] = override
retval.append(row)