# -*- coding: utf-8 -*- """ $Id$ Copyright 2010 Lars Kruse <devel@sumpfralle.de> This file is part of PyCAM. PyCAM 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. PyCAM 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 PyCAM. If not, see <http://www.gnu.org/licenses/>. """ import os import sys import pycam.Utils.log DATA_DIR_ENVIRON_KEY = "PYCAM_DATA_DIR" FONT_DIR_ENVIRON_KEY = "PYCAM_FONT_DIR" DATA_BASE_DIRS = [os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, "share")), os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, "share", "pycam")), os.path.join(sys.prefix, "local", "share", "pycam"), os.path.join(sys.prefix, "share", "pycam")] FONTS_SUBDIR = "fonts" UI_SUBDIR = "ui" # necessary for "pyinstaller" if "_MEIPASS2" in os.environ: DATA_BASE_DIRS.insert(0, os.path.join(os.path.normpath(os.environ["_MEIPASS2"]), "share")) # respect an override via an environment setting if DATA_DIR_ENVIRON_KEY in os.environ: DATA_BASE_DIRS.insert(0, os.path.normpath(os.environ[DATA_DIR_ENVIRON_KEY])) if FONT_DIR_ENVIRON_KEY in os.environ: FONT_DIR_OVERRIDE = os.path.normpath(os.environ[FONT_DIR_ENVIRON_KEY]) else: FONT_DIR_OVERRIDE = None FONT_DIRS_FALLBACK = ["/usr/share/librecad/fonts", "/usr/share/qcad/fonts"] log = pycam.Utils.log.get_logger() def get_ui_file_location(filename, silent=False): return get_data_file_location(os.path.join(UI_SUBDIR, filename), silent=silent) def get_data_file_location(filename, silent=False): for base_dir in DATA_BASE_DIRS: test_path = os.path.join(base_dir, filename) if os.path.exists(test_path): return test_path else: if not silent: lines = [] lines.append("Failed to locate a resource file (%s) in %s!" \ % (filename, DATA_BASE_DIRS)) lines.append("You can extend the search path by setting the " \ + "environment variable '%s'." % str(DATA_DIR_ENVIRON_KEY)) log.error(os.linesep.join(lines)) return None def get_font_dir(): if FONT_DIR_OVERRIDE: if os.path.isdir(FONT_DIR_OVERRIDE): return FONT_DIR_OVERRIDE else: log.warn(("You specified a font dir that does not exist (%s). " \ + "I will ignore it.") % FONT_DIR_OVERRIDE) font_dir = get_data_file_location(FONTS_SUBDIR, silent=True) if not font_dir is None: return font_dir else: log.warn(("Failed to locate the fonts directory '%s' below '%s'. " \ + "Falling back to '%s'.") \ % (FONTS_SUBDIR, DATA_BASE_DIRS, ":".join(FONT_DIRS_FALLBACK))) for font_dir_fallback in FONT_DIRS_FALLBACK: if os.path.isdir(font_dir_fallback): return font_dir_fallback else: log.warn(("None of the fallback font directories (%s) exist. " + \ "No fonts will be available.") % \ ":".join(FONT_DIRS_FALLBACK)) return None def get_external_program_location(key): extensions = ["", ".exe"] potential_names = ["%s%s" % (key, ext) for ext in extensions] windows_program_directories = {'inkscape': ['Inkscape'], 'pstoedit': ['pstoedit']} # check the windows path via win32api try: import win32api location = win32api.FindExecutable(key)[1] if location: return location except Exception: # Wildcard (non-system exiting) exeception to match "ImportError" and # "pywintypes.error" (for "not found"). pass # go through the PATH environment variable if "PATH" in os.environ: path_env = os.environ["PATH"] for one_dir in path_env.split(os.pathsep): for basename in potential_names: location = os.path.join(one_dir, basename) if os.path.isfile(location): return location # do a manual scan in the programs directory (only for windows) program_dirs = ["C:\\Program Files", "C:\\Programme"] try: from win32com.shell import shellcon, shell # The frozen application somehow dows not provide this setting. program_dirs.insert(0, shell.SHGetFolderPath(0, shellcon.CSIDL_PROGRAM_FILES, 0, 0)) except ImportError: # no other options for non-windows systems pass # scan the program directory for program_dir in program_dirs: for sub_dir in windows_program_directories[key]: for basename in potential_names: location = os.path.join(program_dir, sub_dir, basename) if os.path.isfile(location): return location # nothing found return None def get_all_program_locations(core): # TODO: this should move to a plugin # import all external program locations into a dict program_locations = {} prefix = "external_program_" for key in core: if key.startswith(prefix) and core[key]: program_locations[key[len(prefix):]] = core[key] return program_locations