+def find_file(
+ file_name=None,
+ root_path=None,
+ search_path=None,
+ default_dir=None,
+ relative=None,
+ universe=None
+):
+ u"""Return an absolute file path based on configuration."""
+ import os, os.path, sys
+
+ # make sure to get rid of any surrounding quotes first thing
+ if file_name: file_name = file_name.strip(u"\"'")
+
+ # this is all unnecessary if it's already absolute
+ if file_name and os.path.isabs(file_name):
+ return os.path.realpath(file_name)
+
+ # when no file name is specified, look for <argv[0]>.conf
+ elif not file_name: file_name = os.path.basename( sys.argv[0] ) + u".conf"
+
+ # if a universe was provided, try to get some defaults from there
+ if universe:
+
+ if hasattr(
+ universe,
+ u"contents"
+ ) and u"internal:storage" in universe.contents:
+ storage = universe.categories[u"internal"][u"storage"]
+ if not root_path: root_path = storage.get(u"root_path").strip("\"'")
+ if not search_path: search_path = storage.getlist(u"search_path")
+ if not default_dir: default_dir = storage.get(u"default_dir").strip("\"'")
+
+ # if there's only one file loaded, try to work around a chicken<egg
+ elif hasattr(universe, u"files") and len(
+ universe.files
+ ) == 1 and not universe.files[universe.files.keys()[0]].is_writeable():
+ data_file = universe.files[universe.files.keys()[0]].data
+
+ # try for a fallback default directory
+ if not default_dir and data_file.has_option(
+ u"internal:storage",
+ u"default_dir"
+ ):
+ default_dir = data_file.get(
+ u"internal:storage",
+ u"default_dir"
+ ).strip(u"\"'")
+
+ # try for a fallback root path
+ if not root_path and data_file.has_option(
+ u"internal:storage",
+ u"root_path"
+ ):
+ root_path = data_file.get(
+ u"internal:storage",
+ u"root_path"
+ ).strip(u"\"'")
+
+ # try for a fallback search path
+ if not search_path and data_file.has_option(
+ u"internal:storage",
+ u"search_path"
+ ):
+ search_path = makelist(
+ data_file.get(u"internal:storage", u"search_path").strip(u"\"'")
+ )
+
+ # another fallback root path, this time from the universe startdir
+ if not root_path and hasattr(universe, "startdir"):
+ root_path = universe.startdir
+
+ # when no root path is specified, assume the current working directory
+ if not root_path: root_path = os.getcwd()
+
+ # otherwise, make sure it's absolute
+ elif not os.path.isabs(root_path): root_path = os.path.realpath(root_path)
+
+ # if there's no search path, just use the root path and etc
+ if not search_path: search_path = [root_path, u"etc"]
+
+ # work on a copy of the search path, to avoid modifying the caller's
+ else: search_path = search_path[:]
+
+ # if there's no default path, use the last element of the search path
+ if not default_dir: default_dir = search_path[-1]
+
+ # if an existing file or directory reference was supplied, prepend it
+ if relative:
+ relative = relative.strip(u"\"'")
+ if os.path.isdir(relative): search_path = [relative] + search_path
+ else: search_path = [ os.path.dirname(relative) ] + search_path
+
+ # make the search path entries absolute and throw away any dupes
+ clean_search_path = []
+ for each_path in search_path:
+ each_path = each_path.strip(u"\"'")
+ if not os.path.isabs(each_path):
+ each_path = os.path.realpath( os.path.join(root_path, each_path) )
+ if each_path not in clean_search_path:
+ clean_search_path.append(each_path)
+
+ # start hunting for the file now
+ for each_path in clean_search_path:
+
+ # if the file exists and is readable, we're done
+ if os.path.isfile( os.path.join(each_path, file_name) ):
+ file_name = os.path.realpath( os.path.join(each_path, file_name) )
+ break
+
+ # it didn't exist after all, so use the default path instead
+ if not os.path.isabs(file_name):
+ file_name = os.path.join(default_dir, file_name)
+ if not os.path.isabs(file_name):
+ file_name = os.path.join(root_path, file_name)
+
+ # and normalize it last thing before returning
+ file_name = os.path.realpath(file_name)
+
+ # normalize the resulting file path and hand it back
+ return file_name
+