def RenderProcess3D(imageWidth, imageHeight, tempDir, cmd, region, bgcolor, fileQueue): """Renders image with m.nviz.image and writes the resulting ppm filename in the provided file queue :param imageWidth: image width :param imageHeight: image height :param tempDir: directory for rendering :param cmd: m.nviz.image command as a list :param region: region as a dict :param bgcolor: background color as a tuple of 3 values 0 to 255 :param fileQueue: the inter process communication queue storing the file name of the image """ filename = GetFileFromCmd(tempDir, cmd, None) os.environ['GRASS_REGION'] = gcore.region_env(region3d=True, **region) Debug.msg(1, "Render image to file " + str(filename)) cmdTuple = CmdToTuple(cmd) cmdTuple[1]['output'] = os.path.splitext(filename)[0] # set size cmdTuple[1]['size'] = '%d,%d' % (imageWidth, imageHeight) # set format cmdTuple[1]['format'] = 'ppm' cmdTuple[1]['bgcolor'] = bgcolor = ':'.join([str(part) for part in bgcolor]) returncode, stdout, messages = read2_command(cmdTuple[0], **cmdTuple[1]) if returncode != 0: gcore.warning("Rendering failed:\n" + messages) fileQueue.put(None) os.environ.pop('GRASS_REGION') return os.environ.pop('GRASS_REGION') fileQueue.put(filename)
def RenderProcess2D(imageWidth, imageHeight, tempDir, cmd, region, bgcolor, fileQueue): """Render raster or vector files as ppm image and write the resulting ppm filename in the provided file queue :param imageWidth: image width :param imageHeight: image height :param tempDir: directory for rendering :param cmd: d.rast/d.vect command as a list :param region: region as a dict or None :param bgcolor: background color as a tuple of 3 values 0 to 255 :param fileQueue: the inter process communication queue storing the file name of the image """ filename = GetFileFromCmd(tempDir, cmd, region) transparency = True # Set the environment variables for this process _setEnvironment(imageWidth, imageHeight, filename, transparent=transparency, bgcolor=bgcolor) if region: os.environ['GRASS_REGION'] = gcore.region_env(**region) cmdTuple = CmdToTuple(cmd) returncode, stdout, messages = read2_command(cmdTuple[0], **cmdTuple[1]) if returncode != 0: gcore.warning("Rendering failed:\n" + messages) fileQueue.put(None) if region: os.environ.pop('GRASS_REGION') os.remove(filename) return if region: os.environ.pop('GRASS_REGION') fileQueue.put(filename)
def list_available_extensions_svn(): grass.message(_('Fetching list of extensions from GRASS-Addons SVN repository (be patient)...')) pattern = re.compile(r'(<li><a href=".+">)(.+)(</a></li>)', re.IGNORECASE) if flags['c']: grass.warning(_("Flag 'c' ignored, metadata file not available")) if flags['g']: grass.warning(_("Flag 'g' ignored, metadata file not available")) prefix = ['d', 'db', 'g', 'i', 'm', 'ps', 'p', 'r', 'r3', 's', 'v'] for d in prefix: modclass = expand_module_class_name(d) grass.verbose(_("Checking for '%s' modules...") % modclass) url = '%s/%s' % (options['svnurl'], modclass) grass.debug("url = %s" % url, debug = 2) try: f = urlopen(url, proxies=PROXIES) except HTTPError: grass.debug(_("Unable to fetch '%s'") % url, debug = 1) continue for line in f.readlines(): # list extensions sline = pattern.search(line) if not sline: continue name = sline.group(2).rstrip('/') if name.split('.', 1)[0] == d: print name
def list_available_modules(url, mlist = None): # try to download XML metadata file first url = url + "modules.xml" grass.debug("url=%s" % url, 1) try: f = urlopen(url, proxies=PROXIES) try: tree = etree.fromstring(f.read()) except: grass.warning(_("Unable to parse '%s'. Trying to scan SVN repository (may take some time)...") % url) list_available_extensions_svn() return for mnode in tree.findall('task'): name = mnode.get('name').strip() if mlist and name not in mlist: continue if flags['c'] or flags['g']: desc, keyw = get_optional_params(mnode) if flags['g']: print 'name=' + name print 'description=' + desc print 'keywords=' + keyw elif flags['c']: if mlist: print '*', print name + ' - ' + desc else: print name except HTTPError: list_available_extensions_svn()
def list_wxgui_extensions(print_module = True): mlist = list() grass.debug('Fetching list of wxGUI extensions from GRASS-Addons SVN (be patient)...') pattern = re.compile(r'(<li><a href=".+">)(.+)(</a></li>)', re.IGNORECASE) grass.verbose(_("Checking for '%s' modules...") % 'gui/wxpython') url = '%s/%s' % (options['svnurl'], 'gui/wxpython') grass.debug("url = %s" % url, debug = 2) f = urlopen(url) if not f: grass.warning(_("Unable to fetch '%s'") % url) return for line in f.readlines(): # list extensions sline = pattern.search(line) if not sline: continue name = sline.group(2).rstrip('/') if name not in ('..', 'Makefile'): if print_module: print name mlist.append(name) return mlist
def GetData(self, idx, server, query, output): """Download data""" grass.message(_("Downloading data (tile %d)...") % idx) grass.verbose("Requesting data: %s" % self.options['mapserver']) if not self.flags['g']: # -> post try: urllib.urlretrieve(server, output, data = query) except IOError: grass.fatal(_("Failed while downloading the data")) if not os.path.exists(output): grass.fatal(_("Failed while downloading the data")) # work-around for brain-dead ArcIMS servers which want POST-data as part of the GET URL # (this is technically allowed by OGC WMS def v1.3.0 Sec6.3.4) if os.path.getsize(output) == 0: grass.warning(_("Downloaded image file is empty -- trying another method")) self.flags['g'] = True if self.flags['g']: # -> get try: urllib.urlretrieve(server + '?' + query, output, data = None) except IOError: grass.fatal(_("Failed while downloading the data")) if not os.path.exists(output) or os.path.getsize(output) == 0: grass.fatal(_("Failed while downloading the data"))
def list_available_extensions(): mlist = list() # try to download XML metadata file first url = "http://grass.osgeo.org/addons/grass%s/modules.xml" % grass.version()['version'].split('.')[0] grass.debug("url=%s" % url, 1) try: f = urlopen(url) try: tree = etree.fromstring(f.read()) except: grass.warning(_("Unable to parse '%s'. Trying to scan SVN (may take some time)...") % url) list_available_extensions_svn() return for mnode in tree.findall('task'): name = mnode.get('name') if flags['c'] or flags['g']: desc, keyw = get_optional_params(mnode) if flags['g']: print 'name=' + name print 'description=' + desc print 'keywords=' + keyw elif flags['c']: print name + ' - ' + desc else: print name except HTTPError: return list_available_extensions_svn() return mlist
def watcher(self): """Redraw, if new layer appears (check's timestamp of cmdfile) """ ### # TODO: find a better solution ### # the check below disabled, it's too much invasive to call # g.gisenv in the watcher... # try: # GISBASE and other system enviromental variables can not be used # since the process inherited them from GRASS # raises exception when vaiable does not exists # grass.gisenv()['GISDBASE'] # except KeyError: # self.timer.Stop() # return # todo: events try: currentCmdFileTime = os.path.getmtime(monFile['cmd']) if currentCmdFileTime > self.cmdTimeStamp: self.timer.Stop() self.cmdTimeStamp = currentCmdFileTime self.mapFrm.GetMap().GetLayersFromCmdFile() self.timer.Start(mtime) except OSError as e: grass.warning("%s" % e) self.timer.Stop()
def __call__(self): import shutil if os.path.exists(self._tempDir): try: shutil.rmtree(self._tempDir) Debug.msg(5, 'CleanUp: removed directory {t}'.format(t=self._tempDir)) except OSError: gcore.warning(_("Directory {t} not removed.").format(t=self._tempDir))
def import_directory_of_rasters(directory, recursive): for dir, dirnames, filenames in os.walk(directory): for filename in filenames: if grass.run_command('r.external', flags=flags_string, input=os.path.join(dir, filename), band=options['band'], output=filename[:-4], title=filename[:-4]) != 0: grass.warning('Cannot import file' + filename) if not recursive: break for dirname in dirnames: import_directory_of_rasters(dirname, recursive)
def thumbnail_image(input_file, output_file): print input_file, output_file try: import Image image = Image.open(input_file) image.thumbnail((200, 200), Image.ANTIALIAS) image.save(output_file, 'PNG') except ImportError, error: gcore.warning(_("Cannot thumbnail image ({error})." " Maybe you don't have PIL." " Will output the same image.") % error)
def _createPath(path): """Creates path (for toolboxes) if it doesn't exist'""" if not os.path.exists(path): try: os.mkdir(path) except OSError as e: # we cannot use GError or similar because the gui doesn't start at all gcore.warning('%(reason)s\n%(detail)s' % ({'reason':_('Unable to create toolboxes directory.'), 'detail': str(e)})) return False return True
def remove_extension(force = False): # try to read XML metadata file first fXML = os.path.join(options['prefix'], 'modules.xml') name = options['extension'] if name not in get_installed_extensions(): grass.warning(_("Extension <%s> not found") % name) if force: grass.verbose(_("List of removed files:")) else: grass.info(_("Files to be removed (use flag 'f' to force removal):")) if os.path.exists(fXML): f = open(fXML, 'r') tree = etree.fromstring(f.read()) flist = [] for task in tree.findall('task'): if name == task.get('name', default = '') and \ task.find('binary') is not None: for f in task.find('binary').findall('file'): flist.append(f.text) if flist: removed = False err = list() for fpath in flist: try: if force: grass.verbose(fpath) os.remove(fpath) removed = True else: print fpath except OSError: err.append((_("Unable to remove file '%s'") % fpath)) if force and not removed: grass.fatal(_("Extension <%s> not found") % options['extension']) if err: for e in err: grass.error(e) else: remove_extension_std(force) else: remove_extension_std(force) if force: grass.message(_("Updating metadata file...")) remove_extension_xml() grass.message(_("Extension <%s> successfully uninstalled.") % options['extension']) else: grass.warning(_("Extension <%s> not removed.\n" "Re-run '%s' with 'f' flag to force removal") % (options['extension'], 'g.extension'))
def remove_modules(mlist, force = False): # try to read XML metadata file first fXML = os.path.join(options['prefix'], 'modules.xml') installed = get_installed_modules() if os.path.exists(fXML): f = open(fXML, 'r') tree = etree.fromstring(f.read()) f.close() else: tree = None for name in mlist: if name not in installed: # try even if module does not seem to be available, # as the user may be trying to get rid of left over cruft grass.warning(_("Extension <%s> not found") % name) if tree is not None: flist = [] for task in tree.findall('task'): if name == task.get('name') and \ task.find('binary') is not None: for f in task.find('binary').findall('file'): flist.append(f.text) break if flist: removed = False err = list() for fpath in flist: try: if force: grass.verbose(fpath) removed = True os.remove(fpath) else: print fpath except OSError: err.append((_("Unable to remove file '%s'") % fpath)) if force and not removed: grass.fatal(_("Extension <%s> not found") % name) if err: for e in err: grass.error(e) else: remove_extension_std(name, force) else: remove_extension_std(name, force)
def OnEPSGList(self, event): """ @description: called on selection of an epsg code from the epsg list(ComboBox) displayed. Sets self.selectedEPSG variable. @todo:None @param self: reference variable @param event: event associated. @return: None """ info = self.epsgList.GetValue() if (not info.isdigit()): message = 'Please select an EPSG Code' grass.warning(message) seld.show_message(message) StatusBar_fields = [message] self.StatusBar.SetStatusText(StatusBar_fields[0], 0) return self.selectedEPSG = info
def OnGetCapabilities(self, event): # wxGlade: wmsFrame.<event_handler> """ @description: called on press of getCapabilities button. Performs fetching of the getCapabilties document for the selected URL. @todo:None @param self: reference variable @param event: event associated. @return: None """ if (self.selectedURL == "No server selected"): message = 'No Server selected' self.ShowMessage(message, 'Warning') StatusBar_fields = [message] self.StatusBar.SetStatusText(StatusBar_fields[0], 0) grass.warning(message) return try: self.epsgList.SetSelection(0) except: message = 'epsg list is empty' grass.warning(message) self.usernameInput.Enable() self.passwordInput.Enable() self.LayerTree.CollapseAndReset(self.layerTreeRoot) url = self.selectedURL url = url + '?request=GetCapabilities&service=wms&version=1.1.1' StatusBar_fields = ["GetCapabilities Request Sent..."] self.StatusBar.SetStatusText(StatusBar_fields[0], 0) req = Request(url) try: response = urlopen(req, None, self.timeoutValueSeconds) xml = response.read() if (not isValidResponse(xml)): message = "Invalid GetCapabilities response" self.ShowMessage(message, 'Warning') StatusBar_fields = [message] self.StatusBar.SetStatusText(StatusBar_fields[0], 0) grass.warning(message) return if (isServiceException(xml)): message = 'Service Exception in Get Capabilities' self.ShowMessage(message, 'Warning') StatusBar_fields = [message] self.StatusBar.SetStatusText(StatusBar_fields[0], 0) grass.warning(message) return layerDataDict = parsexml2(xml) ld = LayerData() #ld.appendLayerTree(layerDataDict, self.LayerTree, self.layerTreeRoot) self.keyToEPSGCodes = ld.setKeyToEPSGCodes(layerDataDict) self.selectedEPSG = None self.layerDataDict1 = test(xml, self.LayerTree, self.layerTreeRoot) print self.layerDataDict1 self.LayerTree.Expand(self.layerTreeRoot) except HTTPError, e: message = 'The server couldn\'t fulfill the request.' message = str(e)
def checkForm(jsonn): """Function to check the forms""" try: form = jsonn['form'] except: try: form = jsonn['forms'] except: grass.fatal(_("Error importing notes")) if type(form) == DictType: values = form['formitems'] elif type(form) == ListType and len(form) == 1: values = form[0]['formitems'] elif type(form) == ListType and len(form) > 1: grass.warning( _("Form contains more fields and it is no yet supported")) return values
def change_detection(before, after, change, height_threshold, cells_threshold, add, max_detected, debug, env): diff_thr = 'diff_thr_' + str(uuid.uuid4()).replace('-', '') diff_thr_clump = 'diff_thr_clump_' + str(uuid.uuid4()).replace('-', '') coeff = gcore.parse_command('r.regression.line', mapx=after, mapy=before, flags='g', env=env) grast.mapcalc('diff = {a} + {b} * {after} - {before}'.format(a=coeff['a'], b=coeff['b'],before=before,after=after), env=env) try: if add: grast.mapcalc("{diff_thr} = if(({a} + {b} * {after} - {before}) > {thr1} &&" " ({a} + {b} * {after} - {before}) < {thr2}, 1, null())".format(a=coeff['a'], b=coeff['b'], diff_thr=diff_thr, after=after, before=before, thr1=height_threshold[0], thr2=height_threshold[1]), env=env) else: grast.mapcalc("{diff_thr} = if(({before} - {a} + {b} * {after}) > {thr}, 1, null())".format(diff_thr=diff_thr, a=coeff['a'], b=coeff['b'], after=after, before=before, thr=height_threshold), env=env) gcore.run_command('r.clump', input=diff_thr, output=diff_thr_clump, env=env) stats = gcore.read_command('r.stats', flags='cn', input=diff_thr_clump, sort='desc', env=env).strip().splitlines() if debug: print 'DEBUG: {}'.format(stats) if len(stats) > 0 and stats[0]: cats = [] found = 0 for stat in stats: if found >= max_detected: break if float(stat.split()[1]) < cells_threshold[1] and float(stat.split()[1]) > cells_threshold[0]: # larger than specified number of cells found += 1 cat, value = stat.split() cats.append(cat) if cats: rules = ['{c}:{c}:1'.format(c=c) for c in cats] gcore.write_command('r.recode', input=diff_thr_clump, output=change, rules='-', stdin='\n'.join(rules), env=env) gcore.run_command('r.volume', flags='f', input=change, clump=diff_thr_clump, centroids=change, env=env) else: gcore.warning("No change found!") gcore.run_command('v.edit', map=change, tool='create', env=env) else: gcore.warning("No change found!") gcore.run_command('v.edit', map=change, tool='create', env=env) gcore.run_command('g.remove', flags='f', type=['raster'], name=[diff_thr, diff_thr_clump], env=env) except: gcore.run_command('g.remove', flags='f', type=['raster'], name=[diff_thr, diff_thr_clump], env=env)
def checkForm(jsonn): """Function to check the forms""" try: form = jsonn["form"] except KeyError: try: form = jsonn["forms"] except KeyError: grass.fatal(_("Error importing notes")) if isinstance(form, dict): values = form["formitems"] elif isinstance(form, list) and len(form) == 1: values = form[0]["formitems"] elif isinstance(form, list) and len(form) > 1: grass.warning( _("Form contains more fields and it is no yet supported")) return values
def UnregisterMouseEventHandler(self, event, handler): """Unbinds event handler for event @deprecated This method is deprecated. Use Signals or drawing API instead. Before handler is unregistered it is called with string value "unregistered" of event parameter. Emits mouseHandlerUnregistered signal after handler is unregistered. :param handler: handler to unbind :param event: event from which handler will be unbinded :return: True if successful :return: False if event cannot be unbind """ # removes handler from list for containerEv, handlers in six.iteritems(self.handlersContainer): if event != containerEv: continue try: handler("unregistered") if handler in handlers: handlers.remove(handler) else: grass.warning( _("Handler: %s was not registered") % handler.__name__) except: GError( parent=self, message= _("Error occurred during unregistration of handler: %s \n \ Handler was unregistered") % handler.__name__, ) handlers.remove(handler) # restore mouse use (previous state) self.mouse["use"] = self.mouse["useBeforeGenericEvent"] # restore overridden cursor if self._overriddenCursor: self.SetNamedCursor(self._overriddenCursor) self.mouseHandlerUnregistered.emit() return True
def change_detection(before, after, change, height_threshold, cells_threshold, add, max_detected, env): diff_thr = 'diff_thr_' + str(uuid.uuid4()).replace('-', '') diff_thr_clump = 'diff_thr_clump_' + str(uuid.uuid4()).replace('-', '') change_vector = 'change_vector_' + str(uuid.uuid4()).replace('-', '') if add: gcore.run_command('r.mapcalc', expression="{diff_thr} = if(({after} - {before}) > {thr1} &&" " ({after} - {before}) < {thr2}, 1, null())".format(diff_thr=diff_thr, after=after, before=before, thr1=height_threshold[0], thr2=height_threshold[1]), env=env) else: gcore.run_command('r.mapcalc', expression="{diff_thr} = if(({before} - {after}) > {thr}, 1, null())".format(diff_thr=diff_thr, after=after, before=before, thr=height_threshold), env=env) gcore.run_command('r.clump', input=diff_thr, output=diff_thr_clump, env=env) stats = gcore.read_command('r.stats', flags='cn', input=diff_thr_clump, sort='desc', env=env).strip().split(os.linesep) if len(stats) > 0 and stats[0]: print stats cats = [] found = 0 for stat in stats: if found >= max_detected: break if float(stat.split()[1]) < cells_threshold[1] and float(stat.split()[1]) > cells_threshold[0]: # larger than specified number of cells found += 1 cat, value = stat.split() cats.append(cat) if cats: expression = '{change} = if(('.format(change=change) for i, cat in enumerate(cats): if i != 0: expression += ' || ' expression += '{diff_thr_clump} == {val}'.format(diff_thr_clump=diff_thr_clump, val=cat) expression += '), 1, null())' gcore.run_command('r.mapcalc', overwrite=True, env=env, expression=expression) gcore.run_command('r.to.vect', flags='st', input=change, output=change_vector, type='area', env=env) gcore.run_command('v.to.points', flags='t', input=change_vector, type='centroid', output=change, env=env) else: gcore.warning("No change found!") gcore.run_command('v.edit', map=change, tool='create', env=env) else: gcore.warning("No change found!") gcore.run_command('v.edit', map=change, tool='create', env=env) gcore.run_command('g.remove', flags='f', type='raster', name=[diff_thr, diff_thr_clump], env=env)
def sortfile(infile, outfile): inf = file(infile, 'r') outf = file(outfile, 'w') if grass.find_program('sort', '--help'): grass.run_command('sort', flags = 'n', stdin = inf, stdout = outf) else: # FIXME: we need a large-file sorting function grass.warning(_("'sort' not found: sorting in memory")) lines = inf.readlines() for i in range(len(lines)): lines[i] = float(lines[i].rstrip('\r\n')) lines.sort() for line in lines: outf.write(str(line) + '\n') inf.close() outf.close()
def sortfile(infile, outfile): inf = file(infile, 'r') outf = file(outfile, 'w') if grass.find_program('sort', '--help'): grass.run_command('sort', flags='n', stdin=inf, stdout=outf) else: # FIXME: we need a large-file sorting function grass.warning(_("'sort' not found: sorting in memory")) lines = inf.readlines() for i in range(len(lines)): lines[i] = float(lines[i].rstrip('\r\n')) lines.sort() for line in lines: outf.write(str(line) + '\n') inf.close() outf.close()
def CompositeProcess(imageWidth, imageHeight, tempDir, cmdList, region, opacities, bgcolor, fileQueue): """Performs the composition of image ppm files and writes the resulting ppm filename in the provided file queue :param imageWidth: image width :param imageHeight: image height :param tempDir: directory for rendering :param cmdList: list of d.rast/d.vect commands :param region: region as a dict or None :param opacites: list of opacities :param bgcolor: background color as a tuple of 3 values 0 to 255 :param fileQueue: the inter process communication queue storing the file name of the image """ maps = [] masks = [] for cmd in cmdList: maps.append(GetFileFromCmd(tempDir, cmd, region)) masks.append(GetFileFromCmd(tempDir, cmd, region, 'pgm')) filename = GetFileFromCmds(tempDir, cmdList, region) # Set the environment variables for this process _setEnvironment(imageWidth, imageHeight, filename, transparent=False, bgcolor=bgcolor) opacities = [str(op) for op in opacities] bgcolor = ':'.join([str(part) for part in bgcolor]) returncode, stdout, messages = read2_command('g.pnmcomp', overwrite=True, input='%s' % ",".join(reversed(maps)), mask='%s' % ",".join(reversed(masks)), opacity='%s' % ",".join(reversed(opacities)), bgcolor=bgcolor, width=imageWidth, height=imageHeight, output=filename) if returncode != 0: gcore.warning("Rendering composite failed:\n" + messages) fileQueue.put(None) os.remove(filename) return fileQueue.put(filename)
def _createPath(path): """Creates path (for toolboxes) if it doesn't exist'""" if not os.path.exists(path): try: os.mkdir(path) except OSError as e: # we cannot use GError or similar because the gui doesn't start at # all gcore.warning( "%(reason)s\n%(detail)s" % ( { "reason": _("Unable to create toolboxes directory."), "detail": str(e), } ) ) return False return True
def main(): magnitude = options['magnitude'] direction = options['direction'] divergence = options['output'] global TMP, CLEANUP tmp_name = 'tmp_divergence_' + str(os.getpid()) qsx = tmp_name + "qsx" qsy = tmp_name + "qsy" qsx_dx = tmp_name + "qsx_dx" qsy_dy = tmp_name + "qsy_dy" TMP.extend([qsx, qsy, qsx_dx, qsy_dy]) # checks if there are already some maps old_maps = temp_maps_exist() if old_maps: if not gcore.overwrite(): CLEANUP = False gcore.fatal( _("You have to first check overwrite flag or remove" " the following maps:\n" "names}").format(names=','.join(old_maps))) else: gcore.warning( _("The following maps will be overwritten: {names}").format( names=','.join(old_maps))) try: grast.mapcalc(exp="{qsx}={mag} * cos({direct})".format( qsx=qsx, mag=magnitude, direct=direction)) grast.mapcalc(exp="{qsy}={mag} * sin({direct})".format( qsy=qsy, mag=magnitude, direct=direction)) gcore.run_command('r.slope.aspect', elevation=qsx, dx=qsx_dx) gcore.run_command('r.slope.aspect', elevation=qsy, dy=qsy_dy) grast.mapcalc(exp="{div}={qsx_dx} + {qsy_dy}".format( div=divergence, qsx_dx=qsx_dx, qsy_dy=qsy_dy)) except CalledModuleError: gcore.fatal( _("r.divergence failed, check errors above. Please report this problem to developers." )) return 1 grast.raster_history(divergence) return 0
def main(): # get currently selected monitor monitor = check_monitor() if not monitor: fatal(_("No graphics device selected. Use d.mon to select graphics device.")) if flags['e']: # remove frames and erase monitor and exit erase(monitor) return if flags['p']: # print current frame and exit print_frames(monitor, current_only=True) return if flags['a']: # print all frames including their position and exit print_frames(monitor, current_only=False, full=True) return found = find_frame(monitor, options['frame']) if not found: if not flags['c']: fatal(_("Frame <%s> doesn't exist, exiting. " "To create a new frame use '-c' flag.") % options['frame']) else: if not options['at']: fatal(_("Required parameter <%s> not set") % "at") # create new frame if not exists create_frame(monitor, options['frame'], options['at']) else: if os.getenv('GRASS_OVERWRITE', '0') == '1': warning(_("Frame <%s> already exists and will be overwritten") % options['frame']) create_frame(monitor, options['frame'], options['at'], overwrite=True) else: if options['at']: warning( _("Frame <%s> already found. An existing frame can be overwritten by '%s' flag.") % (options['frame'], "--overwrite")) # select givenframe select_frame(monitor, options['frame'])
def wkt2standards(prj_txt): srs = osr.SpatialReference() srs.ImportFromESRI([prj_txt]) if flags["w"]: print("wkt=%s" % srs.ExportToWkt()) if flags["p"]: print("proj4=%s" % srs.ExportToProj4()) srs.AutoIdentifyEPSG() try: int(srs.GetAuthorityCode(None)) epsg = srs.GetAuthorityCode(None) print("epsg=%s" % epsg) if flags["s"]: if isPermanent(): writeEPSGtoPEMANENT(epsg) else: grass.warning("Unable to access PERMANENT mapset") except: grass.error("EPSG code cannot be identified")
def export_legend(mapname, filename, width, height): # using png driver but need to set bg color if we want transparency # otherwise png driver will set pixels to ffffff and PIL will # not crop the legend _setEnvironment(width, height, filename, transparent=True, backgroud_color='000000', driver='png') returncode, stdout, messages = _read2_command('d.legend', rast=mapname) try: from PIL import Image image = Image.open(filename) imageBox = image.getbbox() cropped_image = image.crop(imageBox) cropped_image.save(filename, 'PNG') except ImportError, error: gcore.warning(_("Cannot crop legend image ({error})." " Maybe you don't have PIL." " Uncropped legend image will be used.") % error)
def OnServerList(self, event): # wxGlade: wmsFrame.<event_handler> """ @description: called on selection of a URL from ServerList(ComboBox) displayed. Sets self.selectedURL variable. @todo:None @param self: reference variable @param event: event associated. @return: None """ info = self.ServerList.GetValue() if len(info) == 0: return urlarr = info.split(self.name_url_delimiter) if len(urlarr) == 2: try: uid = self.map_servernameTouid[urlarr[0]] self.selectedURL = self.servers[uid].url except KeyError, e: message = "key error reported" grass.warning(message)
def main(): # get currently selected monitor monitor = check_monitor() if not monitor: fatal(_("No graphics device selected. Use d.mon to select graphics device.")) if flags['e']: # remove frames and erase monitor and exit erase(monitor) return if flags['p']: # print current frame and exit print_frames(monitor, current_only=True) return if flags['a']: # print all frames including their position and exit print_frames(monitor, current_only=False, full=True) return found = find_frame(monitor, options['frame']) if not found: if not flags['c']: fatal(_("Frame <%s> doesn't exist, exiting. " "To create a new frame use '-c' flag.") % options['frame']) else: if not options['at']: fatal(_("Required parameter <%s> not set") % "at") # create new frame if not exists create_frame(monitor, options['frame'], options['at']) else: if os.getenv('GRASS_OVERWRITE', '0') == '1': warning(_("Frame <%s> already exists and will be overwritten") % options['frame']) create_frame(monitor, options['frame'], options['at'], overwrite=True) else: if options['at']: warning(_("Frame <%s> already found. An existing frame can be overwritten by '%s' flag.") % \ (options['frame'], "--overwrite")) # select givenframe select_frame(monitor, options['frame'])
def patch_analysis_per_subregion(development_diff, subregions, threshold, tmp_clump, tmp_clump_cat): gcore.run_command("r.clump", input=development_diff, output=tmp_clump, overwrite=True, quiet=True) cats = (gcore.read_command("r.describe", flags="1n", map=subregions, quiet=True).strip().splitlines()) subregions_data = {} env = os.environ.copy() for cat in cats: grast.mapcalc( "{new} = if ({reg} == {cat}, {clump}, null())".format( new=tmp_clump_cat, reg=subregions, cat=cat, clump=tmp_clump), overwrite=True, ) env["GRASS_REGION"] = gcore.region_env(zoom=tmp_clump_cat) try: data = gcore.read_command( "r.object.geometry", input=tmp_clump_cat, flags="m", separator="comma", env=env, quiet=True, ).strip() data = np.loadtxt(StringIO(data), delimiter=",", usecols=(1, 2), skiprows=1) # in case there is just one record data = data.reshape((-1, 2)) subregions_data[cat] = data[data[:, 0] > threshold] except CalledModuleError: gcore.warning( "Subregion {cat} has no changes in development, no patches found." .format(cat=cat)) subregions_data[cat] = np.empty([0, 2]) return subregions_data
def UnregisterMouseEventHandler(self, event, handler): """Unbinds event handler for event @depreciated This method is depreciated. Use Signals or drawing API instead. Before handler is unregistered it is called with string value "unregistered" of event parameter. Emits mouseHandlerUnregistered signal after handler is unregistered. :param handler: handler to unbind :param event: event from which handler will be unbinded :return: True if successful :return: False if event cannot be unbind """ # removes handler from list for containerEv, handlers in self.handlersContainer.iteritems(): if event != containerEv: continue try: handler("unregistered") if handler in handlers: handlers.remove(handler) else: grass.warning(_("Handler: %s was not registered") \ % handler.__name__) except: GError(parent = self, message = _("Error occurred during unregistration of handler: %s \n \ Handler was unregistered") % handler.__name__) handlers.remove(handler) # restore mouse use (previous state) self.mouse['use'] = self.mouse['useBeforeGenericEvent'] # restore overridden cursor if self._overriddenCursor: self.SetNamedCursor(self._overriddenCursor) self.mouseHandlerUnregistered.emit() return True
def remove_extension(force = False): if flags['t']: mlist = get_toolbox_modules(options['extension']) else: mlist = [options['extension']] if force: grass.verbose(_("List of removed files:")) else: grass.info(_("Files to be removed (use flag 'f' to force removal):")) remove_modules(mlist, force) if force: grass.message(_("Updating metadata file...")) remove_extension_xml(mlist) grass.message(_("Extension <%s> successfully uninstalled.") % options['extension']) else: grass.warning(_("Extension <%s> not removed.\n" "Re-run '%s' with 'f' flag to force removal") % (options['extension'], 'g.extension'))
def grassEpsg(): proj = Module("g.proj", flags="p", quiet=True, stdout_=PIPE) proj = proj.outputs.stdout lines = proj.splitlines() for e, line in enumerate(lines): if "EPSG" in line: epsg = lines[e + 1].split(":")[1].replace(" ", "") print("epsg=%s" % epsg) if flags["s"]: if isPermanent(): writeEPSGtoPEMANENT(epsg) else: grass.warning("Unable to access PERMANENT mapset") return try: proj = Module("g.proj", flags="wf", quiet=True, stdout_=PIPE) proj = proj.outputs.stdout wkt2standards(proj) except: grass.error("WKT input error")
def grassEpsg(): proj = Module('g.proj', flags='p', quiet=True, stdout_=PIPE) proj = proj.outputs.stdout lines = proj.splitlines() for e, line in enumerate(lines): if 'EPSG' in line: epsg = lines[e + 1].split(':')[1].replace(' ', '') print('epsg=%s' % epsg) if flags['s']: if isPermanent(): writeEPSGtoPEMANENT(epsg) else: grass.warning("Unable to access PERMANENT mapset") return try: proj = Module('g.proj', flags='wf', quiet=True, stdout_=PIPE) proj = proj.outputs.stdout wkt2standards(proj) except: grass.error('WKT input error')
def UnregisterMouseEventHandler(self, event, handler): """!Unbinds event handler for event Before handler is unregistered it is called with string value "unregistered" of event parameter. @param handler handler to unbind @param event event from which handler will be unbinded @return True if successful @return False if event cannot be unbind """ # removes handler from list for containerEv, handlers in self.handlersContainer.iteritems(): if event != containerEv: continue try: handler("unregistered") if handler in handlers: handlers.remove(handler) else: grass.warning( _("Handler: %s was not registered") % handler.__name__) except: GError( parent=self, message=_( "Error occured during unregistration of handler: %s \n \ Handler was unregistered") % handler.__name__, ) handlers.remove(handler) # restore mouse use (previous state) self.mouse["use"] = self.mouse["useBeforeGenericEvent"] # restore overridden cursor if self._overriddenCursor: self.SetCursor(self._overriddenCursor) return True
def main(): env = grass.gisenv() mapset = env["MAPSET"] converted = 0 ret = 0 for vect in grass.list_grouped("oldvect")[mapset]: inmap = "%s@%s" % (vect, mapset) outmap = vect.replace(".", "_") if grass.run_command("v.convert", input=inmap, output=outmap) == 0: converted += 1 else: grass.warning(_("Error converting map <%s> to <%s>") % (inmap, outmap)) ret = 1 if converted < 1: grass.warning(_("No vector maps converted as no old vector maps present in current mapset.")) else: grass.message(_("Total %u vector maps in current mapset converted.") % converted) grass.message(_("Please verify new vector map(s) before deleting old vector map(s).")) sys.exit(ret)
def install_extension(): gisbase = os.getenv('GISBASE') if not gisbase: grass.fatal(_('$GISBASE not defined')) if options['extension'] in get_installed_extensions(force = True): grass.warning(_("Extension <%s> already installed. Re-installing...") % options['extension']) if sys.platform == "win32": ret = install_extension_win() else: ret = install_extension_other() if ret != 0: grass.warning(_('Installation failed, sorry. Please check above error messages.')) else: grass.message(_("Updating metadata file...")) install_extension_xml() grass.message(_("Installation of <%s> successfully finished") % options['extension']) # cleanup build cruft if not flags['s']: tidy_citizen() if not os.environ.has_key('GRASS_ADDON_PATH') or \ not os.environ['GRASS_ADDON_PATH']: grass.warning(_('This add-on module will not function until you set the ' 'GRASS_ADDON_PATH environment variable (see "g.manual variables")'))
def _writeEnvFile(self, data): """!Write display-related variable to the file (used for standalone app) """ if not self.envfile: return try: fd = open(self.envfile, "r") for line in fd.readlines(): key, value = line.split('=') if key not in data.keys(): data[key] = value fd.close() fd = open(self.envfile, "w") for k, v in data.iteritems(): fd.write('%s=%s\n' % (k.strip(), str(v).strip())) except IOError, e: grass.warning(_("Unable to open file '%(file)s' for writting. Details: %(det)s") % \ { 'cmd' : self.envfile, 'det' : e }) return
def list_available_modules(): mlist = list() grass.message(_('Fetching list of modules from GRASS-Addons SVN (be patient)...')) pattern = re.compile(r'(<li><a href=".+">)(.+)(</a></li>)', re.IGNORECASE) i = 0 prefix = ['d', 'db', 'g', 'i', 'm', 'ps', 'p', 'r', 'r3', 's', 'v'] nprefix = len(prefix) for d in prefix: if flags['g']: grass.percent(i, nprefix, 1) i += 1 modclass = expand_module_class_name(d) grass.verbose(_("Checking for '%s' modules...") % modclass) url = '%s/%s' % (options['svnurl'], modclass) grass.debug("url = %s" % url, debug = 2) f = urllib.urlopen(url) if not f: grass.warning(_("Unable to fetch '%s'") % url) continue for line in f.readlines(): # list modules sline = pattern.search(line) if not sline: continue name = sline.group(2).rstrip('/') if name.split('.', 1)[0] == d: print_module_desc(name, url) mlist.append(name) mlist += list_wxgui_extensions() if flags['g']: grass.percent(1, 1, 1) return mlist
def RenderProcess2D(imageWidth, imageHeight, tempDir, cmd, region, bgcolor, fileQueue): """Render raster or vector files as ppm image and write the resulting ppm filename in the provided file queue :param imageWidth: image width :param imageHeight: image height :param tempDir: directory for rendering :param cmd: d.rast/d.vect command as a list :param region: region as a dict or None :param bgcolor: background color as a tuple of 3 values 0 to 255 :param fileQueue: the inter process communication queue storing the file name of the image """ filename = GetFileFromCmd(tempDir, cmd, region) transparency = True # Set the environment variables for this process _setEnvironment(imageWidth, imageHeight, filename, transparent=transparency, bgcolor=bgcolor) if region: os.environ["GRASS_REGION"] = gcore.region_env(**region) cmdTuple = cmdlist_to_tuple(cmd) returncode, stdout, messages = read2_command(cmdTuple[0], **cmdTuple[1]) if returncode != 0: gcore.warning("Rendering failed:\n" + messages) fileQueue.put(None) if region: os.environ.pop("GRASS_REGION") os.remove(filename) return if region: os.environ.pop("GRASS_REGION") fileQueue.put(filename)
def main(): env = grass.gisenv() mapset = env['MAPSET'] converted = 0 ret = 0 for site in grass.list_grouped('sites')[mapset]: inmap = "%s@%s" % (site, mapset) outmap = site.replace(".", "_") + "_points" grass.message(_("Processing %s -> %s") % (inmap, outmap)) if grass.run_command("v.in.sites", input = inmap, output = outmap) == 0: converted += 1 else: grass.warning(_("Error converting map %s to %s") % (inmap, outmap)) ret = 1 if converted < 1: grass.warning(_("No sites maps converted as no old sites maps present in current mapset.")) else: grass.message(_("Total %u sites maps in current mapset converted to vector maps (original names extended by '_points')") % converted) grass.message(_("Please verify new vector map(s) before deleting old sites map(s).")) sys.exit(ret)
def list_available_extensions_svn(): mlist = list() grass.message(_('Fetching list of extensions from GRASS-Addons SVN (be patient)...')) pattern = re.compile(r'(<li><a href=".+">)(.+)(</a></li>)', re.IGNORECASE) if flags['c']: grass.warning(_("Flag 'c' ignored, metadata file not available")) if flags['g']: grass.warning(_("Flag 'g' ignored, metadata file not available")) prefix = ['d', 'db', 'g', 'i', 'm', 'ps', 'p', 'r', 'r3', 's', 'v'] nprefix = len(prefix) for d in prefix: modclass = expand_module_class_name(d) grass.verbose(_("Checking for '%s' modules...") % modclass) url = '%s/%s' % (options['svnurl'], modclass) grass.debug("url = %s" % url, debug = 2) try: f = urlopen(url) except HTTPError: grass.debug(_("Unable to fetch '%s'") % url, debug = 1) continue for line in f.readlines(): # list extensions sline = pattern.search(line) if not sline: continue name = sline.group(2).rstrip('/') if name.split('.', 1)[0] == d: print name mlist.append(name) mlist += list_wxgui_extensions() return mlist
def patch_analysis(development_diff, threshold, tmp_clump): gcore.run_command('r.clump', input=development_diff, output=tmp_clump, overwrite=True, quiet=True) try: data = gcore.read_command('r.object.geometry', input=tmp_clump, flags='m', separator='comma', quiet=True).strip() data = np.loadtxt(StringIO(data), delimiter=',', usecols=(1, 2), skiprows=1) # in case there is just one record data = data.reshape((-1, 2)) data = data[data[:, 0] > threshold] except CalledModuleError: gcore.warning("No changes in development, no patches found.") data = np.empty([0, 2]) return data
def drop(self, cursor=None, force=False): """Method to drop table from database :param cursor: the cursor to connect, if None it use the cursor of connection table object :type cursor: Cursor object :param force: True to remove the table, by default False to print advice :type force: bool """ cur = cursor if cursor else self.conn.cursor() if self.exist(cursor=cur): used = db_table_in_vector(self.name) if used is not None and len(used) > 0 and not force: print(_("Deleting table <%s> which is attached" " to following map(s):") % self.name) for vect in used: warning("%s" % vect) print(_("You must use the force flag to actually" " remove it. Exiting.")) else: cur.execute(sql.DROP_TAB.format(tname=self.name))
def drop(self, cursor=None, force=False): """Method to drop table from database :param cursor: the cursor to connect, if None it use the cursor of connection table object :type cursor: Cursor object :param force: True to remove the table, by default False to print advice :type force: bool """ cur = cursor if cursor else self.conn.cursor() if self.exist(cursor=cur): used = db_table_in_vector(self.name) if len(used) > 0 and not force: print(_("Deleting table <%s> which is attached" " to following map(s):") % self.name) for vect in used: warning("%s" % vect) print(_("You must use the force flag to actually" " remove it. Exiting.")) else: cur.execute(sql.DROP_TAB.format(tname=self.name))
def get_wxgui_extensions(): mlist = list() grass.debug('Fetching list of wxGUI extensions from GRASS-Addons SVN repository (be patient)...') pattern = re.compile(r'(<li><a href=".+">)(.+)(</a></li>)', re.IGNORECASE) grass.verbose(_("Checking for '%s' modules...") % 'gui/wxpython') url = '%s/%s' % (options['svnurl'], 'gui/wxpython') grass.debug("url = %s" % url, debug = 2) f = urlopen(url, proxies=PROXIES) if not f: grass.warning(_("Unable to fetch '%s'") % url) return for line in f.readlines(): # list extensions sline = pattern.search(line) if not sline: continue name = sline.group(2).rstrip('/') if name not in ('..', 'Makefile'): mlist.append(name) return mlist
def saveXMLData(self): """ @description: Saves the information (soup) , in the file ServersList.xml. @todo:None @param self: reference variable @return: Boolean, True if save is successful else returns False. """ xml = self.soup.prettify() try: TMP = grass.tempfile() if TMP is None: grass.fatal_error(_("Unable to create temporary files")) f = open(TMP, 'w') f.write(xml) f.close() except: message = _( 'Unable to write in %s file. Save not successful') % TMP grass.warning(message) return False try: copyCommand = "cp " + TMP + " ServersList.xml" # FIXME r, w, e = popen2.popen3(copyCommand) if len(e.readlines()) != 0: message = 'Copy failed, raising excpetion in savexml()' grass.warning(message) r.close() w.close() e.close() raise Exception r.close() w.close() e.close() except: return False return True
def updateData(data, modules): """Update menu data tree""" # list of modules to be ignored ignore = ['v.type_wrapper.py', 'vcolors'] menu_modules = list() for node in data.tree.getiterator(): if node.tag != 'menuitem': continue item = dict() for child in node.getchildren(): item[child.tag] = child.text if 'command' not in item: continue if item['command'] in ignore: continue module = item['command'].split(' ')[0] if module not in modules: grass.warning("'%s' not found in modules" % item['command']) continue if modules[module]['label']: desc = modules[module]['label'] else: desc = modules[module]['desc'] if node.find('handler').text == 'OnMenuCmd': node.find('help').text = desc if 'keywords' not in modules[module]: grass.warning('%s: keywords missing' % module) else: if node.find('keywords') is None: node.insert(2, etree.Element('keywords')) grass.warning("Adding tag 'keywords' to '%s'" % module) node.find('keywords').text = ','.join(modules[module]['keywords']) menu_modules.append(item['command']) for module in modules.keys(): if module not in menu_modules: grass.warning("'%s' not available from the menu" % module)
def _parseCmdFile(self): """!Parse cmd file for standalone application """ nlayers = 0 try: fd = open(self.cmdfile, 'r') grass.try_remove(self.mapfile) cmdLines = fd.readlines() gcmd.RunCommand('g.gisenv', set = 'MONITOR_%s_CMDFILE=' % self.monitor) for cmd in cmdLines: cmdStr = cmd.strip().split(' ') cmd = utils.CmdToTuple(cmdStr) gcmd.RunCommand(cmd[0], **cmd[1]) nlayers += 1 gcmd.RunCommand('g.gisenv', set = 'MONITOR_%s_CMDFILE=%s' % (self.monitor, self.cmdfile)) except IOError, e: grass.warning(_("Unable to read cmdfile '%(cmd)s'. Details: %(det)s") % \ { 'cmd' : self.cmdfile, 'det' : e }) return
def get_installed_extensions(force = False): fXML = os.path.join(options['prefix'], 'modules.xml') if not os.path.exists(fXML): if force: write_xml_modules(fXML) else: grass.warning(_("No metadata file available")) return [] # read XML file fo = open(fXML, 'r') try: tree = etree.fromstring(fo.read()) except: os.remove(fXML) write_xml_modules(fXML) return [] fo.close() ret = list() for tnode in tree.findall('task'): ret.append(tnode.get('name').strip()) return ret
def watcher(self): """Redraw, if new layer appears (check's timestamp of cmdfile) """ try: # GISBASE and other sytem enviromental variables can not be used # since the process inherited them from GRASS # raises exception when vaiable does not exists grass.gisenv()['GISDBASE'] except KeyError: self.timer.Stop() return # todo: events try: currentCmdFileTime = os.path.getmtime(monFile['cmd']) if currentCmdFileTime > self.cmdTimeStamp: self.timer.Stop() self.cmdTimeStamp = currentCmdFileTime self.mapFrm.GetMap().GetLayersFromCmdFile() self.timer.Start(mtime) except OSError as e: grass.warning("%s" % e) self.timer.Stop()
def RenderProcess3D(imageWidth, imageHeight, tempDir, cmd, region, bgcolor, fileQueue): """Renders image with m.nviz.image and writes the resulting ppm filename in the provided file queue :param imageWidth: image width :param imageHeight: image height :param tempDir: directory for rendering :param cmd: m.nviz.image command as a list :param region: region as a dict :param bgcolor: background color as a tuple of 3 values 0 to 255 :param fileQueue: the inter process communication queue storing the file name of the image """ filename = GetFileFromCmd(tempDir, cmd, None) os.environ["GRASS_REGION"] = gcore.region_env(region3d=True, **region) Debug.msg(1, "Render image to file " + str(filename)) cmdTuple = cmdlist_to_tuple(cmd) cmdTuple[1]["output"] = os.path.splitext(filename)[0] # set size cmdTuple[1]["size"] = "%d,%d" % (imageWidth, imageHeight) # set format cmdTuple[1]["format"] = "ppm" cmdTuple[1]["bgcolor"] = bgcolor = ":".join( [str(part) for part in bgcolor]) returncode, stdout, messages = read2_command(cmdTuple[0], **cmdTuple[1]) if returncode != 0: gcore.warning("Rendering failed:\n" + messages) fileQueue.put(None) os.environ.pop("GRASS_REGION") return os.environ.pop("GRASS_REGION") fileQueue.put(filename)
def updateData(data, modules): """Update menu data tree""" # list of modules to be ignored ignore = ["v.type_wrapper.py", "vcolors"] menu_modules = list() for node in data.tree.iter(): if node.tag != "menuitem": continue item = dict() for child in node: item[child.tag] = child.text if "command" not in item: continue if item["command"] in ignore: continue module = item["command"].split(" ")[0] if module not in modules: grass.warning("'%s' not found in modules" % item["command"]) continue if modules[module]["label"]: desc = modules[module]["label"] else: desc = modules[module]["desc"] if node.find("handler").text == "OnMenuCmd": node.find("help").text = desc if "keywords" not in modules[module]: grass.warning("%s: keywords missing" % module) else: if node.find("keywords") is None: node.insert(2, etree.Element("keywords")) grass.warning("Adding tag 'keywords' to '%s'" % module) node.find("keywords").text = ",".join(modules[module]["keywords"]) menu_modules.append(item["command"]) for module in modules.keys(): if module not in menu_modules: grass.warning("'%s' not available from the menu" % module)
def main(): # check dependecies if sys.platform != "win32": check_progs() # define path if flags['s']: options['prefix'] = os.environ['GISBASE'] if options['prefix'] == '$GRASS_ADDON_PATH': if not os.environ.has_key('GRASS_ADDON_PATH') or \ not os.environ['GRASS_ADDON_PATH']: major_version = int(grass.version()['version'].split('.', 1)[0]) grass.warning(_("GRASS_ADDON_PATH is not defined, " "installing to ~/.grass%d/addons/") % major_version) options['prefix'] = os.path.join(os.environ['HOME'], '.grass%d' % major_version, 'addons') else: path_list = os.environ['GRASS_ADDON_PATH'].split(os.pathsep) if len(path_list) < 1: grass.fatal(_("Invalid GRASS_ADDON_PATH value - '%s'") % os.environ['GRASS_ADDON_PATH']) if len(path_list) > 1: grass.warning(_("GRASS_ADDON_PATH has more items, using first defined - '%s'") % path_list[0]) options['prefix'] = path_list[0] # list available modules if flags['l'] or flags['c'] or flags['g']: list_available_extensions() return 0 elif flags['a']: elist = get_installed_extensions() if elist: grass.message(_("List of installed extensions:")) sys.stdout.write('\n'.join(elist)) sys.stdout.write('\n') else: grass.info(_("No extension installed")) return 0 else: if not options['extension']: grass.fatal(_('You need to define an extension name or use -l')) if flags['d']: if options['operation'] != 'add': grass.warning(_("Flag 'd' is relevant only to 'operation=add'. Ignoring this flag.")) else: global remove_tmpdir remove_tmpdir = False if options['operation'] == 'add': check_dirs() install_extension() else: # remove remove_extension(flags['f']) return 0