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

View File

@ -41,7 +41,7 @@ import logging
# Gramps imports # 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 .utils.configmanager import ConfigManager
from .const import GRAMPS_LOCALE as glocale from .const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = glocale.translation.gettext
@ -166,7 +166,7 @@ register('database.compress-backup', True)
register('database.backup-path', USER_HOME) register('database.backup-path', USER_HOME)
register('database.backup-on-exit', True) register('database.backup-on-exit', True)
register('database.autobackup', 0) 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.host', '')
register('database.port', '') 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: # we can tell by seeing if there is a key file for this version:
if not os.path.exists(CONFIGMAN.filename): if not os.path.exists(CONFIGMAN.filename):
# If not, let's read old if there: # 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: # read it in old style:
logging.warning("Importing old key file 'keys.ini'...") 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) oldstyle=True)
logging.warning("Done importing old key file 'keys.ini'") logging.warning("Done importing old key file 'keys.ini'")
# other version upgrades here... # other version upgrades here...

View File

@ -34,6 +34,8 @@ import os
import sys import sys
import uuid import uuid
from gi.repository import GLib
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Gramps modules # Gramps modules
@ -113,22 +115,34 @@ if 'SAFEMODE' in os.environ:
HOME_DIR = get_env_var('SAFEMODE') HOME_DIR = get_env_var('SAFEMODE')
VERSION_DIR = os.path.join( if (os.path.exists(HOME_DIR) or 'GRAMPSHOME' in os.environ
HOME_DIR, "gramps%s%s" % (VERSION_TUPLE[0], VERSION_TUPLE[1])) 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") CUSTOM_FILTERS = os.path.join(VERSION_DIR, "custom_filters.xml")
REPORT_OPTIONS = os.path.join(HOME_DIR, "report_options.xml") REPORT_OPTIONS = os.path.join(USER_CONFIG, "report_options.xml")
TOOL_OPTIONS = os.path.join(HOME_DIR, "tool_options.xml") TOOL_OPTIONS = os.path.join(USER_CONFIG, "tool_options.xml")
PLACE_FORMATS = os.path.join(HOME_DIR, "place_formats.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_NORMAL = os.path.join(THUMB_DIR, "normal")
THUMB_LARGE = os.path.join(THUMB_DIR, "large") THUMB_LARGE = os.path.join(THUMB_DIR, "large")
USER_PLUGINS = os.path.join(VERSION_DIR, "plugins") USER_PLUGINS = os.path.join(USER_DATA_VERSION, "plugins")
USER_CSS = os.path.join(HOME_DIR, "css") USER_CSS = os.path.join(USER_DATA, "css")
# dirs checked/made for each Gramps session # dirs checked/made for each Gramps session
USER_DIRLIST = (USER_HOME, HOME_DIR, VERSION_DIR, THUMB_DIR, USER_DIRLIST = (USER_HOME, USER_CACHE, USER_CONFIG, USER_DATA, VERSION_DIR,
THUMB_NORMAL, THUMB_LARGE, USER_PLUGINS, USER_CSS) 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 = { ENV = {
"USER_HOME": USER_HOME, "USER_HOME": USER_HOME,
"HOME_DIR": HOME_DIR, "USER_CACHE": USER_CACHE,
"USER_CONFIG": USER_CONFIG,
"USER_DATA": USER_DATA,
"VERSION": VERSION, "VERSION": VERSION,
"major_version": major_version, "major_version": major_version,
"VERSION_DIR": VERSION_DIR, "VERSION_DIR": VERSION_DIR,
"USER_DATA_VERSION": USER_DATA_VERSION,
"THUMB_DIR": THUMB_DIR, "THUMB_DIR": THUMB_DIR,
"THUMB_NORMAL": THUMB_NORMAL, "THUMB_NORMAL": THUMB_NORMAL,
"THUMB_LARGE": THUMB_LARGE, "THUMB_LARGE": THUMB_LARGE,

View File

@ -57,7 +57,7 @@ from xml.sax.saxutils import escape
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from ...const import GRAMPS_LOCALE as glocale from ...const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = 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 ...utils.cast import get_type_converter_by_name, type_name
from ..docgen import StyleSheet, StyleSheetList from ..docgen import StyleSheet, StyleSheetList
from .. import BasePluginManager from .. import BasePluginManager
@ -433,7 +433,7 @@ class BookList:
self.dbase = dbase self.dbase = dbase
self.bookmap = {} self.bookmap = {}
self._needs_saving = None self._needs_saving = None
self.file = os.path.join(HOME_DIR, filename) self.file = os.path.join(USER_DATA, filename)
self.parse() self.parse()
def delete_book(self, name): 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') # (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 ...config import config
from ..docgen import PAPER_PORTRAIT from ..docgen import PAPER_PORTRAIT
from .. import _options from .. import _options
@ -739,7 +739,7 @@ class OptionHandler(_options.OptionHandler):
# Get the first part of name, if it contains a comma: # Get the first part of name, if it contains a comma:
# (will just be module_name, if no comma) # (will just be module_name, if no comma)
filename = "%s.xml" % self.module_name.split(",")[0] 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): def get_default_stylesheet_name(self):
""" get the default stylesheet name """ """ get the default stylesheet name """

View File

@ -37,7 +37,7 @@ try:
except ImportError: except ImportError:
USE_LOCK = False USE_LOCK = False
from .const import HOME_DIR, GRAMPS_LOCALE as glocale from .const import USER_DATA, GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = glocale.translation.gettext
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -45,7 +45,7 @@ _ = glocale.translation.gettext
# Constants # 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 MAX_GRAMPS_ITEMS = 10
#------------------------------------------------------------------------- #-------------------------------------------------------------------------

View File

@ -50,7 +50,7 @@ if "-S" in sys.argv or "--safe" in sys.argv:
# Gramps modules # 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 .gen.constfunc import mac
from .version import VERSION_TUPLE from .version import VERSION_TUPLE
from .gen.constfunc import win, get_env_var 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 win():
# If running in GUI mode redirect stdout and stderr to log file # If running in GUI mode redirect stdout and stderr to log file
if not sys.stdout: if not sys.stdout:
logfile = os.path.join(HOME_DIR, logfile = os.path.join(USER_DATA,
"Gramps%s%s.log") % (VERSION_TUPLE[0], "Gramps%s%s.log") % (VERSION_TUPLE[0],
VERSION_TUPLE[1]) VERSION_TUPLE[1])
# We now carry out the first step in build_user_paths(), to make sure # 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 # 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, # user directory fails here, there is no way to report the failure,
# because stdout/stderr are not available, and neither is the logfile. # 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 pass # ok
elif not os.path.isdir(HOME_DIR): elif not os.path.isdir(USER_DATA):
os.makedirs(HOME_DIR) os.makedirs(USER_DATA)
sys.stdout = sys.stderr = open(logfile, "w", encoding='utf-8') sys.stdout = sys.stderr = open(logfile, "w", encoding='utf-8')
# macOS sets stderr to /dev/null when running without a terminal, # macOS sets stderr to /dev/null when running without a terminal,
# e.g. if Gramps.app is lauched by double-clicking on it in # 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.config import config
from gramps.gen.const import GRAMPS_LOCALE as glocale 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.datehandler import get_date_formats
from gramps.gen.display.name import displayer as _nd from gramps.gen.display.name import displayer as _nd
from gramps.gen.display.name import NameDisplayError from gramps.gen.display.name import NameDisplayError
@ -2088,7 +2088,7 @@ class GrampsPreferences(ConfigureDialog):
_('_Apply'), Gtk.ResponseType.OK) _('_Apply'), Gtk.ResponseType.OK)
dbpath = config.get('database.path') dbpath = config.get('database.path')
if not dbpath: 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)) f.set_current_folder(os.path.dirname(dbpath))
status = f.run() status = f.run()

View File

@ -77,7 +77,7 @@ from .utils import AvailableUpdates
from .pluginmanager import GuiPluginManager from .pluginmanager import GuiPluginManager
from gramps.gen.relationship import get_relationship_calculator from gramps.gen.relationship import get_relationship_calculator
from .displaystate import DisplayState, RecentDocsMenu 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, URL_MAILINGLIST, URL_MANUAL_PAGE, URL_WIKISTRING,
WIKI_EXTRAPLUGINS, URL_BUGHOME) WIKI_EXTRAPLUGINS, URL_BUGHOME)
from gramps.gen.constfunc import is_quartz 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) _('_Apply'), Gtk.ResponseType.OK)
mpath = path_entry.get_text() mpath = path_entry.get_text()
if not mpath: if not mpath:
mpath = HOME_DIR mpath = USER_DATA
fdialog.set_current_folder(os.path.dirname(mpath)) fdialog.set_current_folder(os.path.dirname(mpath))
fdialog.set_filename(os.path.join(mpath, ".")) fdialog.set_filename(os.path.join(mpath, "."))
status = fdialog.run() status = fdialog.run()

View File

@ -29,7 +29,7 @@ import os
import gi import gi
from gi.repository import OsmGpsMap as osmgpsmap from gi.repository import OsmGpsMap as osmgpsmap
from gramps.gen.lib import EventType 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') gi.require_version('OsmGpsMap', '1.0')
@ -38,7 +38,7 @@ gi.require_version('OsmGpsMap', '1.0')
# Constants # Constants
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
GEOGRAPHY_PATH = os.path.join(HOME_DIR, "maps") GEOGRAPHY_PATH = os.path.join(USER_CACHE, "maps")
ICONS = { ICONS = {
EventType.BIRTH : 'gramps-geo-birth', 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.gui.views.navigationview import NavigationView
from gramps.gen.utils.libformatting import FormattingHelper from gramps.gen.utils.libformatting import FormattingHelper
from gramps.gen.errors import WindowActiveError 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.gen.config import config
from gramps.gui.editors import EditPlace, EditEvent, EditFamily, EditPerson from gramps.gui.editors import EditPlace, EditEvent, EditFamily, EditPerson
from gramps.gui.selectors.selectplace import SelectPlace from gramps.gui.selectors.selectplace import SelectPlace
@ -1023,7 +1023,7 @@ class GeoGraphyView(OsmGps, NavigationView):
transient_for=self.uistate.window) transient_for=self.uistate.window)
kml.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL, kml.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Apply'), Gtk.ResponseType.OK) _('_Apply'), Gtk.ResponseType.OK)
mpath = HOME_DIR mpath = USER_HOME
kml.set_current_folder(os.path.dirname(mpath)) kml.set_current_folder(os.path.dirname(mpath))
kml.set_filter(filtering) kml.set_filter(filtering)
@ -1388,7 +1388,7 @@ class GeoGraphyView(OsmGps, NavigationView):
_('_Apply'), Gtk.ResponseType.OK) _('_Apply'), Gtk.ResponseType.OK)
mpath = config.get('geography.path') mpath = config.get('geography.path')
if not mpath: if not mpath:
mpath = HOME_DIR mpath = USER_HOME
selected_dir.set_current_folder(os.path.dirname(mpath)) selected_dir.set_current_folder(os.path.dirname(mpath))
status = selected_dir.run() status = selected_dir.run()

View File

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

View File

@ -24,7 +24,7 @@
#------------------------------------------------ #------------------------------------------------
import os import os
import re 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 from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext _ = glocale.translation.sgettext
@ -218,10 +218,10 @@ def process_list(data):
file = row[3] file = row[3]
if file: if file:
dummy_path, filename = os.path.split(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 # eg, ~/.gramps/gramps34/webstuff/Web_Nebraska.css
# if so, replace this one: # 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): if os.path.exists(override):
row[3] = override row[3] = override
retval.append(row) retval.append(row)