source: grass/branches/releasebranch_7_0/lib/init/grass.py

Last change on this file was 70183, checked in by neteler, 8 years ago

Happy New Year

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-python
File size: 50.2 KB
Line 
1#!/usr/bin/env python
2#############################################################################
3#
4# MODULE: GRASS initialization script
5# AUTHOR(S): Original author unknown - probably CERL
6# Andreas Lange <andreas.lange rhein-main.de>
7# Huidae Cho <grass4u gmail.com>
8# Justin Hickey <jhickey hpcc.nectec.or.th>
9# Markus Neteler <neteler osgeo.org>
10# Hamish Bowman <hamish_b yahoo.com>
11#
12# GRASS 7: converted to Python (based on init.sh shell
13# script from GRASS 6) by Glynn Clements
14# Martin Landa <landa.martin gmail.com>
15# Luca Delucchi <lucadeluge gmail.com>
16# PURPOSE: Sets up environment variables, parses any remaining
17# command line options for setting the GISDBASE, LOCATION,
18# and/or MAPSET. Finally it starts GRASS with the appropriate
19# user interface and cleans up after it is finished.
20# COPYRIGHT: (C) 2000-2017 by the GRASS Development Team
21#
22# This program is free software under the GNU General
23# Public License (>=v2). Read the file COPYING that
24# comes with GRASS for details.
25#
26#############################################################################
27
28import sys
29import os
30import atexit
31import string
32import subprocess
33import re
34import platform
35import tempfile
36
37# Variables substituted during build process
38if 'GISBASE' in os.environ:
39 gisbase = os.environ['GISBASE']
40else:
41 gisbase = "@GISBASE@"
42cmd_name = "@START_UP@"
43grass_version = "@GRASS_VERSION_NUMBER@"
44ld_library_path_var = '@LD_LIBRARY_PATH_VAR@'
45if 'GRASS_PROJSHARE' in os.environ:
46 config_projshare = os.environ['GRASS_PROJSHARE']
47else:
48 config_projshare = "@CONFIG_PROJSHARE@"
49
50# configuration directory
51grass_env_file = None # see check_shell()
52if sys.platform == 'win32':
53 grass_config_dirname = "GRASS7"
54 grass_config_dir = os.path.join(os.getenv('APPDATA'), grass_config_dirname)
55else:
56 grass_config_dirname = ".grass7"
57 grass_config_dir = os.path.join(os.getenv('HOME'), grass_config_dirname)
58
59gisbase = os.path.normpath(gisbase)
60
61# i18N
62import gettext
63gettext.install('grasslibs', os.path.join(gisbase, 'locale'))
64
65tmpdir = None
66lockfile = None
67remove_lockfile = True
68location = None
69create_new = None
70grass_gui = None
71exit_grass = None
72
73def warning(text):
74 sys.stderr.write(_("WARNING") + ': ' + text + os.linesep)
75
76
77def try_remove(path):
78 try:
79 os.remove(path)
80 except:
81 pass
82
83
84def try_rmdir(path):
85 try:
86 os.rmdir(path)
87 except:
88 pass
89
90
91def clean_env():
92 env_curr = read_gisrc()
93 env_new = {}
94 for k,v in env_curr.iteritems():
95 if 'MONITOR' in k or k.endswith('PID'):
96 continue
97 env_new[k] = v
98
99 write_gisrc(env_new)
100
101
102def cleanup_dir(path):
103 if not path:
104 return
105
106 for root, dirs, files in os.walk(path, topdown=False):
107 for name in files:
108 try_remove(os.path.join(root, name))
109 for name in dirs:
110 try_rmdir(os.path.join(root, name))
111
112
113def cleanup():
114 tmpdir, lockfile, remove_lockfile
115 # all exits after setting up tmp dirs (system/location) should
116 # also tidy it up
117 cleanup_dir(tmpdir)
118 try_rmdir(tmpdir)
119 if location:
120 tmpdir_loc = os.path.join(location, ".tmp")
121 cleanup_dir(tmpdir_loc)
122 try_rmdir(tmpdir_loc)
123
124 # remove lock-file if requested
125 if lockfile and remove_lockfile:
126 try_remove(lockfile)
127
128
129def fatal(msg):
130 sys.stderr.write("%s: " % _('ERROR') + msg + os.linesep)
131 sys.exit(_("Exiting..."))
132
133
134def message(msg):
135 sys.stderr.write(msg + "\n")
136 sys.stderr.flush()
137
138
139def readfile(path):
140 f = open(path, 'r')
141 s = f.read()
142 f.close()
143 return s
144
145
146def writefile(path, s):
147 f = open(path, 'w')
148 f.write(s)
149 f.close()
150
151
152def call(cmd, **kwargs):
153 if windows:
154 kwargs['shell'] = True
155 return subprocess.call(cmd, **kwargs)
156
157
158def Popen(cmd, **kwargs):
159 if windows:
160 kwargs['shell'] = True
161 return subprocess.Popen(cmd, **kwargs)
162
163
164def gfile(*args):
165 return os.path.join(gisbase, *args)
166
167help_text = r"""GRASS GIS %s
168Geographic Resources Analysis Support System (GRASS GIS).
169
170%s:
171 $CMD_NAME [-h | -help | --help] [-v | --version] [-c | -c geofile | -c EPSG:code[:datum_trans]]
172 [-e] [-text | -gui] [--config param]
173 [[[<GISDBASE>/]<LOCATION_NAME>/]<MAPSET>]
174
175%s:
176 -h or -help or --help %s
177 -v or --version %s
178 -c %s
179 -e %s
180 -text %s
181 %s
182 -gtext %s
183 %s
184 -gui %s
185 %s
186 --config %s
187 %s
188
189%s:
190 GISDBASE %s
191 LOCATION_NAME %s
192 MAPSET %s
193
194 GISDBASE/LOCATION_NAME/MAPSET %s
195
196%s:
197 GRASS_GUI %s
198 GRASS_HTML_BROWSER %s
199 GRASS_ADDON_PATH %s
200 GRASS_ADDON_BASE %s
201 GRASS_BATCH_JOB %s
202 GRASS_PYTHON %s
203""" % (grass_version,
204 _("Usage"),
205 _("Flags"),
206 _("print this help message"),
207 _("show version information and exit"),
208 _("create given database, location or mapset if it doesn't exist"),
209 _("exit after creation of location or mapset. Only with -c flag"),
210 _("use text based interface (skip welcome screen)"),
211 _("and set as default"),
212 _("use text based interface (show welcome screen)"),
213 _("and set as default"),
214 _("use $DEFAULT_GUI graphical user interface"),
215 _("and set as default"),
216 _("print GRASS configuration parameters"),
217 _("options: arch,build,compiler,path,revision"),
218 _("Parameters"),
219 _("initial database (path to GIS data)"),
220 _("initial location"),
221 _("initial mapset"),
222 _("fully qualified initial mapset directory"),
223 _("Environment variables relevant for startup"),
224 _("select GUI (text, gui)"),
225 _("set html web browser for help pages"),
226 _("set additional path(s) to local GRASS modules or user scripts"),
227 _("set additional GISBASE for locally installed GRASS Addons"),
228 _("shell script to be processed as batch job"),
229 _("set python shell name to override 'python'"))
230
231
232def help_message():
233 t = string.Template(help_text)
234 s = t.substitute(CMD_NAME=cmd_name, DEFAULT_GUI=default_gui)
235 sys.stderr.write(s)
236
237
238def create_tmp():
239 global tmpdir
240 ## use $TMPDIR if it exists, then $TEMP, otherwise /tmp
241 tmp = os.getenv('TMPDIR')
242 if not tmp:
243 tmp = os.getenv('TEMP')
244 if not tmp:
245 tmp = os.getenv('TMP')
246 if not tmp:
247 tmp = tempfile.gettempdir()
248 if tmp:
249 tmpdir = os.path.join(tmp, "grass7-%(user)s-%(lock)s" % {'user': user,
250 'lock': gis_lock})
251 try:
252 os.mkdir(tmpdir, 0700)
253 except:
254 tmp = None
255 if not tmp:
256 for ttmp in ("/tmp", "/var/tmp", "/usr/tmp"):
257 tmp = ttmp
258 tmpdir = os.path.join(tmp, "grass7-%(user)s-%(lock)s" % {
259 'user': user, 'lock': gis_lock})
260 try:
261 os.mkdir(tmpdir, 0700)
262 except:
263 tmp = None
264 if tmp:
265 break
266 if not tmp:
267 fatal(_("Unable to create temporary directory <grass7-%(user)s-" \
268 "%(lock)s>! Exiting.") % {'user': user, 'lock': gis_lock})
269
270
271def create_gisrc():
272 global gisrc, gisrcrc
273 # Set the session grassrc file
274 gisrc = os.path.join(tmpdir, "gisrc")
275 os.environ['GISRC'] = gisrc
276
277 # remove invalid GISRC file to avoid disturbing error messages:
278 try:
279 s = readfile(gisrcrc)
280 if "UNKNOWN" in s:
281 try_remove(gisrcrc)
282 s = None
283 except:
284 s = None
285
286 # Copy the global grassrc file to the session grassrc file
287 if s:
288 writefile(gisrc, s)
289
290
291def read_gisrc():
292 kv = {}
293 try:
294 f = open(gisrc, 'r')
295 except IOError:
296 return kv
297
298 for line in f:
299 try:
300 k, v = line.split(':', 1)
301 except ValueError as e:
302 sys.stderr.write(_("ERROR: Invalid line in RC file: '%s' (%s)\n") % (line, e))
303 continue
304 kv[k.strip()] = v.strip()
305 f.close()
306
307 return kv
308
309
310def read_env_file(path):
311 kv = {}
312 f = open(path, 'r')
313 for line in f:
314 k, v = line.split(':', 1)
315 kv[k.strip()] = v.strip()
316 f.close()
317 return kv
318
319
320def write_gisrc(kv):
321 f = open(gisrc, 'w')
322 for k, v in kv.iteritems():
323 f.write("%s: %s\n" % (k, v))
324 f.close()
325
326
327def read_gui():
328 global grass_gui
329 # At this point the GRASS user interface variable has been set from the
330 # command line, been set from an external environment variable, or is
331 # not set. So we check if it is not set
332 if not grass_gui:
333 # Check for a reference to the GRASS user interface in the grassrc file
334 if os.access(gisrc, os.R_OK):
335 kv = read_gisrc()
336 if 'GRASS_GUI' in os.environ:
337 grass_gui = os.environ['GRASS_GUI']
338 elif 'GUI' in kv:
339 grass_gui = kv['GUI']
340 elif 'GRASS_GUI' in kv:
341 # For backward compatibility (GRASS_GUI renamed to GUI)
342 grass_gui = kv['GRASS_GUI']
343 else:
344 # Set the GRASS user interface to the default if needed
345 grass_gui = default_gui
346
347 if not grass_gui:
348 grass_gui = default_gui
349
350 if grass_gui == 'gui':
351 grass_gui = default_gui
352
353 # FIXME oldtcltk, gis.m, d.m no longer exist
354 if grass_gui in ['d.m', 'gis.m', 'oldtcltk', 'tcltk']:
355 warning(_("GUI <%s> not supported in this version") % grass_gui)
356 grass_gui = default_gui
357
358
359def path_prepend(dir, var):
360 path = os.getenv(var)
361 if path:
362 path = dir + os.pathsep + path
363 else:
364 path = dir
365 os.environ[var] = path
366
367
368def path_append(dir, var):
369 path = os.getenv(var)
370 if path:
371 path = path + os.pathsep + dir
372 else:
373 path = dir
374 os.environ[var] = path
375
376
377def set_paths():
378 # addons (path)
379 addon_path = os.getenv('GRASS_ADDON_PATH')
380 if addon_path:
381 for path in addon_path.split(os.pathsep):
382 path_prepend(addon_path, 'PATH')
383
384 # addons (base)
385 addon_base = os.getenv('GRASS_ADDON_BASE')
386 if not addon_base:
387 addon_base = os.path.join(grass_config_dir, 'addons')
388 os.environ['GRASS_ADDON_BASE'] = addon_base
389 if not windows:
390 path_prepend(os.path.join(addon_base, 'scripts'), 'PATH')
391 path_prepend(os.path.join(addon_base, 'bin'), 'PATH')
392
393 # standard installation
394 if not windows:
395 path_prepend(gfile('scripts'), 'PATH')
396 path_prepend(gfile('bin'), 'PATH')
397
398 # Set PYTHONPATH to find GRASS Python modules
399 if os.path.exists(gfile('gui', 'wxpython')):
400 path_prepend(gfile('gui', 'wxpython'), 'PYTHONPATH')
401 if os.path.exists(gfile('etc', 'python')):
402 path_prepend(gfile('etc', 'python'), 'PYTHONPATH')
403
404 # set path for the GRASS man pages
405 grass_man_path = os.path.join(gisbase, 'docs', 'man')
406 addons_man_path = os.path.join(addon_base, 'docs', 'man')
407 man_path = os.getenv('MANPATH')
408 sys_man_path = None
409 if man_path:
410 path_prepend(addons_man_path, 'MANPATH')
411 path_prepend(grass_man_path, 'MANPATH')
412 else:
413 try:
414 nul = open(os.devnull, 'w')
415 p = Popen(['manpath'], stdout=subprocess.PIPE, stderr=nul)
416 nul.close()
417 s = p.stdout.read()
418 p.wait()
419 sys_man_path = s.strip()
420 except:
421 pass
422
423 if sys_man_path:
424 os.environ['MANPATH'] = sys_man_path
425 path_prepend(addons_man_path, 'MANPATH')
426 path_prepend(grass_man_path, 'MANPATH')
427 else:
428 os.environ['MANPATH'] = addons_man_path
429 path_prepend(grass_man_path, 'MANPATH')
430
431
432def find_exe(pgm):
433 for dir in os.getenv('PATH').split(os.pathsep):
434 path = os.path.join(dir, pgm)
435 if os.access(path, os.X_OK):
436 return path
437 return None
438
439
440def set_defaults():
441 # GRASS_PAGER
442 if not os.getenv('GRASS_PAGER'):
443 if find_exe("more"):
444 pager = "more"
445 elif find_exe("less"):
446 pager = "less"
447 elif windows:
448 pager = "more"
449 else:
450 pager = "cat"
451 os.environ['GRASS_PAGER'] = pager
452
453 # GRASS_PYTHON
454 if not os.getenv('GRASS_PYTHON'):
455 if windows:
456 os.environ['GRASS_PYTHON'] = "python.exe"
457 else:
458 os.environ['GRASS_PYTHON'] = "python"
459
460 # GRASS_GNUPLOT
461 if not os.getenv('GRASS_GNUPLOT'):
462 os.environ['GRASS_GNUPLOT'] = "gnuplot -persist"
463
464 # GRASS_PROJSHARE
465 if not os.getenv('GRASS_PROJSHARE'):
466 os.environ['GRASS_PROJSHARE'] = config_projshare
467
468
469def set_browser():
470 # GRASS_HTML_BROWSER
471 browser = os.getenv('GRASS_HTML_BROWSER')
472 if not browser:
473 if macosx:
474 # OSX doesn't execute browsers from the shell PATH - route thru a
475 # script
476 browser = gfile('etc', "html_browser_mac.sh")
477 os.environ['GRASS_HTML_BROWSER_MACOSX'] = "-b com.apple.helpviewer"
478
479 if windows:
480 browser = "start"
481 elif cygwin:
482 browser = "explorer"
483 else:
484 # the usual suspects
485 browsers = ["xdg-open", "x-www-browser", "htmlview", "konqueror", "mozilla",
486 "mozilla-firefox", "firefox", "iceweasel", "opera",
487 "netscape", "dillo", "lynx", "links", "w3c"]
488 for b in browsers:
489 if find_exe(b):
490 browser = b
491 break
492
493 elif macosx:
494 # OSX doesn't execute browsers from the shell PATH - route thru a
495 # script
496 os.environ['GRASS_HTML_BROWSER_MACOSX'] = "-b %s" % browser
497 browser = gfile('etc', "html_browser_mac.sh")
498
499 if not browser:
500 warning(_("Searched for a web browser, but none found"))
501 # even so we set konqueror to make lib/gis/parser.c happy:
502 browser = "konqueror"
503
504 os.environ['GRASS_HTML_BROWSER'] = browser
505
506
507def create_initial_gisrc():
508 # for convenience, define GISDBASE as pwd:
509 s = r"""GISDBASE: %s
510LOCATION_NAME: <UNKNOWN>
511MAPSET: <UNKNOWN>
512""" % os.getcwd()
513 writefile(gisrc, s)
514
515
516def check_gui():
517 global grass_gui, wxpython_base
518 # Check if we are running X windows by checking the DISPLAY variable
519 if os.getenv('DISPLAY') or windows or macosx:
520 # Check if python is working properly
521 if grass_gui in ('wxpython', 'gtext'):
522 nul = open(os.devnull, 'w')
523 p = Popen([os.environ['GRASS_PYTHON']], stdin=subprocess.PIPE,
524 stdout=nul, stderr=nul)
525 nul.close()
526 p.stdin.write("variable=True")
527 p.stdin.close()
528 p.wait()
529 if p.returncode == 0:
530 # Set the wxpython base directory
531 wxpython_base = gfile("gui", "wxpython")
532 else:
533 # Python was not found - switch to text interface mode
534 warning(_("The python command does not work as expected!\n"
535 "Please check your GRASS_PYTHON environment variable.\n"
536 "Use the -help option for details.\n"
537 "Switching to text based interface mode.\n\n"
538 "Hit RETURN to continue.\n"))
539 sys.stdin.readline()
540 grass_gui = 'text'
541
542 else:
543 # Display a message if a graphical interface was expected
544 if grass_gui != 'text':
545 # Set the interface mode to text
546 warning(_("It appears that the X Windows system is not active.\n"
547 "A graphical based user interface is not supported.\n"
548 "Switching to text based interface mode.\n\n"
549 "Hit RETURN to continue"""))
550 sys.stdin.readline()
551 grass_gui = 'text'
552
553 # Save the user interface variable in the grassrc file - choose a temporary
554 # file name that should not match another file
555 if os.access(gisrc, os.F_OK):
556 kv = read_gisrc()
557 kv['GUI'] = grass_gui
558 write_gisrc(kv)
559
560
561def non_interactive(arg, geofile=None):
562 global gisdbase, location_name, mapset, location
563 # Try non-interactive startup
564 l = None
565
566 if arg == '-':
567 if location:
568 l = location
569 else:
570 l = arg
571
572 if l:
573 if l == '.':
574 l = os.getcwd()
575 elif not os.path.isabs(l):
576 l = os.path.abspath(l)
577
578 l, mapset = os.path.split(l)
579 if not mapset:
580 l, mapset = os.path.split(l)
581 l, location_name = os.path.split(l)
582 gisdbase = l
583
584 if gisdbase and location_name and mapset:
585 location = os.path.join(gisdbase, location_name, mapset)
586
587 # check if 'location' is a valid GRASS location/mapset
588 if not os.access(os.path.join(location, "WIND"), os.R_OK):
589 if not create_new:
590 # 'location' is not valid, check if 'location_name' is
591 # a valid GRASS location
592 if not os.path.exists(os.path.join(gisdbase, location_name)):
593 fatal(_("Location <%s> doesn't exist") % os.path.join(gisdbase, location_name))
594 elif 'PERMANENT' not in os.listdir(os.path.join(gisdbase, location_name)) or \
595 not os.path.isdir(os.path.join(gisdbase, location_name, 'PERMANENT')) or \
596 not os.path.isfile((os.path.join(gisdbase, location_name, 'PERMANENT',
597 'DEFAULT_WIND'))):
598 fatal(_("ERROR: <%s> is not a valid GRASS location") % \
599 os.path.join(gisdbase, location_name))
600 else:
601 fatal(_("Mapset <%s> doesn't exist in GRASS location <%s>. "
602 "A new mapset can be created by '-c' switch.") % (mapset, location_name))
603
604 else:
605 # 'location' is not valid, the user wants to create
606 # mapset on the fly
607 if not os.access(os.path.join(gisdbase, location_name,
608 "PERMANENT",
609 "DEFAULT_WIND"), os.F_OK):
610 # 'location_name' is not a valid GRASS location,
611 # create new location and 'PERMANENT' mapset
612 gisdbase = os.path.join(gisdbase, location_name)
613 location_name = mapset
614 mapset = "PERMANENT"
615 if os.access(os.path.join(os.path.join(gisdbase,
616 location_name,
617 "PERMANENT",
618 "DEFAULT_WIND")),
619 os.F_OK):
620 fatal(_("Failed to create new location. "
621 "The location <%s> already exists." % location_name))
622
623 if gfile('etc', 'python') not in sys.path:
624 sys.path.append(gfile('etc', 'python'))
625 from grass.script import core as grass
626
627 try:
628 if geofile and geofile.upper().find('EPSG:') > -1:
629 # create location using EPSG code
630 epsg = geofile.split(':', 1)[1]
631 if ':' in epsg:
632 epsg, datum_trans = epsg.split(':', 1)
633 else:
634 datum_trans = None
635 grass.create_location(gisdbase, location_name,
636 epsg=epsg, datum_trans=datum_trans)
637 else:
638 # create location using georeferenced file
639 grass.create_location(gisdbase, location_name,
640 filename=geofile)
641 except grass.ScriptError as e:
642 fatal(e.value.strip('"').strip("'").replace('\\n',
643 os.linesep))
644 else:
645 # 'location_name' is a valid GRASS location,
646 # create new mapset
647 os.mkdir(location)
648 # copy PERMANENT/DEFAULT_WIND to <mapset>/WIND
649 s = readfile(os.path.join(gisdbase, location_name,
650 "PERMANENT", "DEFAULT_WIND"))
651 writefile(os.path.join(location, "WIND"), s)
652 message(_("Missing WIND file fixed"))
653
654 if os.access(gisrc, os.R_OK):
655 kv = read_gisrc()
656 else:
657 kv = {}
658
659 kv['GISDBASE'] = gisdbase
660 kv['LOCATION_NAME'] = location_name
661 kv['MAPSET'] = mapset
662 write_gisrc(kv)
663 else:
664 fatal(_("GISDBASE, LOCATION_NAME and MAPSET variables not set properly.\n"
665 "Interactive startup needed."))
666
667
668def set_data():
669 # User selects LOCATION and MAPSET if not set
670 if not location:
671 # Check for text interface
672 if grass_gui == 'text':
673 pass
674 # Check for GUI
675 elif grass_gui in ('gtext', 'wxpython'):
676 if not os.path.exists(gfile(wxpython_base, "gis_set.py")):
677 # No GUI available, update gisrc file
678 fatal(_("<{}> requested, but not available. Run GRASS in text "
679 "mode (-text) or install missing package (usually "
680 "'grass-gui').").format(grass_gui))
681 else:
682 gui_startup(grass_gui == 'gtext')
683 else:
684 # Shouldn't need this but you never know
685 fatal(_("Invalid user interface specified - <%s>. "
686 "Use the --help option to see valid interface names.") % grass_gui)
687
688
689def gui_startup(wscreen_only = False):
690 if grass_gui in ('wxpython', 'gtext'):
691 ret = call([os.getenv('GRASS_PYTHON'), gfile(wxpython_base, "gis_set.py")])
692
693 if ret == 0:
694 pass
695 elif ret == 1:
696 # The startup script printed an error message so wait
697 # for user to read it
698 message(_("Error in GUI startup. If necessary, please "
699 "report this error to the GRASS developers.\n"
700 "Switching to text mode now.\n\n"
701 "Hit RETURN to continue..."))
702 sys.stdin.readline()
703
704 os.execlp(cmd_name, "-text")
705 sys.exit(1)
706 elif ret == 2:
707 # User wants to exit from GRASS
708 message(_("Received EXIT message from GUI.\nGRASS is not started. Bye."))
709 sys.exit(0)
710 else:
711 fatal(_("Invalid return code from GUI startup script.\n"
712 "Please advise GRASS developers of this error."))
713
714
715def load_gisrc():
716 global gisdbase, location_name, mapset, location
717 kv = read_gisrc()
718 gisdbase = kv.get('GISDBASE')
719 location_name = kv.get('LOCATION_NAME')
720 mapset = kv.get('MAPSET')
721 if not gisdbase or not location_name or not mapset:
722 fatal(_("Error reading data path information from g.gisenv.\n"
723 "GISDBASE=%(gisbase)s\n"
724 "LOCATION_NAME=%(location)s\n"
725 "MAPSET=%(mapset)s\n\n"
726 "Check the <%s(file)> file." % \
727 {'gisbase': gisdbase, 'location': location_name,
728 'mapset': mapset, 'file': gisrcrc}))
729
730 location = os.path.join(gisdbase, location_name, mapset)
731
732
733# load environmental variables from grass_env_file
734def load_env():
735 if not os.access(grass_env_file, os.R_OK):
736 return
737
738 for line in readfile(grass_env_file).split(os.linesep):
739 try:
740 k, v = map(lambda x: x.strip(), line.strip().split(' ', 1)[1].split('=', 1))
741 except:
742 continue
743
744 evalue = os.getenv(k)
745 if evalue:
746 if k == 'GRASS_ADDON_PATH':
747 os.environ[k] = evalue + os.pathsep + v
748 else:
749 warning(_("Environmental variable '%s' already set, ignoring value '%s'") % \
750 (k, v))
751 else:
752 os.environ[k] = v
753
754 # Allow for mixed ISIS-GRASS Environment
755 if os.getenv('ISISROOT'):
756 isis = os.getenv('ISISROOT')
757 os.environ['ISIS_LIB'] = isis + os.sep + "lib"
758 os.environ['ISIS_3RDPARTY'] = isis + os.sep + "3rdParty" + os.sep + "lib"
759 os.environ['QT_PLUGIN_PATH'] = isis + os.sep + "3rdParty" + os.sep + "plugins"
760 #os.environ['ISIS3DATA'] = isis + "$ISIS3DATA"
761 libpath = os.getenv('LD_LIBRARY_PATH', '')
762 isislibpath = os.getenv('ISIS_LIB')
763 isis3rdparty = os.getenv('ISIS_3RDPARTY')
764 os.environ['LD_LIBRARY_PATH'] = libpath + os.pathsep + isislibpath + os.pathsep + isis3rdparty
765
766def set_language():
767 # This function is used to override system default language and locale
768 # Such override can be requested only from wxGUI
769 # An override if user has provided correct environmental variables as
770 # LC_MESSAGES or LANG is not necessary.
771 # Unfortunately currently a working solution for Windows is lacking
772 # thus it always on Vista and XP will print an error.
773 # See discussion for Windows not following its own documentation and
774 # not accepting ISO codes as valid locale identifiers http://bugs.python.org/issue10466
775 import locale
776
777 language = 'None' # Such string sometimes is present in wx file
778 encoding = None
779
780 # Override value is stored in wxGUI preferences file.
781 # As it's the only thing required, we'll just grep it out.
782 try:
783 fd = open(os.path.join(grass_config_dir, 'wx'), 'r')
784 except:
785 # Even if there is no override, we still need to set locale.
786 pass
787 else:
788 for line in fd:
789 if re.search('^language', line):
790 line = line.rstrip(' %s' % os.linesep)
791 language = ''.join(line.split(';')[-1:])
792 break
793 fd.close()
794
795 if language == 'None' or language == '' or not language:
796 # Language override is disabled (system language specified)
797 # As by default program runs with C locale, but users expect to
798 # have their default locale, we'll just set default locale
799 try:
800 locale.setlocale(locale.LC_ALL, '')
801 except locale.Error as e:
802 # If we get here, system locale settings are terribly wrong
803 # There is no point to continue as GRASS/Python will fail
804 # in some other unpredictable way.
805 print("System locale is not usable (LC_ALL variable not defined). "
806 "It indicates misconfigured environment.")
807 print("Reported error message: %s" % e)
808 ## TOO DRASTIC: sys.exit("Fix system locale settings and then try again.")
809 locale.setlocale(locale.LC_ALL, 'C')
810 warning(_("Default locale settings are missing. GRASS running with C locale."))
811
812 language, encoding = locale.getdefaultlocale()
813 if not language:
814 warning(_("Default locale settings are missing. GRASS running with C locale."))
815 return
816
817 else:
818 if grass_debug:
819 message(_("A language override has been requested. Trying to switch GRASS into '%s'...") % language)
820
821 try:
822 locale.setlocale(locale.LC_ALL, language)
823 except locale.Error as e:
824 try:
825 # Locale lang.encoding might be missing. Let's try
826 # UTF-8 encoding before giving up as on Linux systems
827 # lang.UTF-8 locales are more common than legacy
828 # ISO-8859 ones.
829 encoding = 'UTF-8'
830 normalized = locale.normalize('%s.%s' % (language, encoding))
831 locale.setlocale(locale.LC_ALL, normalized)
832 except locale.Error as e:
833 # The last attempt...
834 try:
835 encoding = locale.getpreferredencoding()
836 normalized = locale.normalize('%s.%s' % (language, encoding))
837 locale.setlocale(locale.LC_ALL, normalized)
838 except locale.Error as e:
839 # If we got so far, attempts to set up language and locale have failed
840 # on this system
841 sys.stderr.write("Failed to enforce user specified language '%s' with error: '%s'\n" % (language, e))
842 sys.stderr.write("A LANGUAGE environmental variable has been set.\nPart of messages will be displayed in the requested language.\n")
843 # Even if setting locale will fail, let's set LANG in a hope,
844 # that UI will use it GRASS texts will be in selected language,
845 # system messages (i.e. OK, Cancel etc.) - in system default
846 # language
847 os.environ['LANGUAGE'] = language
848 return
849
850 # Set up environment for subprocesses
851 os.environ['LANGUAGE'] = language
852 os.environ['LANG'] = language
853 if encoding:
854 normalized = locale.normalize('%s.%s' % (language, encoding))
855 else:
856 normalized = language
857 for lc in ('LC_CTYPE', 'LC_MESSAGES', 'LC_TIME', 'LC_COLLATE',
858 'LC_MONETARY', 'LC_PAPER', 'LC_NAME', 'LC_ADDRESS',
859 'LC_TELEPHONE', 'LC_MEASUREMENT', 'LC_IDENTIFICATION'):
860 os.environ[lc] = normalized
861
862 # Some code in GRASS might not like other decimal separators than .
863 # Other potential sources for problems are: LC_TIME LC_CTYPE
864 locale.setlocale(locale.LC_NUMERIC, 'C')
865 os.environ['LC_NUMERIC'] = 'C'
866 if os.getenv('LC_ALL'):
867 del os.environ['LC_ALL'] # Remove LC_ALL to not override LC_NUMERIC
868
869 # From now on enforce the new language
870 if encoding:
871 gettext.install('grasslibs', os.path.join(gisbase, 'locale'), codeset=encoding)
872 else:
873 gettext.install('grasslibs', os.path.join(gisbase, 'locale'))
874
875def check_lock():
876 global lockfile
877 if not os.path.exists(location):
878 fatal(_("Path '%s' doesn't exist") % location)
879 if not os.access(location, os.W_OK):
880 error = _("Path '%s' not accessible.") % location
881 stat_info = os.stat(location)
882 mapset_uid = stat_info.st_uid
883 if mapset_uid != os.getuid():
884 # GTC %s is mapset's folder path
885 error = "%s\n%s" % (error, _("You are not the owner of '%s'.") % location)
886 fatal(error)
887
888 # Check for concurrent use
889 lockfile = os.path.join(location, ".gislock")
890 ret = call([gfile("etc", "lock"), lockfile, "%d" % os.getpid()])
891 if ret == 0:
892 msg = None
893 elif ret == 2:
894 msg = _("%(user)s is currently running GRASS in selected mapset (" \
895 "file %(file)s found). Concurrent use not allowed." % {
896 'user': user, 'file': lockfile})
897 else:
898 msg = _("Unable to properly access '%s'.\n"
899 "Please notify system personel.") % lockfile
900
901 if msg:
902 if grass_gui == "wxpython":
903 call([os.getenv('GRASS_PYTHON'), gfile(wxpython_base, "gis_set_error.py"), msg])
904 else:
905 global remove_lockfile
906 remove_lockfile = False
907 fatal(msg)
908
909
910def make_fontcap():
911 fc = os.getenv('GRASS_FONT_CAP')
912 if fc and not os.access(fc, os.R_OK):
913 message(_("Building user fontcap..."))
914 call(["g.mkfontcap"])
915
916
917def check_shell():
918 global sh, shellname, grass_env_file
919 # cygwin has many problems with the shell setup
920 # below, so i hardcoded everything here.
921 if sys.platform == 'cygwin':
922 sh = "cygwin"
923 shellname = "GNU Bash (Cygwin)"
924 os.environ['SHELL'] = "/usr/bin/bash.exe"
925 os.environ['OSTYPE'] = "cygwin"
926 else:
927 # in docker the 'SHELL' variable may not be
928 # visible in a Python session
929 try:
930 sh = os.path.basename(os.getenv('SHELL'))
931 except:
932 sh = 'sh'
933 os.environ['SHELL'] = sh
934
935 if windows and sh:
936 sh = os.path.splitext(sh)[0]
937
938 if sh == "ksh":
939 shellname = "Korn Shell"
940 elif sh == "csh":
941 shellname = "C Shell"
942 elif sh == "tcsh":
943 shellname = "TC Shell"
944 elif sh == "bash":
945 shellname = "Bash Shell"
946 elif sh == "sh":
947 shellname = "Bourne Shell"
948 elif sh == "zsh":
949 shellname = "Z Shell"
950 elif sh == "cmd":
951 shellname = "Command Shell"
952 else:
953 shellname = "shell"
954
955 if sh in ['csh', 'tcsh']:
956 grass_env_file = os.path.join(grass_config_dir, 'cshrc')
957 elif sh in ['bash', 'msh', 'cygwin', 'sh']:
958 grass_env_file = os.path.join(grass_config_dir, 'bashrc')
959 elif sh == 'zsh':
960 grass_env_file = os.path.join(grass_config_dir, 'zshrc')
961 elif sh == 'cmd':
962 grass_env_file = os.path.join(grass_config_dir, 'env.bat')
963 else:
964 grass_env_file = os.path.join(grass_config_dir, 'bashrc')
965 warning(_("Unsupported shell <%(sh)s>: %(env)s") % {'sh': sh,
966 'env': grass_env_file})
967
968 # check for SHELL
969 if not os.getenv('SHELL'):
970 fatal(_("The SHELL variable is not set"))
971
972
973def check_batch_job():
974 global batch_job
975 # hack to process batch jobs:
976 batch_job = os.getenv('GRASS_BATCH_JOB')
977 if batch_job:
978 # defined, but ...
979 if not os.access(batch_job, os.F_OK):
980 # wrong file
981 fatal(_("Job file '%s' has been defined in "
982 "the 'GRASS_BATCH_JOB' variable but not found. Exiting.\n\n"
983 "Use 'unset GRASS_BATCH_JOB' to disable batch job processing.") % batch_job)
984 elif not os.access(batch_job, os.X_OK):
985 # right file, but ...
986 fatal(_("Change file permission to 'executable' for '%s'") % batch_job)
987 else:
988 message(_("Executing '%s' ...") % batch_job)
989 grass_gui = "text"
990 shell = batch_job
991 bj = Popen(shell, shell=True)
992 bj.wait()
993 message(_("Execution of '%s' finished.") % batch_job)
994
995
996def start_gui():
997 # Start the chosen GUI but ignore text
998 if grass_debug:
999 message(_("GRASS GUI should be <%s>") % grass_gui)
1000
1001 # Check for gui interface
1002 if grass_gui == "wxpython":
1003 Popen([os.getenv('GRASS_PYTHON'), gfile(wxpython_base, "wxgui.py")])
1004
1005
1006def close_gui():
1007 """Close GUI if running"""
1008 if gfile('etc', 'python') not in sys.path:
1009 sys.path.append(gfile('etc', 'python'))
1010 from grass.script import core as gcore # pylint: disable=E0611
1011 env = gcore.gisenv()
1012 if 'GUI_PID' not in env:
1013 return
1014 import signal
1015 for pid in env['GUI_PID'].split(','):
1016 if grass_debug:
1017 message("Exiting GUI with pid={}".format(pid))
1018 os.kill(int(pid), signal.SIGTERM)
1019
1020def clear_screen():
1021 if windows:
1022 pass
1023 # TODO: uncomment when PDCurses works.
1024 # cls
1025 else:
1026 if not os.getenv('GRASS_BATCH_JOB') and not grass_debug and not exit_grass:
1027 call(["tput", "clear"])
1028
1029
1030def show_banner():
1031 sys.stderr.write(r"""
1032 __________ ___ __________ _______________
1033 / ____/ __ \/ | / ___/ ___/ / ____/ _/ ___/
1034 / / __/ /_/ / /| | \__ \\_ \ / / __ / / \__ \
1035 / /_/ / _, _/ ___ |___/ /__/ / / /_/ // / ___/ /
1036 \____/_/ |_/_/ |_/____/____/ \____/___//____/
1037
1038""")
1039
1040
1041def say_hello():
1042 sys.stderr.write(_("Welcome to GRASS GIS %s") % grass_version)
1043 if grass_version.endswith('svn'):
1044 try:
1045 filerev = open(os.path.join(gisbase, 'etc', 'VERSIONNUMBER'))
1046 linerev = filerev.readline().rstrip('\n')
1047 filerev.close()
1048
1049 revision = linerev.split(' ')[1]
1050 sys.stderr.write(' (' + revision + ')')
1051 except:
1052 pass
1053
1054def show_info():
1055 sys.stderr.write(
1056r"""
1057%-41shttp://grass.osgeo.org
1058%-41s%s (%s)
1059%-41sg.manual -i
1060%-41sg.version -c
1061%-41sg.version -x
1062""" % (_("GRASS GIS homepage:"),
1063 # GTC Running through: SHELL NAME
1064 _("This version running through:"),
1065 shellname, os.getenv('SHELL'),
1066 _("Help is available with the command:"),
1067 _("See the licence terms with:"),
1068 _("See citation options with:")))
1069
1070 if grass_gui == 'wxpython':
1071 message("%-41sg.gui wxpython" % _("If required, restart the GUI with:"))
1072 else:
1073 message("%-41sg.gui %s" % (_("Start the GUI with:"), default_gui))
1074
1075 message("%-41sexit" % _("When ready to quit enter:"))
1076 message("")
1077
1078
1079def csh_startup():
1080 userhome = os.getenv('HOME') # save original home
1081 home = location
1082 os.environ['HOME'] = home
1083
1084 cshrc = os.path.join(home, ".cshrc")
1085 tcshrc = os.path.join(home, ".tcshrc")
1086 try_remove(cshrc)
1087 try_remove(tcshrc)
1088
1089 f = open(cshrc, 'w')
1090 f.write("set home = %s\n" % userhome)
1091 f.write("set history = 3000 savehist = 3000 noclobber ignoreeof\n")
1092 f.write("set histfile = %s\n" % os.path.join(os.getenv('HOME'),
1093 ".history"))
1094
1095 f.write("set prompt = '\\\n")
1096 f.write("Mapset <%s> in Location <%s> \\\n" % (mapset, location_name))
1097 f.write("GRASS GIS %s > '\n" % grass_version)
1098 f.write("set BOGUS=``;unset BOGUS\n")
1099
1100 path = os.path.join(userhome, ".grass.cshrc") # left for backward compatibility
1101 if os.access(path, os.R_OK):
1102 f.write(readfile(path) + '\n')
1103 if os.access(grass_env_file, os.R_OK):
1104 f.write(readfile(grass_env_file) + '\n')
1105
1106 mail_re = re.compile(r"^ *set *mail *= *")
1107
1108 for filename in [".cshrc", ".tcshrc", ".login"]:
1109 path = os.path.join(userhome, filename)
1110 if os.access(path, os.R_OK):
1111 s = readfile(path)
1112 lines = s.splitlines()
1113 for l in lines:
1114 if mail_re.match(l):
1115 f.write(l)
1116
1117 path = os.getenv('PATH').split(':')
1118 f.write("set path = ( %s ) \n" % ' '.join(path))
1119
1120 f.close()
1121 writefile(tcshrc, readfile(cshrc))
1122
1123 process = Popen([gfile("etc", "run"), os.getenv('SHELL')])
1124
1125 os.environ['HOME'] = userhome
1126
1127 return process
1128
1129def bash_startup():
1130 # save command history in mapset dir and remember more
1131 os.environ['HISTFILE'] = os.path.join(location, ".bash_history")
1132 if not os.getenv('HISTSIZE') and not os.getenv('HISTFILESIZE'):
1133 os.environ['HISTSIZE'] = "3000"
1134
1135 # instead of changing $HOME, start bash with: --rcfile "$LOCATION/.bashrc" ?
1136 # if so, must care be taken to explicity call .grass.bashrc et al for
1137 # non-interactive bash batch jobs?
1138 userhome = os.getenv('HOME') # save original home
1139 home = location # save .bashrc in $LOCATION
1140 os.environ['HOME'] = home
1141
1142 bashrc = os.path.join(home, ".bashrc")
1143 try_remove(bashrc)
1144
1145 f = open(bashrc, 'w')
1146 f.write("test -r ~/.alias && . ~/.alias\n")
1147 if os.getenv('ISISROOT'):
1148 f.write("PS1='ISIS-GRASS %s (%s):\w > '\n" % (grass_version, location_name))
1149 else:
1150 f.write("PS1='GRASS %s (%s):\w > '\n" % (grass_version, location_name))
1151
1152 f.write("""grass_prompt() {
1153 LOCATION="`g.gisenv get=GISDBASE,LOCATION_NAME,MAPSET separator='/'`"
1154 if test -d "$LOCATION/grid3/G3D_MASK" && test -f "$LOCATION/cell/MASK" ; then
1155 echo [%s]
1156 elif test -f "$LOCATION/cell/MASK" ; then
1157 echo [%s]
1158 elif test -d "$LOCATION/grid3/G3D_MASK" ; then
1159 echo [%s]
1160 fi
1161}
1162PROMPT_COMMAND=grass_prompt\n""" % (_("2D and 3D raster MASKs present"),
1163 _("Raster MASK present"),
1164 _("3D raster MASK present")))
1165
1166 # read environmental variables
1167 path = os.path.join(userhome, ".grass.bashrc") # left for backward compatibility
1168 if os.access(path, os.R_OK):
1169 f.write(readfile(path) + '\n')
1170 for env in os.environ.keys():
1171 if env.startswith('GRASS'):
1172 val = os.environ[env]
1173 if ' ' in val:
1174 val = '"%s"' % val
1175 f.write('export %s=%s\n' % (env, val))
1176 ### Replaced by code above (do not override already set up environment variables)
1177 ### if os.access(grass_env_file, os.R_OK):
1178 ### f.write(readfile(grass_env_file) + '\n')
1179
1180 f.write("export PATH=\"%s\"\n" % os.getenv('PATH'))
1181 f.write("export HOME=\"%s\"\n" % userhome) # restore user home path
1182
1183 f.close()
1184
1185 process = Popen([gfile("etc", "run"), os.getenv('SHELL')])
1186
1187 os.environ['HOME'] = userhome
1188
1189 return process
1190
1191def default_startup():
1192 if windows:
1193 os.environ['PS1'] = "GRASS %s> " % (grass_version)
1194 # "$ETC/run" doesn't work at all???
1195 process = subprocess.Popen([os.getenv('SHELL')])
1196 cleanup_dir(os.path.join(location, ".tmp")) # remove GUI session files from .tmp
1197 else:
1198 os.environ['PS1'] = "GRASS %s (%s):\w > " % (grass_version, location_name)
1199 process = Popen([gfile("etc", "run"), os.getenv('SHELL')])
1200
1201 return process
1202
1203def done_message():
1204 if batch_job and os.access(batch_job, os.X_OK):
1205 message(_("Batch job '%s' (defined in GRASS_BATCH_JOB variable) was executed.") % batch_job)
1206 message(_("Goodbye from GRASS GIS"))
1207 sys.exit(0)
1208 else:
1209 message(_("Done."))
1210 message("")
1211 message(_("Goodbye from GRASS GIS"))
1212 message("")
1213
1214
1215def clean_temp():
1216 message(_("Cleaning up temporary files..."))
1217 nul = open(os.devnull, 'w')
1218 call([gfile("etc", "clean_temp")], stdout=nul, stderr=nul)
1219 nul.close()
1220
1221
1222def grep(string,list):
1223 expr = re.compile(string)
1224 return [elem for elem in list if expr.match(elem)]
1225
1226
1227def print_params():
1228 plat = gfile(gisbase, 'include', 'Make', 'Platform.make')
1229 if not os.path.exists(plat):
1230 fatal(_("Please install the GRASS GIS development package"))
1231 fileplat = open(plat)
1232 linesplat = fileplat.readlines()
1233 fileplat.close()
1234
1235 params = sys.argv[2:]
1236 if not params:
1237 params = ['arch', 'build', 'compiler', 'path', 'revision']
1238
1239 for arg in params:
1240 if arg == 'path':
1241 sys.stdout.write("%s\n" % gisbase)
1242 elif arg == 'arch':
1243 val = grep('ARCH',linesplat)
1244 sys.stdout.write("%s\n" % val[0].split('=')[1].strip())
1245 elif arg == 'build':
1246 build = os.path.join(gisbase,'include','grass','confparms.h')
1247 filebuild = open(build)
1248 val = filebuild.readline()
1249 filebuild.close()
1250 sys.stdout.write("%s\n" % val.strip().strip('"').strip())
1251 elif arg == 'compiler':
1252 val = grep('CC',linesplat)
1253 sys.stdout.write("%s\n" % val[0].split('=')[1].strip())
1254 elif arg == 'revision':
1255 rev = os.path.join(gisbase,'include','grass','gis.h')
1256 filerev = open(rev)
1257 linesrev = filerev.readlines()
1258 val = grep('#define GIS_H_VERSION', linesrev)
1259 filerev.close()
1260 sys.stdout.write("%s\n" % val[0].split(':')[1].rstrip('$"\n').strip())
1261 else:
1262 message(_("Parameter <%s> not supported") % arg)
1263
1264
1265def get_username():
1266 global user
1267 if windows:
1268 user = os.getenv('USERNAME')
1269 if not user:
1270 user = "user_name"
1271 else:
1272 user = os.getenv('USER')
1273 if not user:
1274 user = os.getenv('LOGNAME')
1275 if not user:
1276 try:
1277 p = Popen(['whoami'], stdout = subprocess.PIPE)
1278 s = p.stdout.read()
1279 p.wait()
1280 user = s.strip()
1281 except:
1282 pass
1283 if not user:
1284 user = "user_%d" % os.getuid()
1285
1286
1287def parse_cmdline():
1288 global args, grass_gui, create_new, exit_grass
1289 args = []
1290 for i in sys.argv[1:]:
1291 # Check if the user asked for the version
1292 if i in ["-v", "--version"]:
1293 message("GRASS GIS %s" % grass_version)
1294 message('\n' + readfile(gfile("etc", "license")))
1295 sys.exit()
1296 # Check if the user asked for help
1297 elif i in ["help", "-h", "-help", "--help"]:
1298 help_message()
1299 sys.exit()
1300 # Check if the -text flag was given
1301 elif i in ["-text", "--text"]:
1302 grass_gui = 'text'
1303 # Check if the -gtext flag was given
1304 elif i in ["-gtext", "--gtext"]:
1305 grass_gui = 'gtext'
1306 # Check if the -gui flag was given
1307 elif i in ["-gui", "--gui"]:
1308 grass_gui = default_gui
1309 # Check if the -wxpython flag was given
1310 elif i in ["-wxpython", "-wx", "--wxpython", "--wx"]:
1311 grass_gui = 'wxpython'
1312 # Check if the user wants to create a new mapset
1313 elif i == "-c":
1314 create_new = True
1315 elif i == "-e":
1316 exit_grass = True
1317 elif i == "--config":
1318 print_params()
1319 sys.exit()
1320 else:
1321 args.append(i)
1322
1323### MAIN script starts here
1324
1325# Get the system name
1326windows = sys.platform == 'win32'
1327cygwin = "cygwin" in sys.platform
1328macosx = "darwin" in sys.platform
1329
1330### commented-out: broken winGRASS
1331# if 'GISBASE' in os.environ:
1332# sys.exit(_("ERROR: GRASS GIS is already running "
1333# "(environmental variable GISBASE found)"))
1334
1335# Set GISBASE
1336os.environ['GISBASE'] = gisbase
1337
1338# set HOME
1339if windows and not os.getenv('HOME'):
1340 os.environ['HOME'] = os.path.join(os.getenv('HOMEDRIVE'),
1341 os.getenv('HOMEPATH'))
1342
1343# set SHELL
1344if windows:
1345 if os.getenv('GRASS_SH'):
1346 os.environ['SHELL'] = os.getenv('GRASS_SH')
1347 if not os.getenv('SHELL'):
1348 os.environ['SHELL'] = os.getenv('COMSPEC', 'cmd.exe')
1349
1350atexit.register(cleanup)
1351
1352# Set default GUI
1353default_gui = "wxpython"
1354
1355# the following is only meant to be an internal variable for debugging this
1356# script. use 'g.gisenv set="DEBUG=[0-5]"' to turn GRASS debug mode on properly
1357grass_debug = os.getenv('GRASS_DEBUG')
1358
1359# Set GRASS version number for R interface etc (must be an env_var for MS-Windows)
1360os.environ['GRASS_VERSION'] = grass_version
1361
1362# Set the GIS_LOCK variable to current process id
1363gis_lock = str(os.getpid())
1364os.environ['GIS_LOCK'] = gis_lock
1365
1366if not os.path.exists(grass_config_dir):
1367 os.mkdir(grass_config_dir)
1368
1369# Set the global grassrc file
1370batch_job = os.getenv('GRASS_BATCH_JOB')
1371if batch_job:
1372 gisrcrc = os.path.join(grass_config_dir, "rc.%s" % platform.node())
1373 if not os.access(gisrcrc, os.R_OK):
1374 gisrcrc = os.path.join(grass_config_dir, "rc")
1375else:
1376 gisrcrc = os.path.join(grass_config_dir, "rc")
1377
1378# Set the username and working directory
1379get_username()
1380
1381# Parse the command-line options
1382parse_cmdline()
1383
1384if exit_grass and not create_new:
1385 fatal(_("Flag -e required also flag -c"))
1386# Set language
1387# This has to be called before any _() function call!
1388# Subsequent functions are using _() calls and
1389# thus must be called only after Language has been set.
1390set_language()
1391
1392# Create the temporary directory and session grassrc file
1393create_tmp()
1394
1395# Create the session grassrc file
1396create_gisrc()
1397
1398# Set shell (needs to be called before load_env())
1399check_shell()
1400
1401# Load environmental variables from the file
1402load_env()
1403
1404# Ensure GUI is set
1405read_gui()
1406
1407# Set PATH, PYTHONPATH
1408set_paths()
1409
1410# Set LD_LIBRARY_PATH (etc) to find GRASS shared libraries
1411path_prepend(gfile("lib"), ld_library_path_var)
1412
1413# Set GRASS_PAGER, GRASS_PYTHON, GRASS_GNUPLOT, GRASS_PROJSHARE
1414set_defaults()
1415
1416# Set GRASS_HTML_BROWSER
1417set_browser()
1418
1419#predefine monitor size for certain architectures
1420if os.getenv('HOSTTYPE') == 'arm':
1421 # small monitor on ARM (iPAQ, zaurus... etc)
1422 os.environ['GRASS_RENDER_HEIGHT'] = "320"
1423 os.environ['GRASS_RENDER_WIDTH'] = "240"
1424
1425# First time user - GISRC is defined in the GRASS script
1426if not os.access(gisrc, os.F_OK):
1427 if grass_gui == 'text' and len(args) == 0:
1428 fatal(_("Unable to start GRASS. You can:\n"
1429 " - Launch GRASS with '-gui' switch (`grass70 -gui`)\n"
1430 " - Create manually GISRC file (%s)\n"
1431 " - Launch GRASS with path to "
1432 "the location/mapset as an argument (`grass70 /path/to/location/mapset`)\n"
1433 " - Use '--help' for further options (`grass70 --help`)\n"
1434 " See also: https://grass.osgeo.org/grass70/manuals/helptext.html") % gisrcrc)
1435 create_initial_gisrc()
1436else:
1437 clean_temp()
1438
1439if create_new:
1440 message(_("Creating new GRASS GIS location/mapset..."))
1441else:
1442 message(_("Starting GRASS GIS..."))
1443
1444# Check that the GUI works
1445check_gui()
1446
1447# Parsing argument to get LOCATION
1448if not args:
1449 # Try interactive startup
1450 location = None
1451else:
1452 if create_new:
1453 if len(args) > 1:
1454 non_interactive(args[1], args[0])
1455 else:
1456 non_interactive(args[0])
1457 else:
1458 non_interactive(args[0])
1459
1460# User selects LOCATION and MAPSET if not set
1461set_data()
1462
1463# Set GISDBASE, LOCATION_NAME, MAPSET, LOCATION from $GISRC
1464load_gisrc()
1465
1466# Check .gislock file
1467check_lock()
1468
1469# build user fontcap if specified but not present
1470make_fontcap()
1471
1472# predefine default driver if DB connection not defined
1473# is this really needed?? Modules should call this when/if required.
1474if not os.access(os.path.join(location, "VAR"), os.F_OK):
1475 call(['db.connect', '-c', '--quiet'])
1476
1477check_batch_job()
1478
1479if not batch_job and not exit_grass:
1480 start_gui()
1481
1482clear_screen()
1483
1484# Display the version and license info
1485if batch_job:
1486 grass_gui = 'text'
1487 clear_screen()
1488 clean_temp()
1489 try_remove(lockfile)
1490 sys.exit(0)
1491elif exit_grass:
1492 clean_temp()
1493 try_remove(lockfile)
1494 sys.exit(0)
1495else:
1496 show_banner()
1497 say_hello()
1498 show_info()
1499 if grass_gui == "wxpython":
1500 message(_("Launching <%s> GUI in the background, please wait...") % grass_gui)
1501
1502if sh in ['csh', 'tcsh']:
1503 shell_process = csh_startup()
1504elif sh in ['bash', 'msh', 'cygwin']:
1505 shell_process = bash_startup()
1506else:
1507 shell_process = default_startup()
1508
1509# start GUI and register shell PID in rc file
1510kv = read_gisrc()
1511kv['PID'] = str(shell_process.pid)
1512write_gisrc(kv)
1513exit_val = shell_process.wait()
1514if exit_val != 0:
1515 warning(_("Failed to start shell '%s'") % os.getenv('SHELL'))
1516
1517# close GUI if running
1518close_gui()
1519
1520clear_screen()
1521
1522clean_env()
1523clean_temp()
1524
1525try_remove(lockfile)
1526
1527# Save GISRC
1528s = readfile(gisrc)
1529writefile(gisrcrc, s)
1530
1531cleanup()
1532
1533# After this point no more grass modules may be called
1534
1535done_message()
Note: See TracBrowser for help on using the repository browser.