Beispiel #1
0
 def test_valid_location(self):
     """Test that different parameter combinations work and return true"""
     db_path = call_module("g.gisenv", get="GISDBASE").strip()
     loc_name = call_module("g.gisenv", get="LOCATION_NAME").strip()
     self.assertTrue(is_location_valid(db_path, loc_name))
     self.assertTrue(is_location_valid(os.path.join(db_path, loc_name)))
     self.assertTrue(is_location_valid(Path(db_path), loc_name))
     self.assertTrue(is_location_valid(Path(db_path) / loc_name))
Beispiel #2
0
def find_location_in_directory(path, recurse=0):
    """Return path to location in one of the subdirectories or None

    The first location found is returned. The expected usage is looking for one
    location somewhere nested in subdirectories.

    By default only the immediate subdirectories of the provided directory are
    tested, but with ``recurse >= 1`` additional levels of subdirectories
    are tested for being locations.

    Directory names are sorted to provide a stable result.

    :param path: Path to the directory to search
    :param recurse: How many additional levels of subdirectories to explore
    """
    assert recurse >= 0
    full_paths = [os.path.join(path, i) for i in os.listdir(path)]
    candidates = sorted([i for i in full_paths if os.path.isdir(i)])
    for candidate in candidates:
        if is_location_valid(candidate):
            return candidate
    if recurse:
        for candidate in candidates:
            result = find_location_in_directory(candidate, recurse - 1)
            if result:
                return result
    return None
Beispiel #3
0
def main(options, unused_flags):
    """Download and copy location to destination"""
    url = options["url"]
    name = options["name"]
    database = options["path"]

    if not database:
        # Use the current database path.
        database = gs.gisenv()["GISDBASE"]
    if not name:
        name = location_name_from_url(url)
    destination = Path(database) / name

    if destination.exists():
        gs.fatal(
            _("Location named <{}> already exists, download canceled").format(
                name))

    gs.message(_("Downloading and extracting..."))
    try:
        directory = download_and_extract(url)
        if not directory.is_dir():
            gs.fatal(
                _("Archive contains only one file and no mapset directories"))
        atexit.register(lambda: try_rmdir(directory))
    except DownloadError as error:
        gs.fatal(_("Unable to get the location: {error}").format(error=error))
    if not is_location_valid(directory):
        gs.verbose(_("Searching for valid location..."))
        # This in fact deal with location being on the third level of directories
        # thanks to how the extraction functions work (leaving out one level).
        result = find_location_in_directory(directory, recurse=1)
        if result:
            # We just want to show relative path in the message.
            # The relative path misses the root directory (name), because we
            # loose it on the way. (We should use parent directory to get the
            # full relative path, but the directory name is diffrent now.
            # This is the consequence of how the extract functions work.)
            relative = os.path.relpath(result, start=directory)
            gs.verbose(
                _("Location found in a nested directory '{directory}'").format(
                    directory=relative))
            directory = result
        else:
            # The list is similarly misleading as the relative path above
            # as it misses the root directory, but it still should be useful.
            files_and_dirs = os.listdir(directory)
            gs.fatal(
                _("The dowloaded file is not a valid GRASS Location."
                  " The extracted file contains these files and directories:"
                  "\n{files_and_dirs}").format(
                      files_and_dirs=" ".join(files_and_dirs)))
    gs.verbose(_("Copying to final destination..."))
    shutil.copytree(src=directory, dst=destination)
    gs.message(_("Path to the location now <{path}>").format(path=destination))
Beispiel #4
0
def ensure_demolocation():
    """Ensure that demolocation exists

    Creates both database directory and location if needed.

    Returns the db, location name, and preferred mapset of the demolocation.
    """
    grassdb = get_possible_database_path()
    # If nothing found, try to create GRASS directory and copy startup loc
    if grassdb is None:
        grassdb = create_database_directory()
    location = "world_latlong_wgs84"
    if not is_location_valid(grassdb, location):
        create_startup_location_in_grassdb(grassdb, location)
    return (grassdb, location, "PERMANENT")
Beispiel #5
0
def download_location(url, name, database):
    """Wrapper to return DownloadError by value

    It also moves the location directory to the database.
    """
    try:
        # TODO: the unpacking could go right to the path (but less
        # robust) or replace copytree here with move
        directory = download_and_extract(source=url, reporthook=reporthook)
        destination = os.path.join(database, name)
        if not is_location_valid(directory):
            return _("Downloaded location is not valid")
        shutil.copytree(src=directory, dst=destination)
        try_rmdir(directory)
    except DownloadError as error:
        return error
    return None
Beispiel #6
0
def ensure_default_data_hierarchy():
    """Ensure that default gisdbase, location and mapset exist.
    Creates database directory based on the default path determined
    according to OS if needed. Creates location if needed.

    Returns the db, loc, mapset, mapset_path"""

    gisdbase = get_possible_database_path()
    location = cfg.default_location
    mapset = cfg.permanent_mapset

    # If nothing found, try to create GRASS directory
    if not gisdbase:
        gisdbase = create_database_directory()

    if not is_location_valid(gisdbase, location):
        # If not valid, copy startup loc
        create_startup_location_in_grassdb(gisdbase, location)

    mapset_path = os.path.join(gisdbase, location, mapset)

    return gisdbase, location, mapset, mapset_path