/
environ.py
229 lines (191 loc) · 7.92 KB
/
environ.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
import os
import sys
import time
import argparse
import contextlib
import functools
class RoamApp(object):
def __init__(self, sysargv, apppath, prefixpath, settingspath, libspath, i18npath, projectsroot):
self.sysargv = sysargv
self.apppath = apppath
self.prefixpath = prefixpath
self.settingspath = settingspath
self.approot = apppath
self.profileroot = apppath
self.libspath = libspath
self.i18npath = i18npath
self.app = None
self.translationFile = None
self.projectsroot = projectsroot
self._oldhook = sys.excepthook
self.sourcerun = False
self.config = None
self.args = argparse.Namespace()
def init(self, logo, title, **kwargs):
from qgis.core import QgsApplication
from qgis.PyQt.QtWidgets import QApplication
from qgis.PyQt.QtGui import QFont, QIcon
from qgis.PyQt.QtCore import QLocale, QTranslator
try:
import qgis.PyQt.QtSql
except ImportError:
pass
# In python3 we need to convert to a bytes object (or should
# QgsApplication accept a QString instead of const char* ?)
try:
argvb = list(map(os.fsencode, sys.argv))
except AttributeError:
argvb = sys.argv
self.app = QgsApplication(argvb, True)
QgsApplication.setPrefixPath(self.prefixpath, True)
QgsApplication.initQgis()
locale = QLocale.system().name()
self.translationFile = os.path.join(self.i18npath, '{0}.qm'.format(locale))
translator = QTranslator()
translator.load(self.translationFile, "i18n")
self.app.installTranslator(translator)
QApplication.setStyle("Plastique")
QApplication.setFont(QFont('Segoe UI'))
QApplication.setWindowIcon(QIcon(logo))
QApplication.setApplicationName(title)
import roam.editorwidgets.core
if "register_widgets" not in kwargs:
register_widgets = True
else:
register_widgets = False
if register_widgets:
roam.editorwidgets.core.registerallwidgets()
import roam.qgisfunctions
return self
@property
def data_folder(self):
return os.path.join(self.projectsroot, "_data")
def set_error_handler(self, errorhandler, logger):
sys.excepthook = functools.partial(self.excepthook, errorhandler)
self.logger = logger
def excepthook(self, errorhandler, exctype, value, traceback):
self.logger.error("Uncaught exception", exc_info=(exctype, value, traceback))
errorhandler(exctype, value, traceback)
def exec_(self):
self.app.exec_()
def exit(self):
sys.excepthook = self._oldhook
from qgis.core import QgsApplication
QgsApplication.exitQgis()
QgsApplication.quit()
def setActiveWindow(self, widget):
self.app.setActiveWindow(widget)
def dump_configinfo(self):
from qgis.core import QgsApplication, QgsProviderRegistry
import roam
from qgis.core import Qgis
config = []
config.append("====Providers===")
config.append(QgsProviderRegistry.instance().pluginList())
config.append("====Library paths===")
config.append('\n'.join(QgsApplication.libraryPaths()))
config.append("====Translation File===")
config.append(self.translationFile)
config.append("Roam Version: {}".format(roam.__version__))
config.append(u"QGIS Version: {}-{}".format(str(Qgis.QGIS_VERSION), str(Qgis.QGIS_DEV_VERSION)))
return '\n'.join(config)
def _setup(apppath=None, logo='', title='', **kwargs):
frozen = getattr(sys, "frozen", False)
RUNNING_FROM_FILE = not frozen
if not apppath:
apppath = os.path.dirname(os.path.realpath(sys.argv[0]))
import roam.utils
if RUNNING_FROM_FILE:
roam.utils.debug("Running from file")
roam.utils.debug("App path {0}".format(apppath))
i18npath = os.path.join(apppath, "i18n")
if os.name == 'posix':
prefixpath = os.environ.get('QGIS_PREFIX_PATH', '/usr/')
else:
prefixpath = os.environ['QGIS_PREFIX_PATH']
libspath = prefixpath
else:
# Set the PATH and GDAL_DRIVER_PATH for gdal to find the plugins.
# Not sure why we have to set these here but GDAL doesn't like it if we
# don't
roam.utils.debug("Running from package")
prefixpath = os.path.join(apppath, "lib", "qgis")
libspath = os.path.join(apppath, "lib", "roam")
i18npath = os.path.join(libspath, "i18n")
projectroot = os.path.join(apppath, "projects")
profileroot = apppath
## Setup default paths for profile location
try:
settingspath = kwargs['config']
except KeyError:
settingspath = os.path.join(apppath, "roam.config")
if not os.path.exists(settingspath):
settingspath = os.path.join(apppath, "settings.config")
parser = argparse.ArgumentParser(description="Roam")
parser.add_argument('--load-first', action="store_true", help='Auto load the first project that was added')
parser.add_argument('--config', metavar='c', type=str, default=settingspath, help='Path to Roam.config')
parser.add_argument('--profile', metavar='p', type=str, default=profileroot,
help='Root folder for roam.config, and roam settings'
'including plugins and projects')
parser.add_argument('projectsroot', nargs='?', default=projectroot, help="Root location of projects. Will override"
"default projects folder path")
args, unknown = parser.parse_known_args()
projectroot = args.projectsroot
# Profile will override the projectroot
if args.profile:
profileroot = args.profile
projectroot = os.path.join(args.profile, "projects")
settingspath = os.path.join(args.profile, "roam.config")
else:
settingspath = args.config
# This will also make the higher level profile folder for use
if not os.path.exists(projectroot):
os.makedirs(projectroot)
pluginfolder = os.path.join(profileroot, "plugins")
if not os.path.exists(pluginfolder):
os.makedirs(pluginfolder)
import roam.config
if isinstance(args.config, dict):
roam.config.settings = args.config
else:
if not os.path.exists(settingspath):
## Make a new setting file on load if it's not found.
roam.config.save(settingspath)
roam.config.load(settingspath)
app = RoamApp(sys.argv, apppath, prefixpath, settingspath, libspath, i18npath, projectroot).init(logo, title, **kwargs)
# Pass the command line args down to the app
app.args = args
app.sourcerun = RUNNING_FROM_FILE
app.profileroot = profileroot
roam.utils.info("Profile Root: {0}".format(app.profileroot))
roam.utils.info("Project Root: {0}".format(app.projectsroot))
roam.utils.info("Settings file: {0}".format(settingspath))
return app
@contextlib.contextmanager
def setup(apppath=None, logo='', title=''):
"""
Setup the environment for Roam.
Returns the QGIS prefix path and settings path.
"""
import roam.utils
import roam.config
roam.utils.info("Loading Roam")
start = time.time()
app = _setup(apppath, logo, title)
roam.utils.info("Roam Loaded in {}".format(str(time.time() - start)))
roam.utils.info(app.dump_configinfo())
yield app
app.exec_()
app.exit()
def projectpaths(baseprojectpath, settings={}):
# Add the default paths
paths = []
paths.append(baseprojectpath)
paths.extend(settings.get('projectpaths', []))
for path in paths:
rootfolder = os.path.abspath(os.path.join(path, '..'))
sys.path.append(rootfolder)
sys.path.extend(paths)
import roam.utils
roam.utils.log("Project locations:{}".format(paths))
return paths