utils.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. """
  2. @package startup.utils
  3. @brief General GUI-independent utilities for GUI startup of GRASS GIS
  4. (C) 2017-2018 by Vaclav Petras the GRASS Development Team
  5. This program is free software under the GNU General Public License
  6. (>=v2). Read the file COPYING that comes with GRASS for details.
  7. @author Vaclav Petras <wenzeslaus gmail com>
  8. @author Linda Kladivova <l.kladivova@seznam.cz>
  9. This file should not use (import) anything from GUI code (wx or wxGUI).
  10. This can potentially be part of the Python library (i.e. it needs to
  11. solve the errors etc. in a general manner).
  12. """
  13. import os
  14. import tempfile
  15. import getpass
  16. import sys
  17. from shutil import copytree, ignore_patterns
  18. from grass.grassdb.create import create_mapset, get_default_mapset_name
  19. def get_possible_database_path():
  20. """Looks for directory 'grassdata' (case-insensitive) in standard
  21. locations to detect existing GRASS Database.
  22. Returns the path as a string or None if nothing was found.
  23. """
  24. home = os.path.expanduser("~")
  25. # try some common directories for grassdata
  26. candidates = [
  27. home,
  28. os.path.join(home, "Documents"),
  29. ]
  30. # find possible database path
  31. for candidate in candidates:
  32. if os.path.exists(candidate):
  33. for subdir in next(os.walk(candidate))[1]:
  34. if "grassdata" in subdir.lower():
  35. return os.path.join(candidate, subdir)
  36. return None
  37. def create_database_directory():
  38. """Creates the standard GRASS GIS directory.
  39. Creates database directory named grassdata in the standard location
  40. according to the platform.
  41. Returns the new path as a string or None if nothing was found or created.
  42. """
  43. home = os.path.expanduser("~")
  44. # Determine the standard path according to the platform
  45. if sys.platform == "win32":
  46. path = os.path.join(home, "Documents", "grassdata")
  47. else:
  48. path = os.path.join(home, "grassdata")
  49. # Create "grassdata" directory
  50. try:
  51. os.mkdir(path)
  52. return path
  53. except OSError:
  54. pass
  55. # Create a temporary "grassdata" directory if GRASS is running
  56. # in some special environment and the standard directories
  57. # cannot be created which might be the case in some "try out GRASS"
  58. # use cases.
  59. path = os.path.join(tempfile.gettempdir(), "grassdata_{}".format(getpass.getuser()))
  60. # The created tmp is not cleaned by GRASS, so we are relying on
  61. # the system to do it at some point. The positive outcome is that
  62. # another GRASS instance will find the data created by the first
  63. # one which is desired in the "try out GRASS" use case we are
  64. # aiming towards."
  65. if os.path.exists(path):
  66. return path
  67. try:
  68. os.mkdir(path)
  69. return path
  70. except OSError:
  71. pass
  72. return None
  73. def _get_startup_location_in_distribution():
  74. """Check for startup location directory in distribution.
  75. Returns startup location if found or None if nothing was found.
  76. """
  77. gisbase = os.getenv("GISBASE")
  78. startup_location = os.path.join(gisbase, "demolocation")
  79. # Find out if startup location exists
  80. if os.path.exists(startup_location):
  81. return startup_location
  82. return None
  83. def _copy_startup_location(startup_location, location_in_grassdb):
  84. """Copy the simple startup_location with some data to GRASS database.
  85. Returns True if successfully copied or False
  86. when an error was encountered.
  87. """
  88. # Copy source startup location into GRASS database
  89. try:
  90. copytree(startup_location, location_in_grassdb,
  91. ignore=ignore_patterns('*.tmpl', 'Makefile*'))
  92. return True
  93. except (IOError, OSError):
  94. pass
  95. return False
  96. def _create_startup_mapset(location_path):
  97. """Create the new empty startup mapset named after user.
  98. Returns new mapset name if successfully created or None when
  99. an error was encountered.
  100. """
  101. mapset_name = default_name = get_default_mapset_name()
  102. mapset_path = os.path.join(location_path, mapset_name)
  103. # Create new startup mapset
  104. try:
  105. grassdatabase, location = os.path.split(location_path)
  106. create_mapset(grassdatabase, location, mapset_name)
  107. return mapset_name
  108. except (IOError, OSError):
  109. pass
  110. return None
  111. def create_startup_location_in_grassdb(grassdatabase, startup_location_name):
  112. """Create a new startup location in the given GRASS database.
  113. Returns the newly created mapset name on success. Returns None if there is
  114. no location to copy in the installation or copying failed.
  115. """
  116. # Find out if startup location exists
  117. startup_location = _get_startup_location_in_distribution()
  118. if not startup_location:
  119. return None
  120. # Copy the simple startup_location with some data to GRASS database.
  121. mapset = None
  122. location_in_grassdb = os.path.join(grassdatabase, startup_location_name)
  123. if _copy_startup_location(startup_location, location_in_grassdb):
  124. mapset = _create_startup_mapset(location_in_grassdb)
  125. return mapset
  126. return None