source: orange/Orange/utils/environ.py @ 11410:9e01d26814dc

Revision 11410:9e01d26814dc, 10.5 KB checked in by Ales Erjavec <ales.erjavec@…>, 13 months ago (diff)

Fixed global orangerc.cfg file parsing.

RevLine 
[8042]1"""
2==============================================
3Orange environment configuration (``environ``)
4==============================================
5
6This module contains some basic customization options for Orange
7(for now mostly changing directories where orange settings are saved).
8
9How it works
10------------
11
12When this module is imported it will first load and parse a global
[9059]13configuration `orangerc.cfg` (located in the root directory of the orange
[8042]14installation). Further, it will look for and try to load a user specific
15configuration file located in $(HOME)/.orangerc.cfg or
[8044]16`application_dir`/orangerc.cfg where `application_dir` is a variable defined
[8042]17in the global configuration file.
18
19.. note:: in the configuration files all OS defined environment variables
20    (e.g $HOME, $USER, ...) are available.
21
22After all the parsing has taken place the select variables defined in the
23configuration will be made available as top level module variables.
24
25Example
26-------
27
28To change the location where settings are saved for Orange Canvas
29on Windows edit the global `orangerc.cfg` file and in the
30`[directories win32]` section change the `application_dir` variable:
31   
32    [directories win32]
33   
34    application_dir = D:/SharedAppData/orange/
35   
36In this way we can hard code the path instead of using the system default
37(defined in the the %APPDATA variable)
38
39Variables
40---------
41
42The following variables are exposed as top level module members
43
44`install_dir`:
45    Directory where Orange is installed.
46   
47`canvas_install_dir`:
48    Directory where Orange Canvas is installed.
49
50`widget_install_dir`:
51    Directory where Orange Widgets are installed.
52
53`icons_install_dir`:
54    Directory where icons for widgets are installed.
55
56`doc_install_dir`:
[8045]57    Directory with Orange documentation.
58 
59`dataset_install_dir`:
60    Directory with example data sets.
61
[8042]62`add_ons_dir`:
63    Directory where system-wide add-ons are installed
64   
65`add_ons_dir_user`:
66    Directory where user add-ons are installed
67   
68`application_dir`:
69    Directory where applications can save their data.
70     
71`output_dir`:
72    Directory where Orange saves settings/data.
73   
74`default_reports_dir`:
75    Directory where Orange Canvas saves the reports.
76   
77`orange_settings_dir`:
78    Directory where Orange settings are saved.
79   
80`canvas_settings_dir`:
81    Directory where Orange Canvas settings are saved.
82   
83`widget_settings_dir`:
84    Directory where Orange Widgets settings are saved.
85   
86`buffer_dir`:
[10582]87    Directory where :obj:`Orange.utils.serverfiles` downloads are stored. 
[8042]88
89`orange_no_deprecated_members`:
90    If True all deprecated members in Orange 2.5 will not be available.
91     
92"""
93
94import os, sys
95import ConfigParser
[10838]96import pkg_resources
97from pkg_resources import working_set
[8042]98
99def _path_fix():
100    """ Fix some common problems with $(PATH) and sys.path
101    """
102    if os.name == "nt":
103        ## Move any miktex paths containing Qt's dll to the end of the %PATH%
104        paths = os.environ["PATH"].split(";")
105        paths.sort(lambda x,y: -1 if "PyQt4" in x else (1 if "miktex" in y and \
106                        os.path.exists(os.path.join(y, "QtCore4.dll")) else 0))
107        os.environ["PATH"] = ";".join(paths)
108       
109    if sys.platform == "darwin":
110        ## PyQt4 installed from fink is installed in %{FINK_ROOT}lib/qt4-mac/lib/python${PYVERSION}/site-packages"
111        posible_fink_pyqt4_path = os.path.join(sys.prefix, 
112                "lib/qt4-mac/lib/python" + sys.version[:3] + "/site-packages")
113        if os.path.exists(posible_fink_pyqt4_path):
114            sys.path.append(posible_fink_pyqt4_path)
115           
116_path_fix()
117
118def _get_default_env():
119    """ Return a dictionary with default Orange environment."""
[8044]120
[8042]121    version = "orange"
122    version_display = "Orange 2.5"
123    orange_no_deprecated_members = "False"
124   
[9685]125    install_dir = os.path.dirname(os.path.abspath(__file__)) # Orange/misc
126    install_dir = os.path.dirname(install_dir) # Orange/
127
[9691]128    doc_install_dir = os.path.join(install_dir, "doc")
[11085]129    dataset_install_dir = os.path.join(install_dir, "datasets")
[8042]130
131    canvas_install_dir = os.path.join(install_dir, "OrangeCanvas")
132    widget_install_dir = os.path.join(install_dir, "OrangeWidgets")
133    icons_install_dir = os.path.join(widget_install_dir, "icons")
134    add_ons_dir = os.path.join(install_dir, "add-ons")
135
136    home = os.path.expanduser("~/")
137   
138    if sys.platform == "win32":
139        if home[-1] == ":":
140            home += "\\"
141        application_dir = os.environ["APPDATA"]
142        output_dir = os.path.join(application_dir, version)
[9593]143        default_reports_dir = os.path.join(home, "My Documents")
[8042]144    elif sys.platform == "darwin":
145        application_dir = os.path.join(home, "Library", "Application Support")
146        output_dir = os.path.join(application_dir, version)
[9593]147        default_reports_dir = os.path.join(home, "Documents")
[8042]148    else:
149        application_dir = home
150        output_dir = os.path.join(home, "." + version)
[9593]151       
152        documents = os.path.join(home, "Documents")
153        # Need to make sure Documents folder actually exists
154        if os.path.exists(documents) and os.path.isdir(documents):
155            default_reports_dir = documents
156        else:
157            default_reports_dir = home
[8042]158
159    add_ons_dir_user = os.path.join(output_dir, "add-ons")
160
161    orange_settings_dir = output_dir
162    canvas_settings_dir = os.path.join(output_dir, "OrangeCanvasQt4")
163    widget_settings_dir = os.path.join(output_dir, "widgetSettingsQt4")
164   
165    if sys.platform == "darwin":
166        buffer_dir = os.path.join(home, "Library", "Caches", version)
167    else:
168        buffer_dir = os.path.join(output_dir, "buffer")
169
170    return locals()
171
172_ALL_ENV_OPTIONS = ["version", "version_display", "is_canvas_installed",
173                    "orange_no_deprecated_members"]
174
175_ALL_DIR_OPTIONS = ["install_dir", "canvas_install_dir",
176                    "widget_install_dir", "icons_install_dir",
[8073]177                    "doc_install_dir", "dataset_install_dir", 
[11010]178                    "add_ons_dir", "add_ons_dir_user",
[8042]179                    "application_dir", "output_dir", "default_reports_dir",
180                    "orange_settings_dir", "canvas_settings_dir",
181                    "widget_settings_dir", "buffer_dir"]
182
183def get_platform_option(section, option):
184    """ Return the platform specific configuration `option` from `section`.
185    """
186    try:
187        return parser.get(section + " " + sys.platform, option)
188    except Exception:
189        return parser.get(section, option)
[8044]190
191#options read from environment variables
192_ENVIRON_OPTIONS = [ "orange_no_deprecated_members" ]
193
[8042]194def _configure_env(defaults=None):
195    """ Apply the configuration files on the default environment
196    and return the instance of SafeConfigParser
197     
198    """
199    if defaults is None:
200        defaults = dict(os.environ)
201        defaults.update(_get_default_env())
[8044]202
203    for opt in _ENVIRON_OPTIONS:
204        if opt in os.environ:
205            defaults[opt] = os.environ[opt]
206   
[8042]207    parser = ConfigParser.SafeConfigParser(defaults)
[11410]208    global_cfg = os.path.join(defaults["install_dir"], "orng", "orangerc.cfg")
209
[8042]210    if not parser.read([global_cfg]):
211        pass
212#        import warnings
213#        warnings.warn("Could not read global orange configuration file.")
214
215    # In case the global_cfg does not exist or is empty
216    if not parser.has_section("directories"):
217        parser.add_section("directories")
218    if not parser.has_section("Orange"):
219        parser.add_section("Orange")
220       
221    platform = sys.platform
222    try:
223        application_dir = parser.get("directories " + platform, "application_dir")
224    except Exception:
225        application_dir = parser.get("directories", "application_dir")
226   
227    parser.read([os.path.join(application_dir, "orangerc.cfg"),
228                 os.path.expanduser("~/.orangerc.cfg")])
229   
230    return parser
231
232parser = _configure_env()
233
234for dirname in _ALL_DIR_OPTIONS:
235    globals()[dirname] = get_platform_option("directories", dirname)
236   
237
238if not os.path.isdir(widget_install_dir) or not os.path.isdir(widget_install_dir):
239    # Canvas and widgets are not installed
240    canvas_install_dir = None
241    widget_install_dir = None
242    canvas_settings_dir = None
243    widget_settings_dir = None
244    is_canvas_installed = False
245else:
246    is_canvas_installed = True
247   
248if not os.path.isdir(icons_install_dir):
249    icons_install_dir = ""
250   
251version = parser.get("Orange", "version")
252version_display = parser.get("Orange", "version_display")
253orange_no_deprecated_members = parser.getboolean("Orange", "orange_no_deprecated_members")
254version = get_platform_option("Orange", "version")
255   
256# Create the directories if missing
[9587]257# TODO: This are not needed if using orange without the GUI
258
[8042]259_directories_to_create = ["application_dir", "orange_settings_dir",
[9587]260        "buffer_dir", "widget_settings_dir", "canvas_settings_dir"]
[8042]261
262for dname in _directories_to_create:
263    dname = globals()[dname]
264    if dname is not None and not os.path.isdir(dname):
265        try:
266            os.makedirs(dname)        # Vista has roaming profiles that will say that this folder does not exist and will then fail to create it, because it exists...
267        except Exception:
268            pass
269       
270def samepath(path1, path2):
271    """ Do the paths path1 and path2 point to the same location.
272    """
273    return os.path.normcase(os.path.realpath(os.path.normpath(path1))) == \
274           os.path.normcase(os.path.realpath(os.path.normpath(path2)))
275
276def add_orange_directories_to_path():
277    """Add orange directory paths to sys.path."""
[9725]278
[10146]279    paths_to_add = [] #[install_dir]
[8042]280
281    if canvas_install_dir is not None:
282        paths_to_add.append(canvas_install_dir)
283
284    # Instead of doing this OrangeWidgets should be a package
285    if widget_install_dir is not None and os.path.isdir(widget_install_dir):
286        paths_to_add.append(widget_install_dir)
287        default_widgets_dirs = [os.path.join(widget_install_dir, x) \
288                                for x in os.listdir(widget_install_dir) \
289                                if os.path.isdir(os.path.join(widget_install_dir, x))]
290        paths_to_add.extend(default_widgets_dirs)
291
292    for path in paths_to_add:
293        if os.path.isdir(path) and not any([samepath(path, x) for x in sys.path]):
294            sys.path.insert(0, path)
295           
296add_orange_directories_to_path()
297directories = dict([(dname, globals()[dname]) for dname in _ALL_DIR_OPTIONS])
[10838]298
299def load_eggs(search_path):
300    distributions, errors = working_set.find_plugins(
301        pkg_resources.Environment(search_path)
302    )
303    map(working_set.add, distributions)
304
305    if errors:
306        import warnings
307        warnings.warn("Error loading eggs: %s" % (errors,))
308
309load_eggs([add_ons_dir_user])
Note: See TracBrowser for help on using the repository browser.