utils.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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. This file should not use (import) anything from GUI code (wx or wxGUI).
  9. This can potentially be part of the Python library (i.e. it needs to
  10. solve the errors etc. in a general manner).
  11. """
  12. import os
  13. import shutil
  14. import tempfile
  15. import getpass
  16. import sys
  17. def get_possible_database_path():
  18. """Looks for directory 'grassdata' (case-insensitive) in standard
  19. locations to detect existing GRASS Database.
  20. Returns the path as a string or None if nothing was found.
  21. """
  22. home = os.path.expanduser("~")
  23. # try some common directories for grassdata
  24. candidates = [
  25. home,
  26. os.path.join(home, "Documents"),
  27. ]
  28. # find possible database path
  29. for candidate in candidates:
  30. if os.path.exists(candidate):
  31. for subdir in next(os.walk(candidate))[1]:
  32. if "grassdata" in subdir.lower():
  33. return os.path.join(candidate, subdir)
  34. return None
  35. def create_database_directory():
  36. """Creates the standard GRASS GIS directory.
  37. Creates database directory named grassdata in the standard location
  38. according to the platform.
  39. Returns the new path as a string or None if nothing was found or created.
  40. """
  41. home = os.path.expanduser("~")
  42. # Determine the standard path according to the platform
  43. if sys.platform == "win32":
  44. path = os.path.join(home, "Documents", "grassdata")
  45. else:
  46. path = os.path.join(home, "grassdata")
  47. # Create "grassdata" directory
  48. try:
  49. os.mkdir(path)
  50. return path
  51. except OSError:
  52. pass
  53. # Create a temporary "grassdata" directory if GRASS is running
  54. # in some special environment and the standard directories
  55. # cannot be created which might be the case in some "try out GRASS"
  56. # use cases.
  57. path = os.path.join(tempfile.gettempdir(), "grassdata_{}".format(getpass.getuser()))
  58. # The created tmp is not cleaned by GRASS, so we are relying on
  59. # the system to do it at some point. The positive outcome is that
  60. # another GRASS instance will find the data created by the first
  61. # one which is desired in the "try out GRASS" use case we are
  62. # aiming towards."
  63. if os.path.exists(path):
  64. return path
  65. try:
  66. os.mkdir(path)
  67. return path
  68. except OSError:
  69. pass
  70. return None
  71. def get_lockfile_if_present(database, location, mapset):
  72. """Return path to lock if present, None otherwise
  73. Returns the path as a string or None if nothing was found, so the
  74. return value can be used to test if the lock is present.
  75. """
  76. lock_name = ".gislock"
  77. lockfile = os.path.join(database, location, mapset, lock_name)
  78. if os.path.isfile(lockfile):
  79. return lockfile
  80. else:
  81. return None
  82. def create_mapset(database, location, mapset):
  83. """Creates a mapset in a specified location"""
  84. location_path = os.path.join(database, location)
  85. mapset_path = os.path.join(location_path, mapset)
  86. # create an empty directory
  87. os.mkdir(mapset_path)
  88. # copy DEFAULT_WIND file and its permissions from PERMANENT
  89. # to WIND in the new mapset
  90. region_path1 = os.path.join(location_path, "PERMANENT", "DEFAULT_WIND")
  91. region_path2 = os.path.join(location_path, mapset, "WIND")
  92. shutil.copy(region_path1, region_path2)
  93. # set permissions to u+rw,go+r (disabled; why?)
  94. # os.chmod(os.path.join(database,location,mapset,'WIND'), 0644)
  95. def delete_mapset(database, location, mapset):
  96. """Deletes a specified mapset"""
  97. if mapset == "PERMANENT":
  98. # TODO: translatable or not?
  99. raise ValueError(
  100. "Mapset PERMANENT cannot be deleted" " (whole location can be)"
  101. )
  102. shutil.rmtree(os.path.join(database, location, mapset))
  103. def delete_location(database, location):
  104. """Deletes a specified location"""
  105. shutil.rmtree(os.path.join(database, location))
  106. def rename_mapset(database, location, old_name, new_name):
  107. """Rename mapset from *old_name* to *new_name*"""
  108. location_path = os.path.join(database, location)
  109. os.rename(
  110. os.path.join(location_path, old_name), os.path.join(location_path, new_name)
  111. )
  112. def rename_location(database, old_name, new_name):
  113. """Rename location from *old_name* to *new_name*"""
  114. os.rename(os.path.join(database, old_name), os.path.join(database, new_name))
  115. def mapset_exists(database, location, mapset):
  116. """Returns True whether mapset path exists."""
  117. location_path = os.path.join(database, location)
  118. mapset_path = os.path.join(location_path, mapset)
  119. if os.path.exists(mapset_path):
  120. return True
  121. return False
  122. def location_exists(database, location):
  123. """Returns True whether location path exists."""
  124. location_path = os.path.join(database, location)
  125. if os.path.exists(location_path):
  126. return True
  127. return False
  128. def get_default_mapset_name():
  129. """Returns default name for mapset."""
  130. try:
  131. defaultName = getpass.getuser()
  132. defaultName.encode("ascii")
  133. except UnicodeEncodeError:
  134. # raise error if not ascii (not valid mapset name)
  135. defaultName = "user"
  136. return defaultName